( model: string, newContext?: LLMRequestNewContext, messagesForAPI?: APIMessage[], fastMode?: boolean, )
| 272 | } |
| 273 | |
| 274 | export function startLLMRequestSpan( |
| 275 | model: string, |
| 276 | newContext?: LLMRequestNewContext, |
| 277 | messagesForAPI?: APIMessage[], |
| 278 | fastMode?: boolean, |
| 279 | ): Span { |
| 280 | // Start Perfetto span regardless of OTel tracing state |
| 281 | const perfettoSpanId = isPerfettoTracingEnabled() |
| 282 | ? startLLMRequestPerfettoSpan({ |
| 283 | model, |
| 284 | querySource: newContext?.querySource, |
| 285 | messageId: undefined, // Will be set in endLLMRequestSpan |
| 286 | }) |
| 287 | : undefined |
| 288 | |
| 289 | if (!isAnyTracingEnabled()) { |
| 290 | // Still track Perfetto span even if OTel is disabled |
| 291 | if (perfettoSpanId) { |
| 292 | const dummySpan = trace.getActiveSpan() || getTracer().startSpan('dummy') |
| 293 | const spanId = getSpanId(dummySpan) |
| 294 | const spanContextObj: SpanContext = { |
| 295 | span: dummySpan, |
| 296 | startTime: Date.now(), |
| 297 | attributes: { model }, |
| 298 | perfettoSpanId, |
| 299 | } |
| 300 | activeSpans.set(spanId, new WeakRef(spanContextObj)) |
| 301 | strongSpans.set(spanId, spanContextObj) |
| 302 | return dummySpan |
| 303 | } |
| 304 | return trace.getActiveSpan() || getTracer().startSpan('dummy') |
| 305 | } |
| 306 | |
| 307 | const tracer = getTracer() |
| 308 | const parentSpanCtx = interactionContext.getStore() |
| 309 | |
| 310 | const attributes = createSpanAttributes('llm_request', { |
| 311 | model: model, |
| 312 | 'llm_request.context': parentSpanCtx ? 'interaction' : 'standalone', |
| 313 | speed: fastMode ? 'fast' : 'normal', |
| 314 | }) |
| 315 | |
| 316 | const ctx = parentSpanCtx |
| 317 | ? trace.setSpan(otelContext.active(), parentSpanCtx.span) |
| 318 | : otelContext.active() |
| 319 | const span = tracer.startSpan('claude_code.llm_request', { attributes }, ctx) |
| 320 | |
| 321 | // Add query_source (agent name) if provided |
| 322 | if (newContext?.querySource) { |
| 323 | span.setAttribute('query_source', newContext.querySource) |
| 324 | } |
| 325 | |
| 326 | // Add experimental attributes (system prompt, new_context) |
| 327 | addBetaLLMRequestAttributes(span, newContext, messagesForAPI) |
| 328 | |
| 329 | const spanId = getSpanId(span) |
| 330 | const spanContextObj: SpanContext = { |
| 331 | span, |
no test coverage detected