@ai-sdk/otel 1.0.0-beta.55 → 1.0.0-beta.58
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +63 -0
- package/dist/index.d.ts +29 -32
- package/dist/index.js +122 -74
- package/dist/index.js.map +1 -1
- package/package.json +7 -6
- package/src/index.ts +2 -2
- package/src/{open-telemetry-integration.ts → legacy-open-telemetry.ts} +69 -60
- package/src/{gen-ai-open-telemetry-integration.ts → open-telemetry.ts} +187 -122
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import { LanguageModelV4Prompt } from '@ai-sdk/provider';
|
|
2
|
-
import type { Context as AISDKContext } from '@ai-sdk/provider-utils';
|
|
3
1
|
import {
|
|
4
2
|
Attributes,
|
|
5
3
|
AttributeValue,
|
|
@@ -12,27 +10,29 @@ import {
|
|
|
12
10
|
Tracer,
|
|
13
11
|
} from '@opentelemetry/api';
|
|
14
12
|
import type {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
EmbedOnStartEvent,
|
|
13
|
+
EmbeddingModelCallEndEvent,
|
|
14
|
+
EmbedEndEvent,
|
|
18
15
|
EmbedStartEvent,
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
16
|
+
LanguageModelCallEndEvent,
|
|
17
|
+
LanguageModelCallStartEvent,
|
|
18
|
+
EmbeddingModelCallStartEvent,
|
|
19
|
+
GenerateObjectEndEvent,
|
|
20
|
+
GenerateObjectStartEvent,
|
|
21
|
+
GenerateObjectStepEndEvent,
|
|
22
|
+
GenerateObjectStepStartEvent,
|
|
23
|
+
StreamTextChunkEvent,
|
|
24
|
+
GenerateTextEndEvent,
|
|
25
|
+
GenerateTextStartEvent,
|
|
26
|
+
GenerateTextStepEndEvent,
|
|
27
|
+
GenerateTextStepStartEvent,
|
|
28
28
|
ToolExecutionEndEvent,
|
|
29
29
|
ToolExecutionStartEvent,
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
RerankOnFinishEvent,
|
|
33
|
-
RerankOnStartEvent,
|
|
30
|
+
RerankingModelCallEndEvent,
|
|
31
|
+
RerankEndEvent,
|
|
34
32
|
RerankStartEvent,
|
|
35
|
-
|
|
33
|
+
RerankingModelCallStartEvent,
|
|
34
|
+
InferTelemetryEvent,
|
|
35
|
+
Telemetry,
|
|
36
36
|
TelemetryOptions,
|
|
37
37
|
ToolSet,
|
|
38
38
|
} from 'ai';
|
|
@@ -115,16 +115,6 @@ function selectAttributes(
|
|
|
115
115
|
return result;
|
|
116
116
|
}
|
|
117
117
|
|
|
118
|
-
interface OtelStepStartEvent<
|
|
119
|
-
TOOLS extends ToolSet = ToolSet,
|
|
120
|
-
RUNTIME_CONTEXT extends AISDKContext = AISDKContext,
|
|
121
|
-
OUTPUT extends Output = Output,
|
|
122
|
-
> extends OnStepStartEvent<TOOLS, RUNTIME_CONTEXT, OUTPUT> {
|
|
123
|
-
readonly promptMessages?: LanguageModelV4Prompt;
|
|
124
|
-
readonly stepTools?: ReadonlyArray<Record<string, unknown>>;
|
|
125
|
-
readonly stepToolChoice?: unknown;
|
|
126
|
-
}
|
|
127
|
-
|
|
128
118
|
interface CallState {
|
|
129
119
|
operationId: string;
|
|
130
120
|
telemetry: TelemetryOptions | undefined;
|
|
@@ -132,6 +122,8 @@ interface CallState {
|
|
|
132
122
|
rootContext: OpenTelemetryContext | undefined;
|
|
133
123
|
stepSpan: Span | undefined;
|
|
134
124
|
stepContext: OpenTelemetryContext | undefined;
|
|
125
|
+
inferenceSpan: Span | undefined;
|
|
126
|
+
inferenceContext: OpenTelemetryContext | undefined;
|
|
135
127
|
embedSpans: Map<string, { span: Span; context: OpenTelemetryContext }>;
|
|
136
128
|
rerankSpan: { span: Span; context: OpenTelemetryContext } | undefined;
|
|
137
129
|
toolSpans: Map<string, { span: Span; context: OpenTelemetryContext }>;
|
|
@@ -140,7 +132,7 @@ interface CallState {
|
|
|
140
132
|
modelId: string;
|
|
141
133
|
}
|
|
142
134
|
|
|
143
|
-
export class
|
|
135
|
+
export class OpenTelemetry implements Telemetry {
|
|
144
136
|
private readonly callStates = new Map<string, CallState>();
|
|
145
137
|
|
|
146
138
|
private readonly tracer: Tracer;
|
|
@@ -181,23 +173,23 @@ export class GenAIOpenTelemetryIntegration implements TelemetryIntegration {
|
|
|
181
173
|
|
|
182
174
|
onStart(
|
|
183
175
|
event:
|
|
184
|
-
|
|
|
185
|
-
|
|
|
186
|
-
|
|
|
187
|
-
|
|
|
176
|
+
| InferTelemetryEvent<GenerateTextStartEvent>
|
|
177
|
+
| InferTelemetryEvent<GenerateObjectStartEvent>
|
|
178
|
+
| InferTelemetryEvent<EmbedStartEvent>
|
|
179
|
+
| InferTelemetryEvent<RerankStartEvent>,
|
|
188
180
|
): void {
|
|
189
|
-
if (event.isEnabled === false) return;
|
|
190
|
-
|
|
191
181
|
if (
|
|
192
182
|
event.operationId === 'ai.embed' ||
|
|
193
183
|
event.operationId === 'ai.embedMany'
|
|
194
184
|
) {
|
|
195
|
-
this.onEmbedOperationStart(event as
|
|
185
|
+
this.onEmbedOperationStart(event as InferTelemetryEvent<EmbedStartEvent>);
|
|
196
186
|
return;
|
|
197
187
|
}
|
|
198
188
|
|
|
199
189
|
if (event.operationId === 'ai.rerank') {
|
|
200
|
-
this.onRerankOperationStart(
|
|
190
|
+
this.onRerankOperationStart(
|
|
191
|
+
event as InferTelemetryEvent<RerankStartEvent>,
|
|
192
|
+
);
|
|
201
193
|
return;
|
|
202
194
|
}
|
|
203
195
|
|
|
@@ -205,16 +197,19 @@ export class GenAIOpenTelemetryIntegration implements TelemetryIntegration {
|
|
|
205
197
|
event.operationId === 'ai.generateObject' ||
|
|
206
198
|
event.operationId === 'ai.streamObject'
|
|
207
199
|
) {
|
|
208
|
-
this.onObjectOperationStart(
|
|
200
|
+
this.onObjectOperationStart(
|
|
201
|
+
event as InferTelemetryEvent<GenerateObjectStartEvent>,
|
|
202
|
+
);
|
|
209
203
|
return;
|
|
210
204
|
}
|
|
211
205
|
|
|
212
|
-
this.onGenerateStart(event as
|
|
206
|
+
this.onGenerateStart(event as InferTelemetryEvent<GenerateTextStartEvent>);
|
|
213
207
|
}
|
|
214
208
|
|
|
215
|
-
private onGenerateStart(
|
|
209
|
+
private onGenerateStart(
|
|
210
|
+
event: InferTelemetryEvent<GenerateTextStartEvent>,
|
|
211
|
+
): void {
|
|
216
212
|
const telemetry: TelemetryOptions = {
|
|
217
|
-
isEnabled: event.isEnabled,
|
|
218
213
|
recordInputs: event.recordInputs,
|
|
219
214
|
recordOutputs: event.recordOutputs,
|
|
220
215
|
functionId: event.functionId,
|
|
@@ -260,7 +255,7 @@ export class GenAIOpenTelemetryIntegration implements TelemetryIntegration {
|
|
|
260
255
|
input: () =>
|
|
261
256
|
JSON.stringify(
|
|
262
257
|
formatModelMessages({
|
|
263
|
-
prompt:
|
|
258
|
+
prompt: undefined,
|
|
264
259
|
messages: event.messages,
|
|
265
260
|
}),
|
|
266
261
|
),
|
|
@@ -281,6 +276,8 @@ export class GenAIOpenTelemetryIntegration implements TelemetryIntegration {
|
|
|
281
276
|
rootContext,
|
|
282
277
|
stepSpan: undefined,
|
|
283
278
|
stepContext: undefined,
|
|
279
|
+
inferenceSpan: undefined,
|
|
280
|
+
inferenceContext: undefined,
|
|
284
281
|
embedSpans: new Map(),
|
|
285
282
|
rerankSpan: undefined,
|
|
286
283
|
toolSpans: new Map(),
|
|
@@ -290,9 +287,10 @@ export class GenAIOpenTelemetryIntegration implements TelemetryIntegration {
|
|
|
290
287
|
});
|
|
291
288
|
}
|
|
292
289
|
|
|
293
|
-
private onObjectOperationStart(
|
|
290
|
+
private onObjectOperationStart(
|
|
291
|
+
event: InferTelemetryEvent<GenerateObjectStartEvent>,
|
|
292
|
+
): void {
|
|
294
293
|
const telemetry: TelemetryOptions = {
|
|
295
|
-
isEnabled: event.isEnabled,
|
|
296
294
|
recordInputs: event.recordInputs,
|
|
297
295
|
recordOutputs: event.recordOutputs,
|
|
298
296
|
functionId: event.functionId,
|
|
@@ -358,6 +356,8 @@ export class GenAIOpenTelemetryIntegration implements TelemetryIntegration {
|
|
|
358
356
|
rootContext,
|
|
359
357
|
stepSpan: undefined,
|
|
360
358
|
stepContext: undefined,
|
|
359
|
+
inferenceSpan: undefined,
|
|
360
|
+
inferenceContext: undefined,
|
|
361
361
|
embedSpans: new Map(),
|
|
362
362
|
rerankSpan: undefined,
|
|
363
363
|
toolSpans: new Map(),
|
|
@@ -368,7 +368,7 @@ export class GenAIOpenTelemetryIntegration implements TelemetryIntegration {
|
|
|
368
368
|
}
|
|
369
369
|
|
|
370
370
|
/** @deprecated */
|
|
371
|
-
onObjectStepStart(event:
|
|
371
|
+
onObjectStepStart(event: GenerateObjectStepStartEvent): void {
|
|
372
372
|
const state = this.getCallState(event.callId);
|
|
373
373
|
if (!state?.rootSpan || !state.rootContext) return;
|
|
374
374
|
|
|
@@ -403,22 +403,25 @@ export class GenAIOpenTelemetryIntegration implements TelemetryIntegration {
|
|
|
403
403
|
});
|
|
404
404
|
|
|
405
405
|
const spanName = `chat ${event.modelId}`;
|
|
406
|
-
state.
|
|
406
|
+
state.inferenceSpan = this.tracer.startSpan(
|
|
407
407
|
spanName,
|
|
408
408
|
{ attributes, kind: SpanKind.CLIENT },
|
|
409
409
|
state.rootContext,
|
|
410
410
|
);
|
|
411
|
-
state.
|
|
411
|
+
state.inferenceContext = trace.setSpan(
|
|
412
|
+
state.rootContext,
|
|
413
|
+
state.inferenceSpan,
|
|
414
|
+
);
|
|
412
415
|
}
|
|
413
416
|
|
|
414
417
|
/** @deprecated */
|
|
415
|
-
onObjectStepFinish(event:
|
|
418
|
+
onObjectStepFinish(event: GenerateObjectStepEndEvent): void {
|
|
416
419
|
const state = this.getCallState(event.callId);
|
|
417
|
-
if (!state?.
|
|
420
|
+
if (!state?.inferenceSpan) return;
|
|
418
421
|
|
|
419
422
|
const { telemetry } = state;
|
|
420
423
|
|
|
421
|
-
state.
|
|
424
|
+
state.inferenceSpan.setAttributes(
|
|
422
425
|
selectAttributes(telemetry, {
|
|
423
426
|
'gen_ai.response.finish_reasons': [event.finishReason],
|
|
424
427
|
'gen_ai.response.id': event.response.id,
|
|
@@ -443,14 +446,15 @@ export class GenAIOpenTelemetryIntegration implements TelemetryIntegration {
|
|
|
443
446
|
}),
|
|
444
447
|
);
|
|
445
448
|
|
|
446
|
-
state.
|
|
447
|
-
state.
|
|
448
|
-
state.
|
|
449
|
+
state.inferenceSpan.end();
|
|
450
|
+
state.inferenceSpan = undefined;
|
|
451
|
+
state.inferenceContext = undefined;
|
|
449
452
|
}
|
|
450
453
|
|
|
451
|
-
private onEmbedOperationStart(
|
|
454
|
+
private onEmbedOperationStart(
|
|
455
|
+
event: InferTelemetryEvent<EmbedStartEvent>,
|
|
456
|
+
): void {
|
|
452
457
|
const telemetry: TelemetryOptions = {
|
|
453
|
-
isEnabled: event.isEnabled,
|
|
454
458
|
recordInputs: event.recordInputs,
|
|
455
459
|
recordOutputs: event.recordOutputs,
|
|
456
460
|
functionId: event.functionId,
|
|
@@ -482,6 +486,8 @@ export class GenAIOpenTelemetryIntegration implements TelemetryIntegration {
|
|
|
482
486
|
rootContext,
|
|
483
487
|
stepSpan: undefined,
|
|
484
488
|
stepContext: undefined,
|
|
489
|
+
inferenceSpan: undefined,
|
|
490
|
+
inferenceContext: undefined,
|
|
485
491
|
embedSpans: new Map(),
|
|
486
492
|
rerankSpan: undefined,
|
|
487
493
|
toolSpans: new Map(),
|
|
@@ -491,14 +497,31 @@ export class GenAIOpenTelemetryIntegration implements TelemetryIntegration {
|
|
|
491
497
|
});
|
|
492
498
|
}
|
|
493
499
|
|
|
494
|
-
onStepStart(event:
|
|
500
|
+
onStepStart(event: GenerateTextStepStartEvent<ToolSet>): void {
|
|
495
501
|
const state = this.getCallState(event.callId);
|
|
496
502
|
if (!state?.rootSpan || !state.rootContext) return;
|
|
497
503
|
|
|
504
|
+
const { telemetry } = state;
|
|
505
|
+
const stepAttributes = selectAttributes(telemetry, {
|
|
506
|
+
'gen_ai.operation.name': 'agent_step',
|
|
507
|
+
});
|
|
508
|
+
|
|
509
|
+
state.stepSpan = this.tracer.startSpan(
|
|
510
|
+
`step ${event.steps.length + 1}`,
|
|
511
|
+
{ attributes: stepAttributes, kind: SpanKind.INTERNAL },
|
|
512
|
+
state.rootContext,
|
|
513
|
+
);
|
|
514
|
+
state.stepContext = trace.setSpan(state.rootContext, state.stepSpan);
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
onLanguageModelCallStart(event: LanguageModelCallStartEvent): void {
|
|
518
|
+
const state = this.getCallState(event.callId);
|
|
519
|
+
if (!state?.stepContext) return;
|
|
520
|
+
|
|
498
521
|
const { telemetry } = state;
|
|
499
522
|
const providerName = mapProviderName(event.provider);
|
|
500
523
|
|
|
501
|
-
const
|
|
524
|
+
const inferenceAttributes = selectAttributes(telemetry, {
|
|
502
525
|
'gen_ai.operation.name': 'chat',
|
|
503
526
|
'gen_ai.provider.name': providerName,
|
|
504
527
|
'gen_ai.request.model': event.modelId,
|
|
@@ -520,24 +543,74 @@ export class GenAIOpenTelemetryIntegration implements TelemetryIntegration {
|
|
|
520
543
|
'gen_ai.request.top_k': state.settings.topK as number | undefined,
|
|
521
544
|
'gen_ai.request.top_p': state.settings.topP as number | undefined,
|
|
522
545
|
'gen_ai.input.messages': {
|
|
523
|
-
input: () =>
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
:
|
|
546
|
+
input: () => {
|
|
547
|
+
const formattedMessages = formatModelMessages({
|
|
548
|
+
prompt: undefined,
|
|
549
|
+
messages: event.messages,
|
|
550
|
+
});
|
|
551
|
+
|
|
552
|
+
return formattedMessages.length > 0
|
|
553
|
+
? JSON.stringify(formattedMessages)
|
|
554
|
+
: undefined;
|
|
555
|
+
},
|
|
527
556
|
},
|
|
528
557
|
'gen_ai.tool.definitions': {
|
|
529
|
-
input: () =>
|
|
530
|
-
event.stepTools ? JSON.stringify(event.stepTools) : undefined,
|
|
558
|
+
input: () => (event.tools ? JSON.stringify(event.tools) : undefined),
|
|
531
559
|
},
|
|
532
560
|
});
|
|
533
561
|
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
562
|
+
state.inferenceSpan = this.tracer.startSpan(
|
|
563
|
+
`chat ${event.modelId}`,
|
|
564
|
+
{ attributes: inferenceAttributes, kind: SpanKind.CLIENT },
|
|
565
|
+
state.stepContext,
|
|
566
|
+
);
|
|
567
|
+
state.inferenceContext = trace.setSpan(
|
|
568
|
+
state.stepContext,
|
|
569
|
+
state.inferenceSpan,
|
|
539
570
|
);
|
|
540
|
-
|
|
571
|
+
}
|
|
572
|
+
|
|
573
|
+
onLanguageModelCallEnd(event: LanguageModelCallEndEvent<ToolSet>): void {
|
|
574
|
+
const state = this.getCallState(event.callId);
|
|
575
|
+
if (!state?.inferenceSpan) return;
|
|
576
|
+
|
|
577
|
+
const { telemetry } = state;
|
|
578
|
+
|
|
579
|
+
state.inferenceSpan.setAttributes(
|
|
580
|
+
selectAttributes(telemetry, {
|
|
581
|
+
'gen_ai.response.finish_reasons': [event.finishReason],
|
|
582
|
+
'gen_ai.response.id': event.responseId,
|
|
583
|
+
'gen_ai.usage.input_tokens': event.usage.inputTokens,
|
|
584
|
+
'gen_ai.usage.output_tokens': event.usage.outputTokens,
|
|
585
|
+
'gen_ai.usage.cache_read.input_tokens':
|
|
586
|
+
event.usage.inputTokenDetails?.cacheReadTokens ??
|
|
587
|
+
event.usage.cachedInputTokens,
|
|
588
|
+
'gen_ai.usage.cache_creation.input_tokens':
|
|
589
|
+
event.usage.inputTokenDetails?.cacheWriteTokens,
|
|
590
|
+
'gen_ai.output.messages': {
|
|
591
|
+
output: () =>
|
|
592
|
+
JSON.stringify(
|
|
593
|
+
formatOutputMessages({
|
|
594
|
+
text:
|
|
595
|
+
event.content
|
|
596
|
+
.filter(p => p.type === 'text')
|
|
597
|
+
.map(p => p.text)
|
|
598
|
+
.join('') || undefined,
|
|
599
|
+
reasoning: event.content.filter(p => p.type === 'reasoning'),
|
|
600
|
+
toolCalls: event.content.filter(p => p.type === 'tool-call'),
|
|
601
|
+
files: event.content
|
|
602
|
+
.filter(p => p.type === 'file')
|
|
603
|
+
.map(p => p.file),
|
|
604
|
+
finishReason: event.finishReason,
|
|
605
|
+
}),
|
|
606
|
+
),
|
|
607
|
+
},
|
|
608
|
+
}),
|
|
609
|
+
);
|
|
610
|
+
|
|
611
|
+
state.inferenceSpan.end();
|
|
612
|
+
state.inferenceSpan = undefined;
|
|
613
|
+
state.inferenceContext = undefined;
|
|
541
614
|
}
|
|
542
615
|
|
|
543
616
|
onToolExecutionStart(event: ToolExecutionStartEvent<ToolSet>): void {
|
|
@@ -581,12 +654,13 @@ export class GenAIOpenTelemetryIntegration implements TelemetryIntegration {
|
|
|
581
654
|
const { span } = toolSpanEntry;
|
|
582
655
|
const { telemetry } = state;
|
|
583
656
|
|
|
584
|
-
|
|
657
|
+
const { toolOutput } = event;
|
|
658
|
+
if (toolOutput.type === 'tool-result') {
|
|
585
659
|
try {
|
|
586
660
|
span.setAttributes(
|
|
587
661
|
selectAttributes(telemetry, {
|
|
588
662
|
'gen_ai.tool.call.result': {
|
|
589
|
-
output: () => JSON.stringify(
|
|
663
|
+
output: () => JSON.stringify(toolOutput.output),
|
|
590
664
|
},
|
|
591
665
|
}),
|
|
592
666
|
);
|
|
@@ -594,46 +668,17 @@ export class GenAIOpenTelemetryIntegration implements TelemetryIntegration {
|
|
|
594
668
|
// JSON.stringify might fail for non-serializable results
|
|
595
669
|
}
|
|
596
670
|
} else {
|
|
597
|
-
recordSpanError(span,
|
|
671
|
+
recordSpanError(span, toolOutput.error);
|
|
598
672
|
}
|
|
599
673
|
|
|
600
674
|
span.end();
|
|
601
675
|
state.toolSpans.delete(event.toolCall.toolCallId);
|
|
602
676
|
}
|
|
603
677
|
|
|
604
|
-
onStepFinish(event:
|
|
678
|
+
onStepFinish(event: GenerateTextStepEndEvent<ToolSet>): void {
|
|
605
679
|
const state = this.getCallState(event.callId);
|
|
606
680
|
if (!state?.stepSpan) return;
|
|
607
681
|
|
|
608
|
-
const { telemetry } = state;
|
|
609
|
-
|
|
610
|
-
state.stepSpan.setAttributes(
|
|
611
|
-
selectAttributes(telemetry, {
|
|
612
|
-
'gen_ai.response.finish_reasons': [event.finishReason],
|
|
613
|
-
'gen_ai.response.id': event.response.id,
|
|
614
|
-
'gen_ai.response.model': event.response.modelId,
|
|
615
|
-
'gen_ai.usage.input_tokens': event.usage.inputTokens,
|
|
616
|
-
'gen_ai.usage.output_tokens': event.usage.outputTokens,
|
|
617
|
-
'gen_ai.usage.cache_read.input_tokens':
|
|
618
|
-
event.usage.inputTokenDetails?.cacheReadTokens ??
|
|
619
|
-
event.usage.cachedInputTokens,
|
|
620
|
-
'gen_ai.usage.cache_creation.input_tokens':
|
|
621
|
-
event.usage.inputTokenDetails?.cacheWriteTokens,
|
|
622
|
-
'gen_ai.output.messages': {
|
|
623
|
-
output: () =>
|
|
624
|
-
JSON.stringify(
|
|
625
|
-
formatOutputMessages({
|
|
626
|
-
text: event.text ?? undefined,
|
|
627
|
-
reasoning: event.reasoning as ReadonlyArray<{ text?: string }>,
|
|
628
|
-
toolCalls: event.toolCalls,
|
|
629
|
-
files: event.files,
|
|
630
|
-
finishReason: event.finishReason,
|
|
631
|
-
}),
|
|
632
|
-
),
|
|
633
|
-
},
|
|
634
|
-
}),
|
|
635
|
-
);
|
|
636
|
-
|
|
637
682
|
state.stepSpan.end();
|
|
638
683
|
state.stepSpan = undefined;
|
|
639
684
|
state.stepContext = undefined;
|
|
@@ -641,10 +686,10 @@ export class GenAIOpenTelemetryIntegration implements TelemetryIntegration {
|
|
|
641
686
|
|
|
642
687
|
onFinish(
|
|
643
688
|
event:
|
|
644
|
-
|
|
|
645
|
-
|
|
|
646
|
-
|
|
|
647
|
-
|
|
|
689
|
+
| GenerateTextEndEvent<ToolSet>
|
|
690
|
+
| GenerateObjectEndEvent<unknown>
|
|
691
|
+
| EmbedEndEvent
|
|
692
|
+
| RerankEndEvent,
|
|
648
693
|
): void {
|
|
649
694
|
const state = this.getCallState(event.callId);
|
|
650
695
|
if (!state?.rootSpan) return;
|
|
@@ -653,12 +698,12 @@ export class GenAIOpenTelemetryIntegration implements TelemetryIntegration {
|
|
|
653
698
|
state.operationId === 'ai.embed' ||
|
|
654
699
|
state.operationId === 'ai.embedMany'
|
|
655
700
|
) {
|
|
656
|
-
this.onEmbedOperationFinish(event as
|
|
701
|
+
this.onEmbedOperationFinish(event as EmbedEndEvent);
|
|
657
702
|
return;
|
|
658
703
|
}
|
|
659
704
|
|
|
660
705
|
if (state.operationId === 'ai.rerank') {
|
|
661
|
-
this.onRerankOperationFinish(event as
|
|
706
|
+
this.onRerankOperationFinish(event as RerankEndEvent);
|
|
662
707
|
return;
|
|
663
708
|
}
|
|
664
709
|
|
|
@@ -666,14 +711,14 @@ export class GenAIOpenTelemetryIntegration implements TelemetryIntegration {
|
|
|
666
711
|
state.operationId === 'ai.generateObject' ||
|
|
667
712
|
state.operationId === 'ai.streamObject'
|
|
668
713
|
) {
|
|
669
|
-
this.onObjectOperationFinish(event as
|
|
714
|
+
this.onObjectOperationFinish(event as GenerateObjectEndEvent<unknown>);
|
|
670
715
|
return;
|
|
671
716
|
}
|
|
672
717
|
|
|
673
|
-
this.onGenerateFinish(event as
|
|
718
|
+
this.onGenerateFinish(event as GenerateTextEndEvent<ToolSet>);
|
|
674
719
|
}
|
|
675
720
|
|
|
676
|
-
private onGenerateFinish(event:
|
|
721
|
+
private onGenerateFinish(event: GenerateTextEndEvent<ToolSet>): void {
|
|
677
722
|
const state = this.getCallState(event.callId);
|
|
678
723
|
if (!state?.rootSpan) return;
|
|
679
724
|
|
|
@@ -708,7 +753,9 @@ export class GenAIOpenTelemetryIntegration implements TelemetryIntegration {
|
|
|
708
753
|
this.cleanupCallState(event.callId);
|
|
709
754
|
}
|
|
710
755
|
|
|
711
|
-
private onObjectOperationFinish(
|
|
756
|
+
private onObjectOperationFinish(
|
|
757
|
+
event: GenerateObjectEndEvent<unknown>,
|
|
758
|
+
): void {
|
|
712
759
|
const state = this.getCallState(event.callId);
|
|
713
760
|
if (!state?.rootSpan) return;
|
|
714
761
|
|
|
@@ -738,7 +785,7 @@ export class GenAIOpenTelemetryIntegration implements TelemetryIntegration {
|
|
|
738
785
|
this.cleanupCallState(event.callId);
|
|
739
786
|
}
|
|
740
787
|
|
|
741
|
-
private onEmbedOperationFinish(event:
|
|
788
|
+
private onEmbedOperationFinish(event: EmbedEndEvent): void {
|
|
742
789
|
const state = this.getCallState(event.callId);
|
|
743
790
|
if (!state?.rootSpan) return;
|
|
744
791
|
|
|
@@ -754,7 +801,7 @@ export class GenAIOpenTelemetryIntegration implements TelemetryIntegration {
|
|
|
754
801
|
this.cleanupCallState(event.callId);
|
|
755
802
|
}
|
|
756
803
|
|
|
757
|
-
onEmbedStart(event:
|
|
804
|
+
onEmbedStart(event: EmbeddingModelCallStartEvent): void {
|
|
758
805
|
const state = this.getCallState(event.callId);
|
|
759
806
|
if (!state?.rootSpan || !state.rootContext) return;
|
|
760
807
|
|
|
@@ -781,7 +828,7 @@ export class GenAIOpenTelemetryIntegration implements TelemetryIntegration {
|
|
|
781
828
|
});
|
|
782
829
|
}
|
|
783
830
|
|
|
784
|
-
onEmbedFinish(event:
|
|
831
|
+
onEmbedFinish(event: EmbeddingModelCallEndEvent): void {
|
|
785
832
|
const state = this.getCallState(event.callId);
|
|
786
833
|
if (!state) return;
|
|
787
834
|
|
|
@@ -801,9 +848,10 @@ export class GenAIOpenTelemetryIntegration implements TelemetryIntegration {
|
|
|
801
848
|
state.embedSpans.delete(event.embedCallId);
|
|
802
849
|
}
|
|
803
850
|
|
|
804
|
-
private onRerankOperationStart(
|
|
851
|
+
private onRerankOperationStart(
|
|
852
|
+
event: InferTelemetryEvent<RerankStartEvent>,
|
|
853
|
+
): void {
|
|
805
854
|
const telemetry: TelemetryOptions = {
|
|
806
|
-
isEnabled: event.isEnabled,
|
|
807
855
|
recordInputs: event.recordInputs,
|
|
808
856
|
recordOutputs: event.recordOutputs,
|
|
809
857
|
functionId: event.functionId,
|
|
@@ -835,6 +883,8 @@ export class GenAIOpenTelemetryIntegration implements TelemetryIntegration {
|
|
|
835
883
|
rootContext,
|
|
836
884
|
stepSpan: undefined,
|
|
837
885
|
stepContext: undefined,
|
|
886
|
+
inferenceSpan: undefined,
|
|
887
|
+
inferenceContext: undefined,
|
|
838
888
|
embedSpans: new Map(),
|
|
839
889
|
rerankSpan: undefined,
|
|
840
890
|
toolSpans: new Map(),
|
|
@@ -844,7 +894,7 @@ export class GenAIOpenTelemetryIntegration implements TelemetryIntegration {
|
|
|
844
894
|
});
|
|
845
895
|
}
|
|
846
896
|
|
|
847
|
-
private onRerankOperationFinish(event:
|
|
897
|
+
private onRerankOperationFinish(event: RerankEndEvent): void {
|
|
848
898
|
const state = this.getCallState(event.callId);
|
|
849
899
|
if (!state?.rootSpan) return;
|
|
850
900
|
|
|
@@ -852,7 +902,7 @@ export class GenAIOpenTelemetryIntegration implements TelemetryIntegration {
|
|
|
852
902
|
this.cleanupCallState(event.callId);
|
|
853
903
|
}
|
|
854
904
|
|
|
855
|
-
onRerankStart(event:
|
|
905
|
+
onRerankStart(event: RerankingModelCallStartEvent): void {
|
|
856
906
|
const state = this.getCallState(event.callId);
|
|
857
907
|
if (!state?.rootSpan || !state.rootContext) return;
|
|
858
908
|
|
|
@@ -876,7 +926,7 @@ export class GenAIOpenTelemetryIntegration implements TelemetryIntegration {
|
|
|
876
926
|
state.rerankSpan = { span: rerankSpan, context: rerankContext };
|
|
877
927
|
}
|
|
878
928
|
|
|
879
|
-
onRerankFinish(event:
|
|
929
|
+
onRerankFinish(event: RerankingModelCallEndEvent): void {
|
|
880
930
|
const state = this.getCallState(event.callId);
|
|
881
931
|
if (!state?.rerankSpan) return;
|
|
882
932
|
|
|
@@ -886,7 +936,7 @@ export class GenAIOpenTelemetryIntegration implements TelemetryIntegration {
|
|
|
886
936
|
state.rerankSpan = undefined;
|
|
887
937
|
}
|
|
888
938
|
|
|
889
|
-
onChunk(_event:
|
|
939
|
+
onChunk(_event: StreamTextChunkEvent<ToolSet>): void {
|
|
890
940
|
// No-op: streaming chunk events are not part of the GenAI SemConv.
|
|
891
941
|
}
|
|
892
942
|
|
|
@@ -899,9 +949,24 @@ export class GenAIOpenTelemetryIntegration implements TelemetryIntegration {
|
|
|
899
949
|
|
|
900
950
|
const actualError = event.error ?? error;
|
|
901
951
|
|
|
952
|
+
for (const { span: toolSpan } of state.toolSpans.values()) {
|
|
953
|
+
recordSpanError(toolSpan, actualError);
|
|
954
|
+
toolSpan.end();
|
|
955
|
+
}
|
|
956
|
+
state.toolSpans.clear();
|
|
957
|
+
|
|
958
|
+
if (state.inferenceSpan) {
|
|
959
|
+
recordSpanError(state.inferenceSpan, actualError);
|
|
960
|
+
state.inferenceSpan.end();
|
|
961
|
+
state.inferenceSpan = undefined;
|
|
962
|
+
state.inferenceContext = undefined;
|
|
963
|
+
}
|
|
964
|
+
|
|
902
965
|
if (state.stepSpan) {
|
|
903
966
|
recordSpanError(state.stepSpan, actualError);
|
|
904
967
|
state.stepSpan.end();
|
|
968
|
+
state.stepSpan = undefined;
|
|
969
|
+
state.stepContext = undefined;
|
|
905
970
|
}
|
|
906
971
|
|
|
907
972
|
for (const { span: embedSpan } of state.embedSpans.values()) {
|