|
Live tool visibility: pending cards, sub-agent step log
Backend: - ToolStarted event: emitted before tool execution begins so client can render a pending card with spinner immediately - ToolEvent gains is_subagent flag; ToolStarted same - current_event_sink ContextVar in tools/base.py — run_stream() sets it to an asyncio.Queue before create_task(); run_ephemeral() reads it and puts ToolStarted/ToolEvent into the queue as each sub-agent step runs - run_stream() tool loop: sequential execution via create_task() + polling drain loop (20ms sleep); yields ToolStarted → sub-agent events from sink → ToolEvent (completed) for each tool call - run_ephemeral() rewritten to inline sequential tool execution with sink emission (replaces _execute_tool_calls gather) - _run_single_tool() helper extracted for run_stream() - websocket.py handles tool_started and adds is_subagent to tool_call Frontend: - appendPendingToolCard(): creates card with spinner; spawn_agent opens body immediately to show sub-agent log as it fills - finalizeToolCard(): fills result, removes spinner, adds toggle; strips "[Sub-agent result — ...]" reminder prefix from displayed text - appendSubagentStep() / finalizeSubagentStep(): live step log inside spawn_agent card — each sub-agent tool call gets a ↳ row - app.js: tool_started → pending card; tool_call → finalize card; is_subagent routing to sub-step vs main card; abandonStream() resets pendingToolCard/pendingSubStep - CSS: .spinner-inline for card headers; .subagent-log / .subagent-step for nested step display; .tool-body-open for always-open spawn_agent body; .tool-card.pending suppresses chevron Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> |
|---|
|
|
| client/js/app.js |
|---|
| client/js/chat.js |
|---|
| client/style.css |
|---|
| navi/api/websocket.py |
|---|
| navi/core/agent.py |
|---|
| navi/core/events.py |
|---|
| navi/tools/base.py |
|---|