@ai-sdk/otel 1.0.123 → 1.0.126
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 +24 -0
- package/dist/index.d.ts +13 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +237 -1
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
- package/src/gen-ai-format-messages.ts +3 -0
- package/src/legacy-open-telemetry.ts +153 -2
- package/src/open-telemetry.ts +217 -2
- package/src/provider-usage-attributes.ts +69 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,29 @@
|
|
|
1
1
|
# @ai-sdk/otel
|
|
2
2
|
|
|
3
|
+
## 1.0.126
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Updated dependencies [4f3d236]
|
|
8
|
+
- ai@7.0.126
|
|
9
|
+
|
|
10
|
+
## 1.0.125
|
|
11
|
+
|
|
12
|
+
### Patch Changes
|
|
13
|
+
|
|
14
|
+
- Updated dependencies [ff3dcef]
|
|
15
|
+
- ai@7.0.125
|
|
16
|
+
|
|
17
|
+
## 1.0.124
|
|
18
|
+
|
|
19
|
+
### Patch Changes
|
|
20
|
+
|
|
21
|
+
- 8c65988: feat(ai): add telemetry to speech generation and transcription, including
|
|
22
|
+
provider usage propagation and experimental streaming lifecycle callbacks
|
|
23
|
+
- Updated dependencies [8c65988]
|
|
24
|
+
- ai@7.0.124
|
|
25
|
+
- @ai-sdk/provider@4.0.21
|
|
26
|
+
|
|
3
27
|
## 1.0.123
|
|
4
28
|
|
|
5
29
|
### Patch Changes
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Attributes, Tracer } from "@opentelemetry/api";
|
|
2
|
-
import { EmbedEndEvent, EmbedStartEvent, EmbeddingModelCallEndEvent, EmbeddingModelCallStartEvent, Experimental_EvaluateEndEvent, Experimental_EvaluateStartEvent, Experimental_EvaluationModelCallEndEvent, Experimental_EvaluationModelCallStartEvent, GenerateObjectEndEvent, GenerateObjectStartEvent, GenerateObjectStepEndEvent, GenerateObjectStepStartEvent, GenerateTextAbortEvent, GenerateTextEndEvent, GenerateTextStartEvent, GenerateTextStepEndEvent, GenerateTextStepStartEvent, InferTelemetryEvent, LanguageModelCallEndEvent, LanguageModelCallStartEvent, Output, RerankEndEvent, RerankStartEvent, RerankingModelCallEndEvent, RerankingModelCallStartEvent, Telemetry, ToolExecutionEndEvent, ToolExecutionStartEvent, ToolSet } from "ai";
|
|
2
|
+
import { EmbedEndEvent, EmbedStartEvent, EmbeddingModelCallEndEvent, EmbeddingModelCallStartEvent, Experimental_EvaluateEndEvent, Experimental_EvaluateStartEvent, Experimental_EvaluationModelCallEndEvent, Experimental_EvaluationModelCallStartEvent, Experimental_StreamTranscriptionEndEvent, Experimental_StreamTranscriptionStartEvent, GenerateObjectEndEvent, GenerateObjectStartEvent, GenerateObjectStepEndEvent, GenerateObjectStepStartEvent, GenerateSpeechEndEvent, GenerateSpeechStartEvent, GenerateTextAbortEvent, GenerateTextEndEvent, GenerateTextStartEvent, GenerateTextStepEndEvent, GenerateTextStepStartEvent, InferTelemetryEvent, LanguageModelCallEndEvent, LanguageModelCallStartEvent, Output, RerankEndEvent, RerankStartEvent, RerankingModelCallEndEvent, RerankingModelCallStartEvent, Telemetry, ToolExecutionEndEvent, ToolExecutionStartEvent, ToolSet, TranscriptionEndEvent, TranscriptionStartEvent } from "ai";
|
|
3
3
|
import { APICallError, LanguageModelV4Prompt } from "@ai-sdk/provider";
|
|
4
4
|
//#region src/supplemental-attributes.d.ts
|
|
5
5
|
type OpenTelemetrySpanType = 'operation' | 'step' | 'languageModel' | 'tool' | 'embedding' | 'reranking' | 'experimental_evaluation';
|
|
@@ -83,7 +83,9 @@ export declare class OpenTelemetry implements Telemetry {
|
|
|
83
83
|
callId: string;
|
|
84
84
|
execute: () => PromiseLike<T>;
|
|
85
85
|
}): PromiseLike<T>;
|
|
86
|
-
onStart(event: InferTelemetryEvent<GenerateTextStartEvent> | InferTelemetryEvent<GenerateObjectStartEvent> | InferTelemetryEvent<EmbedStartEvent> | InferTelemetryEvent<RerankStartEvent>): void;
|
|
86
|
+
onStart(event: InferTelemetryEvent<GenerateTextStartEvent> | InferTelemetryEvent<GenerateObjectStartEvent> | InferTelemetryEvent<EmbedStartEvent> | InferTelemetryEvent<RerankStartEvent> | InferTelemetryEvent<GenerateSpeechStartEvent> | InferTelemetryEvent<TranscriptionStartEvent>): void;
|
|
87
|
+
experimental_onStreamTranscriptionStart(event: InferTelemetryEvent<Experimental_StreamTranscriptionStartEvent>): void;
|
|
88
|
+
private onAudioOperationStart;
|
|
87
89
|
private onGenerateStart;
|
|
88
90
|
private onObjectOperationStart;
|
|
89
91
|
/** @deprecated */
|
|
@@ -99,7 +101,9 @@ export declare class OpenTelemetry implements Telemetry {
|
|
|
99
101
|
onStepEnd(event: GenerateTextStepEndEvent<ToolSet>): void;
|
|
100
102
|
/** @deprecated Use `onStepEnd` instead. */
|
|
101
103
|
onStepFinish(event: GenerateTextStepEndEvent<ToolSet>): void;
|
|
102
|
-
onEnd(event: GenerateTextEndEvent<ToolSet> | GenerateObjectEndEvent<unknown> | EmbedEndEvent | RerankEndEvent): void;
|
|
104
|
+
onEnd(event: GenerateTextEndEvent<ToolSet> | GenerateObjectEndEvent<unknown> | EmbedEndEvent | RerankEndEvent | GenerateSpeechEndEvent | TranscriptionEndEvent): void;
|
|
105
|
+
experimental_onStreamTranscriptionEnd(event: InferTelemetryEvent<Experimental_StreamTranscriptionEndEvent>): void;
|
|
106
|
+
private onAudioOperationEnd;
|
|
103
107
|
private onGenerateEnd;
|
|
104
108
|
private onObjectOperationEnd;
|
|
105
109
|
private onEmbedOperationEnd;
|
|
@@ -162,7 +166,9 @@ export declare class LegacyOpenTelemetry implements Telemetry {
|
|
|
162
166
|
callId: string;
|
|
163
167
|
execute: () => PromiseLike<T>;
|
|
164
168
|
}): PromiseLike<T>;
|
|
165
|
-
onStart(event: InferTelemetryEvent<GenerateTextStartEvent> | InferTelemetryEvent<GenerateObjectStartEvent> | InferTelemetryEvent<EmbedStartEvent> | InferTelemetryEvent<RerankStartEvent>): void;
|
|
169
|
+
onStart(event: InferTelemetryEvent<GenerateTextStartEvent> | InferTelemetryEvent<GenerateObjectStartEvent> | InferTelemetryEvent<EmbedStartEvent> | InferTelemetryEvent<RerankStartEvent> | InferTelemetryEvent<GenerateSpeechStartEvent> | InferTelemetryEvent<TranscriptionStartEvent>): void;
|
|
170
|
+
experimental_onStreamTranscriptionStart(event: InferTelemetryEvent<Experimental_StreamTranscriptionStartEvent>): void;
|
|
171
|
+
private onAudioOperationStart;
|
|
166
172
|
private onGenerateStart;
|
|
167
173
|
private onObjectOperationStart;
|
|
168
174
|
/** @deprecated */
|
|
@@ -176,7 +182,9 @@ export declare class LegacyOpenTelemetry implements Telemetry {
|
|
|
176
182
|
onStepEnd(event: GenerateTextStepEndEvent<ToolSet>): void;
|
|
177
183
|
/** @deprecated Use `onStepEnd` instead. */
|
|
178
184
|
onStepFinish(event: GenerateTextStepEndEvent<ToolSet>): void;
|
|
179
|
-
onEnd(event: GenerateTextEndEvent<ToolSet> | GenerateObjectEndEvent<unknown> | EmbedEndEvent | RerankEndEvent): void;
|
|
185
|
+
onEnd(event: GenerateTextEndEvent<ToolSet> | GenerateObjectEndEvent<unknown> | EmbedEndEvent | RerankEndEvent | GenerateSpeechEndEvent | TranscriptionEndEvent): void;
|
|
186
|
+
experimental_onStreamTranscriptionEnd(event: InferTelemetryEvent<Experimental_StreamTranscriptionEndEvent>): void;
|
|
187
|
+
private onAudioOperationEnd;
|
|
180
188
|
private onGenerateEnd;
|
|
181
189
|
private onObjectOperationEnd;
|
|
182
190
|
private onEmbedOperationEnd;
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","names":["OtelStepStartEvent","EvaluateStartEvent","EvaluateEndEvent","EvaluationModelCallStartEvent","EvaluationModelCallEndEvent","AISDKContext","EvaluateStartEvent","EvaluateEndEvent","EvaluationModelCallStartEvent","EvaluationModelCallEndEvent"],"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;;;;;EAMT,aAAa;;;;EAKb;;;;EAKA;;;;EAKA;;;;EAKA;;;;EAKA;;;;EAKA;;;;EAKA;;;;EAKA;;;;EAKA;;;;
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":["OtelStepStartEvent","StreamTranscriptionStartEvent","StreamTranscriptionEndEvent","EvaluateStartEvent","EvaluateEndEvent","EvaluationModelCallStartEvent","EvaluationModelCallEndEvent","AISDKContext","StreamTranscriptionStartEvent","StreamTranscriptionEndEvent","EvaluateStartEvent","EvaluateEndEvent","EvaluationModelCallStartEvent","EvaluationModelCallEndEvent"],"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;;;;;EAMT,aAAa;;;;EAKb;;;;EAKA;;;;EAKA;;;;EAKA;;;;EAKA;;;;EAKA;;;;EAKA;;;;EAKA;;;;EAKA;;;;UClBQA,6BAA2B,2BAA2B;WACrD;;qBA2CE,yBAAyB;mBACnB;mBAEA;mBACA;mBACA;EAEL,YAAA,UAAS;UAMb;UAIA;UAIA;EAgCR,YAAY,KACV,QACA,YACA;IAEA;IACA;IACA,eAAe,YAAY;MACzB,YAAY;;;;;EAchB,yBAAyB,KACvB,QACA;IAEA;IACA,eAAe,YAAY;MACzB,YAAY;EAWhB,QACE,OACI,oBAAoB,0BACpB,oBAAoB,4BACpB,oBAAoB,mBACpB,oBAAoB,oBACpB,oBAAoB,4BACpB,oBAAoB;EA4C1B,wCACE,OAAO,oBAAoBC;UAKrB;UA0FA;UAuGA;;EA6GR,kBAAkB,OAAO;;EAuEzB,gBAAgB,OAAO;UAiDf;EA6ER,YAAY,OAAOD;EAwCnB,yBAAyB,OAAO;EAyEhC,uBAAuB,OAAO,0BAA0B;EAiKxD,qBAAqB,OAAO,wBAAwB;EAyCpD,mBAAmB,OAAO,sBAAsB;EAqChD,UAAU,OAAO,yBAAyB;;EAuB1C,aAAa,OAAO,yBAAyB;EAI7C,MACE,OACI,qBAAqB,WACrB,kCACA,gBACA,iBACA,yBACA;EAuCN,sCACE,OAAO,oBAAoBE;UAKrB;UA8EA;UAiDA;UA2CA;EAoCR,aAAa,OAAO;EA4CpB,WAAW,OAAO;UAgCV;UAoEA;EAQR,cAAc,OAAO;EAyCrB,YAAY,OAAO;UAsBX;UAkEA;EAqBR,6BACE,OAAO,oBAAoBC;EAK7B,2BAA2B,OAAOC;EAIlC,wCACE,OAAOC;EA8CT,sCACE,OAAOC;EA+BT,QAAQ,OAAO,uBAAuB;EAwCtC,QAAQ;;;;QCljCF;YACM;;;;;;;;;KC22BT,UAAU;;;UCr+CL,mBACR,cAAc,UAAU,SACxB,wBAAwBC,UAAeA,SACvC,eAAe,OAAO,SAAS,OAAO,gBAC9B,2BAA2B,OAAO,iBAAiB;WAClD,iBAAiB;WACjB,YAAY,cAAc;WAC1B;;qBAkBE,+BAA+B;mBACzB;;;;mBAKA;EAGf,YAAA;IACE,SAAS;;UAML;UAIA;EAIR,YAAY,KACV,QACA,YACA;IAEA;IACA;IACA,eAAe,YAAY;MACzB,YAAY;;;;;EAchB,yBAAyB,KACvB,QACA;IAEA;IACA,eAAe,YAAY;MACzB,YAAY;EAUhB,QACE,OACI,oBAAoB,0BACpB,oBAAoB,4BACpB,oBAAoB,mBACpB,oBAAoB,oBACpB,oBAAoB,4BACpB,oBAAoB;EA4C1B,wCACE,OAAO,oBAAoBC;UAKrB;UAyDA;UAgEA;;EAqER,kBAAkB,OAAO;;EAmDzB,gBAAgB,OAAO;UAuDf;EA6DR,YAAY,OAAO;EAiEnB,qBAAqB,OAAO,wBAAwB;EAqCpD,mBAAmB,OAAO,sBAAsB;EA+BhD,UAAU,OAAO,yBAAyB;;EA4G1C,aAAa,OAAO,yBAAyB;EAI7C,MACE,OACI,qBAAqB,WACrB,kCACA,gBACA,iBACA,yBACA;EAuCN,sCACE,OAAO,oBAAoBC;UAKrB;UA+CA;UAyEA;UA+BA;EA6BR,aAAa,OAAO;EA8BpB,WAAW,OAAO;UAwBV;UAkDA;EAQR,cAAc,OAAO;EA2BrB,YAAY,OAAO;UAoBX;UA8CA;EAeR,6BACE,OAAO,oBAAoBC;EAK7B,2BAA2B,OAAOC;EAIlC,wCACE,OAAOC;EA6BT,sCACE,OAAOC;EAqBT,QAAQ,OAAO,uBAAuB;EAkCtC,QAAQ"}
|
package/dist/index.js
CHANGED
|
@@ -46,7 +46,10 @@ function mapOperationName(operationId) {
|
|
|
46
46
|
"ai.streamObject": "invoke_agent",
|
|
47
47
|
"ai.embed": "embeddings",
|
|
48
48
|
"ai.embedMany": "embeddings",
|
|
49
|
-
"ai.rerank": "rerank"
|
|
49
|
+
"ai.rerank": "rerank",
|
|
50
|
+
"ai.generateSpeech": "ai.generateSpeech",
|
|
51
|
+
"ai.transcribe": "ai.transcribe",
|
|
52
|
+
"ai.streamTranscribe": "ai.streamTranscribe"
|
|
50
53
|
}[operationId] ?? operationId;
|
|
51
54
|
}
|
|
52
55
|
/**
|
|
@@ -460,6 +463,48 @@ function recordErrorOnSpan(span, error) {
|
|
|
460
463
|
} else span.setStatus({ code: SpanStatusCode.ERROR });
|
|
461
464
|
}
|
|
462
465
|
//#endregion
|
|
466
|
+
//#region src/provider-usage-attributes.ts
|
|
467
|
+
const usageKeyAliases = {
|
|
468
|
+
inputtokens: "input_tokens",
|
|
469
|
+
prompttokens: "input_tokens",
|
|
470
|
+
prompttokencount: "input_tokens",
|
|
471
|
+
totalinputtokens: "input_tokens",
|
|
472
|
+
outputtokens: "output_tokens",
|
|
473
|
+
completiontokens: "output_tokens",
|
|
474
|
+
completiontokencount: "output_tokens",
|
|
475
|
+
candidatestokencount: "output_tokens",
|
|
476
|
+
totaltokens: "total_tokens",
|
|
477
|
+
totaltokencount: "total_tokens"
|
|
478
|
+
};
|
|
479
|
+
function normalizeUsageKey(key) {
|
|
480
|
+
const aliasKey = key.replace(/[^a-zA-Z0-9]/g, "").toLowerCase();
|
|
481
|
+
const alias = usageKeyAliases[aliasKey];
|
|
482
|
+
if (alias != null) return alias;
|
|
483
|
+
return key.replace(/([a-z0-9])([A-Z])/g, "$1_$2").replace(/[^a-zA-Z0-9]+/g, "_").replace(/^_+|_+$/g, "").toLowerCase();
|
|
484
|
+
}
|
|
485
|
+
/**
|
|
486
|
+
* Converts provider-native usage objects into numeric span attributes.
|
|
487
|
+
*
|
|
488
|
+
* Usage units such as tokens, characters, and seconds remain distinct so
|
|
489
|
+
* observability backends can apply the provider/model-specific price unit.
|
|
490
|
+
*/
|
|
491
|
+
function getProviderUsageAttributes({ usage, prefix }) {
|
|
492
|
+
const attributes = {};
|
|
493
|
+
const addValue = (value, path) => {
|
|
494
|
+
if (typeof value === "number") {
|
|
495
|
+
if (Number.isFinite(value) && path.length > 0) attributes[`${prefix}.${path.join(".")}`] = value;
|
|
496
|
+
return;
|
|
497
|
+
}
|
|
498
|
+
if (value == null || typeof value !== "object" || Array.isArray(value)) return;
|
|
499
|
+
for (const [key, nestedValue] of Object.entries(value)) {
|
|
500
|
+
const normalizedKey = normalizeUsageKey(key);
|
|
501
|
+
if (normalizedKey !== "") addValue(nestedValue, [...path, normalizedKey]);
|
|
502
|
+
}
|
|
503
|
+
};
|
|
504
|
+
addValue(usage, []);
|
|
505
|
+
return attributes;
|
|
506
|
+
}
|
|
507
|
+
//#endregion
|
|
463
508
|
//#region src/sanitize-attribute-value.ts
|
|
464
509
|
function isPrimitiveAttributeValue(value) {
|
|
465
510
|
return typeof value === "string" || typeof value === "number" || typeof value === "boolean";
|
|
@@ -641,6 +686,14 @@ var OpenTelemetry = class {
|
|
|
641
686
|
return context.with(modelCallContext, execute);
|
|
642
687
|
}
|
|
643
688
|
onStart(event) {
|
|
689
|
+
if (event.operationId === "ai.generateSpeech") {
|
|
690
|
+
this.onAudioOperationStart(event);
|
|
691
|
+
return;
|
|
692
|
+
}
|
|
693
|
+
if (event.operationId === "ai.transcribe") {
|
|
694
|
+
this.onAudioOperationStart(event);
|
|
695
|
+
return;
|
|
696
|
+
}
|
|
644
697
|
if (event.operationId === "ai.embed" || event.operationId === "ai.embedMany") {
|
|
645
698
|
this.onEmbedOperationStart(event);
|
|
646
699
|
return;
|
|
@@ -655,6 +708,70 @@ var OpenTelemetry = class {
|
|
|
655
708
|
}
|
|
656
709
|
this.onGenerateStart(event);
|
|
657
710
|
}
|
|
711
|
+
experimental_onStreamTranscriptionStart(event) {
|
|
712
|
+
this.onAudioOperationStart(event);
|
|
713
|
+
}
|
|
714
|
+
onAudioOperationStart(event) {
|
|
715
|
+
const telemetry = {
|
|
716
|
+
recordInputs: event.recordInputs,
|
|
717
|
+
recordOutputs: event.recordOutputs,
|
|
718
|
+
functionId: event.functionId
|
|
719
|
+
};
|
|
720
|
+
const providerName = mapProviderName(event.provider);
|
|
721
|
+
const operationName = mapOperationName(event.operationId);
|
|
722
|
+
const audio = "audio" in event ? event.audio : void 0;
|
|
723
|
+
const text = "text" in event ? event.text : void 0;
|
|
724
|
+
const baseSupplementalAttributes = selectSupplementalAttributes(telemetry, this.supplementalAttributes, { headers: getHeaderAttributes(event.headers) });
|
|
725
|
+
const attributes = selectAttributes$1(telemetry, {
|
|
726
|
+
"gen_ai.operation.name": operationName,
|
|
727
|
+
"gen_ai.provider.name": providerName,
|
|
728
|
+
"gen_ai.request.model": event.modelId,
|
|
729
|
+
"gen_ai.agent.name": telemetry.functionId,
|
|
730
|
+
"gen_ai.output.type": event.operationId === "ai.generateSpeech" ? "speech" : "text",
|
|
731
|
+
"gen_ai.request.stream": event.operationId === "ai.streamTranscribe",
|
|
732
|
+
"gen_ai.input.messages": text == null ? void 0 : { input: () => JSON.stringify([{
|
|
733
|
+
role: "user",
|
|
734
|
+
parts: [{
|
|
735
|
+
type: "text",
|
|
736
|
+
content: text
|
|
737
|
+
}]
|
|
738
|
+
}]) },
|
|
739
|
+
"ai.request.text": text == null ? void 0 : { input: () => text },
|
|
740
|
+
"ai.request.audio.size": audio?.byteLength == null ? void 0 : { input: () => audio.byteLength },
|
|
741
|
+
"ai.request.audio.media_type": audio == null ? void 0 : { input: () => audio.mediaType },
|
|
742
|
+
...baseSupplementalAttributes
|
|
743
|
+
});
|
|
744
|
+
const rootSpan = this.tracer.startSpan(`${operationName} ${event.modelId}`, {
|
|
745
|
+
attributes: this.getSpanAttributes({
|
|
746
|
+
attributes,
|
|
747
|
+
spanType: "operation",
|
|
748
|
+
operationId: event.operationId,
|
|
749
|
+
callId: event.callId,
|
|
750
|
+
runtimeContext: void 0
|
|
751
|
+
}),
|
|
752
|
+
kind: SpanKind.CLIENT
|
|
753
|
+
});
|
|
754
|
+
const rootContext = trace.setSpan(context.active(), rootSpan);
|
|
755
|
+
this.callStates.set(event.callId, {
|
|
756
|
+
operationId: event.operationId,
|
|
757
|
+
telemetry,
|
|
758
|
+
rootSpan,
|
|
759
|
+
rootContext,
|
|
760
|
+
stepSpan: void 0,
|
|
761
|
+
stepContext: void 0,
|
|
762
|
+
inferenceSpan: void 0,
|
|
763
|
+
inferenceContext: void 0,
|
|
764
|
+
embedSpans: /* @__PURE__ */ new Map(),
|
|
765
|
+
rerankSpan: void 0,
|
|
766
|
+
evaluationSpan: void 0,
|
|
767
|
+
toolSpans: /* @__PURE__ */ new Map(),
|
|
768
|
+
settings: {},
|
|
769
|
+
provider: event.provider,
|
|
770
|
+
modelId: event.modelId,
|
|
771
|
+
runtimeContext: void 0,
|
|
772
|
+
baseSupplementalAttributes
|
|
773
|
+
});
|
|
774
|
+
}
|
|
658
775
|
onGenerateStart(event) {
|
|
659
776
|
const telemetry = {
|
|
660
777
|
recordInputs: event.recordInputs,
|
|
@@ -1139,12 +1256,51 @@ var OpenTelemetry = class {
|
|
|
1139
1256
|
this.onRerankOperationEnd(event);
|
|
1140
1257
|
return;
|
|
1141
1258
|
}
|
|
1259
|
+
if (state.operationId === "ai.generateSpeech" || state.operationId === "ai.transcribe") {
|
|
1260
|
+
this.onAudioOperationEnd(event);
|
|
1261
|
+
return;
|
|
1262
|
+
}
|
|
1142
1263
|
if (state.operationId === "ai.generateObject" || state.operationId === "ai.streamObject") {
|
|
1143
1264
|
this.onObjectOperationEnd(event);
|
|
1144
1265
|
return;
|
|
1145
1266
|
}
|
|
1146
1267
|
this.onGenerateEnd(event);
|
|
1147
1268
|
}
|
|
1269
|
+
experimental_onStreamTranscriptionEnd(event) {
|
|
1270
|
+
this.onAudioOperationEnd(event);
|
|
1271
|
+
}
|
|
1272
|
+
onAudioOperationEnd(event) {
|
|
1273
|
+
const state = this.getCallState(event.callId);
|
|
1274
|
+
if (!state?.rootSpan) return;
|
|
1275
|
+
const outputAudio = event.operationId === "ai.generateSpeech" ? event.audio : void 0;
|
|
1276
|
+
const inputAudio = event.operationId === "ai.generateSpeech" ? void 0 : event.audio;
|
|
1277
|
+
const transcript = "segments" in event ? event.text : void 0;
|
|
1278
|
+
state.rootSpan.setAttributes(selectAttributes$1(state.telemetry, {
|
|
1279
|
+
"ai.request.audio.size": inputAudio == null ? void 0 : { input: () => inputAudio.byteLength },
|
|
1280
|
+
"ai.request.audio.media_type": inputAudio == null ? void 0 : { input: () => inputAudio.mediaType },
|
|
1281
|
+
"ai.response.text": transcript == null ? void 0 : { output: () => transcript },
|
|
1282
|
+
"gen_ai.output.messages": transcript == null ? void 0 : { output: () => JSON.stringify([{
|
|
1283
|
+
role: "assistant",
|
|
1284
|
+
parts: [{
|
|
1285
|
+
type: "text",
|
|
1286
|
+
content: transcript
|
|
1287
|
+
}]
|
|
1288
|
+
}]) },
|
|
1289
|
+
"ai.response.audio.size": outputAudio == null ? void 0 : { output: () => outputAudio.byteLength },
|
|
1290
|
+
"ai.response.audio.media_type": outputAudio == null ? void 0 : { output: () => outputAudio.mediaType },
|
|
1291
|
+
"ai.response.audio.format": outputAudio == null || !("format" in outputAudio) ? void 0 : { output: () => String(outputAudio.format) },
|
|
1292
|
+
...getProviderUsageAttributes({
|
|
1293
|
+
usage: event.usage,
|
|
1294
|
+
prefix: "gen_ai.usage"
|
|
1295
|
+
}),
|
|
1296
|
+
...selectSupplementalAttributes(state.telemetry, this.supplementalAttributes, {
|
|
1297
|
+
usage: { "ai.response.usage": event.usage == null ? void 0 : JSON.stringify(event.usage) },
|
|
1298
|
+
providerMetadata: { "ai.response.providerMetadata": event.providerMetadata == null ? void 0 : JSON.stringify(event.providerMetadata) }
|
|
1299
|
+
})
|
|
1300
|
+
}));
|
|
1301
|
+
state.rootSpan.end();
|
|
1302
|
+
this.cleanupCallState(event.callId);
|
|
1303
|
+
}
|
|
1148
1304
|
onGenerateEnd(event) {
|
|
1149
1305
|
const state = this.getCallState(event.callId);
|
|
1150
1306
|
if (!state?.rootSpan) return;
|
|
@@ -1641,6 +1797,14 @@ var LegacyOpenTelemetry = class {
|
|
|
1641
1797
|
return context.with(stepContext, execute);
|
|
1642
1798
|
}
|
|
1643
1799
|
onStart(event) {
|
|
1800
|
+
if (event.operationId === "ai.generateSpeech") {
|
|
1801
|
+
this.onAudioOperationStart(event);
|
|
1802
|
+
return;
|
|
1803
|
+
}
|
|
1804
|
+
if (event.operationId === "ai.transcribe") {
|
|
1805
|
+
this.onAudioOperationStart(event);
|
|
1806
|
+
return;
|
|
1807
|
+
}
|
|
1644
1808
|
if (event.operationId === "ai.embed" || event.operationId === "ai.embedMany") {
|
|
1645
1809
|
this.onEmbedOperationStart(event);
|
|
1646
1810
|
return;
|
|
@@ -1655,6 +1819,49 @@ var LegacyOpenTelemetry = class {
|
|
|
1655
1819
|
}
|
|
1656
1820
|
this.onGenerateStart(event);
|
|
1657
1821
|
}
|
|
1822
|
+
experimental_onStreamTranscriptionStart(event) {
|
|
1823
|
+
this.onAudioOperationStart(event);
|
|
1824
|
+
}
|
|
1825
|
+
onAudioOperationStart(event) {
|
|
1826
|
+
const telemetry = {
|
|
1827
|
+
recordInputs: event.recordInputs,
|
|
1828
|
+
recordOutputs: event.recordOutputs,
|
|
1829
|
+
functionId: event.functionId
|
|
1830
|
+
};
|
|
1831
|
+
const audio = "audio" in event ? event.audio : void 0;
|
|
1832
|
+
const text = "text" in event ? event.text : void 0;
|
|
1833
|
+
const baseTelemetryAttributes = {
|
|
1834
|
+
"ai.model.provider": event.provider,
|
|
1835
|
+
"ai.model.id": event.modelId,
|
|
1836
|
+
...Object.fromEntries(Object.entries(event.headers ?? {}).map(([key, value]) => [`ai.request.headers.${key}`, value]))
|
|
1837
|
+
};
|
|
1838
|
+
const attributes = selectAttributes(telemetry, {
|
|
1839
|
+
...assembleOperationName({
|
|
1840
|
+
operationId: event.operationId,
|
|
1841
|
+
telemetry
|
|
1842
|
+
}),
|
|
1843
|
+
...baseTelemetryAttributes,
|
|
1844
|
+
"ai.request.text": text == null ? void 0 : { input: () => text },
|
|
1845
|
+
"ai.request.audio.size": audio?.byteLength == null ? void 0 : { input: () => audio.byteLength },
|
|
1846
|
+
"ai.request.audio.mediaType": audio == null ? void 0 : { input: () => audio.mediaType }
|
|
1847
|
+
});
|
|
1848
|
+
const rootSpan = this.tracer.startSpan(event.operationId, { attributes });
|
|
1849
|
+
const rootContext = trace.setSpan(context.active(), rootSpan);
|
|
1850
|
+
this.callStates.set(event.callId, {
|
|
1851
|
+
operationId: event.operationId,
|
|
1852
|
+
telemetry,
|
|
1853
|
+
rootSpan,
|
|
1854
|
+
rootContext,
|
|
1855
|
+
stepSpan: void 0,
|
|
1856
|
+
stepContext: void 0,
|
|
1857
|
+
embedSpans: /* @__PURE__ */ new Map(),
|
|
1858
|
+
rerankSpan: void 0,
|
|
1859
|
+
evaluationSpan: void 0,
|
|
1860
|
+
toolSpans: /* @__PURE__ */ new Map(),
|
|
1861
|
+
baseTelemetryAttributes,
|
|
1862
|
+
settings: {}
|
|
1863
|
+
});
|
|
1864
|
+
}
|
|
1658
1865
|
onGenerateStart(event) {
|
|
1659
1866
|
const telemetry = {
|
|
1660
1867
|
recordInputs: event.recordInputs,
|
|
@@ -2006,12 +2213,41 @@ var LegacyOpenTelemetry = class {
|
|
|
2006
2213
|
this.onRerankOperationEnd(event);
|
|
2007
2214
|
return;
|
|
2008
2215
|
}
|
|
2216
|
+
if (state.operationId === "ai.generateSpeech" || state.operationId === "ai.transcribe") {
|
|
2217
|
+
this.onAudioOperationEnd(event);
|
|
2218
|
+
return;
|
|
2219
|
+
}
|
|
2009
2220
|
if (state.operationId === "ai.generateObject" || state.operationId === "ai.streamObject") {
|
|
2010
2221
|
this.onObjectOperationEnd(event);
|
|
2011
2222
|
return;
|
|
2012
2223
|
}
|
|
2013
2224
|
this.onGenerateEnd(event);
|
|
2014
2225
|
}
|
|
2226
|
+
experimental_onStreamTranscriptionEnd(event) {
|
|
2227
|
+
this.onAudioOperationEnd(event);
|
|
2228
|
+
}
|
|
2229
|
+
onAudioOperationEnd(event) {
|
|
2230
|
+
const state = this.getCallState(event.callId);
|
|
2231
|
+
if (!state?.rootSpan) return;
|
|
2232
|
+
const isSpeech = event.operationId === "ai.generateSpeech";
|
|
2233
|
+
const audio = event.audio;
|
|
2234
|
+
state.rootSpan.setAttributes(selectAttributes(state.telemetry, {
|
|
2235
|
+
"ai.request.audio.size": isSpeech ? void 0 : { input: () => audio.byteLength },
|
|
2236
|
+
"ai.request.audio.mediaType": isSpeech ? void 0 : { input: () => audio.mediaType },
|
|
2237
|
+
"ai.response.text": "segments" in event ? { output: () => event.text } : void 0,
|
|
2238
|
+
"ai.response.audio.size": isSpeech ? { output: () => audio.byteLength } : void 0,
|
|
2239
|
+
"ai.response.audio.mediaType": isSpeech ? { output: () => audio.mediaType } : void 0,
|
|
2240
|
+
"ai.response.audio.format": isSpeech && "format" in audio ? { output: () => audio.format } : void 0,
|
|
2241
|
+
...getProviderUsageAttributes({
|
|
2242
|
+
usage: event.usage,
|
|
2243
|
+
prefix: "ai.usage"
|
|
2244
|
+
}),
|
|
2245
|
+
"ai.response.usage": event.usage == null ? void 0 : JSON.stringify(event.usage),
|
|
2246
|
+
"ai.response.providerMetadata": event.providerMetadata == null ? void 0 : JSON.stringify(event.providerMetadata)
|
|
2247
|
+
}));
|
|
2248
|
+
state.rootSpan.end();
|
|
2249
|
+
this.cleanupCallState(event.callId);
|
|
2250
|
+
}
|
|
2015
2251
|
onGenerateEnd(event) {
|
|
2016
2252
|
const state = this.getCallState(event.callId);
|
|
2017
2253
|
if (!state?.rootSpan) return;
|