Skip to content

feat(kanban): add inject_as_turn notification to trigger active agent turns - #54871

Closed
CarlitoDon wants to merge 3 commits into
NousResearch:mainfrom
CarlitoDon:feat/kanban-inject-as-turn
Closed

feat(kanban): add inject_as_turn notification to trigger active agent turns#54871
CarlitoDon wants to merge 3 commits into
NousResearch:mainfrom
CarlitoDon:feat/kanban-inject-as-turn

Conversation

@CarlitoDon

Copy link
Copy Markdown

Summary

Adds inject_as_turn flag to kanban notify subscriptions. When enabled, terminal-state notifications are injected as MessageEvent(internal=True) via adapter.handle_message() instead of a silent adapter.send(), so the gateway treats them as an inbound user message and triggers an active agent turn.

Changes

1. Schema: kanban_notify_subs table (hermes_cli/kanban_db.py)

  • Added inject_as_turn INTEGER NOT NULL DEFAULT 0 column
  • Includes self-healing migration for existing databases
  • Updated add_notify_sub() with inject_as_turn: bool = False parameter

2. CLI: notify-subscribe command (hermes_cli/kanban.py)

  • Added --inject flag
  • Passes inject_as_turn=True to DB layer

3. Notifier: kanban_watchers.py

When sub['inject_as_turn'] is true:

  • Builds SessionSource + MessageEvent(internal=True)
  • Calls adapter.handle_message() to inject as a user turn
  • Falls back to adapter.send() for non-inject subscriptions

Verified

  • Test task t_0add136d with --inject subscription confirmed working: gateway log shows inbound message: platform=telegram chat=8215203590 msg='✔ @coder ...' followed by response ready — Carlito processed and replied normally.

Copilot AI review requested due to automatic review settings June 29, 2026 11:52

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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_turn support to kanban notify subscriptions (DB schema + CLI flag) and taught the gateway notifier to inject notifications as inbound turns when enabled.
  • Refactored StreamingContextScrubber import timing in agent_init (lazy import inside init_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.

Comment thread toolsets.py
Comment on lines 78 to 82
# Computer use (macOS, gated on cua-driver being installed via check_fn)
"computer_use",
# Sequential Thinking MCP
"mcp_sequential_thinking_sequential_thinking",
]
Comment thread hermes_cli/commands.py
Comment on lines 549 to 552
_TELEGRAM_MENU_PRIORITY = (
# Custom pinned commands
"llm-wiki",
# Most-typed everyday commands first.
Comment on lines +391 to +406
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,
)
Comment thread hermes_cli/commands.py
Comment on lines +917 to +932
# 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
@alt-glitch alt-glitch added type/feature New feature or request P3 Low — cosmetic, nice to have comp/cron Cron scheduler and job management comp/gateway Gateway runner, session dispatch, delivery sweeper:risk-message-delivery Sweeper risk: may drop, duplicate, misroute, or suppress messages labels Jun 29, 2026

@tonydwb tonydwb left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 tonydwb left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 tonydwb left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

@teknium1

Copy link
Copy Markdown
Contributor

Thanks for the kanban notification work. This is now implemented on current main by a merged successor, so this PR is redundant.

@teknium1 teknium1 closed this Jul 15, 2026
@teknium1 teknium1 added sweeper:implemented-on-main Sweeper: behavior already present on current main sweeper:risk-session-state Sweeper risk: may lose/corrupt/mis-associate session or context state sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades sweeper:blast-moderate Sweeper blast radius: moderate — a subsystem or single platform labels Jul 15, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/cron Cron scheduler and job management comp/gateway Gateway runner, session dispatch, delivery P3 Low — cosmetic, nice to have sweeper:blast-moderate Sweeper blast radius: moderate — a subsystem or single platform sweeper:implemented-on-main Sweeper: behavior already present on current main sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades sweeper:risk-message-delivery Sweeper risk: may drop, duplicate, misroute, or suppress messages sweeper:risk-session-state Sweeper risk: may lose/corrupt/mis-associate session or context state type/feature New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants