Conversation
roborev: Combined Review (
|
|
Addressed the Codex subagent threading feedback in Fixes included:
|
roborev: Combined Review (
|
|
Latest roborev item from the PR thread is addressed in This follow-up makes the |
roborev: Combined Review (
|
|
Addressed the latest PR-thread roborev finding in This follow-up keeps terminal subagent notifications pending until the parser knows whether a later |
roborev: Combined Review (
|
|
Addressed the latest PR-thread roborev finding in This follow-up preserves chronology for no-wait fallback cases by reserving notification order and inserting the synthesized result back into the parsed stream at that original position when no later |
roborev: Combined Review (
|
|
Addressed the newest PR-thread roborev finding in This follow-up forces a full reparse when a late Codex |
roborev: Combined Review (
|
|
Im going back to the drawing board on the Codex subagent threading so this lands as a coherent fix instead of another incremental patch. The first few rounds showed that trying to force this workflow into the existing single-result pairing model is still leaving chronology/ownership edge cases, so Im reworking it more comprehensively before the next push. |
|
Superseded by #247. I kept running into ownership and chronology edge cases while trying to fit Codex subagent terminal status into the existing single Please review #247 instead of this branch for the current approach. |
Closes #233. Supersedes #242. ## Summary - model Codex subagent terminal status as first-class `tool_result_events` in SQLite and PostgreSQL - keep `tool_calls.result_content` as a derived/latest compatibility summary instead of the canonical storage shape - render the latest summary by default and expose full chronological subagent result history in the tool block UI - preserve event history across full resyncs, PG pushes, and orphan-copy recovery ## How This Differs From #242 `#242` tried to solve Codex subagent workflows inside the existing single-result model by: - rebinding `wait` / `<subagent_notification>` output into one mutable `tool_calls.result_content` - synthesizing tool-result-like transcript rows to preserve some ordering information - adding parser heuristics to decide which source should "own" the final blob That approach improved the raw JSON problem, but it kept running into ownership and chronology edge cases because Codex subagent status is not actually a single final blob. This PR switches to a different model: - add additive `tool_result_events` tables in both SQLite and PostgreSQL - attach chronological result events directly to the originating tool call - derive `tool_calls.result_content` from those events for compatibility/search/compact UI - keep the existing subagent session linkage on `spawn_agent` Practical effect: - chronology is preserved without retroactively mutating older transcript rows - `wait` output and fallback notifications are stored as canonical event history - PG-backed multi-host views and local SQLite views share the same result-event model ## Details - `spawn_agent` remains a `Task` tool call and still maps to `subagent_session_id` - terminal `wait` output becomes `tool_result_events` - terminal `<subagent_notification>` messages also become `tool_result_events` - blocked categories are enforced server-side for event history as well as the compact summary - orphan-copy / resync paths preserve stored event history for sessions whose source files no longer exist ## Upgrade / Rollout - SQLite: additive schema change plus `dataVersion` bump - PostgreSQL: additive schema change, no drop/recreate required - exporters should upgrade and run `agentsview pg push --full` once, or let the normal full-sync path re-export after resync Known limit: - sessions whose original Codex JSONL source is already gone can only preserve event history that was already stored in SQLite; they cannot derive brand new history from missing raw files ## Test Plan - `CC=/usr/bin/gcc CXX=/usr/bin/g++ CGO_ENABLED=1 go test -tags fts5 ./internal/parser ./internal/sync ./internal/db ./internal/postgres -count=1` - `cd frontend && npm test -- --run src/lib/components/content/ToolBlock.test.ts src/lib/utils/messages.test.ts` ## Local Review - local `codex`, `claude-code`, and `gemini` review runs covered both `default` and `security` - the first v2 pass surfaced issues around stale `tool_result_events`, blocked-category history leakage, and same-ordinal orphan chronology - those follow-up fixes are included in this branch
Closes #233.
Summary
spawn_agentcalls as real subagent-linked tool calls using existingsubagent_session_idplumbingwait/<subagent_notification>status into structured tool output instead of raw user-lane JSONdataVersionso upgraded hosts auto-resync and re-export historical file-backed Codex sessionsDetails
This PR teaches the Codex parser to preserve the information needed for the existing subagent UI path instead of dropping it on the floor:
function_callmessages now retaincall_idasToolUseIDspawn_agentis categorized as aTaskspawn_agentoutputs map the parent tool call to the child Codex session ID (codex:<agent_id>)waitterminal results become paired tool output<subagent_notification>becomes a fallback source of terminal output when no matchingwaitresult was recordedrunningnotifications are ignored so they do not suppress later completion/error resultsThe frontend also hides raw
<subagent_notification>transcript rows, so already-synced databases stop showing the JSON blobs immediately after upgrading.Upgrade / Rollout
dataVersionis bumped so upgraded hosts automatically perform a full local resyncagentsview pg pushalready forces a full PG push after a local resync, so exporters will re-export automatically on the next full push pathPractical effect for self-hosted PG users:
agentsview pg push --fullonce, or let the existing periodic exporter do the next full-sync cycleKnown limit:
function_call_outputlinkage dataTest Plan
CC=/usr/bin/gcc CXX=/usr/bin/g++ CGO_ENABLED=1 go test -tags fts5 ./internal/db -count=1CC=/usr/bin/gcc CXX=/usr/bin/g++ CGO_ENABLED=1 go test -tags fts5 ./internal/parser -count=1npm test -- --run src/lib/utils/messages.test.ts