( spanName: string, attributes: Record<string, string | number | boolean> | undefined, fn: (span: Span) => Promise<T>, parentContext?: Context )
| 250 | // across multiple awaits (otherwise the child falls back to a framework |
| 251 | // span that the sampler drops). |
| 252 | export async function withCopilotSpan<T>( |
| 253 | spanName: string, |
| 254 | attributes: Record<string, string | number | boolean> | undefined, |
| 255 | fn: (span: Span) => Promise<T>, |
| 256 | parentContext?: Context |
| 257 | ): Promise<T> { |
| 258 | const tracer = getTracer() |
| 259 | const runBody = async (span: Span) => { |
| 260 | try { |
| 261 | const result = await fn(span) |
| 262 | span.setStatus({ code: SpanStatusCode.OK }) |
| 263 | return result |
| 264 | } catch (error) { |
| 265 | markSpanForError(span, error) |
| 266 | throw error |
| 267 | } finally { |
| 268 | span.end() |
| 269 | } |
| 270 | } |
| 271 | if (parentContext) { |
| 272 | return tracer.startActiveSpan(spanName, { attributes }, parentContext, runBody) |
| 273 | } |
| 274 | return tracer.startActiveSpan(spanName, { attributes }, runBody) |
| 275 | } |
| 276 | |
| 277 | // External OTel `tool.execute` span for Sim-side tool work (the Go |
| 278 | // side's `tool.execute` is just the enqueue, stays ~0ms). |
no test coverage detected