@ai-sdk/otel 1.0.158 → 1.0.160
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 +16 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +48 -1
- package/dist/index.js.map +1 -1
- package/package.json +3 -2
- package/src/open-telemetry.ts +82 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
# @ai-sdk/otel
|
|
2
2
|
|
|
3
|
+
## 1.0.160
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 5946558: Record the `gen_ai.client.inference.duration` OpenTelemetry histogram in seconds for `generateText` and `streamText` model calls, including errors, cancellation, and failed stream retry attempts, so configured metric exporters can report inference latency.
|
|
8
|
+
- Updated dependencies [a71172d]
|
|
9
|
+
- Updated dependencies [cf27969]
|
|
10
|
+
- Updated dependencies [17b6923]
|
|
11
|
+
- ai@7.0.160
|
|
12
|
+
|
|
13
|
+
## 1.0.159
|
|
14
|
+
|
|
15
|
+
### Patch Changes
|
|
16
|
+
|
|
17
|
+
- ai@7.0.159
|
|
18
|
+
|
|
3
19
|
## 1.0.158
|
|
4
20
|
|
|
5
21
|
### Patch Changes
|
package/dist/index.d.ts
CHANGED
|
@@ -86,6 +86,7 @@ export declare class OpenTelemetry implements Telemetry {
|
|
|
86
86
|
constructor(options?: OpenTelemetryOptions);
|
|
87
87
|
private getCallState;
|
|
88
88
|
private cleanupCallState;
|
|
89
|
+
private recordInferenceDuration;
|
|
89
90
|
private getAgentSpanName;
|
|
90
91
|
private getSpanAttributes;
|
|
91
92
|
executeTool<T>({ callId, toolCallId, execute }: {
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","names":["OtelStepStartEvent","StreamTranscriptionStartEvent","StreamTranscriptionEndEvent","DecideStartEvent","DecideEndEvent","DecisionModelCallStartEvent","DecisionModelCallEndEvent","AISDKContext","StreamTranscriptionStartEvent","StreamTranscriptionEndEvent","DecideStartEvent","DecideEndEvent","DecisionModelCallStartEvent","DecisionModelCallEndEvent"],"sources":["../src/supplemental-attributes.ts","../src/open-telemetry.ts","../../../node_modules/.pnpm/zod@3.25.76/node_modules/zod/v4/core/schemas.d.cts","../../provider-utils/dist/index.d.ts","../src/legacy-open-telemetry.ts"],"x_google_ignoreList":[2],"mappings":";;;;KAwBY;KASA,cAAc;EACxB,UAAU;EACV;EACA;EACA,gBAAgB;MACZ;KAEM;;;;EAIV,SAAS;;;;;;;;;;;EAYT,6CAGM;IACA;IACA;;;;;;EAON,aAAa;;;;EAKb;;;;EAKA;;;;EAKA;;;;EAKA;;;;EAKA;;EAGA;;;;EAKA;;;;EAKA;;;;EAKA;;;;EAKA;;;;
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":["OtelStepStartEvent","StreamTranscriptionStartEvent","StreamTranscriptionEndEvent","DecideStartEvent","DecideEndEvent","DecisionModelCallStartEvent","DecisionModelCallEndEvent","AISDKContext","StreamTranscriptionStartEvent","StreamTranscriptionEndEvent","DecideStartEvent","DecideEndEvent","DecisionModelCallStartEvent","DecisionModelCallEndEvent"],"sources":["../src/supplemental-attributes.ts","../src/open-telemetry.ts","../../../node_modules/.pnpm/zod@3.25.76/node_modules/zod/v4/core/schemas.d.cts","../../provider-utils/dist/index.d.ts","../src/legacy-open-telemetry.ts"],"x_google_ignoreList":[2],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { SpanKind, SpanStatusCode, context, trace } from "@opentelemetry/api";
|
|
1
|
+
import { SpanKind, SpanStatusCode, context, metrics, trace } from "@opentelemetry/api";
|
|
2
2
|
import { RetryError, convertDataContentToBase64String } from "ai";
|
|
3
3
|
import { APICallError } from "@ai-sdk/provider";
|
|
4
4
|
//#region src/gen-ai-format-messages.ts
|
|
@@ -693,6 +693,37 @@ var OpenTelemetry = class {
|
|
|
693
693
|
cleanupCallState(callId) {
|
|
694
694
|
this.callStates.delete(callId);
|
|
695
695
|
}
|
|
696
|
+
recordInferenceDuration(state, { responseTimeMs, provider, responseModelId, errorType } = {}) {
|
|
697
|
+
const inference = state.inferenceMetrics;
|
|
698
|
+
if (inference == null) return;
|
|
699
|
+
state.inferenceMetrics = void 0;
|
|
700
|
+
metrics.getMeter("gen_ai").createHistogram("gen_ai.client.inference.duration", {
|
|
701
|
+
description: "GenAI client inference operation duration.",
|
|
702
|
+
unit: "s",
|
|
703
|
+
advice: { explicitBucketBoundaries: [
|
|
704
|
+
.01,
|
|
705
|
+
.02,
|
|
706
|
+
.04,
|
|
707
|
+
.08,
|
|
708
|
+
.16,
|
|
709
|
+
.32,
|
|
710
|
+
.64,
|
|
711
|
+
1.28,
|
|
712
|
+
2.56,
|
|
713
|
+
5.12,
|
|
714
|
+
10.24,
|
|
715
|
+
20.48,
|
|
716
|
+
40.96,
|
|
717
|
+
81.92
|
|
718
|
+
] }
|
|
719
|
+
}).record((responseTimeMs ?? performance.now() - inference.startTime) / 1e3, selectAttributes$1(state.telemetry, {
|
|
720
|
+
"gen_ai.operation.name": "chat",
|
|
721
|
+
"gen_ai.provider.name": mapProviderName(provider ?? inference.provider),
|
|
722
|
+
"gen_ai.request.model": inference.modelId,
|
|
723
|
+
"gen_ai.response.model": responseModelId,
|
|
724
|
+
"error.type": errorType
|
|
725
|
+
}), state.inferenceContext);
|
|
726
|
+
}
|
|
696
727
|
getAgentSpanName({ operationName, modelId, functionId }) {
|
|
697
728
|
const defaultName = `${operationName} ${modelId}`;
|
|
698
729
|
if (operationName !== "invoke_agent") return defaultName;
|
|
@@ -1135,9 +1166,15 @@ var OpenTelemetry = class {
|
|
|
1135
1166
|
onLanguageModelCallStart(event) {
|
|
1136
1167
|
const state = this.getCallState(event.callId);
|
|
1137
1168
|
if (!state?.stepContext) return;
|
|
1169
|
+
this.recordInferenceDuration(state, { errorType: "_OTHER" });
|
|
1138
1170
|
const { telemetry } = state;
|
|
1139
1171
|
const providerName = mapProviderName(event.provider);
|
|
1140
1172
|
state.inferenceToolDefinitions = event.tools;
|
|
1173
|
+
state.inferenceMetrics = {
|
|
1174
|
+
startTime: performance.now(),
|
|
1175
|
+
provider: event.provider,
|
|
1176
|
+
modelId: event.modelId
|
|
1177
|
+
};
|
|
1141
1178
|
const inferenceAttributes = selectAttributes$1(telemetry, {
|
|
1142
1179
|
"gen_ai.operation.name": "chat",
|
|
1143
1180
|
"gen_ai.provider.name": providerName,
|
|
@@ -1174,6 +1211,12 @@ var OpenTelemetry = class {
|
|
|
1174
1211
|
onLanguageModelCallEnd(event) {
|
|
1175
1212
|
const state = this.getCallState(event.callId);
|
|
1176
1213
|
if (!state?.inferenceSpan) return;
|
|
1214
|
+
this.recordInferenceDuration(state, {
|
|
1215
|
+
responseTimeMs: event.performance.responseTimeMs,
|
|
1216
|
+
provider: event.provider,
|
|
1217
|
+
responseModelId: event.modelId,
|
|
1218
|
+
errorType: event.finishReason === "error" ? "_OTHER" : void 0
|
|
1219
|
+
});
|
|
1177
1220
|
if (event.finishReason === "error") state.inferenceSpan.setStatus({ code: SpanStatusCode.ERROR });
|
|
1178
1221
|
const { telemetry } = state;
|
|
1179
1222
|
const providerName = mapProviderName(event.provider);
|
|
@@ -1296,6 +1339,7 @@ var OpenTelemetry = class {
|
|
|
1296
1339
|
onStepEnd(event) {
|
|
1297
1340
|
const state = this.getCallState(event.callId);
|
|
1298
1341
|
if (!state?.stepSpan) return;
|
|
1342
|
+
this.recordInferenceDuration(state, { errorType: event.finishReason === "error" ? "_OTHER" : void 0 });
|
|
1299
1343
|
if (event.finishReason === "error") state.stepSpan.setStatus({ code: SpanStatusCode.ERROR });
|
|
1300
1344
|
const { telemetry } = state;
|
|
1301
1345
|
state.stepSpan.setAttributes(selectSupplementalAttributes(telemetry, this.supplementalAttributes, {
|
|
@@ -1313,6 +1357,7 @@ var OpenTelemetry = class {
|
|
|
1313
1357
|
onStepError(event) {
|
|
1314
1358
|
const state = this.getCallState(event.callId);
|
|
1315
1359
|
if (!state?.stepSpan) return;
|
|
1360
|
+
this.recordInferenceDuration(state, { errorType: event.error instanceof Error ? event.error.name : "_OTHER" });
|
|
1316
1361
|
if (state.inferenceSpan) {
|
|
1317
1362
|
recordErrorOnSpan(state.inferenceSpan, event.error);
|
|
1318
1363
|
state.inferenceSpan.end();
|
|
@@ -1704,6 +1749,7 @@ var OpenTelemetry = class {
|
|
|
1704
1749
|
onAbort(event) {
|
|
1705
1750
|
const state = this.getCallState(event.callId);
|
|
1706
1751
|
if (!state?.rootSpan) return;
|
|
1752
|
+
this.recordInferenceDuration(state, { errorType: "AbortError" });
|
|
1707
1753
|
for (const { span: toolSpan } of state.toolSpans.values()) toolSpan.end();
|
|
1708
1754
|
state.toolSpans.clear();
|
|
1709
1755
|
if (state.inferenceSpan) {
|
|
@@ -1735,6 +1781,7 @@ var OpenTelemetry = class {
|
|
|
1735
1781
|
const state = this.getCallState(event.callId);
|
|
1736
1782
|
if (!state?.rootSpan) return;
|
|
1737
1783
|
const actualError = event.error ?? error;
|
|
1784
|
+
this.recordInferenceDuration(state, { errorType: actualError instanceof Error ? actualError.name : "_OTHER" });
|
|
1738
1785
|
for (const { span: toolSpan } of state.toolSpans.values()) {
|
|
1739
1786
|
recordErrorOnSpan(toolSpan, actualError);
|
|
1740
1787
|
toolSpan.end();
|