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
Merged
Conversation
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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
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