You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
feat(server-utils): Parent the tool spans of an Anthropic session runner under one span per session #25768
#25554 gives each tool call of a Managed Agents session runner an execute_tool span, but nothing parents them. When EnvironmentWorker drives the runners from its own poll loop (lib/environments/worker.mjs, for await (const _ of runner)), no user span is active, so every tool call becomes its own root segment. The agent.tool_use event has no session id and tool objects are shared across runners, so the spans can't be tied back to a session either. The same happens when beta.sessions.events.toolRunner() is iterated outside a span.
Anthropic's own OTel tracing already groups them. EnvironmentWorker runs each work item inside an anthropic.environment.work span that carries anthropic.session.id, and the session runner parents its tool spans to the context active when its loop starts. We could do the same: start one span per runner and set gen_ai.conversation.id from runner.sessionId, so its tool spans nest under it.
Open questions:
Which op and name the span should have, and whether invoke_agent fits a session runner.
Where to start it. The tool calls run from the runner's background loop, which begins on the first next(), not when [Symbol.asyncIterator]() is called.
How a span that lasts a whole session (hours, with reconnects and idle waits) behaves under span streaming.
What happens when the user already has a span active around the loop.
Activity
linear-code commentedon Oct 27, 2026
JS-4011