TUI subagent history should render nickname/role instead of raw thread ids

Resolved 💬 2 comments Opened May 26, 2026 by iqdoctor Closed May 26, 2026

Summary

Subagent tool-call history can show raw thread IDs instead of the human-readable subagent nickname/role, even though the /agents picker already knows the labels.

Observed behavior

In the transcript history, newly spawned/waited subagents were rendered as UUIDs:

• Spawned 019e641a-860b-7c71-96bb-d4f3a3ba88f1 (gpt-5.5 high)
  └ CODE REVIEW TASK

• Spawned 019e641a-a268-7ba2-a9ef-c9ea813676b0 (gpt-5.5 high)
  └ ARCHITECTURE / DEVIL'S-ADVOCATE REVIEW TASK

• Waiting for 2 agents
  └ 019e641a-860b-7c71-96bb-d4f3a3ba88f1
    019e641a-a268-7ba2-a9ef-c9ea813676b0

But the /agents picker showed the same threads with readable labels:

6. • Hume [code-reviewer]      019e641a-860b-7c71-96bb-d4f3a3ba88f1
7. • Hilbert [architect]       019e641a-a268-7ba2-a9ef-c9ea813676b0

Why this is a problem

The raw UUIDs make multi-agent transcripts hard to read and audit. The user-visible history should use the same label contract as the agent picker when nickname/role metadata is available.

Root-cause hypothesis

The lower-level collab events already carry metadata such as new_agent_nickname, new_agent_role, receiver_agents, and agent_statuses, but the app-server ThreadItem::CollabAgentToolCall.agents_states shape does not preserve nickname/role metadata. The TUI then caches a receiver thread with empty metadata before rendering the tool-call history, so agent_label(...) falls back to the raw thread id.

Suggested fix outline

  • Preserve optional agent_nickname / agent_role on CollabAgentState.
  • Populate it from spawn-end, wait-begin, and wait-end collab events.
  • Let the TUI cache/upgrade receiver metadata from metadata-bearing collab notifications before rendering live and replayed history.
  • Keep UUID as fallback only when no metadata exists.

I have a candidate branch/PR ready for discussion with the implementation details and a focused diff.

View original on GitHub ↗

2 Comments

iqdoctor · 3 months ago

I could not open a PR directly against openai/codex because external fork PR creation is not permitted for this account:

GraphQL: iqdoctor does not have the correct permissions to execute `CreatePullRequest`

I prepared a fork PR with the candidate implementation here:

Core code shape:

let mut received_status = CollabAgentState::from(end_event.status.clone());
received_status.agent_nickname = end_event.new_agent_nickname.clone();
received_status.agent_role = end_event.new_agent_role.clone();

and for wait events:

CollabAgentState {
    status: CollabAgentStatus::PendingInit,
    message: None,
    agent_nickname: agent.agent_nickname.clone(),
    agent_role: agent.agent_role.clone(),
}

The TUI then caches/upgrades receiver metadata from CollabAgentToolCall.agents_states before rendering live/replayed history, so Spawned / Waiting for rows can use the same nickname/role labels as /agents and keep UUIDs only as fallback.

iqdoctor · 3 months ago

Update: after an OMX read-only review, I fixed the one stale test expectation in the fork branch. Current reference commit is d4b5392c6 on strato-space:fix/subagent-event-labels.

Validation available in my environment:

cargo fmt --all
cd .. && git diff --check origin/main...HEAD

Full Rust test execution remains blocked locally by missing OpenSSL development files (openssl.pc / libssl-dev), but the diff has been review-checked for the metadata propagation paths described above.