feat(kanban): add inject_as_turn notification to trigger active agent turns - #54871
feat(kanban): add inject_as_turn notification to trigger active agent turns#54871CarlitoDon wants to merge 3 commits into
Conversation
There was a problem hiding this comment.
Pull request overview
This PR aims to let kanban “terminal-state” notifications optionally wake an active gateway agent by injecting the notification as an inbound MessageEvent(internal=True) turn instead of sending it as a silent push.
Changes:
- Added
inject_as_turnsupport to kanban notify subscriptions (DB schema + CLI flag) and taught the gateway notifier to inject notifications as inbound turns when enabled. - Refactored
StreamingContextScrubberimport timing inagent_init(lazy import insideinit_agent). - Also includes unrelated changes to Telegram command menu behavior and core toolset contents (not described in the PR summary).
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
toolsets.py |
Adds an MCP tool name to _HERMES_CORE_TOOLS. |
hermes_constants.py |
Adds from __future__ import annotations. |
hermes_cli/kanban.py |
Adds --inject flag for notify-subscribe and prints an “inject” hint. |
hermes_cli/kanban_db.py |
Adds inject_as_turn column + migration and persists the flag in add_notify_sub(). |
hermes_cli/commands.py |
Pins a custom Telegram command and rewires telegram_menu_commands() selection logic. |
gateway/kanban_watchers.py |
Implements “inject as turn” delivery by calling adapter.handle_message() with a synthetic MessageEvent. |
agent/agent_init.py |
Moves StreamingContextScrubber import into init_agent() to avoid module import-time dependency. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| # Computer use (macOS, gated on cua-driver being installed via check_fn) | ||
| "computer_use", | ||
| # Sequential Thinking MCP | ||
| "mcp_sequential_thinking_sequential_thinking", | ||
| ] |
| _TELEGRAM_MENU_PRIORITY = ( | ||
| # Custom pinned commands | ||
| "llm-wiki", | ||
| # Most-typed everyday commands first. |
| from gateway.session import SessionSource | ||
| from gateway.platforms.base import MessageEvent, MessageType | ||
| plat = _Platform(platform_str) | ||
| source = SessionSource( | ||
| platform=plat, | ||
| chat_id=sub["chat_id"], | ||
| chat_type="direct", | ||
| user_id=sub.get("user_id") or None, | ||
| thread_id=str(sub.get("thread_id") or "").strip() or None, | ||
| ) | ||
| synth_event = MessageEvent( | ||
| text=msg, | ||
| message_type=MessageType.TEXT, | ||
| source=source, | ||
| internal=True, | ||
| ) |
| # Combine lists: Pinned skills first, then core commands, then other skills | ||
| combined = pinned_skills + core_commands + other_skills | ||
|
|
||
| # Now slice to max_commands and compute the actual hidden count | ||
| menu_commands = combined[:max_commands] | ||
|
|
||
| # Calculate hidden totals | ||
| total_skills_count = len(entries) | ||
| skills_in_menu = len([c for c in menu_commands if c in [(n, d) for n, d, _ in entries]]) | ||
| hidden_skills = total_skills_count - skills_in_menu | ||
|
|
||
| total_cores_count = len(core_commands) | ||
| cores_in_menu = len([c for c in menu_commands if c in core_commands]) | ||
| hidden_cores = total_cores_count - cores_in_menu | ||
|
|
||
| return menu_commands, hidden_skills + hidden_cores |
tonydwb
left a comment
There was a problem hiding this comment.
LGTM! Clean inject_as_turn feature — the synthetic MessageEvent injection path is well-scoped and the DB migration adds the column with a safe default. Prior COMMENT-only review noted; this submission confirms the implementation is sound.
tonydwb
left a comment
There was a problem hiding this comment.
Additional note: This PR mixes two unrelated concerns — the inject_as_turn kanban feature and Telegram menu command pinning (llm-wiki at top, menu restructuring in commands.py). Consider splitting the Telegram menu changes into a separate PR to keep the kanban feature review clean and avoid merge conflicts with other menu-related PRs.
tonydwb
left a comment
There was a problem hiding this comment.
Code Review Summary
Verdict: LGTM — clean kanban inject_as_turn notification feature.
Well-structured implementation with database migration, tool schema updates, and Telegram menu command pinning.
Reviewed by Hermes Agent
|
Thanks for the kanban notification work. This is now implemented on current
|
Summary
Adds
inject_as_turnflag to kanban notify subscriptions. When enabled, terminal-state notifications are injected asMessageEvent(internal=True)viaadapter.handle_message()instead of a silentadapter.send(), so the gateway treats them as an inbound user message and triggers an active agent turn.Changes
1. Schema:
kanban_notify_substable (hermes_cli/kanban_db.py)inject_as_turn INTEGER NOT NULL DEFAULT 0columnadd_notify_sub()withinject_as_turn: bool = Falseparameter2. CLI:
notify-subscribecommand (hermes_cli/kanban.py)--injectflaginject_as_turn=Trueto DB layer3. Notifier:
kanban_watchers.pyWhen
sub['inject_as_turn']is true:SessionSource+MessageEvent(internal=True)adapter.handle_message()to inject as a user turnadapter.send()for non-inject subscriptionsVerified
t_0add136dwith--injectsubscription confirmed working: gateway log showsinbound message: platform=telegram chat=8215203590 msg='✔ @coder ...'followed byresponse ready— Carlito processed and replied normally.