feat(kanban): return agent-created task completions to origin#21523
feat(kanban): return agent-created task completions to origin#21523verkyyi wants to merge 2 commits into
Conversation
|
Reviewed this end-to-end — really want this landed because the missing-completion-notification gap is biting our team daily. Rebased onto current Overall LGTM with one blocker plus a few smaller concerns. Would love to see this merged. 🔴 Blocker
Scenario: user runs Suggested fix: conn.execute(
"""INSERT INTO kanban_notify_subs
(task_id, platform, chat_id, thread_id, user_id, notification_mode, origin_context)
VALUES (?, ?, ?, ?, ?, ?, ?)
ON CONFLICT(task_id, platform, chat_id, thread_id) DO UPDATE SET
notification_mode = excluded.notification_mode,
origin_context = COALESCE(excluded.origin_context, origin_context),
user_id = COALESCE(excluded.user_id, user_id)""",
(...),
)(Preserves 🟡 Concerns
✅ LGTM
@verkyyi thanks for putting this together. The blocker is a one-line conflict-clause swap; happy to push a fixup commit if it'd help unblock the merge. cc: maintainers — this is a real production issue for agent-orchestrated kanban workflows. |
|
Pushed a one-commit fixup against this branch (rebased on Branch: Change: Test: Happy to open this as a PR against your branch if that's easier than a cherry-pick — let me know. — Tem |
|
Thanks Theo — good catch on the duplicate subscription path. I pulled in the important behavior from your rebase branch: duplicate notify subscriptions now use an upsert instead of I also addressed the concurrency concern from my local patches in this PR branch: synthesis/native turns for the same origin session now serialize on the active origin session lock, while notifications for unrelated chats do not block behind that lock. Added tests for both the same-origin waiting case and the unrelated-chat non-blocking case. Pushed the fix in I kept this focused to the blocker + concurrency issue. I did not add a separate bounded synthesis worker queue/thread-pool policy here; happy to do that as a follow-up if you think we should make that explicit in this PR. |
58b062c to
ed1a56b
Compare
|
Thanks @verkyyi — closing this one. Adding |
3592c35 removed the idempotent ALTER guards for notification_mode / origin_session_id / origin_profile / origin_context / request_id on the rationale that they were "in the base CREATE TABLE as of upstream v0.14.0." That premise is false: these columns are fork-local. PR NousResearch#21523 (which would add them upstream) is UNMERGED — even after the 2026-05-27 catchup to upstream/main @ 2d5dcfa, upstream's kanban_notify_subs base schema ships only notifier_profile. be4900d is our own commit / the PR head, not an upstream merge. Because the columns are in *our* base CREATE TABLE but not upstream's, and CREATE TABLE IF NOT EXISTS is a no-op against a table first created by an upstream-schema (or older-fork) checkout, these idempotent guards are the only thing that backfills the columns on such a DB. Restore them. Keep across upstream merges; retire only once PR NousResearch#21523 lands upstream. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…ord NousResearch#1 mixin-extraction plan - NousResearch#4: the entry claimed the five origin/mode columns were "in the base CREATE TABLE as of upstream v0.14.0" and the migration guards were redundant. False: the columns are fork-local; PR NousResearch#21523 is unmerged and upstream main @ 2d5dcfa ships only notifier_profile (verified). Retitle, document that the guards are fork-local and must survive upstream merges, reference the restoration (7ee0882). - NousResearch#1: record the planned KanbanNotifierMixin extraction (gateway/run.py is still the hot file post-merge; the notifier watcher is confirmed still there) and why a plugin/hook rewrite was rejected. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Records the redesign of the Kanban completion-notification path after upstream PR NousResearch#21523 was closed: replace the gateway-side LLM synthesis mixin with two primitives built on existing machinery — a kanban_decompose self-park/re-wake tool (generalizing upstream decompose_triage_task) and _wake_origin_session (re-enter the anchor handoff into the origin gateway session via the proven _process_handoff path). Collapses four fork-local notify-sub columns to upstream-identical, moves delivery mode to config, and rolls child progress onto the single anchor via the swarm blackboard. Both load-bearing claims and both open lifecycle/capability items verified against the code.
Summary
This PR tightens the loop for agent-driven Kanban orchestration so a normal user request can fan out to board tasks and still return results to the originating surface.
Included changes:
platform,chat_id,thread_id,user_id,session_id, and current user message excerpt) fromAIAgentthrough tool dispatch.notification_modefor Kanban subscriptions:direct,synthesize, orsilent.SendResult(success=False)as delivery failure so completion notifications are retried instead of silently dropped.Motivation / workflow
This is meant to support the workflow discussed in Discord:
The existing slash/CLI task creation path could subscribe an origin, but model-tool-created tasks from a normal/orchestrator chat did not have an equivalent generic return path. This PR stores enough provenance on the subscription to deliver the terminal event back to the routable chat/topic and optionally synthesize a clean user-facing completion.
Design notes
kanban_notify_subsgains generic provenance fields (notification_mode,origin_session_id,origin_profile,origin_context) with migration support.silentmode suppresses terminal pings but still lets code use the same subscription/cursor machinery.kanban.dispatch_in_gateway) so a secondary profile gateway does not consume shared notification rows intended for another bot. Operators can override withkanban.notify_in_gatewayorHERMES_KANBAN_NOTIFY_IN_GATEWAY.Explicitly excluded
This PR intentionally excludes local deployment/personal patches, including profile-specific Telegram/Weixin config, AgentFeeds tooling, cron/reporting setup, local dashboards, personal docs, model/provider config, and any machine-specific files.
Tests
python -m pytest tests/tools/test_kanban_tools.py tests/gateway/test_kanban_notifier.py -qgit diff --checkpython -m py_compile gateway/run.py hermes_cli/kanban_db.py model_tools.py run_agent.py tools/kanban_tools.py toolsets.py hermes_cli/tools_config.py tests/tools/test_kanban_tools.py tests/gateway/test_kanban_notifier.pyFollow-up design questions
This PR implements a conservative durable-board + notification return path. A deeper continuation model could still be discussed separately: should worker completion become active orchestrator-session context that triggers another orchestrator turn automatically, or should it remain durable board/session state until the user/orchestrator asks for follow-up?