Improve tracing for nested tool calls and exec processes (#41950)

## Why

Code-mode callbacks can outlive their initial request and run in separate tasks,
so their trace context must be preserved explicitly.

## What changed

- Preserve the execution context for code-mode callbacks and add spans for
  nested tool invocations in the runtime and dispatch broker.
- Propagate each tool invocation span as the parent of its streamed gRPC
  callback, falling back to the outer execution context when needed.
- Add a `codex.exec_server.process` span for each process lifetime, including
  its process ID and completion result, without retaining the request span.

GitOrigin-RevId: a6059e34d895416f5517e51dad6ca0078355adca
This commit is contained in:
Adam Perry @ OpenAI
2026-09-01 01:00:50 +00:00
committed by copyberry
parent bfa9646787
commit 55e5158e18
10 changed files with 61 additions and 4 deletions
+11
View File
@@ -242,6 +242,17 @@ struct ProtocolDelegate {
}
impl runtime::SessionRuntimeDelegate for ProtocolDelegate {
#[tracing::instrument(
name = "code_mode.runtime.invoke_tool",
level = "info",
skip_all,
fields(
cell.id = %invocation.cell_id,
runtime_tool_call_id = invocation.runtime_tool_call_id.as_str(),
tool_name = invocation.tool_name.name.as_str(),
tool_namespace = invocation.tool_name.namespace.as_deref(),
)
)]
async fn invoke_tool(
&self,
invocation: runtime::NestedToolCall,
@@ -7,6 +7,7 @@ use std::sync::Arc;
use std::sync::atomic::AtomicU64;
use std::sync::atomic::Ordering;
use opentelemetry::context::FutureExt;
use serde_json::Value as JsonValue;
use tokio::sync::Mutex;
use tokio_util::sync::CancellationToken;
@@ -163,6 +164,7 @@ impl<D: SessionRuntimeDelegate> SessionRuntime<D> {
let host = Arc::new(RuntimeCellHost {
cell_id: cell_id.clone(),
inner: Arc::clone(&self.inner),
execution_context: opentelemetry::Context::current(),
});
let mut cells = self.inner.cells.lock().await;
if self.inner.shutdown_token.is_cancelled() {
@@ -235,6 +237,9 @@ impl PendingEvent {
struct RuntimeCellHost<D: SessionRuntimeDelegate> {
cell_id: CellId,
inner: Arc<Inner<D>>,
// Callbacks outlive the initial request and run in separate tasks. Preserve
// their trace parent without retaining the request's tracing span.
execution_context: opentelemetry::Context,
}
impl<D: SessionRuntimeDelegate> CellHost for RuntimeCellHost<D> {
@@ -255,6 +260,7 @@ impl<D: SessionRuntimeDelegate> CellHost for RuntimeCellHost<D> {
},
cancellation_token,
)
.with_context(self.execution_context.clone())
.await
}
@@ -102,6 +102,7 @@ async fn termination_rejects_a_waiting_store_commit_before_the_next_cell_can_loa
let host = RuntimeCellHost {
cell_id: CellId::new("terminating-writer"),
inner: Arc::clone(&runtime.inner),
execution_context: opentelemetry::Context::new(),
};
let completion = CellEvent::Completed {
content_items: vec![OutputItem::Text {