Skip to content
This repository was archived by the owner on Jul 4, 2026. It is now read-only.

feat(codex_app_server): surface tool-progress events to the gateway display - #7

Merged
h4x3rotab merged 4 commits into
phalafrom
feat/codex-app-server-display
May 24, 2026
Merged

feat(codex_app_server): surface tool-progress events to the gateway display#7
h4x3rotab merged 4 commits into
phalafrom
feat/codex-app-server-display

Conversation

@h4x3rotab

Copy link
Copy Markdown

Summary

On the `codex_app_server` runtime, each turn currently runs as a silent black box from the user's perspective: `CodexAppServerSession` accepts an `on_event` display callback, but the callsite in `agent/codex_runtime.py` never passes one in. So the kawaii spinner / TUI tool lines / Telegram tool-progress bubbles that fire on the default `chat_completions` loop don't fire here — the user sees nothing until `turn/completed`.

This wires up the existing slot.

Changes

  • `agent/transports/codex_event_display.py` (new, ~210 lines) — `build_event_display_callback(agent)` translates codex `item/started` / `item/completed` notifications for tool-shaped items (`commandExecution`, `fileChange`, `mcpToolCall`, `dynamicToolCall`, `webSearch`) into the same `agent.tool_progress_callback("tool.started"/"tool.completed", ...)` + `tool_start_callback` + `tool_complete_callback` calls that `agent/tool_executor.py:161-175,386-393` already uses for the chat_completions loop. The gateway wiring at `gateway/run.py:15536` then routes through to TUI / Telegram / Discord unchanged — no other callsite needs to know.

  • `agent/codex_runtime.py` (+3/-1) — pass `on_event=build_event_display_callback(agent)` into the `CodexAppServerSession(...)` instantiation. While in this block, also swap `or os.getcwd()` for `or os.environ.get("TERMINAL_CWD")` so the cwd resolution honours the canonical `terminal.cwd` config (bridged to `$TERMINAL_CWD` by `gateway/run.py:611-657`, consumed by the terminal tool / code_execution / system_prompt / agent_init). codex_runtime joins the existing convention rather than reinventing. `CodexAppServerSession.init:175` already does `self._cwd = cwd or os.getcwd()` so removing the explicit fallback here is safe — falls back the same way.

  • `agent/transports/codex_app_server_session.py` (+13) — also invoke `self._on_event` in the approval-drain branch so notifications that arrive while waiting on an approval reply still surface. Without this the user sees a silent gap whenever codex pauses for permission.

  • `tests/agent/transports/test_codex_event_display.py` (new) — 18 mocked tests covering tool-shaped items, non-tool items (silent), error detection (`exitCode` / `status` / `error` / `success`), missing/throwing callbacks (defensive), orphan completed without started, unknown methods ignored.

Test plan

  • `pytest tests/agent/transports/test_codex_event_display.py tests/agent/transports/test_codex_app_server_session.py tests/agent/transports/test_codex_event_projector.py` → 96/96 pass (18 new + 78 pre-existing, no regressions).
  • Smoke-tested live on a k3s pod running this fork's image (hot-patched the three files in): turn through a Telegram chat shows tool-progress bubbles as the codex subprocess executes shell / apply_patch / mcp calls. Without the patch the chat is silent until completion.

Why now

`Clawdi-AI/hermes-agent:phala` already has Kingsley's commit `f4644c6cb` ("fix(runtime): route custom Codex Responses through app-server") which makes the codex_app_server runtime a real first-class path for custom providers. This PR fixes the visibility gap that lands users on a silent runtime — finishing the user-facing side of that work.

🤖 Generated with Claude Code

Loading
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants