mirror of
https://github.com/openai/codex.git
synced 2026-10-24 18:18:41 +00:00
## What changed - Emit `codex.turn_profile` events with finalized sampling request and retry counts when turns complete or abort, and preserve the caller's tracing span for detached extension interrupts. - Add conversation and turn identifiers to turn and tool dispatch spans, identify tool sources, and include dispatch-to-result-ready duration on tool completion events. - Emit `codex.skill_read.source_selected` before cache or provider access, recording the selected cloud or executor source, skill and plugin identity, resource kind, and continuation status. ## Testing Add regression coverage for trace correlation, tool completion timing, turn profile counters on completion and interruption, detached interrupt span propagation, and skill source attribution including cached cloud reads. GitOrigin-RevId: db78aa270bbcb8dc9e4558d202c109ad54141811
97 lines
2.8 KiB
Rust
97 lines
2.8 KiB
Rust
//! Trace milestones for every direct or code-mode tool call handled by core.
|
|
//! These events contain call identifiers and names, never arguments or output.
|
|
//! Code-mode calls reach the broker before the dispatching turn is known.
|
|
|
|
use std::time::Duration;
|
|
|
|
use codex_protocol::DEFAULT_FUNCTION_NAMESPACE;
|
|
use codex_protocol::ThreadId;
|
|
use codex_tools::ToolName;
|
|
|
|
#[derive(Clone, Copy)]
|
|
pub(crate) enum Source {
|
|
Direct,
|
|
CodeMode,
|
|
}
|
|
|
|
impl Source {
|
|
pub(crate) fn as_str(self) -> &'static str {
|
|
match self {
|
|
Self::Direct => "direct",
|
|
Self::CodeMode => "code_mode",
|
|
}
|
|
}
|
|
}
|
|
|
|
pub(crate) enum Receipt<'a> {
|
|
ModelTurn(&'a str),
|
|
CodeModeBroker {
|
|
cell_id: Option<&'a str>,
|
|
runtime_tool_call_id: Option<&'a str>,
|
|
},
|
|
}
|
|
|
|
pub(crate) fn received(
|
|
thread_id: ThreadId,
|
|
tool_name: &ToolName,
|
|
call_id: &str,
|
|
receipt: Receipt<'_>,
|
|
) {
|
|
let (turn_id, source, cell_id, runtime_tool_call_id) = match receipt {
|
|
Receipt::ModelTurn(turn_id) => (Some(turn_id), Source::Direct, None, None),
|
|
Receipt::CodeModeBroker {
|
|
cell_id,
|
|
runtime_tool_call_id,
|
|
} => (None, Source::CodeMode, cell_id, runtime_tool_call_id),
|
|
};
|
|
tracing::event!(
|
|
name: "codex.tool_call_received",
|
|
target: "codex_otel.trace_safe",
|
|
tracing::Level::INFO,
|
|
event.name = "codex.tool_call_received",
|
|
conversation.id = %thread_id,
|
|
turn_id,
|
|
call_id,
|
|
tool_name = tool_name.name.as_str(),
|
|
tool_namespace = namespace(tool_name),
|
|
tool_source = source.as_str(),
|
|
cell.id = cell_id,
|
|
runtime_tool_call_id,
|
|
);
|
|
}
|
|
|
|
// Record the measured duration on the terminal event so a retained completion
|
|
// remains useful even when its receipt event or dispatch span was not retained.
|
|
// This includes runtime admission and handler work, but excludes broker queuing
|
|
// before dispatch and the sampling loop's later result collection.
|
|
pub(crate) fn result_ready(
|
|
thread_id: ThreadId,
|
|
turn_id: &str,
|
|
tool_name: &ToolName,
|
|
call_id: &str,
|
|
source: Source,
|
|
dispatch_to_result_ready: Duration,
|
|
) {
|
|
tracing::event!(
|
|
name: "codex.tool_result_ready",
|
|
target: "codex_otel.trace_safe",
|
|
tracing::Level::INFO,
|
|
event.name = "codex.tool_result_ready",
|
|
dispatch_to_result_ready_ms = dispatch_to_result_ready.as_secs_f64() * 1000.0,
|
|
conversation.id = %thread_id,
|
|
turn_id,
|
|
call_id,
|
|
tool_name = tool_name.name.as_str(),
|
|
tool_namespace = namespace(tool_name),
|
|
tool_source = source.as_str(),
|
|
);
|
|
}
|
|
|
|
pub(crate) fn namespace(tool_name: &ToolName) -> &str {
|
|
tool_name
|
|
.namespace
|
|
.as_deref()
|
|
.filter(|namespace| !namespace.is_empty())
|
|
.unwrap_or(DEFAULT_FUNCTION_NAMESPACE)
|
|
}
|