Files
codex/codex-rs/core/src/function_tool.rs
T
mikelam-oai 18e28fe1b9 Complete dynamic tool lifecycles on cancellation (#51556)
## Why

Interrupting a turn or terminating a Code Mode cell can drop a pending dynamic tool handler before it publishes its completion. Cancellation needs to settle the call in live events and persisted history without allowing a late response into model context.

## What changed

- Let dynamic tool handlers observe cancellation and publish their terminal item before dispatch finishes. Calls cancelled while awaiting a response complete with a failed item and a cancellation error.
- Keep readiness, dispatch admission, registry lock waits, hooks, and output processing cancellable so cancellation can finish even when a hook is blocked.
- Report an aborted tool lifecycle outcome when cancellation interrupts dispatch, including before handler execution.

## Testing

Add regression tests for turn interruption with pending calls or blocked hooks, cell termination with persisted failure and late-response exclusion, cancellation before dispatch admission, and exactly one completion when a response races cancellation.

GitOrigin-RevId: 0112fc74c8652c91503ed5bbfb334ae2e26930ef
2026-10-07 03:07:51 +00:00

25 lines
778 B
Rust

use std::future::Future;
use codex_async_utils::OrCancelExt;
pub use codex_tools::FunctionCallError;
use tokio_util::sync::CancellationToken;
/// Maps cancellation to the standard tool-call error while preserving the future's output.
pub(crate) trait OrCancelToolExt: OrCancelExt + Send {
fn or_cancel_tool(
self,
token: &CancellationToken,
) -> impl Future<Output = Result<Self::Output, FunctionCallError>> + Send;
}
impl<F: OrCancelExt + Send> OrCancelToolExt for F {
async fn or_cancel_tool(
self,
token: &CancellationToken,
) -> Result<Self::Output, FunctionCallError> {
self.or_cancel(token)
.await
.map_err(|_| FunctionCallError::RespondToModel("tool call cancelled".to_string()))
}
}