Skip to content

feat(examples/hermes): emit AX_GATEWAY_EVENT phase events for tool calls#84

Closed
madtank wants to merge 3 commits intocodex/gateway-control-plane-mvpfrom
orion/hermes-bridge-gateway-events
Closed

feat(examples/hermes): emit AX_GATEWAY_EVENT phase events for tool calls#84
madtank wants to merge 3 commits intocodex/gateway-control-plane-mvpfrom
orion/hermes-bridge-gateway-events

Conversation

@madtank
Copy link
Copy Markdown
Member

@madtank madtank commented Apr 22, 2026

Pipes hermes AIAgent tool_progress_callback into AX_GATEWAY_EVENT tool_start/tool_result pairs + wraps run with status started/thinking/completed/error events. Validated on dev.paxai.app via Gateway-managed dev_sentinel.

anvil and others added 3 commits April 22, 2026 02:48
The hermes_sentinel bridge was final-reply-only: no tool_call, no status,
no AX_GATEWAY_EVENT lines, so Gateway-managed hermes runtimes produced
blank phase bubbles in the UI even though the underlying AIAgent emits
tool_progress callbacks internally.

This pipes hermes's `tool_progress_callback` (AIAgent constructor param,
fires before each tool with (name, args_preview, args_dict)) into
AX_GATEWAY_EVENT `tool_start` / `tool_result` pairs so the UI chip shows
what the agent is doing in real time. Also emits `status` events for
started → thinking → completed / error phases wrapping the run, and
normalizes any run_conversation exception into a clean `error` status
event instead of letting the traceback escape to stderr (which Gateway
would otherwise post as the reply body).

Protocol consumed by Gateway runtime (see ax_cli/gateway.py):
- `AX_GATEWAY_EVENT {"kind":"status","status":"...","message":"..."}`
- `AX_GATEWAY_EVENT {"kind":"tool_start","tool_name":"...","tool_call_id":"...","status":"tool_call",...}`
- `AX_GATEWAY_EVENT {"kind":"tool_result","tool_name":"...","tool_call_id":"...","status":"tool_complete",...}`
Unprefixed stdout continues to accumulate into the final reply body.

Validated on dev.paxai.app: dev_sentinel registered with this bridge,
phase sequence reaches the pending bubble via agent_processing SSE.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…minal chatter doesn't leak into reply

Hermes's AIAgent prints progress animations ("deliberating...", tool
previews, "💻 $ pwd", "ಠ_ಠ computing...", etc.) to stdout even with
quiet_mode=True. Gateway captures unprefixed stdout as the reply body,
so the bubble was receiving Hermes's terminal chatter instead of the
actual final_response — e.g. "[tool] ٩(๑❛ᴗ❛๑)۶ deliberating... ┊ 💻 $
pwd 7.4s" as the user-visible reply.

Fix: capture _real_stdout before the run, redirect sys.stdout/sys.stderr
to /dev/null during run_conversation, emit AX_GATEWAY_EVENT lines and
the final reply via a dedicated writer bound to _real_stdout. Clean
separation: hermes's internal prints get swallowed, our phase events
and the real reply reach Gateway exactly once.

Validated on dev.paxai.app (dev_sentinel msg bf2c87b6):

    reply_sent | pong  cwd: `/home/ax-agent/agents/dev_sentinel`

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Instead of chip reading a generic "@x is using terminal...", surface the
specific command/file so the user sees what the agent is actually doing:

  terminal   + {command:"pwd"}    → "$ pwd"
  read_file  + {path:"AGENTS.md"} → "reading AGENTS.md"
  write_file + {path:"notes.md"}  → "writing notes.md"
  edit_file                       → "editing <path>"
  search/grep                     → "searching <pattern>"
  web_search                      → "web search: <query>"
  fetch                           → "fetching <url>"
  unknown tool                    → first scalar arg or "using <tool>"

Truncated to 80 chars at the emitter so the chip stays short.

Validated on dev.paxai.app (msg 71d14a1b multi-tool run):
  activity="reading /home/ax-agent/agents/dev_sentinel/AGENTS.md"
  activity="$ pwd"

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@madtank
Copy link
Copy Markdown
Member Author

madtank commented Apr 23, 2026

Superseded by #90, which ported these Hermes Gateway event commits onto current main and has now merged.

@madtank madtank closed this Apr 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant