Bump version to 1.6.3

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Ryan Ward
2026-06-12 14:17:06 -05:00
co-authored by Claude Opus 4.6
parent 4ba9706e35
commit 59cfd0e2f5
152 changed files with 8276 additions and 1664 deletions
+8 -2
View File
@@ -739,14 +739,20 @@ impl BlocklistAIActionExecutor {
);
match execution {
AnyActionExecution::NotReady => {
log::info!("[tool-debug] try_to_execute_action: NOT READY - action_id={:?}", action_id);
log::info!(
"[tool-debug] try_to_execute_action: NOT READY - action_id={:?}",
action_id
);
TryExecuteResult::NotExecuted {
reason: NotExecutedReason::NotReady,
action: Box::new(action_clone),
}
}
AnyActionExecution::InvalidAction => {
log::error!("[tool-debug] try_to_execute_action: INVALID ACTION - action_id={:?}", action_id);
log::error!(
"[tool-debug] try_to_execute_action: INVALID ACTION - action_id={:?}",
action_id
);
debug_assert!(false, "Tried to execute AIAgentAction with wrong executor.");
TryExecuteResult::NotExecuted {
reason: NotExecutedReason::NotReady,
@@ -55,7 +55,8 @@ impl AskUserQuestionExecutor {
// For child agent conversations, route the question to the parent
// for silent auto-answer instead of presenting UI to the user.
if let Some(parent_conversation_id) = self.parent_conversation_id(input.conversation_id, ctx)
if let Some(parent_conversation_id) =
self.parent_conversation_id(input.conversation_id, ctx)
{
let question_text = questions
.iter()
@@ -86,14 +87,12 @@ impl AskUserQuestionExecutor {
async move { receiver.recv().await },
|result, _ctx| match result {
Ok(AskUserQuestionDecision::Completed(answers)) => {
AIAgentActionResultType::AskUserQuestion(
AskUserQuestionResult::Success { answers },
)
AIAgentActionResultType::AskUserQuestion(AskUserQuestionResult::Success {
answers,
})
}
Ok(AskUserQuestionDecision::Cancelled) | Err(_) => {
AIAgentActionResultType::AskUserQuestion(
AskUserQuestionResult::Cancelled,
)
AIAgentActionResultType::AskUserQuestion(AskUserQuestionResult::Cancelled)
}
},
);
@@ -141,12 +141,18 @@ impl CallMCPToolExecutor {
};
let Some(reconnecting_peer) = templatable_peer else {
log::error!("[tool-debug] CallMCPToolExecutor: MCP server for tool '{}' NOT FOUND", name_owned);
log::error!(
"[tool-debug] CallMCPToolExecutor: MCP server for tool '{}' NOT FOUND",
name_owned
);
return ActionExecution::Sync(AIAgentActionResultType::CallMCPTool(
CallMCPToolResult::Error("MCP server for tool not found".to_owned()),
));
};
log::info!("[tool-debug] CallMCPToolExecutor: found MCP server peer for tool '{}'", name_owned);
log::info!(
"[tool-debug] CallMCPToolExecutor: found MCP server peer for tool '{}'",
name_owned
);
let name_owned_inner = name_owned.clone();
ActionExecution::new_async(
@@ -111,7 +111,11 @@ impl FileGlobExecutor {
else {
return ActionExecution::InvalidAction;
};
log::info!("[tool-debug] FileGlobExecutor::execute: patterns={:?}, path={:?}", patterns, path);
log::info!(
"[tool-debug] FileGlobExecutor::execute: patterns={:?}, path={:?}",
patterns,
path
);
// If the path is not provided, use the current working directory.
let path = path.clone().unwrap_or_else(|| ".".to_string());
@@ -252,7 +252,11 @@ impl GrepExecutor {
else {
return ActionExecution::InvalidAction;
};
log::info!("[tool-debug] GrepExecutor::execute: queries={:?}, path={:?}", queries, path);
log::info!(
"[tool-debug] GrepExecutor::execute: queries={:?}, path={:?}",
queries,
path
);
let shell_launch_data = self.active_session.as_ref(ctx).shell_launch_data(ctx);
let shell_type = self.active_session.as_ref(ctx).shell_type(ctx);
@@ -151,10 +151,16 @@ impl RequestFileEditsExecutor {
else {
return ActionExecution::InvalidAction;
};
log::info!("[tool-debug] RequestFileEditsExecutor::execute: action_id={:?}", id);
log::info!(
"[tool-debug] RequestFileEditsExecutor::execute: action_id={:?}",
id
);
let Some(diff_view) = self.diff_views.get(id) else {
log::warn!("[tool-debug] RequestFileEditsExecutor: no diff view found for action_id={:?}", id);
log::warn!(
"[tool-debug] RequestFileEditsExecutor: no diff view found for action_id={:?}",
id
);
return ActionExecution::NotReady;
};
@@ -68,7 +68,9 @@ impl StartAgentExecutor {
let history_model = BlocklistAIHistoryModel::handle(ctx);
ctx.subscribe_to_model(&history_model, Self::handle_history_event);
Self { pending: Vec::new() }
Self {
pending: Vec::new(),
}
}
fn handle_history_event(
@@ -91,8 +93,7 @@ impl StartAgentExecutor {
let parent_id = conversation.parent_conversation_id();
// Find the first pending entry that matches this parent and hasn't been assigned a child yet.
if let Some(pending) = self.pending.iter_mut().find(|p| {
p.child_conversation_id.is_none()
&& parent_id == Some(p.parent_conversation_id)
p.child_conversation_id.is_none() && parent_id == Some(p.parent_conversation_id)
}) {
pending.child_conversation_id = Some(*new_conversation_id);
}
@@ -100,17 +101,19 @@ impl StartAgentExecutor {
BlocklistAIHistoryEvent::ConversationServerTokenAssigned {
conversation_id, ..
} => {
let Some(idx) = self.pending.iter().position(|p| {
p.child_conversation_id.as_ref() == Some(conversation_id)
}) else {
let Some(idx) = self
.pending
.iter()
.position(|p| p.child_conversation_id.as_ref() == Some(conversation_id))
else {
return;
};
// Don't remove yet if we're waiting for completion — we need
// the entry to stay so UpdatedConversationStatus can find it.
if self.pending[idx].wait_for_completion {
// Just log and continue — we'll resolve on Success status.
let conversation = BlocklistAIHistoryModel::as_ref(ctx)
.conversation(conversation_id);
let conversation =
BlocklistAIHistoryModel::as_ref(ctx).conversation(conversation_id);
let agent_id = conversation
.and_then(|c| c.orchestration_agent_id())
.or_else(|| {
@@ -132,8 +135,8 @@ impl StartAgentExecutor {
return;
}
let pending = self.pending.remove(idx);
let conversation = BlocklistAIHistoryModel::as_ref(ctx)
.conversation(conversation_id);
let conversation =
BlocklistAIHistoryModel::as_ref(ctx).conversation(conversation_id);
// orchestration_agent_id() uses run_id in v2 mode, which won't
// exist for locally-spawned Bedrock child agents. Fall back to
// the server conversation token (set by the stream Init event)
@@ -195,9 +198,11 @@ impl StartAgentExecutor {
BlocklistAIHistoryEvent::UpdatedConversationStatus {
conversation_id, ..
} => {
let Some(idx) = self.pending.iter().position(|p| {
p.child_conversation_id.as_ref() == Some(conversation_id)
}) else {
let Some(idx) = self
.pending
.iter()
.position(|p| p.child_conversation_id.as_ref() == Some(conversation_id))
else {
return;
};
let history = BlocklistAIHistoryModel::as_ref(ctx);
@@ -227,10 +232,9 @@ impl StartAgentExecutor {
.map(|t| t.as_str().to_string())
})
.unwrap_or_else(|| conversation_id.to_string());
let _ = pending.sender.try_send(StartAgentDecision::Completed {
agent_id,
output,
});
let _ = pending
.sender
.try_send(StartAgentDecision::Completed { agent_id, output });
}
status => {
let error_msg = start_agent_error_message_for_status(
@@ -72,7 +72,7 @@ fn execute_returns_error_when_child_startup_is_blocked_before_initialization() {
assert_eq!(
executor
.pending
.as_ref()
.first()
.and_then(|pending| pending.child_conversation_id),
Some(child_conversation_id)
);
@@ -102,7 +102,7 @@ fn execute_returns_error_when_child_startup_is_blocked_before_initialization() {
));
executor.read(&app, |executor, _| {
assert!(executor.pending.is_none());
assert!(executor.pending.is_empty());
});
});
}