Implement local sub-agent execution for OSS/Bedrock mode

- Fix start_agent tool mapping: route to Tool::StartAgent instead of
  dead-end Tool::Subagent so tool calls become executable actions
- Block start_agent until child finishes: parent waits for child
  conversation to complete and receives full output as tool result
- Fix tool result delivery: add StartAgent/StartAgentV2 cases to
  extract_tool_result_content so the model actually sees agent output
- Support parallel agent spawning: change StartAgent action phase from
  Serial to Parallel, and track multiple pending agents via Vec
- Mark child conversations as Success on EndTurn: emit
  ConversationStatus::Success when a child stream ends with no actions
- Skip orchestration SSE in local mode: prevent app freeze from trying
  to connect to non-existent server
- Remove send_message_to_agent and suggest_next_prompt from tool list:
  these require server infrastructure that doesn't exist in OSS mode
- Add "Waiting for sub-agents..." status message while agents process
- Fix child agent pane close: actually dismiss instead of re-hiding,
  track dismissed IDs to prevent re-creation on restart
- Fix cache_miss_tokens calculation and show per-block cache stats
- Add [tool-debug] logging throughout tool invocation pipeline

Bump version to 1.6.0.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Ryan Ward
2026-06-03 13:29:09 -05:00
co-authored by Claude Opus 4.6
parent 17ecf67970
commit a309006458
18 changed files with 458 additions and 114 deletions
+24
View File
@@ -2656,6 +2656,30 @@ impl BlocklistAIController {
"[bedrock-debug] AfterStreamFinished: NO actions to queue, was_passive={}, is_any_unfinished={}",
was_passive_request, is_any_exchange_unfinished
);
// If this is a child conversation (has a parent) and the
// stream ended with EndTurn and no actions, the child agent
// is done. Mark it as Success so the StartAgentExecutor
// can resolve and return the output to the parent.
let is_child = history_model
.as_ref(ctx)
.conversation(&conversation_id)
.and_then(|c| c.parent_conversation_id())
.is_some();
if is_child && !was_passive_request {
log::info!(
"[bedrock-debug] AfterStreamFinished: child conversation {:?} completed, setting status to Success",
conversation_id
);
history_model.update(ctx, |history_model, ctx| {
history_model.update_conversation_status(
self.terminal_view_id,
conversation_id,
crate::ai::agent::conversation::ConversationStatus::Success,
ctx,
);
});
}
}
// Cancelled streams will handle pending_response_stream updates synchronously.