@ai-sdk/otel 1.0.127 → 1.0.128
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 +15 -0
- package/dist/index.d.ts +33 -15
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +106 -65
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
- package/src/legacy-open-telemetry.ts +79 -38
- package/src/open-telemetry.ts +93 -47
- package/src/supplemental-attributes.ts +9 -5
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ai-sdk/otel",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.128",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"sideEffects": false,
|
|
@@ -26,12 +26,12 @@
|
|
|
26
26
|
}
|
|
27
27
|
},
|
|
28
28
|
"dependencies": {
|
|
29
|
-
"@ai-sdk/provider": "4.0.
|
|
29
|
+
"@ai-sdk/provider": "4.0.22",
|
|
30
30
|
"@opentelemetry/api": "1.9.1",
|
|
31
|
-
"ai": "7.0.
|
|
31
|
+
"ai": "7.0.128"
|
|
32
32
|
},
|
|
33
33
|
"devDependencies": {
|
|
34
|
-
"@ai-sdk/provider-utils": "5.0.
|
|
34
|
+
"@ai-sdk/provider-utils": "5.0.54",
|
|
35
35
|
"@opentelemetry/sdk-trace-base": "2.7.1",
|
|
36
36
|
"@types/node": "22.19.19",
|
|
37
37
|
"@vercel/ai-tsconfig": "0.0.0",
|
|
@@ -28,10 +28,10 @@ import type {
|
|
|
28
28
|
GenerateSpeechStartEvent,
|
|
29
29
|
ToolExecutionEndEvent,
|
|
30
30
|
ToolExecutionStartEvent,
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
31
|
+
Experimental_DecideEndEvent as DecideEndEvent,
|
|
32
|
+
Experimental_DecideStartEvent as DecideStartEvent,
|
|
33
|
+
Experimental_DecisionModelCallEndEvent as DecisionModelCallEndEvent,
|
|
34
|
+
Experimental_DecisionModelCallStartEvent as DecisionModelCallStartEvent,
|
|
35
35
|
Output,
|
|
36
36
|
RerankingModelCallEndEvent,
|
|
37
37
|
RerankEndEvent,
|
|
@@ -147,7 +147,7 @@ interface CallState {
|
|
|
147
147
|
stepContext: OpenTelemetryContext | undefined;
|
|
148
148
|
embedSpans: Map<string, { span: Span; context: OpenTelemetryContext }>;
|
|
149
149
|
rerankSpan: { span: Span; context: OpenTelemetryContext } | undefined;
|
|
150
|
-
|
|
150
|
+
decisionSpan: { span: Span; context: OpenTelemetryContext } | undefined;
|
|
151
151
|
toolSpans: Map<string, { span: Span; context: OpenTelemetryContext }>;
|
|
152
152
|
baseTelemetryAttributes: Attributes;
|
|
153
153
|
settings: Record<string, unknown>;
|
|
@@ -322,7 +322,7 @@ export class LegacyOpenTelemetry implements Telemetry {
|
|
|
322
322
|
stepContext: undefined,
|
|
323
323
|
embedSpans: new Map(),
|
|
324
324
|
rerankSpan: undefined,
|
|
325
|
-
|
|
325
|
+
decisionSpan: undefined,
|
|
326
326
|
toolSpans: new Map(),
|
|
327
327
|
baseTelemetryAttributes,
|
|
328
328
|
settings: {},
|
|
@@ -386,7 +386,7 @@ export class LegacyOpenTelemetry implements Telemetry {
|
|
|
386
386
|
stepContext: undefined,
|
|
387
387
|
embedSpans: new Map(),
|
|
388
388
|
rerankSpan: undefined,
|
|
389
|
-
|
|
389
|
+
decisionSpan: undefined,
|
|
390
390
|
toolSpans: new Map(),
|
|
391
391
|
baseTelemetryAttributes,
|
|
392
392
|
settings,
|
|
@@ -454,7 +454,7 @@ export class LegacyOpenTelemetry implements Telemetry {
|
|
|
454
454
|
stepContext: undefined,
|
|
455
455
|
embedSpans: new Map(),
|
|
456
456
|
rerankSpan: undefined,
|
|
457
|
-
|
|
457
|
+
decisionSpan: undefined,
|
|
458
458
|
toolSpans: new Map(),
|
|
459
459
|
baseTelemetryAttributes,
|
|
460
460
|
settings,
|
|
@@ -517,6 +517,10 @@ export class LegacyOpenTelemetry implements Telemetry {
|
|
|
517
517
|
const state = this.getCallState(event.callId);
|
|
518
518
|
if (!state?.stepSpan) return;
|
|
519
519
|
|
|
520
|
+
if (event.finishReason === 'error') {
|
|
521
|
+
state.stepSpan.setStatus({ code: SpanStatusCode.ERROR });
|
|
522
|
+
}
|
|
523
|
+
|
|
520
524
|
const { telemetry } = state;
|
|
521
525
|
|
|
522
526
|
state.stepSpan.setAttributes(
|
|
@@ -622,7 +626,7 @@ export class LegacyOpenTelemetry implements Telemetry {
|
|
|
622
626
|
stepContext: undefined,
|
|
623
627
|
embedSpans: new Map(),
|
|
624
628
|
rerankSpan: undefined,
|
|
625
|
-
|
|
629
|
+
decisionSpan: undefined,
|
|
626
630
|
toolSpans: new Map(),
|
|
627
631
|
baseTelemetryAttributes,
|
|
628
632
|
settings,
|
|
@@ -766,6 +770,10 @@ export class LegacyOpenTelemetry implements Telemetry {
|
|
|
766
770
|
const state = this.getCallState(event.callId);
|
|
767
771
|
if (!state?.stepSpan) return;
|
|
768
772
|
|
|
773
|
+
if (event.finishReason === 'error') {
|
|
774
|
+
state.stepSpan.setStatus({ code: SpanStatusCode.ERROR });
|
|
775
|
+
}
|
|
776
|
+
|
|
769
777
|
const { telemetry } = state;
|
|
770
778
|
const isStreamText = state.operationId === 'ai.streamText';
|
|
771
779
|
|
|
@@ -977,6 +985,10 @@ export class LegacyOpenTelemetry implements Telemetry {
|
|
|
977
985
|
const state = this.getCallState(event.callId);
|
|
978
986
|
if (!state?.rootSpan) return;
|
|
979
987
|
|
|
988
|
+
if (event.finishReason === 'error') {
|
|
989
|
+
state.rootSpan.setStatus({ code: SpanStatusCode.ERROR });
|
|
990
|
+
}
|
|
991
|
+
|
|
980
992
|
const { telemetry } = state;
|
|
981
993
|
|
|
982
994
|
state.rootSpan.setAttributes(
|
|
@@ -1050,6 +1062,10 @@ export class LegacyOpenTelemetry implements Telemetry {
|
|
|
1050
1062
|
const state = this.getCallState(event.callId);
|
|
1051
1063
|
if (!state?.rootSpan) return;
|
|
1052
1064
|
|
|
1065
|
+
if (event.finishReason === 'error') {
|
|
1066
|
+
state.rootSpan.setStatus({ code: SpanStatusCode.ERROR });
|
|
1067
|
+
}
|
|
1068
|
+
|
|
1053
1069
|
const { telemetry } = state;
|
|
1054
1070
|
|
|
1055
1071
|
state.rootSpan.setAttributes(
|
|
@@ -1203,7 +1219,7 @@ export class LegacyOpenTelemetry implements Telemetry {
|
|
|
1203
1219
|
stepContext: undefined,
|
|
1204
1220
|
embedSpans: new Map(),
|
|
1205
1221
|
rerankSpan: undefined,
|
|
1206
|
-
|
|
1222
|
+
decisionSpan: undefined,
|
|
1207
1223
|
toolSpans: new Map(),
|
|
1208
1224
|
baseTelemetryAttributes,
|
|
1209
1225
|
settings,
|
|
@@ -1265,8 +1281,8 @@ export class LegacyOpenTelemetry implements Telemetry {
|
|
|
1265
1281
|
state.rerankSpan = undefined;
|
|
1266
1282
|
}
|
|
1267
1283
|
|
|
1268
|
-
private
|
|
1269
|
-
event: InferTelemetryEvent<
|
|
1284
|
+
private onDecideOperationStart(
|
|
1285
|
+
event: InferTelemetryEvent<DecideStartEvent>,
|
|
1270
1286
|
): void {
|
|
1271
1287
|
const telemetry: TelemetryOptions = {
|
|
1272
1288
|
recordInputs: event.recordInputs,
|
|
@@ -1285,10 +1301,10 @@ export class LegacyOpenTelemetry implements Telemetry {
|
|
|
1285
1301
|
const attributes = selectAttributes(telemetry, {
|
|
1286
1302
|
...assembleOperationName({ operationId: event.operationId, telemetry }),
|
|
1287
1303
|
...baseTelemetryAttributes,
|
|
1288
|
-
'ai.
|
|
1304
|
+
'ai.decision.state': {
|
|
1289
1305
|
input: () => JSON.stringify(event.state),
|
|
1290
1306
|
},
|
|
1291
|
-
'ai.
|
|
1307
|
+
'ai.decision.questions': {
|
|
1292
1308
|
input: () => JSON.stringify(event.questions),
|
|
1293
1309
|
},
|
|
1294
1310
|
});
|
|
@@ -1304,20 +1320,20 @@ export class LegacyOpenTelemetry implements Telemetry {
|
|
|
1304
1320
|
stepContext: undefined,
|
|
1305
1321
|
embedSpans: new Map(),
|
|
1306
1322
|
rerankSpan: undefined,
|
|
1307
|
-
|
|
1323
|
+
decisionSpan: undefined,
|
|
1308
1324
|
toolSpans: new Map(),
|
|
1309
1325
|
baseTelemetryAttributes,
|
|
1310
1326
|
settings,
|
|
1311
1327
|
});
|
|
1312
1328
|
}
|
|
1313
1329
|
|
|
1314
|
-
private
|
|
1330
|
+
private onDecideOperationEnd(event: DecideEndEvent): void {
|
|
1315
1331
|
const state = this.getCallState(event.callId);
|
|
1316
1332
|
if (!state?.rootSpan) return;
|
|
1317
1333
|
|
|
1318
1334
|
state.rootSpan.setAttributes(
|
|
1319
1335
|
selectAttributes(state.telemetry, {
|
|
1320
|
-
'ai.
|
|
1336
|
+
'ai.decision.answers': {
|
|
1321
1337
|
output: () => JSON.stringify(event.answers),
|
|
1322
1338
|
},
|
|
1323
1339
|
}),
|
|
@@ -1326,18 +1342,42 @@ export class LegacyOpenTelemetry implements Telemetry {
|
|
|
1326
1342
|
this.cleanupCallState(event.callId);
|
|
1327
1343
|
}
|
|
1328
1344
|
|
|
1345
|
+
// Route through deprecated hooks to preserve existing subclass overrides.
|
|
1346
|
+
experimental_onDecideStart(
|
|
1347
|
+
event: InferTelemetryEvent<DecideStartEvent>,
|
|
1348
|
+
): void {
|
|
1349
|
+
this.experimental_onEvaluateStart(event);
|
|
1350
|
+
}
|
|
1351
|
+
|
|
1352
|
+
experimental_onDecideEnd(event: DecideEndEvent): void {
|
|
1353
|
+
this.experimental_onEvaluateEnd(event);
|
|
1354
|
+
}
|
|
1355
|
+
|
|
1356
|
+
experimental_onDecisionModelCallStart(
|
|
1357
|
+
event: DecisionModelCallStartEvent,
|
|
1358
|
+
): void {
|
|
1359
|
+
this.experimental_onEvaluationModelCallStart(event);
|
|
1360
|
+
}
|
|
1361
|
+
|
|
1362
|
+
experimental_onDecisionModelCallEnd(event: DecisionModelCallEndEvent): void {
|
|
1363
|
+
this.experimental_onEvaluationModelCallEnd(event);
|
|
1364
|
+
}
|
|
1365
|
+
|
|
1366
|
+
/** @deprecated Use `experimental_onDecideStart` instead. */
|
|
1329
1367
|
experimental_onEvaluateStart(
|
|
1330
|
-
event: InferTelemetryEvent<
|
|
1368
|
+
event: InferTelemetryEvent<DecideStartEvent>,
|
|
1331
1369
|
): void {
|
|
1332
|
-
this.
|
|
1370
|
+
this.onDecideOperationStart(event);
|
|
1333
1371
|
}
|
|
1334
1372
|
|
|
1335
|
-
|
|
1336
|
-
|
|
1373
|
+
/** @deprecated Use `experimental_onDecideEnd` instead. */
|
|
1374
|
+
experimental_onEvaluateEnd(event: DecideEndEvent): void {
|
|
1375
|
+
this.onDecideOperationEnd(event);
|
|
1337
1376
|
}
|
|
1338
1377
|
|
|
1378
|
+
/** @deprecated Use `experimental_onDecisionModelCallStart` instead. */
|
|
1339
1379
|
experimental_onEvaluationModelCallStart(
|
|
1340
|
-
event:
|
|
1380
|
+
event: InferTelemetryEvent<DecisionModelCallStartEvent>,
|
|
1341
1381
|
): void {
|
|
1342
1382
|
const state = this.getCallState(event.callId);
|
|
1343
1383
|
if (!state?.rootSpan || !state.rootContext) return;
|
|
@@ -1348,10 +1388,10 @@ export class LegacyOpenTelemetry implements Telemetry {
|
|
|
1348
1388
|
telemetry: state.telemetry,
|
|
1349
1389
|
}),
|
|
1350
1390
|
...state.baseTelemetryAttributes,
|
|
1351
|
-
'ai.
|
|
1391
|
+
'ai.decision.state': {
|
|
1352
1392
|
input: () => JSON.stringify(event.state),
|
|
1353
1393
|
},
|
|
1354
|
-
'ai.
|
|
1394
|
+
'ai.decision.questions': {
|
|
1355
1395
|
input: () => JSON.stringify(event.questions),
|
|
1356
1396
|
},
|
|
1357
1397
|
});
|
|
@@ -1360,21 +1400,22 @@ export class LegacyOpenTelemetry implements Telemetry {
|
|
|
1360
1400
|
{ attributes },
|
|
1361
1401
|
state.rootContext,
|
|
1362
1402
|
);
|
|
1363
|
-
state.
|
|
1403
|
+
state.decisionSpan = {
|
|
1364
1404
|
span,
|
|
1365
1405
|
context: trace.setSpan(state.rootContext, span),
|
|
1366
1406
|
};
|
|
1367
1407
|
}
|
|
1368
1408
|
|
|
1409
|
+
/** @deprecated Use `experimental_onDecisionModelCallEnd` instead. */
|
|
1369
1410
|
experimental_onEvaluationModelCallEnd(
|
|
1370
|
-
event:
|
|
1411
|
+
event: InferTelemetryEvent<DecisionModelCallEndEvent>,
|
|
1371
1412
|
): void {
|
|
1372
1413
|
const state = this.getCallState(event.callId);
|
|
1373
|
-
if (!state?.
|
|
1414
|
+
if (!state?.decisionSpan) return;
|
|
1374
1415
|
|
|
1375
|
-
state.
|
|
1416
|
+
state.decisionSpan.span.setAttributes(
|
|
1376
1417
|
selectAttributes(state.telemetry, {
|
|
1377
|
-
'ai.
|
|
1418
|
+
'ai.decision.answers': {
|
|
1378
1419
|
output: () => JSON.stringify(event.answers),
|
|
1379
1420
|
},
|
|
1380
1421
|
'ai.usage.inputTokens': event.usage?.inputTokens,
|
|
@@ -1384,8 +1425,8 @@ export class LegacyOpenTelemetry implements Telemetry {
|
|
|
1384
1425
|
: undefined,
|
|
1385
1426
|
}),
|
|
1386
1427
|
);
|
|
1387
|
-
state.
|
|
1388
|
-
state.
|
|
1428
|
+
state.decisionSpan.span.end();
|
|
1429
|
+
state.decisionSpan = undefined;
|
|
1389
1430
|
}
|
|
1390
1431
|
|
|
1391
1432
|
onAbort(event: GenerateTextAbortEvent<ToolSet>): void {
|
|
@@ -1413,9 +1454,9 @@ export class LegacyOpenTelemetry implements Telemetry {
|
|
|
1413
1454
|
state.rerankSpan = undefined;
|
|
1414
1455
|
}
|
|
1415
1456
|
|
|
1416
|
-
if (state.
|
|
1417
|
-
state.
|
|
1418
|
-
state.
|
|
1457
|
+
if (state.decisionSpan) {
|
|
1458
|
+
state.decisionSpan.span.end();
|
|
1459
|
+
state.decisionSpan = undefined;
|
|
1419
1460
|
}
|
|
1420
1461
|
|
|
1421
1462
|
state.rootSpan.end();
|
|
@@ -1448,10 +1489,10 @@ export class LegacyOpenTelemetry implements Telemetry {
|
|
|
1448
1489
|
state.rerankSpan = undefined;
|
|
1449
1490
|
}
|
|
1450
1491
|
|
|
1451
|
-
if (state.
|
|
1452
|
-
recordSpanError(state.
|
|
1453
|
-
state.
|
|
1454
|
-
state.
|
|
1492
|
+
if (state.decisionSpan) {
|
|
1493
|
+
recordSpanError(state.decisionSpan.span, actualError);
|
|
1494
|
+
state.decisionSpan.span.end();
|
|
1495
|
+
state.decisionSpan = undefined;
|
|
1455
1496
|
}
|
|
1456
1497
|
|
|
1457
1498
|
recordSpanError(state.rootSpan, actualError);
|
package/src/open-telemetry.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
context,
|
|
3
3
|
SpanKind,
|
|
4
|
+
SpanStatusCode,
|
|
4
5
|
trace,
|
|
5
6
|
type Attributes,
|
|
6
7
|
type Context as OpenTelemetryContext,
|
|
@@ -27,10 +28,10 @@ import type {
|
|
|
27
28
|
GenerateSpeechStartEvent,
|
|
28
29
|
ToolExecutionEndEvent,
|
|
29
30
|
ToolExecutionStartEvent,
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
31
|
+
Experimental_DecideEndEvent as DecideEndEvent,
|
|
32
|
+
Experimental_DecideStartEvent as DecideStartEvent,
|
|
33
|
+
Experimental_DecisionModelCallEndEvent as DecisionModelCallEndEvent,
|
|
34
|
+
Experimental_DecisionModelCallStartEvent as DecisionModelCallStartEvent,
|
|
34
35
|
RerankingModelCallEndEvent,
|
|
35
36
|
RerankEndEvent,
|
|
36
37
|
RerankStartEvent,
|
|
@@ -91,7 +92,7 @@ interface CallState {
|
|
|
91
92
|
inferenceToolDefinitions?: ReadonlyArray<Record<string, unknown>>;
|
|
92
93
|
embedSpans: Map<string, { span: Span; context: OpenTelemetryContext }>;
|
|
93
94
|
rerankSpan: { span: Span; context: OpenTelemetryContext } | undefined;
|
|
94
|
-
|
|
95
|
+
decisionSpan: { span: Span; context: OpenTelemetryContext } | undefined;
|
|
95
96
|
toolSpans: Map<string, { span: Span; context: OpenTelemetryContext }>;
|
|
96
97
|
settings: Record<string, unknown>;
|
|
97
98
|
provider: string;
|
|
@@ -348,7 +349,7 @@ export class OpenTelemetry implements Telemetry {
|
|
|
348
349
|
inferenceContext: undefined,
|
|
349
350
|
embedSpans: new Map(),
|
|
350
351
|
rerankSpan: undefined,
|
|
351
|
-
|
|
352
|
+
decisionSpan: undefined,
|
|
352
353
|
toolSpans: new Map(),
|
|
353
354
|
settings: {},
|
|
354
355
|
provider: event.provider,
|
|
@@ -451,7 +452,7 @@ export class OpenTelemetry implements Telemetry {
|
|
|
451
452
|
inferenceContext: undefined,
|
|
452
453
|
embedSpans: new Map(),
|
|
453
454
|
rerankSpan: undefined,
|
|
454
|
-
|
|
455
|
+
decisionSpan: undefined,
|
|
455
456
|
toolSpans: new Map(),
|
|
456
457
|
settings,
|
|
457
458
|
provider: event.provider,
|
|
@@ -558,7 +559,7 @@ export class OpenTelemetry implements Telemetry {
|
|
|
558
559
|
inferenceContext: undefined,
|
|
559
560
|
embedSpans: new Map(),
|
|
560
561
|
rerankSpan: undefined,
|
|
561
|
-
|
|
562
|
+
decisionSpan: undefined,
|
|
562
563
|
toolSpans: new Map(),
|
|
563
564
|
settings,
|
|
564
565
|
provider: event.provider,
|
|
@@ -645,6 +646,10 @@ export class OpenTelemetry implements Telemetry {
|
|
|
645
646
|
const state = this.getCallState(event.callId);
|
|
646
647
|
if (!state?.inferenceSpan) return;
|
|
647
648
|
|
|
649
|
+
if (event.finishReason === 'error') {
|
|
650
|
+
state.inferenceSpan.setStatus({ code: SpanStatusCode.ERROR });
|
|
651
|
+
}
|
|
652
|
+
|
|
648
653
|
const { telemetry } = state;
|
|
649
654
|
|
|
650
655
|
state.inferenceSpan.setAttributes(
|
|
@@ -757,7 +762,7 @@ export class OpenTelemetry implements Telemetry {
|
|
|
757
762
|
inferenceContext: undefined,
|
|
758
763
|
embedSpans: new Map(),
|
|
759
764
|
rerankSpan: undefined,
|
|
760
|
-
|
|
765
|
+
decisionSpan: undefined,
|
|
761
766
|
toolSpans: new Map(),
|
|
762
767
|
settings: { maxRetries: event.maxRetries },
|
|
763
768
|
provider: event.provider,
|
|
@@ -884,6 +889,10 @@ export class OpenTelemetry implements Telemetry {
|
|
|
884
889
|
const state = this.getCallState(event.callId);
|
|
885
890
|
if (!state?.inferenceSpan) return;
|
|
886
891
|
|
|
892
|
+
if (event.finishReason === 'error') {
|
|
893
|
+
state.inferenceSpan.setStatus({ code: SpanStatusCode.ERROR });
|
|
894
|
+
}
|
|
895
|
+
|
|
887
896
|
const { telemetry } = state;
|
|
888
897
|
const providerName = mapProviderName(event.provider);
|
|
889
898
|
const toolDefinitions = [...(state.inferenceToolDefinitions ?? [])];
|
|
@@ -1123,6 +1132,10 @@ export class OpenTelemetry implements Telemetry {
|
|
|
1123
1132
|
const state = this.getCallState(event.callId);
|
|
1124
1133
|
if (!state?.stepSpan) return;
|
|
1125
1134
|
|
|
1135
|
+
if (event.finishReason === 'error') {
|
|
1136
|
+
state.stepSpan.setStatus({ code: SpanStatusCode.ERROR });
|
|
1137
|
+
}
|
|
1138
|
+
|
|
1126
1139
|
const { telemetry } = state;
|
|
1127
1140
|
|
|
1128
1141
|
state.stepSpan.setAttributes(
|
|
@@ -1280,6 +1293,10 @@ export class OpenTelemetry implements Telemetry {
|
|
|
1280
1293
|
const state = this.getCallState(event.callId);
|
|
1281
1294
|
if (!state?.rootSpan) return;
|
|
1282
1295
|
|
|
1296
|
+
if (event.finishReason === 'error') {
|
|
1297
|
+
state.rootSpan.setStatus({ code: SpanStatusCode.ERROR });
|
|
1298
|
+
}
|
|
1299
|
+
|
|
1283
1300
|
const { telemetry } = state;
|
|
1284
1301
|
|
|
1285
1302
|
state.rootSpan.setAttributes(
|
|
@@ -1329,6 +1346,10 @@ export class OpenTelemetry implements Telemetry {
|
|
|
1329
1346
|
const state = this.getCallState(event.callId);
|
|
1330
1347
|
if (!state?.rootSpan) return;
|
|
1331
1348
|
|
|
1349
|
+
if (event.finishReason === 'error') {
|
|
1350
|
+
state.rootSpan.setStatus({ code: SpanStatusCode.ERROR });
|
|
1351
|
+
}
|
|
1352
|
+
|
|
1332
1353
|
const { telemetry } = state;
|
|
1333
1354
|
|
|
1334
1355
|
state.rootSpan.setAttributes(
|
|
@@ -1538,7 +1559,7 @@ export class OpenTelemetry implements Telemetry {
|
|
|
1538
1559
|
inferenceContext: undefined,
|
|
1539
1560
|
embedSpans: new Map(),
|
|
1540
1561
|
rerankSpan: undefined,
|
|
1541
|
-
|
|
1562
|
+
decisionSpan: undefined,
|
|
1542
1563
|
toolSpans: new Map(),
|
|
1543
1564
|
settings: { maxRetries: event.maxRetries },
|
|
1544
1565
|
provider: event.provider,
|
|
@@ -1619,8 +1640,8 @@ export class OpenTelemetry implements Telemetry {
|
|
|
1619
1640
|
state.rerankSpan = undefined;
|
|
1620
1641
|
}
|
|
1621
1642
|
|
|
1622
|
-
private
|
|
1623
|
-
event: InferTelemetryEvent<
|
|
1643
|
+
private onDecideOperationStart(
|
|
1644
|
+
event: InferTelemetryEvent<DecideStartEvent>,
|
|
1624
1645
|
): void {
|
|
1625
1646
|
const telemetry: TelemetryOptions = {
|
|
1626
1647
|
recordInputs: event.recordInputs,
|
|
@@ -1637,22 +1658,22 @@ export class OpenTelemetry implements Telemetry {
|
|
|
1637
1658
|
},
|
|
1638
1659
|
);
|
|
1639
1660
|
const attributes = selectAttributes(telemetry, {
|
|
1640
|
-
'gen_ai.operation.name': '
|
|
1661
|
+
'gen_ai.operation.name': 'decide',
|
|
1641
1662
|
'gen_ai.provider.name': mapProviderName(event.provider),
|
|
1642
1663
|
'gen_ai.request.model': event.modelId,
|
|
1643
1664
|
...baseSupplementalAttributes,
|
|
1644
1665
|
...selectSupplementalAttributes(telemetry, this.supplementalAttributes, {
|
|
1645
|
-
|
|
1646
|
-
'ai.
|
|
1666
|
+
experimental_decision: {
|
|
1667
|
+
'ai.decision.state': {
|
|
1647
1668
|
input: () => JSON.stringify(event.state),
|
|
1648
1669
|
},
|
|
1649
|
-
'ai.
|
|
1670
|
+
'ai.decision.questions': {
|
|
1650
1671
|
input: () => JSON.stringify(event.questions),
|
|
1651
1672
|
},
|
|
1652
1673
|
},
|
|
1653
1674
|
}),
|
|
1654
1675
|
});
|
|
1655
|
-
const rootSpan = this.tracer.startSpan(`
|
|
1676
|
+
const rootSpan = this.tracer.startSpan(`decide ${event.modelId}`, {
|
|
1656
1677
|
attributes: this.getSpanAttributes({
|
|
1657
1678
|
attributes,
|
|
1658
1679
|
spanType: 'operation',
|
|
@@ -1675,7 +1696,7 @@ export class OpenTelemetry implements Telemetry {
|
|
|
1675
1696
|
inferenceContext: undefined,
|
|
1676
1697
|
embedSpans: new Map(),
|
|
1677
1698
|
rerankSpan: undefined,
|
|
1678
|
-
|
|
1699
|
+
decisionSpan: undefined,
|
|
1679
1700
|
toolSpans: new Map(),
|
|
1680
1701
|
settings: { maxRetries: event.maxRetries },
|
|
1681
1702
|
provider: event.provider,
|
|
@@ -1685,7 +1706,7 @@ export class OpenTelemetry implements Telemetry {
|
|
|
1685
1706
|
});
|
|
1686
1707
|
}
|
|
1687
1708
|
|
|
1688
|
-
private
|
|
1709
|
+
private onDecideOperationEnd(event: DecideEndEvent): void {
|
|
1689
1710
|
const state = this.getCallState(event.callId);
|
|
1690
1711
|
if (!state?.rootSpan) return;
|
|
1691
1712
|
|
|
@@ -1694,8 +1715,8 @@ export class OpenTelemetry implements Telemetry {
|
|
|
1694
1715
|
state.telemetry,
|
|
1695
1716
|
this.supplementalAttributes,
|
|
1696
1717
|
{
|
|
1697
|
-
|
|
1698
|
-
'ai.
|
|
1718
|
+
experimental_decision: {
|
|
1719
|
+
'ai.decision.answers': {
|
|
1699
1720
|
output: () => JSON.stringify(event.answers),
|
|
1700
1721
|
},
|
|
1701
1722
|
},
|
|
@@ -1706,24 +1727,48 @@ export class OpenTelemetry implements Telemetry {
|
|
|
1706
1727
|
this.cleanupCallState(event.callId);
|
|
1707
1728
|
}
|
|
1708
1729
|
|
|
1730
|
+
// Route through deprecated hooks to preserve existing subclass overrides.
|
|
1731
|
+
experimental_onDecideStart(
|
|
1732
|
+
event: InferTelemetryEvent<DecideStartEvent>,
|
|
1733
|
+
): void {
|
|
1734
|
+
this.experimental_onEvaluateStart(event);
|
|
1735
|
+
}
|
|
1736
|
+
|
|
1737
|
+
experimental_onDecideEnd(event: DecideEndEvent): void {
|
|
1738
|
+
this.experimental_onEvaluateEnd(event);
|
|
1739
|
+
}
|
|
1740
|
+
|
|
1741
|
+
experimental_onDecisionModelCallStart(
|
|
1742
|
+
event: DecisionModelCallStartEvent,
|
|
1743
|
+
): void {
|
|
1744
|
+
this.experimental_onEvaluationModelCallStart(event);
|
|
1745
|
+
}
|
|
1746
|
+
|
|
1747
|
+
experimental_onDecisionModelCallEnd(event: DecisionModelCallEndEvent): void {
|
|
1748
|
+
this.experimental_onEvaluationModelCallEnd(event);
|
|
1749
|
+
}
|
|
1750
|
+
|
|
1751
|
+
/** @deprecated Use `experimental_onDecideStart` instead. */
|
|
1709
1752
|
experimental_onEvaluateStart(
|
|
1710
|
-
event: InferTelemetryEvent<
|
|
1753
|
+
event: InferTelemetryEvent<DecideStartEvent>,
|
|
1711
1754
|
): void {
|
|
1712
|
-
this.
|
|
1755
|
+
this.onDecideOperationStart(event);
|
|
1713
1756
|
}
|
|
1714
1757
|
|
|
1715
|
-
|
|
1716
|
-
|
|
1758
|
+
/** @deprecated Use `experimental_onDecideEnd` instead. */
|
|
1759
|
+
experimental_onEvaluateEnd(event: DecideEndEvent): void {
|
|
1760
|
+
this.onDecideOperationEnd(event);
|
|
1717
1761
|
}
|
|
1718
1762
|
|
|
1763
|
+
/** @deprecated Use `experimental_onDecisionModelCallStart` instead. */
|
|
1719
1764
|
experimental_onEvaluationModelCallStart(
|
|
1720
|
-
event:
|
|
1765
|
+
event: InferTelemetryEvent<DecisionModelCallStartEvent>,
|
|
1721
1766
|
): void {
|
|
1722
1767
|
const state = this.getCallState(event.callId);
|
|
1723
1768
|
if (!state?.rootSpan || !state.rootContext) return;
|
|
1724
1769
|
|
|
1725
1770
|
const attributes = selectAttributes(state.telemetry, {
|
|
1726
|
-
'gen_ai.operation.name': '
|
|
1771
|
+
'gen_ai.operation.name': 'decide',
|
|
1727
1772
|
'gen_ai.provider.name': mapProviderName(state.provider),
|
|
1728
1773
|
'gen_ai.request.model': state.modelId,
|
|
1729
1774
|
...state.baseSupplementalAttributes,
|
|
@@ -1731,11 +1776,11 @@ export class OpenTelemetry implements Telemetry {
|
|
|
1731
1776
|
state.telemetry,
|
|
1732
1777
|
this.supplementalAttributes,
|
|
1733
1778
|
{
|
|
1734
|
-
|
|
1735
|
-
'ai.
|
|
1779
|
+
experimental_decision: {
|
|
1780
|
+
'ai.decision.state': {
|
|
1736
1781
|
input: () => JSON.stringify(event.state),
|
|
1737
1782
|
},
|
|
1738
|
-
'ai.
|
|
1783
|
+
'ai.decision.questions': {
|
|
1739
1784
|
input: () => JSON.stringify(event.questions),
|
|
1740
1785
|
},
|
|
1741
1786
|
},
|
|
@@ -1743,11 +1788,11 @@ export class OpenTelemetry implements Telemetry {
|
|
|
1743
1788
|
),
|
|
1744
1789
|
});
|
|
1745
1790
|
const span = this.tracer.startSpan(
|
|
1746
|
-
`
|
|
1791
|
+
`decide ${state.modelId}`,
|
|
1747
1792
|
{
|
|
1748
1793
|
attributes: this.getSpanAttributes({
|
|
1749
1794
|
attributes,
|
|
1750
|
-
spanType: '
|
|
1795
|
+
spanType: 'experimental_decision',
|
|
1751
1796
|
operationId: event.operationId,
|
|
1752
1797
|
callId: event.callId,
|
|
1753
1798
|
runtimeContext: state.runtimeContext,
|
|
@@ -1757,19 +1802,20 @@ export class OpenTelemetry implements Telemetry {
|
|
|
1757
1802
|
state.rootContext,
|
|
1758
1803
|
);
|
|
1759
1804
|
|
|
1760
|
-
state.
|
|
1805
|
+
state.decisionSpan = {
|
|
1761
1806
|
span,
|
|
1762
1807
|
context: trace.setSpan(state.rootContext, span),
|
|
1763
1808
|
};
|
|
1764
1809
|
}
|
|
1765
1810
|
|
|
1811
|
+
/** @deprecated Use `experimental_onDecisionModelCallEnd` instead. */
|
|
1766
1812
|
experimental_onEvaluationModelCallEnd(
|
|
1767
|
-
event:
|
|
1813
|
+
event: InferTelemetryEvent<DecisionModelCallEndEvent>,
|
|
1768
1814
|
): void {
|
|
1769
1815
|
const state = this.getCallState(event.callId);
|
|
1770
|
-
if (!state?.
|
|
1816
|
+
if (!state?.decisionSpan) return;
|
|
1771
1817
|
|
|
1772
|
-
state.
|
|
1818
|
+
state.decisionSpan.span.setAttributes(
|
|
1773
1819
|
selectAttributes(state.telemetry, {
|
|
1774
1820
|
'gen_ai.usage.input_tokens': event.usage?.inputTokens,
|
|
1775
1821
|
'gen_ai.usage.output_tokens': event.usage?.outputTokens,
|
|
@@ -1777,8 +1823,8 @@ export class OpenTelemetry implements Telemetry {
|
|
|
1777
1823
|
state.telemetry,
|
|
1778
1824
|
this.supplementalAttributes,
|
|
1779
1825
|
{
|
|
1780
|
-
|
|
1781
|
-
'ai.
|
|
1826
|
+
experimental_decision: {
|
|
1827
|
+
'ai.decision.answers': {
|
|
1782
1828
|
output: () => JSON.stringify(event.answers),
|
|
1783
1829
|
},
|
|
1784
1830
|
},
|
|
@@ -1791,8 +1837,8 @@ export class OpenTelemetry implements Telemetry {
|
|
|
1791
1837
|
),
|
|
1792
1838
|
}),
|
|
1793
1839
|
);
|
|
1794
|
-
state.
|
|
1795
|
-
state.
|
|
1840
|
+
state.decisionSpan.span.end();
|
|
1841
|
+
state.decisionSpan = undefined;
|
|
1796
1842
|
}
|
|
1797
1843
|
|
|
1798
1844
|
onAbort(event: GenerateTextAbortEvent<ToolSet>): void {
|
|
@@ -1826,9 +1872,9 @@ export class OpenTelemetry implements Telemetry {
|
|
|
1826
1872
|
state.rerankSpan = undefined;
|
|
1827
1873
|
}
|
|
1828
1874
|
|
|
1829
|
-
if (state.
|
|
1830
|
-
state.
|
|
1831
|
-
state.
|
|
1875
|
+
if (state.decisionSpan) {
|
|
1876
|
+
state.decisionSpan.span.end();
|
|
1877
|
+
state.decisionSpan = undefined;
|
|
1832
1878
|
}
|
|
1833
1879
|
|
|
1834
1880
|
state.rootSpan.end();
|
|
@@ -1876,10 +1922,10 @@ export class OpenTelemetry implements Telemetry {
|
|
|
1876
1922
|
state.rerankSpan = undefined;
|
|
1877
1923
|
}
|
|
1878
1924
|
|
|
1879
|
-
if (state.
|
|
1880
|
-
recordErrorOnSpan(state.
|
|
1881
|
-
state.
|
|
1882
|
-
state.
|
|
1925
|
+
if (state.decisionSpan) {
|
|
1926
|
+
recordErrorOnSpan(state.decisionSpan.span, actualError);
|
|
1927
|
+
state.decisionSpan.span.end();
|
|
1928
|
+
state.decisionSpan = undefined;
|
|
1883
1929
|
}
|
|
1884
1930
|
|
|
1885
1931
|
recordErrorOnSpan(state.rootSpan, actualError);
|