@ai-sdk/otel 1.0.110 → 1.0.111
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 +9 -0
- package/dist/index.d.ts +18 -2
- package/dist/index.js +293 -5
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/src/legacy-open-telemetry.ts +143 -0
- package/src/open-telemetry.ts +196 -0
- package/src/supplemental-attributes.ts +10 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ai-sdk/otel",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.111",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"sideEffects": false,
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
"dependencies": {
|
|
29
29
|
"@ai-sdk/provider": "4.0.17",
|
|
30
30
|
"@opentelemetry/api": "1.9.1",
|
|
31
|
-
"ai": "7.0.
|
|
31
|
+
"ai": "7.0.111"
|
|
32
32
|
},
|
|
33
33
|
"devDependencies": {
|
|
34
34
|
"@ai-sdk/provider-utils": "5.0.45",
|
|
@@ -26,6 +26,10 @@ import type {
|
|
|
26
26
|
GenerateTextStepStartEvent,
|
|
27
27
|
ToolExecutionEndEvent,
|
|
28
28
|
ToolExecutionStartEvent,
|
|
29
|
+
Experimental_EvaluateEndEvent as EvaluateEndEvent,
|
|
30
|
+
Experimental_EvaluateStartEvent as EvaluateStartEvent,
|
|
31
|
+
Experimental_EvaluationModelCallEndEvent as EvaluationModelCallEndEvent,
|
|
32
|
+
Experimental_EvaluationModelCallStartEvent as EvaluationModelCallStartEvent,
|
|
29
33
|
Output,
|
|
30
34
|
RerankingModelCallEndEvent,
|
|
31
35
|
RerankEndEvent,
|
|
@@ -136,6 +140,7 @@ interface CallState {
|
|
|
136
140
|
stepContext: OpenTelemetryContext | undefined;
|
|
137
141
|
embedSpans: Map<string, { span: Span; context: OpenTelemetryContext }>;
|
|
138
142
|
rerankSpan: { span: Span; context: OpenTelemetryContext } | undefined;
|
|
143
|
+
evaluationSpan: { span: Span; context: OpenTelemetryContext } | undefined;
|
|
139
144
|
toolSpans: Map<string, { span: Span; context: OpenTelemetryContext }>;
|
|
140
145
|
baseTelemetryAttributes: Attributes;
|
|
141
146
|
settings: Record<string, unknown>;
|
|
@@ -295,6 +300,7 @@ export class LegacyOpenTelemetry implements Telemetry {
|
|
|
295
300
|
stepContext: undefined,
|
|
296
301
|
embedSpans: new Map(),
|
|
297
302
|
rerankSpan: undefined,
|
|
303
|
+
evaluationSpan: undefined,
|
|
298
304
|
toolSpans: new Map(),
|
|
299
305
|
baseTelemetryAttributes,
|
|
300
306
|
settings,
|
|
@@ -362,6 +368,7 @@ export class LegacyOpenTelemetry implements Telemetry {
|
|
|
362
368
|
stepContext: undefined,
|
|
363
369
|
embedSpans: new Map(),
|
|
364
370
|
rerankSpan: undefined,
|
|
371
|
+
evaluationSpan: undefined,
|
|
365
372
|
toolSpans: new Map(),
|
|
366
373
|
baseTelemetryAttributes,
|
|
367
374
|
settings,
|
|
@@ -529,6 +536,7 @@ export class LegacyOpenTelemetry implements Telemetry {
|
|
|
529
536
|
stepContext: undefined,
|
|
530
537
|
embedSpans: new Map(),
|
|
531
538
|
rerankSpan: undefined,
|
|
539
|
+
evaluationSpan: undefined,
|
|
532
540
|
toolSpans: new Map(),
|
|
533
541
|
baseTelemetryAttributes,
|
|
534
542
|
settings,
|
|
@@ -1044,6 +1052,7 @@ export class LegacyOpenTelemetry implements Telemetry {
|
|
|
1044
1052
|
stepContext: undefined,
|
|
1045
1053
|
embedSpans: new Map(),
|
|
1046
1054
|
rerankSpan: undefined,
|
|
1055
|
+
evaluationSpan: undefined,
|
|
1047
1056
|
toolSpans: new Map(),
|
|
1048
1057
|
baseTelemetryAttributes,
|
|
1049
1058
|
settings,
|
|
@@ -1105,6 +1114,129 @@ export class LegacyOpenTelemetry implements Telemetry {
|
|
|
1105
1114
|
state.rerankSpan = undefined;
|
|
1106
1115
|
}
|
|
1107
1116
|
|
|
1117
|
+
private onEvaluateOperationStart(
|
|
1118
|
+
event: InferTelemetryEvent<EvaluateStartEvent>,
|
|
1119
|
+
): void {
|
|
1120
|
+
const telemetry: TelemetryOptions = {
|
|
1121
|
+
recordInputs: event.recordInputs,
|
|
1122
|
+
recordOutputs: event.recordOutputs,
|
|
1123
|
+
functionId: event.functionId,
|
|
1124
|
+
};
|
|
1125
|
+
const settings: Record<string, unknown> = {
|
|
1126
|
+
maxRetries: event.maxRetries,
|
|
1127
|
+
};
|
|
1128
|
+
const baseTelemetryAttributes = getBaseTelemetryAttributes({
|
|
1129
|
+
model: { provider: event.provider, modelId: event.modelId },
|
|
1130
|
+
headers: event.headers,
|
|
1131
|
+
settings,
|
|
1132
|
+
context: event.runtimeContext,
|
|
1133
|
+
});
|
|
1134
|
+
const attributes = selectAttributes(telemetry, {
|
|
1135
|
+
...assembleOperationName({ operationId: event.operationId, telemetry }),
|
|
1136
|
+
...baseTelemetryAttributes,
|
|
1137
|
+
'ai.evaluation.state': {
|
|
1138
|
+
input: () => JSON.stringify(event.state),
|
|
1139
|
+
},
|
|
1140
|
+
'ai.evaluation.questions': {
|
|
1141
|
+
input: () => JSON.stringify(event.questions),
|
|
1142
|
+
},
|
|
1143
|
+
});
|
|
1144
|
+
const rootSpan = this.tracer.startSpan(event.operationId, { attributes });
|
|
1145
|
+
const rootContext = trace.setSpan(context.active(), rootSpan);
|
|
1146
|
+
|
|
1147
|
+
this.callStates.set(event.callId, {
|
|
1148
|
+
operationId: event.operationId,
|
|
1149
|
+
telemetry,
|
|
1150
|
+
rootSpan,
|
|
1151
|
+
rootContext,
|
|
1152
|
+
stepSpan: undefined,
|
|
1153
|
+
stepContext: undefined,
|
|
1154
|
+
embedSpans: new Map(),
|
|
1155
|
+
rerankSpan: undefined,
|
|
1156
|
+
evaluationSpan: undefined,
|
|
1157
|
+
toolSpans: new Map(),
|
|
1158
|
+
baseTelemetryAttributes,
|
|
1159
|
+
settings,
|
|
1160
|
+
});
|
|
1161
|
+
}
|
|
1162
|
+
|
|
1163
|
+
private onEvaluateOperationEnd(event: EvaluateEndEvent): void {
|
|
1164
|
+
const state = this.getCallState(event.callId);
|
|
1165
|
+
if (!state?.rootSpan) return;
|
|
1166
|
+
|
|
1167
|
+
state.rootSpan.setAttributes(
|
|
1168
|
+
selectAttributes(state.telemetry, {
|
|
1169
|
+
'ai.evaluation.answers': {
|
|
1170
|
+
output: () => JSON.stringify(event.answers),
|
|
1171
|
+
},
|
|
1172
|
+
}),
|
|
1173
|
+
);
|
|
1174
|
+
state.rootSpan.end();
|
|
1175
|
+
this.cleanupCallState(event.callId);
|
|
1176
|
+
}
|
|
1177
|
+
|
|
1178
|
+
experimental_onEvaluateStart(
|
|
1179
|
+
event: InferTelemetryEvent<EvaluateStartEvent>,
|
|
1180
|
+
): void {
|
|
1181
|
+
this.onEvaluateOperationStart(event);
|
|
1182
|
+
}
|
|
1183
|
+
|
|
1184
|
+
experimental_onEvaluateEnd(event: EvaluateEndEvent): void {
|
|
1185
|
+
this.onEvaluateOperationEnd(event);
|
|
1186
|
+
}
|
|
1187
|
+
|
|
1188
|
+
experimental_onEvaluationModelCallStart(
|
|
1189
|
+
event: EvaluationModelCallStartEvent,
|
|
1190
|
+
): void {
|
|
1191
|
+
const state = this.getCallState(event.callId);
|
|
1192
|
+
if (!state?.rootSpan || !state.rootContext) return;
|
|
1193
|
+
|
|
1194
|
+
const attributes = selectAttributes(state.telemetry, {
|
|
1195
|
+
...assembleOperationName({
|
|
1196
|
+
operationId: event.operationId,
|
|
1197
|
+
telemetry: state.telemetry,
|
|
1198
|
+
}),
|
|
1199
|
+
...state.baseTelemetryAttributes,
|
|
1200
|
+
'ai.evaluation.state': {
|
|
1201
|
+
input: () => JSON.stringify(event.state),
|
|
1202
|
+
},
|
|
1203
|
+
'ai.evaluation.questions': {
|
|
1204
|
+
input: () => JSON.stringify(event.questions),
|
|
1205
|
+
},
|
|
1206
|
+
});
|
|
1207
|
+
const span = this.tracer.startSpan(
|
|
1208
|
+
event.operationId,
|
|
1209
|
+
{ attributes },
|
|
1210
|
+
state.rootContext,
|
|
1211
|
+
);
|
|
1212
|
+
state.evaluationSpan = {
|
|
1213
|
+
span,
|
|
1214
|
+
context: trace.setSpan(state.rootContext, span),
|
|
1215
|
+
};
|
|
1216
|
+
}
|
|
1217
|
+
|
|
1218
|
+
experimental_onEvaluationModelCallEnd(
|
|
1219
|
+
event: EvaluationModelCallEndEvent,
|
|
1220
|
+
): void {
|
|
1221
|
+
const state = this.getCallState(event.callId);
|
|
1222
|
+
if (!state?.evaluationSpan) return;
|
|
1223
|
+
|
|
1224
|
+
state.evaluationSpan.span.setAttributes(
|
|
1225
|
+
selectAttributes(state.telemetry, {
|
|
1226
|
+
'ai.evaluation.answers': {
|
|
1227
|
+
output: () => JSON.stringify(event.answers),
|
|
1228
|
+
},
|
|
1229
|
+
'ai.usage.inputTokens': event.usage?.inputTokens,
|
|
1230
|
+
'ai.usage.outputTokens': event.usage?.outputTokens,
|
|
1231
|
+
'ai.response.providerMetadata': event.providerMetadata
|
|
1232
|
+
? JSON.stringify(event.providerMetadata)
|
|
1233
|
+
: undefined,
|
|
1234
|
+
}),
|
|
1235
|
+
);
|
|
1236
|
+
state.evaluationSpan.span.end();
|
|
1237
|
+
state.evaluationSpan = undefined;
|
|
1238
|
+
}
|
|
1239
|
+
|
|
1108
1240
|
onAbort(event: GenerateTextAbortEvent<ToolSet>): void {
|
|
1109
1241
|
const state = this.getCallState(event.callId);
|
|
1110
1242
|
if (!state?.rootSpan) return;
|
|
@@ -1130,6 +1262,11 @@ export class LegacyOpenTelemetry implements Telemetry {
|
|
|
1130
1262
|
state.rerankSpan = undefined;
|
|
1131
1263
|
}
|
|
1132
1264
|
|
|
1265
|
+
if (state.evaluationSpan) {
|
|
1266
|
+
state.evaluationSpan.span.end();
|
|
1267
|
+
state.evaluationSpan = undefined;
|
|
1268
|
+
}
|
|
1269
|
+
|
|
1133
1270
|
state.rootSpan.end();
|
|
1134
1271
|
this.cleanupCallState(event.callId);
|
|
1135
1272
|
}
|
|
@@ -1160,6 +1297,12 @@ export class LegacyOpenTelemetry implements Telemetry {
|
|
|
1160
1297
|
state.rerankSpan = undefined;
|
|
1161
1298
|
}
|
|
1162
1299
|
|
|
1300
|
+
if (state.evaluationSpan) {
|
|
1301
|
+
recordSpanError(state.evaluationSpan.span, actualError);
|
|
1302
|
+
state.evaluationSpan.span.end();
|
|
1303
|
+
state.evaluationSpan = undefined;
|
|
1304
|
+
}
|
|
1305
|
+
|
|
1163
1306
|
recordSpanError(state.rootSpan, actualError);
|
|
1164
1307
|
|
|
1165
1308
|
state.rootSpan.end();
|
package/src/open-telemetry.ts
CHANGED
|
@@ -25,6 +25,10 @@ import type {
|
|
|
25
25
|
GenerateTextStepStartEvent,
|
|
26
26
|
ToolExecutionEndEvent,
|
|
27
27
|
ToolExecutionStartEvent,
|
|
28
|
+
Experimental_EvaluateEndEvent as EvaluateEndEvent,
|
|
29
|
+
Experimental_EvaluateStartEvent as EvaluateStartEvent,
|
|
30
|
+
Experimental_EvaluationModelCallEndEvent as EvaluationModelCallEndEvent,
|
|
31
|
+
Experimental_EvaluationModelCallStartEvent as EvaluationModelCallStartEvent,
|
|
28
32
|
RerankingModelCallEndEvent,
|
|
29
33
|
RerankEndEvent,
|
|
30
34
|
RerankStartEvent,
|
|
@@ -80,6 +84,7 @@ interface CallState {
|
|
|
80
84
|
inferenceToolDefinitions?: ReadonlyArray<Record<string, unknown>>;
|
|
81
85
|
embedSpans: Map<string, { span: Span; context: OpenTelemetryContext }>;
|
|
82
86
|
rerankSpan: { span: Span; context: OpenTelemetryContext } | undefined;
|
|
87
|
+
evaluationSpan: { span: Span; context: OpenTelemetryContext } | undefined;
|
|
83
88
|
toolSpans: Map<string, { span: Span; context: OpenTelemetryContext }>;
|
|
84
89
|
settings: Record<string, unknown>;
|
|
85
90
|
provider: string;
|
|
@@ -327,6 +332,7 @@ export class OpenTelemetry implements Telemetry {
|
|
|
327
332
|
inferenceContext: undefined,
|
|
328
333
|
embedSpans: new Map(),
|
|
329
334
|
rerankSpan: undefined,
|
|
335
|
+
evaluationSpan: undefined,
|
|
330
336
|
toolSpans: new Map(),
|
|
331
337
|
settings,
|
|
332
338
|
provider: event.provider,
|
|
@@ -433,6 +439,7 @@ export class OpenTelemetry implements Telemetry {
|
|
|
433
439
|
inferenceContext: undefined,
|
|
434
440
|
embedSpans: new Map(),
|
|
435
441
|
rerankSpan: undefined,
|
|
442
|
+
evaluationSpan: undefined,
|
|
436
443
|
toolSpans: new Map(),
|
|
437
444
|
settings,
|
|
438
445
|
provider: event.provider,
|
|
@@ -631,6 +638,7 @@ export class OpenTelemetry implements Telemetry {
|
|
|
631
638
|
inferenceContext: undefined,
|
|
632
639
|
embedSpans: new Map(),
|
|
633
640
|
rerankSpan: undefined,
|
|
641
|
+
evaluationSpan: undefined,
|
|
634
642
|
toolSpans: new Map(),
|
|
635
643
|
settings: { maxRetries: event.maxRetries },
|
|
636
644
|
provider: event.provider,
|
|
@@ -1315,6 +1323,7 @@ export class OpenTelemetry implements Telemetry {
|
|
|
1315
1323
|
inferenceContext: undefined,
|
|
1316
1324
|
embedSpans: new Map(),
|
|
1317
1325
|
rerankSpan: undefined,
|
|
1326
|
+
evaluationSpan: undefined,
|
|
1318
1327
|
toolSpans: new Map(),
|
|
1319
1328
|
settings: { maxRetries: event.maxRetries },
|
|
1320
1329
|
provider: event.provider,
|
|
@@ -1395,6 +1404,182 @@ export class OpenTelemetry implements Telemetry {
|
|
|
1395
1404
|
state.rerankSpan = undefined;
|
|
1396
1405
|
}
|
|
1397
1406
|
|
|
1407
|
+
private onEvaluateOperationStart(
|
|
1408
|
+
event: InferTelemetryEvent<EvaluateStartEvent>,
|
|
1409
|
+
): void {
|
|
1410
|
+
const telemetry: TelemetryOptions = {
|
|
1411
|
+
recordInputs: event.recordInputs,
|
|
1412
|
+
recordOutputs: event.recordOutputs,
|
|
1413
|
+
functionId: event.functionId,
|
|
1414
|
+
};
|
|
1415
|
+
const runtimeContext = event.runtimeContext;
|
|
1416
|
+
const baseSupplementalAttributes = selectSupplementalAttributes(
|
|
1417
|
+
telemetry,
|
|
1418
|
+
this.supplementalAttributes,
|
|
1419
|
+
{
|
|
1420
|
+
runtimeContext: getRuntimeContextAttributes(runtimeContext),
|
|
1421
|
+
headers: getHeaderAttributes(event.headers),
|
|
1422
|
+
},
|
|
1423
|
+
);
|
|
1424
|
+
const attributes = selectAttributes(telemetry, {
|
|
1425
|
+
'gen_ai.operation.name': 'evaluate',
|
|
1426
|
+
'gen_ai.provider.name': mapProviderName(event.provider),
|
|
1427
|
+
'gen_ai.request.model': event.modelId,
|
|
1428
|
+
...baseSupplementalAttributes,
|
|
1429
|
+
...selectSupplementalAttributes(telemetry, this.supplementalAttributes, {
|
|
1430
|
+
experimental_evaluation: {
|
|
1431
|
+
'ai.evaluation.state': {
|
|
1432
|
+
input: () => JSON.stringify(event.state),
|
|
1433
|
+
},
|
|
1434
|
+
'ai.evaluation.questions': {
|
|
1435
|
+
input: () => JSON.stringify(event.questions),
|
|
1436
|
+
},
|
|
1437
|
+
},
|
|
1438
|
+
}),
|
|
1439
|
+
});
|
|
1440
|
+
const rootSpan = this.tracer.startSpan(`evaluate ${event.modelId}`, {
|
|
1441
|
+
attributes: this.getSpanAttributes({
|
|
1442
|
+
attributes,
|
|
1443
|
+
spanType: 'operation',
|
|
1444
|
+
operationId: event.operationId,
|
|
1445
|
+
callId: event.callId,
|
|
1446
|
+
runtimeContext,
|
|
1447
|
+
}),
|
|
1448
|
+
kind: SpanKind.CLIENT,
|
|
1449
|
+
});
|
|
1450
|
+
const rootContext = trace.setSpan(context.active(), rootSpan);
|
|
1451
|
+
|
|
1452
|
+
this.callStates.set(event.callId, {
|
|
1453
|
+
operationId: event.operationId,
|
|
1454
|
+
telemetry,
|
|
1455
|
+
rootSpan,
|
|
1456
|
+
rootContext,
|
|
1457
|
+
stepSpan: undefined,
|
|
1458
|
+
stepContext: undefined,
|
|
1459
|
+
inferenceSpan: undefined,
|
|
1460
|
+
inferenceContext: undefined,
|
|
1461
|
+
embedSpans: new Map(),
|
|
1462
|
+
rerankSpan: undefined,
|
|
1463
|
+
evaluationSpan: undefined,
|
|
1464
|
+
toolSpans: new Map(),
|
|
1465
|
+
settings: { maxRetries: event.maxRetries },
|
|
1466
|
+
provider: event.provider,
|
|
1467
|
+
modelId: event.modelId,
|
|
1468
|
+
runtimeContext,
|
|
1469
|
+
baseSupplementalAttributes,
|
|
1470
|
+
});
|
|
1471
|
+
}
|
|
1472
|
+
|
|
1473
|
+
private onEvaluateOperationEnd(event: EvaluateEndEvent): void {
|
|
1474
|
+
const state = this.getCallState(event.callId);
|
|
1475
|
+
if (!state?.rootSpan) return;
|
|
1476
|
+
|
|
1477
|
+
state.rootSpan.setAttributes(
|
|
1478
|
+
selectSupplementalAttributes(
|
|
1479
|
+
state.telemetry,
|
|
1480
|
+
this.supplementalAttributes,
|
|
1481
|
+
{
|
|
1482
|
+
experimental_evaluation: {
|
|
1483
|
+
'ai.evaluation.answers': {
|
|
1484
|
+
output: () => JSON.stringify(event.answers),
|
|
1485
|
+
},
|
|
1486
|
+
},
|
|
1487
|
+
},
|
|
1488
|
+
),
|
|
1489
|
+
);
|
|
1490
|
+
state.rootSpan.end();
|
|
1491
|
+
this.cleanupCallState(event.callId);
|
|
1492
|
+
}
|
|
1493
|
+
|
|
1494
|
+
experimental_onEvaluateStart(
|
|
1495
|
+
event: InferTelemetryEvent<EvaluateStartEvent>,
|
|
1496
|
+
): void {
|
|
1497
|
+
this.onEvaluateOperationStart(event);
|
|
1498
|
+
}
|
|
1499
|
+
|
|
1500
|
+
experimental_onEvaluateEnd(event: EvaluateEndEvent): void {
|
|
1501
|
+
this.onEvaluateOperationEnd(event);
|
|
1502
|
+
}
|
|
1503
|
+
|
|
1504
|
+
experimental_onEvaluationModelCallStart(
|
|
1505
|
+
event: EvaluationModelCallStartEvent,
|
|
1506
|
+
): void {
|
|
1507
|
+
const state = this.getCallState(event.callId);
|
|
1508
|
+
if (!state?.rootSpan || !state.rootContext) return;
|
|
1509
|
+
|
|
1510
|
+
const attributes = selectAttributes(state.telemetry, {
|
|
1511
|
+
'gen_ai.operation.name': 'evaluate',
|
|
1512
|
+
'gen_ai.provider.name': mapProviderName(state.provider),
|
|
1513
|
+
'gen_ai.request.model': state.modelId,
|
|
1514
|
+
...state.baseSupplementalAttributes,
|
|
1515
|
+
...selectSupplementalAttributes(
|
|
1516
|
+
state.telemetry,
|
|
1517
|
+
this.supplementalAttributes,
|
|
1518
|
+
{
|
|
1519
|
+
experimental_evaluation: {
|
|
1520
|
+
'ai.evaluation.state': {
|
|
1521
|
+
input: () => JSON.stringify(event.state),
|
|
1522
|
+
},
|
|
1523
|
+
'ai.evaluation.questions': {
|
|
1524
|
+
input: () => JSON.stringify(event.questions),
|
|
1525
|
+
},
|
|
1526
|
+
},
|
|
1527
|
+
},
|
|
1528
|
+
),
|
|
1529
|
+
});
|
|
1530
|
+
const span = this.tracer.startSpan(
|
|
1531
|
+
`evaluate ${state.modelId}`,
|
|
1532
|
+
{
|
|
1533
|
+
attributes: this.getSpanAttributes({
|
|
1534
|
+
attributes,
|
|
1535
|
+
spanType: 'experimental_evaluation',
|
|
1536
|
+
operationId: event.operationId,
|
|
1537
|
+
callId: event.callId,
|
|
1538
|
+
runtimeContext: state.runtimeContext,
|
|
1539
|
+
}),
|
|
1540
|
+
kind: SpanKind.CLIENT,
|
|
1541
|
+
},
|
|
1542
|
+
state.rootContext,
|
|
1543
|
+
);
|
|
1544
|
+
|
|
1545
|
+
state.evaluationSpan = {
|
|
1546
|
+
span,
|
|
1547
|
+
context: trace.setSpan(state.rootContext, span),
|
|
1548
|
+
};
|
|
1549
|
+
}
|
|
1550
|
+
|
|
1551
|
+
experimental_onEvaluationModelCallEnd(
|
|
1552
|
+
event: EvaluationModelCallEndEvent,
|
|
1553
|
+
): void {
|
|
1554
|
+
const state = this.getCallState(event.callId);
|
|
1555
|
+
if (!state?.evaluationSpan) return;
|
|
1556
|
+
|
|
1557
|
+
state.evaluationSpan.span.setAttributes(
|
|
1558
|
+
selectAttributes(state.telemetry, {
|
|
1559
|
+
'gen_ai.usage.input_tokens': event.usage?.inputTokens,
|
|
1560
|
+
'gen_ai.usage.output_tokens': event.usage?.outputTokens,
|
|
1561
|
+
...selectSupplementalAttributes(
|
|
1562
|
+
state.telemetry,
|
|
1563
|
+
this.supplementalAttributes,
|
|
1564
|
+
{
|
|
1565
|
+
experimental_evaluation: {
|
|
1566
|
+
'ai.evaluation.answers': {
|
|
1567
|
+
output: () => JSON.stringify(event.answers),
|
|
1568
|
+
},
|
|
1569
|
+
},
|
|
1570
|
+
providerMetadata: {
|
|
1571
|
+
'ai.response.providerMetadata': event.providerMetadata
|
|
1572
|
+
? JSON.stringify(event.providerMetadata)
|
|
1573
|
+
: undefined,
|
|
1574
|
+
},
|
|
1575
|
+
},
|
|
1576
|
+
),
|
|
1577
|
+
}),
|
|
1578
|
+
);
|
|
1579
|
+
state.evaluationSpan.span.end();
|
|
1580
|
+
state.evaluationSpan = undefined;
|
|
1581
|
+
}
|
|
1582
|
+
|
|
1398
1583
|
onAbort(event: GenerateTextAbortEvent<ToolSet>): void {
|
|
1399
1584
|
const state = this.getCallState(event.callId);
|
|
1400
1585
|
if (!state?.rootSpan) return;
|
|
@@ -1426,6 +1611,11 @@ export class OpenTelemetry implements Telemetry {
|
|
|
1426
1611
|
state.rerankSpan = undefined;
|
|
1427
1612
|
}
|
|
1428
1613
|
|
|
1614
|
+
if (state.evaluationSpan) {
|
|
1615
|
+
state.evaluationSpan.span.end();
|
|
1616
|
+
state.evaluationSpan = undefined;
|
|
1617
|
+
}
|
|
1618
|
+
|
|
1429
1619
|
state.rootSpan.end();
|
|
1430
1620
|
this.cleanupCallState(event.callId);
|
|
1431
1621
|
}
|
|
@@ -1471,6 +1661,12 @@ export class OpenTelemetry implements Telemetry {
|
|
|
1471
1661
|
state.rerankSpan = undefined;
|
|
1472
1662
|
}
|
|
1473
1663
|
|
|
1664
|
+
if (state.evaluationSpan) {
|
|
1665
|
+
recordErrorOnSpan(state.evaluationSpan.span, actualError);
|
|
1666
|
+
state.evaluationSpan.span.end();
|
|
1667
|
+
state.evaluationSpan = undefined;
|
|
1668
|
+
}
|
|
1669
|
+
|
|
1474
1670
|
recordErrorOnSpan(state.rootSpan, actualError);
|
|
1475
1671
|
|
|
1476
1672
|
state.rootSpan.end();
|
|
@@ -11,6 +11,7 @@ type SupplementalAttributeOption =
|
|
|
11
11
|
| 'providerMetadata'
|
|
12
12
|
| 'embedding'
|
|
13
13
|
| 'reranking'
|
|
14
|
+
| 'experimental_evaluation'
|
|
14
15
|
| 'runtimeContext'
|
|
15
16
|
| 'headers'
|
|
16
17
|
| 'toolChoice'
|
|
@@ -27,7 +28,8 @@ export type OpenTelemetrySpanType =
|
|
|
27
28
|
| 'languageModel'
|
|
28
29
|
| 'tool'
|
|
29
30
|
| 'embedding'
|
|
30
|
-
| 'reranking'
|
|
31
|
+
| 'reranking'
|
|
32
|
+
| 'experimental_evaluation';
|
|
31
33
|
|
|
32
34
|
export type EnrichSpan = (options: {
|
|
33
35
|
spanType: OpenTelemetrySpanType;
|
|
@@ -68,6 +70,11 @@ export type OpenTelemetryOptions = {
|
|
|
68
70
|
*/
|
|
69
71
|
reranking?: boolean;
|
|
70
72
|
|
|
73
|
+
/**
|
|
74
|
+
* Emit evaluation state, questions, and answers.
|
|
75
|
+
*/
|
|
76
|
+
experimental_evaluation?: boolean;
|
|
77
|
+
|
|
71
78
|
/**
|
|
72
79
|
* Emit runtime context values.
|
|
73
80
|
*/
|
|
@@ -94,6 +101,7 @@ const disabledSupplementalAttributes: SupplementalAttributeOptions = {
|
|
|
94
101
|
providerMetadata: false,
|
|
95
102
|
embedding: false,
|
|
96
103
|
reranking: false,
|
|
104
|
+
experimental_evaluation: false,
|
|
97
105
|
runtimeContext: false,
|
|
98
106
|
headers: false,
|
|
99
107
|
toolChoice: false,
|
|
@@ -109,6 +117,7 @@ export function normalizeSupplementalAttributes(
|
|
|
109
117
|
providerMetadata: options.providerMetadata ?? false,
|
|
110
118
|
embedding: options.embedding ?? false,
|
|
111
119
|
reranking: options.reranking ?? false,
|
|
120
|
+
experimental_evaluation: options.experimental_evaluation ?? false,
|
|
112
121
|
runtimeContext: options.runtimeContext ?? false,
|
|
113
122
|
headers: options.headers ?? false,
|
|
114
123
|
toolChoice: options.toolChoice ?? false,
|