-
Notifications
You must be signed in to change notification settings - Fork 39
v5: heartbeat-by-default, copilot voice fix, autopilot security note #213
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: v4-split-and-trim
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -4809,6 +4809,35 @@ def _start_agency_goal_from_command( | |
| thread_id=goal_thread or thread_id, | ||
| ) | ||
|
|
||
| # Heartbeat: schedule a self-repeating tg-schedule for this topic so | ||
| # the bot, not the agent, drives proactive check-ins. Default cadence | ||
| # is 1 h. `tg-schedule-fire` re-queues itself when `repeat` is set, | ||
| # so this is fire-and-forget. The agent's system prompt does NOT | ||
| # tell it to self-schedule — the bot owns the cadence. | ||
| try: | ||
| env = os.environ.copy() | ||
| env["TG_CHAT_ID"] = str(chat_id) | ||
| env["TG_THREAD_ID"] = str(goal_thread or thread_id) | ||
| heartbeat_prompt = ( | ||
| f"[heartbeat] Continue working on this goal: {title}. " | ||
| "Scan connected sources for changes since the last cycle, " | ||
| "consult agency.db history, and surface the next concrete action under your current mode." | ||
| ) | ||
| subprocess.run( | ||
| [ | ||
| "/usr/local/bin/tg-schedule", | ||
| "+1 hour", | ||
| "--repeat", "+1 hour", | ||
| heartbeat_prompt, | ||
| ], | ||
| env=env, | ||
| check=False, | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. P2: Heartbeat scheduling errors are silently swallowed here, so cadence setup can fail without any log signal. Prompt for AI agents |
||
| stdout=subprocess.DEVNULL, | ||
| stderr=subprocess.DEVNULL, | ||
| ) | ||
| except Exception: | ||
| LOG.exception("goal: failed to schedule first heartbeat") | ||
|
|
||
| def _handle_my_chat_member(self, update: dict) -> None: | ||
| """React to the bot's own membership changing in some chat. | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -13,6 +13,7 @@ from __future__ import annotations | |||||
| import json | ||||||
| import os | ||||||
| import shutil | ||||||
| import subprocess | ||||||
| import sys | ||||||
| from datetime import datetime, timezone | ||||||
| from pathlib import Path | ||||||
|
|
@@ -122,6 +123,32 @@ def main() -> int: | |||||
| bot = Bot(token, setup_token) | ||||||
| bot.run_task((chat_id, thread_id), body, reply_to=None, sender=sender) | ||||||
|
|
||||||
| # Heartbeat mode: re-queue ourselves so the bot, not the agent, | ||||||
| # drives the next fire. tg-schedule's --repeat writes the interval | ||||||
| # into job.json. Inherits the same chat/thread context — the new | ||||||
| # at-job lives or dies on its own job dir. | ||||||
| repeat = str(job.get("repeat") or "").strip() | ||||||
| if repeat: | ||||||
| env = os.environ.copy() | ||||||
| env["TG_CHAT_ID"] = str(chat_id) | ||||||
| env["TG_THREAD_ID"] = str(thread_id) | ||||||
| try: | ||||||
| subprocess.run( | ||||||
| [ | ||||||
| "/usr/local/bin/tg-schedule", | ||||||
| repeat, | ||||||
| "--repeat", | ||||||
| repeat, | ||||||
| prompt, | ||||||
| ], | ||||||
| env=env, | ||||||
| check=False, | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. P1: Heartbeat re-queue failures are silently ignored because subprocess return codes are not checked while output is discarded. Prompt for AI agents
Suggested change
|
||||||
| stdout=subprocess.DEVNULL, | ||||||
| stderr=subprocess.DEVNULL, | ||||||
| ) | ||||||
| except Exception as exc: | ||||||
| print(f"tg-schedule-fire: heartbeat re-queue failed: {exc}", file=sys.stderr) | ||||||
|
|
||||||
| try: | ||||||
| shutil.rmtree(job_dir) | ||||||
| except Exception: | ||||||
|
|
||||||
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
P1: The new bot-level repeating heartbeat conflicts with the existing prompt instruction to self-schedule each cycle, which can create duplicate heartbeat chains.
Prompt for AI agents