(userPrompt: string)
| 174 | * Sets the interaction context for all subsequent operations. |
| 175 | */ |
| 176 | export function startInteractionSpan(userPrompt: string): Span { |
| 177 | ensureCleanupInterval() |
| 178 | |
| 179 | // Start Perfetto span regardless of OTel tracing state |
| 180 | const perfettoSpanId = isPerfettoTracingEnabled() |
| 181 | ? startInteractionPerfettoSpan(userPrompt) |
| 182 | : undefined |
| 183 | |
| 184 | if (!isAnyTracingEnabled()) { |
| 185 | // Still track Perfetto span even if OTel is disabled |
| 186 | if (perfettoSpanId) { |
| 187 | const dummySpan = trace.getActiveSpan() || getTracer().startSpan('dummy') |
| 188 | const spanId = getSpanId(dummySpan) |
| 189 | const spanContextObj: SpanContext = { |
| 190 | span: dummySpan, |
| 191 | startTime: Date.now(), |
| 192 | attributes: {}, |
| 193 | perfettoSpanId, |
| 194 | } |
| 195 | activeSpans.set(spanId, new WeakRef(spanContextObj)) |
| 196 | interactionContext.enterWith(spanContextObj) |
| 197 | return dummySpan |
| 198 | } |
| 199 | return trace.getActiveSpan() || getTracer().startSpan('dummy') |
| 200 | } |
| 201 | |
| 202 | const tracer = getTracer() |
| 203 | const isUserPromptLoggingEnabled = isEnvTruthy( |
| 204 | process.env.OTEL_LOG_USER_PROMPTS, |
| 205 | ) |
| 206 | const promptToLog = isUserPromptLoggingEnabled ? userPrompt : '<REDACTED>' |
| 207 | |
| 208 | interactionSequence++ |
| 209 | |
| 210 | const attributes = createSpanAttributes('interaction', { |
| 211 | user_prompt: promptToLog, |
| 212 | user_prompt_length: userPrompt.length, |
| 213 | 'interaction.sequence': interactionSequence, |
| 214 | }) |
| 215 | |
| 216 | const span = tracer.startSpan('claude_code.interaction', { |
| 217 | attributes, |
| 218 | }) |
| 219 | |
| 220 | // Add experimental attributes (new_context) |
| 221 | addBetaInteractionAttributes(span, userPrompt) |
| 222 | |
| 223 | const spanId = getSpanId(span) |
| 224 | const spanContextObj: SpanContext = { |
| 225 | span, |
| 226 | startTime: Date.now(), |
| 227 | attributes, |
| 228 | perfettoSpanId, |
| 229 | } |
| 230 | activeSpans.set(spanId, new WeakRef(spanContextObj)) |
| 231 | |
| 232 | interactionContext.enterWith(spanContextObj) |
| 233 |
no test coverage detected