Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 23 additions & 1 deletion agent/agency-report
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ Custom buttons: pass --button (repeatable). Layout wraps in pairs of two.
Canonical card layout (HTML parse mode). Order is locked; the *number*
of expandable blocks is variable (0, 1, 2, N — your call):

[optional image]
[optional image — skip when text alone is clearer]
<emoji> <b>headline</b> ← write the specific action here:
"Reply to <user> on Slack: …" or
"Merge PR #347" — *not* "Agency 95"
Expand All @@ -52,6 +52,17 @@ Blocks are specified one of two ways:
three variants A/B/C, or a single "context" block, or zero blocks
(--info-only with just headline + source link).

Yes-tap routing:
• Default — Yes / Edit dispatch in the SAME thread the card lives in.
Follow-up cards inside an existing worker topic don't spawn nested
topics; the conversation stays continuous.
• --spawn-topic — Yes / Edit create a fresh forum topic and dispatch
the lane there instead. Use for the /agency loop's half-hourly cards
(so each cycle's cards live in their own threads) and for any other
case where the work warrants a dedicated topic. Agents inside an
existing worker topic may also set this to fork sub-tasks into yet
another topic — there is no auto-protection against that.

If --image (URL), --image-file (local path), or --image-text (auto-rendered
placeholder) is given, the image renders above the body. For bodies that
fit Telegram's 1024-char caption budget the card is sent via sendPhoto;
Expand Down Expand Up @@ -531,6 +542,16 @@ def main() -> int:
action="store_true",
help="Drop the inline keyboard entirely (FYI cards with no action).",
)
p.add_argument(
"--spawn-topic",
action="store_true",
help="On Yes/Edit tap, spawn a fresh forum topic and dispatch "
"the lane there. Default: run in-place in the current thread. "
"Set this on agency-loop cards (so each cycle's cards live in "
"their own topics) and any other case where the work warrants "
"a dedicated thread. Agents inside an existing worker topic "
"may also set this to fork sub-tasks into yet another topic.",
)
p.add_argument(
"--thread-id",
type=int,
Expand Down Expand Up @@ -573,6 +594,7 @@ def main() -> int:
buttons=button_labels_for_db,
chat_id=chat_id(),
thread_id=args.thread_id,
spawn_topic=args.spawn_topic,
)

body = _build_body(args)
Expand Down
18 changes: 15 additions & 3 deletions agent/agency_db.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ def init_schema(db: sqlite3.Connection) -> None:
title TEXT NOT NULL,
description TEXT NOT NULL,
importance TEXT CHECK (importance IN ('high','med','low')) DEFAULT 'med',
source TEXT, -- e.g. slack-c-minerva, gmail-thread-19df, gh-pr-78
source TEXT, -- e.g. slack-c-foo, gmail-thread-19df, gh-pr-78
prompt TEXT, -- the action that would run if user says yes
buttons_json TEXT, -- JSON list of the labels shown
tg_chat_id INTEGER,
Expand All @@ -69,6 +69,7 @@ def init_schema(db: sqlite3.Connection) -> None:
worker_topic_id INTEGER, -- TG topic where the resulting agent runs
worker_started_at INTEGER,
worker_completed_at INTEGER,
spawn_topic INTEGER NOT NULL DEFAULT 0, -- 1 = Yes-tap creates a fresh topic; 0 = run in-place
created_at INTEGER NOT NULL DEFAULT (CAST(strftime('%s','now') AS INTEGER)),
updated_at INTEGER NOT NULL DEFAULT (CAST(strftime('%s','now') AS INTEGER))
);
Expand All @@ -79,6 +80,15 @@ def init_schema(db: sqlite3.Connection) -> None:
CREATE INDEX IF NOT EXISTS idx_sugg_worker_topic ON suggestions(worker_topic_id);
"""
)
# Backfill spawn_topic on pre-existing tables. ALTER TABLE has no
# IF NOT EXISTS — swallow the duplicate-column error from re-runs.
try:
db.execute(
"ALTER TABLE suggestions ADD COLUMN spawn_topic INTEGER NOT NULL DEFAULT 0"
)
except sqlite3.OperationalError as e:
if "duplicate column" not in str(e).lower():
raise
db.commit()


Expand All @@ -97,13 +107,14 @@ def insert(
buttons: list[str] | None = None,
chat_id: int | None = None,
thread_id: int | None = None,
spawn_topic: bool = False,
) -> int:
cur = db.execute(
"""
INSERT INTO suggestions (
title, description, importance, source, prompt, buttons_json,
tg_chat_id, tg_thread_id
) VALUES (?, ?, ?, ?, ?, ?, ?, ?)
tg_chat_id, tg_thread_id, spawn_topic
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
""",
(
title,
Expand All @@ -114,6 +125,7 @@ def insert(
json.dumps(buttons) if buttons is not None else None,
chat_id,
thread_id,
1 if spawn_topic else 0,
),
)
db.commit()
Expand Down
Loading
Loading