Refactor ToolCallStatus enum to flat variants (#36356)
Replace nested Allowed variant with distinct statuses for clearer status handling. Release Notes: - N/A
This commit is contained in:
parent
da8a692ec0
commit
5895fac377
3 changed files with 72 additions and 70 deletions
|
@ -223,7 +223,7 @@ impl ToolCall {
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(status) = status {
|
if let Some(status) = status {
|
||||||
self.status = ToolCallStatus::Allowed { status };
|
self.status = status.into();
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(title) = title {
|
if let Some(title) = title {
|
||||||
|
@ -344,30 +344,48 @@ impl ToolCall {
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum ToolCallStatus {
|
pub enum ToolCallStatus {
|
||||||
|
/// The tool call hasn't started running yet, but we start showing it to
|
||||||
|
/// the user.
|
||||||
|
Pending,
|
||||||
|
/// The tool call is waiting for confirmation from the user.
|
||||||
WaitingForConfirmation {
|
WaitingForConfirmation {
|
||||||
options: Vec<acp::PermissionOption>,
|
options: Vec<acp::PermissionOption>,
|
||||||
respond_tx: oneshot::Sender<acp::PermissionOptionId>,
|
respond_tx: oneshot::Sender<acp::PermissionOptionId>,
|
||||||
},
|
},
|
||||||
Allowed {
|
/// The tool call is currently running.
|
||||||
status: acp::ToolCallStatus,
|
InProgress,
|
||||||
},
|
/// The tool call completed successfully.
|
||||||
|
Completed,
|
||||||
|
/// The tool call failed.
|
||||||
|
Failed,
|
||||||
|
/// The user rejected the tool call.
|
||||||
Rejected,
|
Rejected,
|
||||||
|
/// The user cancelled generation so the tool call was cancelled.
|
||||||
Canceled,
|
Canceled,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<acp::ToolCallStatus> for ToolCallStatus {
|
||||||
|
fn from(status: acp::ToolCallStatus) -> Self {
|
||||||
|
match status {
|
||||||
|
acp::ToolCallStatus::Pending => Self::Pending,
|
||||||
|
acp::ToolCallStatus::InProgress => Self::InProgress,
|
||||||
|
acp::ToolCallStatus::Completed => Self::Completed,
|
||||||
|
acp::ToolCallStatus::Failed => Self::Failed,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Display for ToolCallStatus {
|
impl Display for ToolCallStatus {
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||||
write!(
|
write!(
|
||||||
f,
|
f,
|
||||||
"{}",
|
"{}",
|
||||||
match self {
|
match self {
|
||||||
|
ToolCallStatus::Pending => "Pending",
|
||||||
ToolCallStatus::WaitingForConfirmation { .. } => "Waiting for confirmation",
|
ToolCallStatus::WaitingForConfirmation { .. } => "Waiting for confirmation",
|
||||||
ToolCallStatus::Allowed { status } => match status {
|
ToolCallStatus::InProgress => "In Progress",
|
||||||
acp::ToolCallStatus::Pending => "Pending",
|
ToolCallStatus::Completed => "Completed",
|
||||||
acp::ToolCallStatus::InProgress => "In Progress",
|
ToolCallStatus::Failed => "Failed",
|
||||||
acp::ToolCallStatus::Completed => "Completed",
|
|
||||||
acp::ToolCallStatus::Failed => "Failed",
|
|
||||||
},
|
|
||||||
ToolCallStatus::Rejected => "Rejected",
|
ToolCallStatus::Rejected => "Rejected",
|
||||||
ToolCallStatus::Canceled => "Canceled",
|
ToolCallStatus::Canceled => "Canceled",
|
||||||
}
|
}
|
||||||
|
@ -759,11 +777,7 @@ impl AcpThread {
|
||||||
AgentThreadEntry::UserMessage(_) => return false,
|
AgentThreadEntry::UserMessage(_) => return false,
|
||||||
AgentThreadEntry::ToolCall(
|
AgentThreadEntry::ToolCall(
|
||||||
call @ ToolCall {
|
call @ ToolCall {
|
||||||
status:
|
status: ToolCallStatus::InProgress | ToolCallStatus::Pending,
|
||||||
ToolCallStatus::Allowed {
|
|
||||||
status:
|
|
||||||
acp::ToolCallStatus::InProgress | acp::ToolCallStatus::Pending,
|
|
||||||
},
|
|
||||||
..
|
..
|
||||||
},
|
},
|
||||||
) if call.diffs().next().is_some() => {
|
) if call.diffs().next().is_some() => {
|
||||||
|
@ -945,9 +959,7 @@ impl AcpThread {
|
||||||
tool_call: acp::ToolCall,
|
tool_call: acp::ToolCall,
|
||||||
cx: &mut Context<Self>,
|
cx: &mut Context<Self>,
|
||||||
) -> Result<(), acp::Error> {
|
) -> Result<(), acp::Error> {
|
||||||
let status = ToolCallStatus::Allowed {
|
let status = tool_call.status.into();
|
||||||
status: tool_call.status,
|
|
||||||
};
|
|
||||||
self.upsert_tool_call_inner(tool_call.into(), status, cx)
|
self.upsert_tool_call_inner(tool_call.into(), status, cx)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1074,9 +1086,7 @@ impl AcpThread {
|
||||||
ToolCallStatus::Rejected
|
ToolCallStatus::Rejected
|
||||||
}
|
}
|
||||||
acp::PermissionOptionKind::AllowOnce | acp::PermissionOptionKind::AllowAlways => {
|
acp::PermissionOptionKind::AllowOnce | acp::PermissionOptionKind::AllowAlways => {
|
||||||
ToolCallStatus::Allowed {
|
ToolCallStatus::InProgress
|
||||||
status: acp::ToolCallStatus::InProgress,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1097,7 +1107,10 @@ impl AcpThread {
|
||||||
match &entry {
|
match &entry {
|
||||||
AgentThreadEntry::ToolCall(call) => match call.status {
|
AgentThreadEntry::ToolCall(call) => match call.status {
|
||||||
ToolCallStatus::WaitingForConfirmation { .. } => return true,
|
ToolCallStatus::WaitingForConfirmation { .. } => return true,
|
||||||
ToolCallStatus::Allowed { .. }
|
ToolCallStatus::Pending
|
||||||
|
| ToolCallStatus::InProgress
|
||||||
|
| ToolCallStatus::Completed
|
||||||
|
| ToolCallStatus::Failed
|
||||||
| ToolCallStatus::Rejected
|
| ToolCallStatus::Rejected
|
||||||
| ToolCallStatus::Canceled => continue,
|
| ToolCallStatus::Canceled => continue,
|
||||||
},
|
},
|
||||||
|
@ -1290,10 +1303,9 @@ impl AcpThread {
|
||||||
if let AgentThreadEntry::ToolCall(call) = entry {
|
if let AgentThreadEntry::ToolCall(call) = entry {
|
||||||
let cancel = matches!(
|
let cancel = matches!(
|
||||||
call.status,
|
call.status,
|
||||||
ToolCallStatus::WaitingForConfirmation { .. }
|
ToolCallStatus::Pending
|
||||||
| ToolCallStatus::Allowed {
|
| ToolCallStatus::WaitingForConfirmation { .. }
|
||||||
status: acp::ToolCallStatus::InProgress
|
| ToolCallStatus::InProgress
|
||||||
}
|
|
||||||
);
|
);
|
||||||
|
|
||||||
if cancel {
|
if cancel {
|
||||||
|
@ -1939,10 +1951,7 @@ mod tests {
|
||||||
assert!(matches!(
|
assert!(matches!(
|
||||||
thread.entries[1],
|
thread.entries[1],
|
||||||
AgentThreadEntry::ToolCall(ToolCall {
|
AgentThreadEntry::ToolCall(ToolCall {
|
||||||
status: ToolCallStatus::Allowed {
|
status: ToolCallStatus::InProgress,
|
||||||
status: acp::ToolCallStatus::InProgress,
|
|
||||||
..
|
|
||||||
},
|
|
||||||
..
|
..
|
||||||
})
|
})
|
||||||
));
|
));
|
||||||
|
@ -1981,10 +1990,7 @@ mod tests {
|
||||||
assert!(matches!(
|
assert!(matches!(
|
||||||
thread.entries[1],
|
thread.entries[1],
|
||||||
AgentThreadEntry::ToolCall(ToolCall {
|
AgentThreadEntry::ToolCall(ToolCall {
|
||||||
status: ToolCallStatus::Allowed {
|
status: ToolCallStatus::Completed,
|
||||||
status: acp::ToolCallStatus::Completed,
|
|
||||||
..
|
|
||||||
},
|
|
||||||
..
|
..
|
||||||
})
|
})
|
||||||
));
|
));
|
||||||
|
|
|
@ -134,7 +134,9 @@ pub async fn test_tool_call(server: impl AgentServer + 'static, cx: &mut TestApp
|
||||||
matches!(
|
matches!(
|
||||||
entry,
|
entry,
|
||||||
AgentThreadEntry::ToolCall(ToolCall {
|
AgentThreadEntry::ToolCall(ToolCall {
|
||||||
status: ToolCallStatus::Allowed { .. },
|
status: ToolCallStatus::Pending
|
||||||
|
| ToolCallStatus::InProgress
|
||||||
|
| ToolCallStatus::Completed,
|
||||||
..
|
..
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
|
@ -212,7 +214,9 @@ pub async fn test_tool_call_with_permission(
|
||||||
assert!(thread.entries().iter().any(|entry| matches!(
|
assert!(thread.entries().iter().any(|entry| matches!(
|
||||||
entry,
|
entry,
|
||||||
AgentThreadEntry::ToolCall(ToolCall {
|
AgentThreadEntry::ToolCall(ToolCall {
|
||||||
status: ToolCallStatus::Allowed { .. },
|
status: ToolCallStatus::Pending
|
||||||
|
| ToolCallStatus::InProgress
|
||||||
|
| ToolCallStatus::Completed,
|
||||||
..
|
..
|
||||||
})
|
})
|
||||||
)));
|
)));
|
||||||
|
@ -223,7 +227,9 @@ pub async fn test_tool_call_with_permission(
|
||||||
thread.read_with(cx, |thread, cx| {
|
thread.read_with(cx, |thread, cx| {
|
||||||
let AgentThreadEntry::ToolCall(ToolCall {
|
let AgentThreadEntry::ToolCall(ToolCall {
|
||||||
content,
|
content,
|
||||||
status: ToolCallStatus::Allowed { .. },
|
status: ToolCallStatus::Pending
|
||||||
|
| ToolCallStatus::InProgress
|
||||||
|
| ToolCallStatus::Completed,
|
||||||
..
|
..
|
||||||
}) = thread
|
}) = thread
|
||||||
.entries()
|
.entries()
|
||||||
|
|
|
@ -1053,14 +1053,10 @@ impl AcpThreadView {
|
||||||
let card_header_id = SharedString::from("inner-tool-call-header");
|
let card_header_id = SharedString::from("inner-tool-call-header");
|
||||||
|
|
||||||
let status_icon = match &tool_call.status {
|
let status_icon = match &tool_call.status {
|
||||||
ToolCallStatus::Allowed {
|
ToolCallStatus::Pending
|
||||||
status: acp::ToolCallStatus::Pending,
|
| ToolCallStatus::WaitingForConfirmation { .. }
|
||||||
}
|
| ToolCallStatus::Completed => None,
|
||||||
| ToolCallStatus::WaitingForConfirmation { .. } => None,
|
ToolCallStatus::InProgress => Some(
|
||||||
ToolCallStatus::Allowed {
|
|
||||||
status: acp::ToolCallStatus::InProgress,
|
|
||||||
..
|
|
||||||
} => Some(
|
|
||||||
Icon::new(IconName::ArrowCircle)
|
Icon::new(IconName::ArrowCircle)
|
||||||
.color(Color::Accent)
|
.color(Color::Accent)
|
||||||
.size(IconSize::Small)
|
.size(IconSize::Small)
|
||||||
|
@ -1071,16 +1067,7 @@ impl AcpThreadView {
|
||||||
)
|
)
|
||||||
.into_any(),
|
.into_any(),
|
||||||
),
|
),
|
||||||
ToolCallStatus::Allowed {
|
ToolCallStatus::Rejected | ToolCallStatus::Canceled | ToolCallStatus::Failed => Some(
|
||||||
status: acp::ToolCallStatus::Completed,
|
|
||||||
..
|
|
||||||
} => None,
|
|
||||||
ToolCallStatus::Rejected
|
|
||||||
| ToolCallStatus::Canceled
|
|
||||||
| ToolCallStatus::Allowed {
|
|
||||||
status: acp::ToolCallStatus::Failed,
|
|
||||||
..
|
|
||||||
} => Some(
|
|
||||||
Icon::new(IconName::Close)
|
Icon::new(IconName::Close)
|
||||||
.color(Color::Error)
|
.color(Color::Error)
|
||||||
.size(IconSize::Small)
|
.size(IconSize::Small)
|
||||||
|
@ -1146,15 +1133,23 @@ impl AcpThreadView {
|
||||||
tool_call.content.is_empty(),
|
tool_call.content.is_empty(),
|
||||||
cx,
|
cx,
|
||||||
)),
|
)),
|
||||||
ToolCallStatus::Allowed { .. } | ToolCallStatus::Canceled => v_flex()
|
ToolCallStatus::Pending
|
||||||
.w_full()
|
| ToolCallStatus::InProgress
|
||||||
.children(tool_call.content.iter().map(|content| {
|
| ToolCallStatus::Completed
|
||||||
div()
|
| ToolCallStatus::Failed
|
||||||
.child(
|
| ToolCallStatus::Canceled => {
|
||||||
self.render_tool_call_content(entry_ix, content, tool_call, window, cx),
|
v_flex()
|
||||||
)
|
.w_full()
|
||||||
.into_any_element()
|
.children(tool_call.content.iter().map(|content| {
|
||||||
})),
|
div()
|
||||||
|
.child(
|
||||||
|
self.render_tool_call_content(
|
||||||
|
entry_ix, content, tool_call, window, cx,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.into_any_element()
|
||||||
|
}))
|
||||||
|
}
|
||||||
ToolCallStatus::Rejected => v_flex().size_0(),
|
ToolCallStatus::Rejected => v_flex().size_0(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1467,12 +1462,7 @@ impl AcpThreadView {
|
||||||
|
|
||||||
let tool_failed = matches!(
|
let tool_failed = matches!(
|
||||||
&tool_call.status,
|
&tool_call.status,
|
||||||
ToolCallStatus::Rejected
|
ToolCallStatus::Rejected | ToolCallStatus::Canceled | ToolCallStatus::Failed
|
||||||
| ToolCallStatus::Canceled
|
|
||||||
| ToolCallStatus::Allowed {
|
|
||||||
status: acp::ToolCallStatus::Failed,
|
|
||||||
..
|
|
||||||
}
|
|
||||||
);
|
);
|
||||||
|
|
||||||
let output = terminal_data.output();
|
let output = terminal_data.output();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue