Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
77 changes: 77 additions & 0 deletions codex-rs/code-mode/src/cell_actor/callbacks.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
use std::sync::Arc;

use tokio::task::JoinSet;
use tokio_util::sync::CancellationToken;
use tracing::warn;

use super::CellHost;
use super::CellToolCall;
use crate::runtime::RuntimeCommand;

#[derive(Clone, Copy)]
pub(super) enum CallbackCompletion {
DrainNotifications,
Cancel,
}

pub(super) fn spawn_notification<H: CellHost>(
tasks: &mut JoinSet<()>,
host: Arc<H>,
call_id: String,
text: String,
cancellation_token: CancellationToken,
) {
tasks.spawn(async move {
if let Err(err) = host.notify(call_id, text, cancellation_token).await {
warn!("failed to deliver code mode notification: {err}");
}
});
}

pub(super) fn spawn_tool<H: CellHost>(
tasks: &mut JoinSet<()>,
host: Arc<H>,
invocation: CellToolCall,
runtime_tx: std::sync::mpsc::Sender<RuntimeCommand>,
cancellation_token: CancellationToken,
) {
tasks.spawn(async move {
let id = invocation.id.clone();
let command = match host.invoke_tool(invocation, cancellation_token).await {
Ok(result) => RuntimeCommand::ToolResponse { id, result },
Err(error_text) => RuntimeCommand::ToolError { id, error_text },
};
let _ = runtime_tx.send(command);
});
}

pub(super) async fn finish_callbacks(
cancellation_token: &CancellationToken,
notification_tasks: &mut JoinSet<()>,
tool_tasks: &mut JoinSet<()>,
completion: CallbackCompletion,
) {
if matches!(completion, CallbackCompletion::Cancel) {
cancellation_token.cancel();
}
drain_tasks(notification_tasks, "notification").await;
cancellation_token.cancel();
drain_tasks(tool_tasks, "tool").await;
}

pub(super) fn log_task_result(
task_result: Option<Result<(), tokio::task::JoinError>>,
description: &str,
) {
if let Some(Err(err)) = task_result
&& !err.is_cancelled()
{
warn!("code mode {description} task failed: {err}");
}
}

async fn drain_tasks(tasks: &mut JoinSet<()>, description: &str) {
while let Some(result) = tasks.join_next().await {
log_task_result(Some(result), description);
}
}
60 changes: 60 additions & 0 deletions codex-rs/code-mode/src/cell_actor/conversions.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
use codex_code_mode_protocol::CodeModeToolKind;
use codex_code_mode_protocol::ExecuteRequest;
use codex_code_mode_protocol::FunctionCallOutputContentItem;
use codex_code_mode_protocol::ImageDetail;
use codex_code_mode_protocol::ToolDefinition;
use codex_protocol::ToolName;

use super::CellImageDetail;
use super::CellOutputItem;
use super::CellRequest;
use super::CellToolKind;

pub(super) fn runtime_request(request: CellRequest) -> ExecuteRequest {
ExecuteRequest {
tool_call_id: request.tool_call_id,
enabled_tools: request
.enabled_tools
.into_iter()
.map(|definition| ToolDefinition {
name: definition.name,
tool_name: ToolName {
name: definition.tool_name.name,
namespace: definition.tool_name.namespace,
},
description: definition.description,
kind: match definition.kind {
CellToolKind::Function => CodeModeToolKind::Function,
CellToolKind::Freeform => CodeModeToolKind::Freeform,
},
input_schema: None,
output_schema: None,
})
.collect(),
source: request.source,
yield_time_ms: None,
max_output_tokens: None,
}
}

pub(super) fn cell_tool_kind(kind: CodeModeToolKind) -> CellToolKind {
match kind {
CodeModeToolKind::Function => CellToolKind::Function,
CodeModeToolKind::Freeform => CellToolKind::Freeform,
}
}

pub(super) fn output_item(item: FunctionCallOutputContentItem) -> CellOutputItem {
match item {
FunctionCallOutputContentItem::InputText { text } => CellOutputItem::Text { text },
FunctionCallOutputContentItem::InputImage { image_url, detail } => CellOutputItem::Image {
image_url,
detail: detail.map(|detail| match detail {
ImageDetail::Auto => CellImageDetail::Auto,
ImageDetail::Low => CellImageDetail::Low,
ImageDetail::High => CellImageDetail::High,
ImageDetail::Original => CellImageDetail::Original,
}),
},
}
}
Loading
Loading