@ai-sdk/otel 1.0.0-beta.5 → 1.0.0-beta.51

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/dist/index.mjs DELETED
@@ -1,845 +0,0 @@
1
- // src/open-telemetry-integration.ts
2
- import {
3
- context,
4
- SpanStatusCode,
5
- trace
6
- } from "@opentelemetry/api";
7
-
8
- // src/assemble-operation-name.ts
9
- function assembleOperationName({
10
- operationId,
11
- telemetry
12
- }) {
13
- return {
14
- // standardized operation and resource name:
15
- "operation.name": `${operationId}${(telemetry == null ? void 0 : telemetry.functionId) != null ? ` ${telemetry.functionId}` : ""}`,
16
- "resource.name": telemetry == null ? void 0 : telemetry.functionId,
17
- // detailed, AI SDK specific data:
18
- "ai.operationId": operationId,
19
- "ai.telemetry.functionId": telemetry == null ? void 0 : telemetry.functionId
20
- };
21
- }
22
-
23
- // src/get-base-telemetry-attributes.ts
24
- function getBaseTelemetryAttributes({
25
- model,
26
- settings,
27
- telemetry,
28
- headers
29
- }) {
30
- var _a;
31
- return {
32
- "ai.model.provider": model.provider,
33
- "ai.model.id": model.modelId,
34
- // settings:
35
- ...Object.entries(settings).reduce((attributes, [key, value]) => {
36
- attributes[`ai.settings.${key}`] = value;
37
- return attributes;
38
- }, {}),
39
- // add metadata as attributes:
40
- ...Object.entries((_a = telemetry == null ? void 0 : telemetry.metadata) != null ? _a : {}).reduce(
41
- (attributes, [key, value]) => {
42
- if (value != void 0) {
43
- attributes[`ai.telemetry.metadata.${key}`] = value;
44
- }
45
- return attributes;
46
- },
47
- {}
48
- ),
49
- // request headers
50
- ...Object.entries(headers != null ? headers : {}).reduce((attributes, [key, value]) => {
51
- if (value !== void 0) {
52
- attributes[`ai.request.headers.${key}`] = value;
53
- }
54
- return attributes;
55
- }, {})
56
- };
57
- }
58
-
59
- // src/stringify-for-telemetry.ts
60
- import { convertDataContentToBase64String } from "ai";
61
- function stringifyForTelemetry(prompt) {
62
- return JSON.stringify(
63
- prompt.map((message) => ({
64
- ...message,
65
- content: typeof message.content === "string" ? message.content : message.content.map(
66
- (part) => part.type === "file" ? {
67
- ...part,
68
- data: part.data instanceof Uint8Array ? convertDataContentToBase64String(part.data) : part.data
69
- } : part
70
- )
71
- }))
72
- );
73
- }
74
-
75
- // src/open-telemetry-integration.ts
76
- function recordSpanError(span, error) {
77
- if (error instanceof Error) {
78
- span.recordException({
79
- name: error.name,
80
- message: error.message,
81
- stack: error.stack
82
- });
83
- span.setStatus({
84
- code: SpanStatusCode.ERROR,
85
- message: error.message
86
- });
87
- } else {
88
- span.setStatus({ code: SpanStatusCode.ERROR });
89
- }
90
- }
91
- function shouldRecord(telemetry) {
92
- return (telemetry == null ? void 0 : telemetry.isEnabled) === true;
93
- }
94
- function selectAttributes(telemetry, attributes) {
95
- if (!shouldRecord(telemetry)) {
96
- return {};
97
- }
98
- const result = {};
99
- for (const [key, value] of Object.entries(attributes)) {
100
- if (value == null) continue;
101
- if (typeof value === "object" && "input" in value && typeof value.input === "function") {
102
- if ((telemetry == null ? void 0 : telemetry.recordInputs) === false) continue;
103
- const resolved = value.input();
104
- if (resolved != null) result[key] = resolved;
105
- continue;
106
- }
107
- if (typeof value === "object" && "output" in value && typeof value.output === "function") {
108
- if ((telemetry == null ? void 0 : telemetry.recordOutputs) === false) continue;
109
- const resolved = value.output();
110
- if (resolved != null) result[key] = resolved;
111
- continue;
112
- }
113
- result[key] = value;
114
- }
115
- return result;
116
- }
117
- var OpenTelemetryIntegration = class {
118
- constructor(options = {}) {
119
- this.callStates = /* @__PURE__ */ new Map();
120
- var _a;
121
- this.tracer = (_a = options.tracer) != null ? _a : trace.getTracer("ai");
122
- }
123
- getCallState(callId) {
124
- return this.callStates.get(callId);
125
- }
126
- cleanupCallState(callId) {
127
- this.callStates.delete(callId);
128
- }
129
- executeTool({
130
- callId,
131
- toolCallId,
132
- execute
133
- }) {
134
- var _a;
135
- const toolSpanEntry = (_a = this.getCallState(callId)) == null ? void 0 : _a.toolSpans.get(toolCallId);
136
- if (toolSpanEntry == null) {
137
- return execute();
138
- }
139
- return context.with(toolSpanEntry.context, execute);
140
- }
141
- onStart(event) {
142
- if (event.isEnabled !== true) return;
143
- if (event.operationId === "ai.embed" || event.operationId === "ai.embedMany") {
144
- this.onEmbedOperationStart(event);
145
- return;
146
- }
147
- if (event.operationId === "ai.rerank") {
148
- this.onRerankOperationStart(event);
149
- return;
150
- }
151
- if (event.operationId === "ai.generateObject" || event.operationId === "ai.streamObject") {
152
- this.onObjectOperationStart(event);
153
- return;
154
- }
155
- this.onGenerateStart(event);
156
- }
157
- onGenerateStart(event) {
158
- const telemetry = {
159
- isEnabled: event.isEnabled,
160
- recordInputs: event.recordInputs,
161
- recordOutputs: event.recordOutputs,
162
- functionId: event.functionId,
163
- metadata: event.metadata
164
- };
165
- const settings = {
166
- maxOutputTokens: event.maxOutputTokens,
167
- temperature: event.temperature,
168
- topP: event.topP,
169
- topK: event.topK,
170
- presencePenalty: event.presencePenalty,
171
- frequencyPenalty: event.frequencyPenalty,
172
- stopSequences: event.stopSequences,
173
- seed: event.seed,
174
- maxRetries: event.maxRetries
175
- };
176
- const baseTelemetryAttributes = getBaseTelemetryAttributes({
177
- model: { provider: event.provider, modelId: event.modelId },
178
- telemetry,
179
- headers: event.headers,
180
- settings
181
- });
182
- const attributes = selectAttributes(telemetry, {
183
- ...assembleOperationName({
184
- operationId: event.operationId,
185
- telemetry
186
- }),
187
- ...baseTelemetryAttributes,
188
- "ai.model.provider": event.provider,
189
- "ai.model.id": event.modelId,
190
- "ai.prompt": {
191
- input: () => JSON.stringify({
192
- system: event.system,
193
- prompt: event.prompt,
194
- messages: event.messages
195
- })
196
- }
197
- });
198
- const rootSpan = this.tracer.startSpan(event.operationId, { attributes });
199
- const rootContext = trace.setSpan(context.active(), rootSpan);
200
- this.callStates.set(event.callId, {
201
- operationId: event.operationId,
202
- telemetry,
203
- rootSpan,
204
- rootContext,
205
- stepSpan: void 0,
206
- stepContext: void 0,
207
- embedSpans: /* @__PURE__ */ new Map(),
208
- rerankSpan: void 0,
209
- toolSpans: /* @__PURE__ */ new Map(),
210
- baseTelemetryAttributes,
211
- settings
212
- });
213
- }
214
- onObjectOperationStart(event) {
215
- const telemetry = {
216
- isEnabled: event.isEnabled,
217
- recordInputs: event.recordInputs,
218
- recordOutputs: event.recordOutputs,
219
- functionId: event.functionId,
220
- metadata: event.metadata
221
- };
222
- const settings = {
223
- maxOutputTokens: event.maxOutputTokens,
224
- temperature: event.temperature,
225
- topP: event.topP,
226
- topK: event.topK,
227
- presencePenalty: event.presencePenalty,
228
- frequencyPenalty: event.frequencyPenalty,
229
- seed: event.seed,
230
- maxRetries: event.maxRetries
231
- };
232
- const baseTelemetryAttributes = getBaseTelemetryAttributes({
233
- model: { provider: event.provider, modelId: event.modelId },
234
- telemetry,
235
- headers: event.headers,
236
- settings
237
- });
238
- const attributes = selectAttributes(telemetry, {
239
- ...assembleOperationName({
240
- operationId: event.operationId,
241
- telemetry
242
- }),
243
- ...baseTelemetryAttributes,
244
- "ai.prompt": {
245
- input: () => JSON.stringify({
246
- system: event.system,
247
- prompt: event.prompt,
248
- messages: event.messages
249
- })
250
- },
251
- "ai.schema": event.schema ? { input: () => JSON.stringify(event.schema) } : void 0,
252
- "ai.schema.name": event.schemaName,
253
- "ai.schema.description": event.schemaDescription,
254
- "ai.settings.output": event.output
255
- });
256
- const rootSpan = this.tracer.startSpan(event.operationId, { attributes });
257
- const rootContext = trace.setSpan(context.active(), rootSpan);
258
- this.callStates.set(event.callId, {
259
- operationId: event.operationId,
260
- telemetry,
261
- rootSpan,
262
- rootContext,
263
- stepSpan: void 0,
264
- stepContext: void 0,
265
- embedSpans: /* @__PURE__ */ new Map(),
266
- rerankSpan: void 0,
267
- toolSpans: /* @__PURE__ */ new Map(),
268
- baseTelemetryAttributes,
269
- settings
270
- });
271
- }
272
- /** @deprecated */
273
- onObjectStepStart(event) {
274
- var _a;
275
- const state = this.getCallState(event.callId);
276
- if (!(state == null ? void 0 : state.rootSpan) || !state.rootContext) return;
277
- const { telemetry } = state;
278
- const stepOperationId = state.operationId === "ai.streamObject" ? "ai.streamObject.doStream" : "ai.generateObject.doGenerate";
279
- const attributes = selectAttributes(telemetry, {
280
- ...assembleOperationName({
281
- operationId: stepOperationId,
282
- telemetry
283
- }),
284
- ...state.baseTelemetryAttributes,
285
- "ai.prompt.messages": {
286
- input: () => event.promptMessages ? stringifyForTelemetry(event.promptMessages) : void 0
287
- },
288
- "gen_ai.system": event.provider,
289
- "gen_ai.request.model": event.modelId,
290
- "gen_ai.request.frequency_penalty": state.settings.frequencyPenalty,
291
- "gen_ai.request.max_tokens": state.settings.maxOutputTokens,
292
- "gen_ai.request.presence_penalty": state.settings.presencePenalty,
293
- "gen_ai.request.temperature": (_a = state.settings.temperature) != null ? _a : void 0,
294
- "gen_ai.request.top_k": state.settings.topK,
295
- "gen_ai.request.top_p": state.settings.topP
296
- });
297
- state.stepSpan = this.tracer.startSpan(
298
- stepOperationId,
299
- { attributes },
300
- state.rootContext
301
- );
302
- state.stepContext = trace.setSpan(state.rootContext, state.stepSpan);
303
- }
304
- /** @deprecated */
305
- onObjectStepFinish(event) {
306
- const state = this.getCallState(event.callId);
307
- if (!(state == null ? void 0 : state.stepSpan)) return;
308
- const { telemetry } = state;
309
- state.stepSpan.setAttributes(
310
- selectAttributes(telemetry, {
311
- "ai.response.finishReason": event.finishReason,
312
- "ai.response.object": {
313
- output: () => {
314
- try {
315
- return JSON.stringify(JSON.parse(event.objectText));
316
- } catch (e) {
317
- return event.objectText;
318
- }
319
- }
320
- },
321
- "ai.response.id": event.response.id,
322
- "ai.response.model": event.response.modelId,
323
- "ai.response.timestamp": event.response.timestamp.toISOString(),
324
- "ai.response.providerMetadata": event.providerMetadata ? JSON.stringify(event.providerMetadata) : void 0,
325
- "ai.usage.inputTokens": event.usage.inputTokens,
326
- "ai.usage.outputTokens": event.usage.outputTokens,
327
- "ai.usage.totalTokens": event.usage.totalTokens,
328
- "ai.usage.reasoningTokens": event.usage.reasoningTokens,
329
- "ai.usage.cachedInputTokens": event.usage.cachedInputTokens,
330
- "gen_ai.response.finish_reasons": [event.finishReason],
331
- "gen_ai.response.id": event.response.id,
332
- "gen_ai.response.model": event.response.modelId,
333
- "gen_ai.usage.input_tokens": event.usage.inputTokens,
334
- "gen_ai.usage.output_tokens": event.usage.outputTokens
335
- })
336
- );
337
- if (event.msToFirstChunk != null) {
338
- state.stepSpan.addEvent("ai.stream.firstChunk", {
339
- "ai.stream.msToFirstChunk": event.msToFirstChunk
340
- });
341
- state.stepSpan.setAttributes({
342
- "ai.stream.msToFirstChunk": event.msToFirstChunk
343
- });
344
- }
345
- state.stepSpan.end();
346
- state.stepSpan = void 0;
347
- state.stepContext = void 0;
348
- }
349
- onEmbedOperationStart(event) {
350
- const telemetry = {
351
- isEnabled: event.isEnabled,
352
- recordInputs: event.recordInputs,
353
- recordOutputs: event.recordOutputs,
354
- functionId: event.functionId,
355
- metadata: event.metadata
356
- };
357
- const settings = {
358
- maxRetries: event.maxRetries
359
- };
360
- const baseTelemetryAttributes = getBaseTelemetryAttributes({
361
- model: { provider: event.provider, modelId: event.modelId },
362
- telemetry,
363
- headers: event.headers,
364
- settings
365
- });
366
- const value = event.value;
367
- const isMany = event.operationId === "ai.embedMany";
368
- const attributes = selectAttributes(telemetry, {
369
- ...assembleOperationName({
370
- operationId: event.operationId,
371
- telemetry
372
- }),
373
- ...baseTelemetryAttributes,
374
- ...isMany ? {
375
- "ai.values": {
376
- input: () => value.map((v) => JSON.stringify(v))
377
- }
378
- } : {
379
- "ai.value": {
380
- input: () => JSON.stringify(value)
381
- }
382
- }
383
- });
384
- const rootSpan = this.tracer.startSpan(event.operationId, { attributes });
385
- const rootContext = trace.setSpan(context.active(), rootSpan);
386
- this.callStates.set(event.callId, {
387
- operationId: event.operationId,
388
- telemetry,
389
- rootSpan,
390
- rootContext,
391
- stepSpan: void 0,
392
- stepContext: void 0,
393
- embedSpans: /* @__PURE__ */ new Map(),
394
- rerankSpan: void 0,
395
- toolSpans: /* @__PURE__ */ new Map(),
396
- baseTelemetryAttributes,
397
- settings
398
- });
399
- }
400
- onStepStart(event) {
401
- var _a;
402
- const state = this.getCallState(event.callId);
403
- if (!(state == null ? void 0 : state.rootSpan) || !state.rootContext) return;
404
- const { telemetry } = state;
405
- const stepOperationId = state.operationId === "ai.streamText" ? "ai.streamText.doStream" : "ai.generateText.doGenerate";
406
- const attributes = selectAttributes(telemetry, {
407
- ...assembleOperationName({
408
- operationId: stepOperationId,
409
- telemetry
410
- }),
411
- ...state.baseTelemetryAttributes,
412
- "ai.model.provider": event.provider,
413
- "ai.model.id": event.modelId,
414
- "ai.prompt.messages": {
415
- input: () => event.promptMessages ? stringifyForTelemetry(event.promptMessages) : void 0
416
- },
417
- "ai.prompt.tools": {
418
- input: () => {
419
- var _a2;
420
- return (_a2 = event.stepTools) == null ? void 0 : _a2.map((tool) => JSON.stringify(tool));
421
- }
422
- },
423
- "ai.prompt.toolChoice": {
424
- input: () => event.stepToolChoice != null ? JSON.stringify(event.stepToolChoice) : void 0
425
- },
426
- "gen_ai.system": event.provider,
427
- "gen_ai.request.model": event.modelId,
428
- "gen_ai.request.frequency_penalty": state.settings.frequencyPenalty,
429
- "gen_ai.request.max_tokens": state.settings.maxOutputTokens,
430
- "gen_ai.request.presence_penalty": state.settings.presencePenalty,
431
- "gen_ai.request.stop_sequences": state.settings.stopSequences,
432
- "gen_ai.request.temperature": (_a = state.settings.temperature) != null ? _a : void 0,
433
- "gen_ai.request.top_k": state.settings.topK,
434
- "gen_ai.request.top_p": state.settings.topP
435
- });
436
- state.stepSpan = this.tracer.startSpan(
437
- stepOperationId,
438
- { attributes },
439
- state.rootContext
440
- );
441
- state.stepContext = trace.setSpan(state.rootContext, state.stepSpan);
442
- }
443
- onToolCallStart(event) {
444
- const state = this.getCallState(event.callId);
445
- if (!(state == null ? void 0 : state.stepContext)) return;
446
- const { telemetry } = state;
447
- const { toolCall } = event;
448
- const attributes = selectAttributes(telemetry, {
449
- ...assembleOperationName({
450
- operationId: "ai.toolCall",
451
- telemetry
452
- }),
453
- "ai.toolCall.name": toolCall.toolName,
454
- "ai.toolCall.id": toolCall.toolCallId,
455
- "ai.toolCall.args": {
456
- output: () => JSON.stringify(toolCall.input)
457
- }
458
- });
459
- const toolSpan = this.tracer.startSpan(
460
- "ai.toolCall",
461
- { attributes },
462
- state.stepContext
463
- );
464
- const toolContext = trace.setSpan(state.stepContext, toolSpan);
465
- state.toolSpans.set(toolCall.toolCallId, {
466
- span: toolSpan,
467
- context: toolContext
468
- });
469
- }
470
- onToolCallFinish(event) {
471
- const state = this.getCallState(event.callId);
472
- if (!state) return;
473
- const toolSpanEntry = state.toolSpans.get(event.toolCall.toolCallId);
474
- if (!toolSpanEntry) return;
475
- const { span } = toolSpanEntry;
476
- const { telemetry } = state;
477
- if (event.success) {
478
- try {
479
- span.setAttributes(
480
- selectAttributes(telemetry, {
481
- "ai.toolCall.result": {
482
- output: () => JSON.stringify(event.output)
483
- }
484
- })
485
- );
486
- } catch (_ignored) {
487
- }
488
- } else {
489
- recordSpanError(span, event.error);
490
- }
491
- span.end();
492
- state.toolSpans.delete(event.toolCall.toolCallId);
493
- }
494
- onStepFinish(event) {
495
- var _a, _b, _c, _d, _e;
496
- const state = this.getCallState(event.callId);
497
- if (!(state == null ? void 0 : state.stepSpan)) return;
498
- const { telemetry } = state;
499
- state.stepSpan.setAttributes(
500
- selectAttributes(telemetry, {
501
- "ai.response.finishReason": event.finishReason,
502
- "ai.response.text": {
503
- output: () => {
504
- var _a2;
505
- return (_a2 = event.text) != null ? _a2 : void 0;
506
- }
507
- },
508
- "ai.response.reasoning": {
509
- output: () => event.reasoning.length > 0 ? event.reasoning.filter((part) => "text" in part).map((part) => part.text).join("\n") : void 0
510
- },
511
- "ai.response.toolCalls": {
512
- output: () => event.toolCalls.length > 0 ? JSON.stringify(
513
- event.toolCalls.map((toolCall) => ({
514
- toolCallId: toolCall.toolCallId,
515
- toolName: toolCall.toolName,
516
- input: toolCall.input
517
- }))
518
- ) : void 0
519
- },
520
- "ai.response.files": {
521
- output: () => event.files.length > 0 ? JSON.stringify(
522
- event.files.map((file) => ({
523
- type: "file",
524
- mediaType: file.mediaType,
525
- data: file.base64
526
- }))
527
- ) : void 0
528
- },
529
- "ai.response.id": event.response.id,
530
- "ai.response.model": event.response.modelId,
531
- "ai.response.timestamp": event.response.timestamp.toISOString(),
532
- "ai.response.providerMetadata": event.providerMetadata ? JSON.stringify(event.providerMetadata) : void 0,
533
- "ai.usage.inputTokens": event.usage.inputTokens,
534
- "ai.usage.outputTokens": event.usage.outputTokens,
535
- "ai.usage.totalTokens": event.usage.totalTokens,
536
- "ai.usage.reasoningTokens": event.usage.reasoningTokens,
537
- "ai.usage.cachedInputTokens": event.usage.cachedInputTokens,
538
- "ai.usage.inputTokenDetails.noCacheTokens": (_a = event.usage.inputTokenDetails) == null ? void 0 : _a.noCacheTokens,
539
- "ai.usage.inputTokenDetails.cacheReadTokens": (_b = event.usage.inputTokenDetails) == null ? void 0 : _b.cacheReadTokens,
540
- "ai.usage.inputTokenDetails.cacheWriteTokens": (_c = event.usage.inputTokenDetails) == null ? void 0 : _c.cacheWriteTokens,
541
- "ai.usage.outputTokenDetails.textTokens": (_d = event.usage.outputTokenDetails) == null ? void 0 : _d.textTokens,
542
- "ai.usage.outputTokenDetails.reasoningTokens": (_e = event.usage.outputTokenDetails) == null ? void 0 : _e.reasoningTokens,
543
- "gen_ai.response.finish_reasons": [event.finishReason],
544
- "gen_ai.response.id": event.response.id,
545
- "gen_ai.response.model": event.response.modelId,
546
- "gen_ai.usage.input_tokens": event.usage.inputTokens,
547
- "gen_ai.usage.output_tokens": event.usage.outputTokens
548
- })
549
- );
550
- state.stepSpan.end();
551
- state.stepSpan = void 0;
552
- state.stepContext = void 0;
553
- }
554
- onFinish(event) {
555
- const state = this.getCallState(event.callId);
556
- if (!(state == null ? void 0 : state.rootSpan)) return;
557
- if (state.operationId === "ai.embed" || state.operationId === "ai.embedMany") {
558
- this.onEmbedOperationFinish(event);
559
- return;
560
- }
561
- if (state.operationId === "ai.rerank") {
562
- this.onRerankOperationFinish(event);
563
- return;
564
- }
565
- if (state.operationId === "ai.generateObject" || state.operationId === "ai.streamObject") {
566
- this.onObjectOperationFinish(event);
567
- return;
568
- }
569
- this.onGenerateFinish(event);
570
- }
571
- onGenerateFinish(event) {
572
- var _a, _b, _c, _d, _e;
573
- const state = this.getCallState(event.callId);
574
- if (!(state == null ? void 0 : state.rootSpan)) return;
575
- const { telemetry } = state;
576
- state.rootSpan.setAttributes(
577
- selectAttributes(telemetry, {
578
- "ai.response.finishReason": event.finishReason,
579
- "ai.response.text": {
580
- output: () => {
581
- var _a2;
582
- return (_a2 = event.text) != null ? _a2 : void 0;
583
- }
584
- },
585
- "ai.response.reasoning": {
586
- output: () => event.reasoning.length > 0 ? event.reasoning.filter((part) => "text" in part).map((part) => part.text).join("\n") : void 0
587
- },
588
- "ai.response.toolCalls": {
589
- output: () => event.toolCalls.length > 0 ? JSON.stringify(
590
- event.toolCalls.map((toolCall) => ({
591
- toolCallId: toolCall.toolCallId,
592
- toolName: toolCall.toolName,
593
- input: toolCall.input
594
- }))
595
- ) : void 0
596
- },
597
- "ai.response.files": {
598
- output: () => event.files.length > 0 ? JSON.stringify(
599
- event.files.map((file) => ({
600
- type: "file",
601
- mediaType: file.mediaType,
602
- data: file.base64
603
- }))
604
- ) : void 0
605
- },
606
- "ai.response.providerMetadata": event.providerMetadata ? JSON.stringify(event.providerMetadata) : void 0,
607
- "ai.usage.inputTokens": event.totalUsage.inputTokens,
608
- "ai.usage.outputTokens": event.totalUsage.outputTokens,
609
- "ai.usage.totalTokens": event.totalUsage.totalTokens,
610
- "ai.usage.reasoningTokens": event.totalUsage.reasoningTokens,
611
- "ai.usage.cachedInputTokens": event.totalUsage.cachedInputTokens,
612
- "ai.usage.inputTokenDetails.noCacheTokens": (_a = event.totalUsage.inputTokenDetails) == null ? void 0 : _a.noCacheTokens,
613
- "ai.usage.inputTokenDetails.cacheReadTokens": (_b = event.totalUsage.inputTokenDetails) == null ? void 0 : _b.cacheReadTokens,
614
- "ai.usage.inputTokenDetails.cacheWriteTokens": (_c = event.totalUsage.inputTokenDetails) == null ? void 0 : _c.cacheWriteTokens,
615
- "ai.usage.outputTokenDetails.textTokens": (_d = event.totalUsage.outputTokenDetails) == null ? void 0 : _d.textTokens,
616
- "ai.usage.outputTokenDetails.reasoningTokens": (_e = event.totalUsage.outputTokenDetails) == null ? void 0 : _e.reasoningTokens
617
- })
618
- );
619
- state.rootSpan.end();
620
- this.cleanupCallState(event.callId);
621
- }
622
- onObjectOperationFinish(event) {
623
- const state = this.getCallState(event.callId);
624
- if (!(state == null ? void 0 : state.rootSpan)) return;
625
- const { telemetry } = state;
626
- state.rootSpan.setAttributes(
627
- selectAttributes(telemetry, {
628
- "ai.response.finishReason": event.finishReason,
629
- "ai.response.object": {
630
- output: () => event.object != null ? JSON.stringify(event.object) : void 0
631
- },
632
- "ai.response.providerMetadata": event.providerMetadata ? JSON.stringify(event.providerMetadata) : void 0,
633
- "ai.usage.inputTokens": event.usage.inputTokens,
634
- "ai.usage.outputTokens": event.usage.outputTokens,
635
- "ai.usage.totalTokens": event.usage.totalTokens,
636
- "ai.usage.reasoningTokens": event.usage.reasoningTokens,
637
- "ai.usage.cachedInputTokens": event.usage.cachedInputTokens
638
- })
639
- );
640
- state.rootSpan.end();
641
- this.cleanupCallState(event.callId);
642
- }
643
- onEmbedOperationFinish(event) {
644
- const state = this.getCallState(event.callId);
645
- if (!(state == null ? void 0 : state.rootSpan)) return;
646
- const { telemetry } = state;
647
- const isMany = state.operationId === "ai.embedMany";
648
- state.rootSpan.setAttributes(
649
- selectAttributes(telemetry, {
650
- ...isMany ? {
651
- "ai.embeddings": {
652
- output: () => event.embedding.map((e) => JSON.stringify(e))
653
- }
654
- } : {
655
- "ai.embedding": {
656
- output: () => JSON.stringify(event.embedding)
657
- }
658
- },
659
- "ai.usage.tokens": event.usage.tokens
660
- })
661
- );
662
- state.rootSpan.end();
663
- this.cleanupCallState(event.callId);
664
- }
665
- onEmbedStart(event) {
666
- const state = this.getCallState(event.callId);
667
- if (!(state == null ? void 0 : state.rootSpan) || !state.rootContext) return;
668
- const { telemetry } = state;
669
- const attributes = selectAttributes(telemetry, {
670
- ...assembleOperationName({
671
- operationId: event.operationId,
672
- telemetry
673
- }),
674
- ...state.baseTelemetryAttributes,
675
- "ai.values": {
676
- input: () => event.values.map((v) => JSON.stringify(v))
677
- }
678
- });
679
- const embedSpan = this.tracer.startSpan(
680
- event.operationId,
681
- { attributes },
682
- state.rootContext
683
- );
684
- const embedContext = trace.setSpan(state.rootContext, embedSpan);
685
- state.embedSpans.set(event.embedCallId, {
686
- span: embedSpan,
687
- context: embedContext
688
- });
689
- }
690
- onEmbedFinish(event) {
691
- const state = this.getCallState(event.callId);
692
- if (!state) return;
693
- const embedSpanEntry = state.embedSpans.get(event.embedCallId);
694
- if (!embedSpanEntry) return;
695
- const { span } = embedSpanEntry;
696
- const { telemetry } = state;
697
- span.setAttributes(
698
- selectAttributes(telemetry, {
699
- "ai.embeddings": {
700
- output: () => event.embeddings.map((embedding) => JSON.stringify(embedding))
701
- },
702
- "ai.usage.tokens": event.usage.tokens
703
- })
704
- );
705
- span.end();
706
- state.embedSpans.delete(event.embedCallId);
707
- }
708
- onRerankOperationStart(event) {
709
- const telemetry = {
710
- isEnabled: event.isEnabled,
711
- recordInputs: event.recordInputs,
712
- recordOutputs: event.recordOutputs,
713
- functionId: event.functionId,
714
- metadata: event.metadata
715
- };
716
- const settings = {
717
- maxRetries: event.maxRetries
718
- };
719
- const baseTelemetryAttributes = getBaseTelemetryAttributes({
720
- model: { provider: event.provider, modelId: event.modelId },
721
- telemetry,
722
- headers: event.headers,
723
- settings
724
- });
725
- const attributes = selectAttributes(telemetry, {
726
- ...assembleOperationName({
727
- operationId: event.operationId,
728
- telemetry
729
- }),
730
- ...baseTelemetryAttributes,
731
- "ai.documents": {
732
- input: () => event.documents.map((d) => JSON.stringify(d))
733
- }
734
- });
735
- const rootSpan = this.tracer.startSpan(event.operationId, { attributes });
736
- const rootContext = trace.setSpan(context.active(), rootSpan);
737
- this.callStates.set(event.callId, {
738
- operationId: event.operationId,
739
- telemetry,
740
- rootSpan,
741
- rootContext,
742
- stepSpan: void 0,
743
- stepContext: void 0,
744
- embedSpans: /* @__PURE__ */ new Map(),
745
- rerankSpan: void 0,
746
- toolSpans: /* @__PURE__ */ new Map(),
747
- baseTelemetryAttributes,
748
- settings
749
- });
750
- }
751
- onRerankOperationFinish(event) {
752
- const state = this.getCallState(event.callId);
753
- if (!(state == null ? void 0 : state.rootSpan)) return;
754
- state.rootSpan.end();
755
- this.cleanupCallState(event.callId);
756
- }
757
- onRerankStart(event) {
758
- const state = this.getCallState(event.callId);
759
- if (!(state == null ? void 0 : state.rootSpan) || !state.rootContext) return;
760
- const { telemetry } = state;
761
- const attributes = selectAttributes(telemetry, {
762
- ...assembleOperationName({
763
- operationId: event.operationId,
764
- telemetry
765
- }),
766
- ...state.baseTelemetryAttributes,
767
- "ai.documents": {
768
- input: () => event.documents.map((d) => JSON.stringify(d))
769
- }
770
- });
771
- const rerankSpan = this.tracer.startSpan(
772
- event.operationId,
773
- { attributes },
774
- state.rootContext
775
- );
776
- const rerankContext = trace.setSpan(state.rootContext, rerankSpan);
777
- state.rerankSpan = { span: rerankSpan, context: rerankContext };
778
- }
779
- onRerankFinish(event) {
780
- const state = this.getCallState(event.callId);
781
- if (!(state == null ? void 0 : state.rerankSpan)) return;
782
- const { span } = state.rerankSpan;
783
- const { telemetry } = state;
784
- span.setAttributes(
785
- selectAttributes(telemetry, {
786
- "ai.ranking.type": event.documentsType,
787
- "ai.ranking": {
788
- output: () => event.ranking.map((r) => JSON.stringify(r))
789
- }
790
- })
791
- );
792
- span.end();
793
- state.rerankSpan = void 0;
794
- }
795
- onChunk(event) {
796
- var _a;
797
- const chunk = event.chunk;
798
- if (typeof chunk.callId !== "string") {
799
- return;
800
- }
801
- if (chunk.type !== "ai.stream.firstChunk" && chunk.type !== "ai.stream.finish") {
802
- return;
803
- }
804
- const state = this.getCallState(chunk.callId);
805
- if (!(state == null ? void 0 : state.stepSpan)) return;
806
- const attributes = Object.fromEntries(
807
- Object.entries(
808
- (_a = chunk.attributes) != null ? _a : {}
809
- ).filter(([, value]) => value != null)
810
- );
811
- state.stepSpan.addEvent(chunk.type, attributes);
812
- if (Object.keys(attributes).length > 0) {
813
- state.stepSpan.setAttributes(attributes);
814
- }
815
- }
816
- onError(error) {
817
- var _a;
818
- const event = error;
819
- if (!(event == null ? void 0 : event.callId)) return;
820
- const state = this.getCallState(event.callId);
821
- if (!(state == null ? void 0 : state.rootSpan)) return;
822
- const actualError = (_a = event.error) != null ? _a : error;
823
- if (state.stepSpan) {
824
- recordSpanError(state.stepSpan, actualError);
825
- state.stepSpan.end();
826
- }
827
- for (const { span: embedSpan } of state.embedSpans.values()) {
828
- recordSpanError(embedSpan, actualError);
829
- embedSpan.end();
830
- }
831
- state.embedSpans.clear();
832
- if (state.rerankSpan) {
833
- recordSpanError(state.rerankSpan.span, actualError);
834
- state.rerankSpan.span.end();
835
- state.rerankSpan = void 0;
836
- }
837
- recordSpanError(state.rootSpan, actualError);
838
- state.rootSpan.end();
839
- this.cleanupCallState(event.callId);
840
- }
841
- };
842
- export {
843
- OpenTelemetryIntegration
844
- };
845
- //# sourceMappingURL=index.mjs.map