@ai-sdk/otel 1.0.0-canary.71 → 1.0.0-canary.73

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 CHANGED
@@ -1,5 +1,23 @@
1
1
  # @ai-sdk/otel
2
2
 
3
+ ## 1.0.0-canary.73
4
+
5
+ ### Patch Changes
6
+
7
+ - c025d60: feat(otel): add option for custom span attributes
8
+ - Updated dependencies [e95e38d]
9
+ - Updated dependencies [016e877]
10
+ - Updated dependencies [ca99fea]
11
+ - Updated dependencies [d775a57]
12
+ - Updated dependencies [538c12b]
13
+ - ai@7.0.0-canary.127
14
+
15
+ ## 1.0.0-canary.72
16
+
17
+ ### Patch Changes
18
+
19
+ - ai@7.0.0-canary.126
20
+
3
21
  ## 1.0.0-canary.71
4
22
 
5
23
  ### Patch Changes
package/dist/index.d.ts CHANGED
@@ -1,13 +1,25 @@
1
1
  import { Telemetry, InferTelemetryEvent, GenerateTextStartEvent, GenerateObjectStartEvent, EmbedStartEvent, RerankStartEvent, GenerateObjectStepStartEvent, GenerateObjectStepEndEvent, GenerateTextStepStartEvent, ToolSet, LanguageModelCallStartEvent, LanguageModelCallEndEvent, ToolExecutionStartEvent, ToolExecutionEndEvent, GenerateTextStepEndEvent, GenerateTextEndEvent, GenerateObjectEndEvent, EmbedEndEvent, RerankEndEvent, EmbeddingModelCallStartEvent, EmbeddingModelCallEndEvent, RerankingModelCallStartEvent, RerankingModelCallEndEvent, StreamTextChunkEvent, OutputInterface } from 'ai';
2
- import { Tracer } from '@opentelemetry/api';
2
+ import { Attributes, Tracer } from '@opentelemetry/api';
3
3
  import { LanguageModelV4Prompt } from '@ai-sdk/provider';
4
4
  import { Context } from '@ai-sdk/provider-utils';
5
5
 
6
+ type OpenTelemetrySpanType = 'operation' | 'step' | 'languageModel' | 'tool' | 'embedding' | 'reranking';
7
+ type EnrichSpan = (options: {
8
+ spanType: OpenTelemetrySpanType;
9
+ operationId: string;
10
+ callId: string;
11
+ runtimeContext: Record<string, unknown> | undefined;
12
+ }) => Attributes | undefined;
6
13
  type OpenTelemetryOptions = {
7
14
  /**
8
15
  * The tracer to use for the telemetry data.
9
16
  */
10
17
  tracer?: Tracer;
18
+ /**
19
+ * Adds custom attributes to spans when they are created. These attributes are
20
+ * not AI SDK-owned semantics and are intended for observability integrations.
21
+ */
22
+ enrichSpan?: EnrichSpan;
11
23
  /**
12
24
  * Emit AI SDK usage details that are not represented by GenAI SemConv.
13
25
  */
@@ -49,9 +61,11 @@ declare class OpenTelemetry implements Telemetry {
49
61
  private readonly callStates;
50
62
  private readonly tracer;
51
63
  private readonly supplementalAttributes;
64
+ private readonly enrichSpan;
52
65
  constructor(options?: OpenTelemetryOptions);
53
66
  private getCallState;
54
67
  private cleanupCallState;
68
+ private getSpanAttributes;
55
69
  executeTool<T>({ callId, toolCallId, execute, }: {
56
70
  callId: string;
57
71
  toolCallId: string;
@@ -132,4 +146,4 @@ declare class LegacyOpenTelemetry implements Telemetry {
132
146
  onError(error: unknown): void;
133
147
  }
134
148
 
135
- export { LegacyOpenTelemetry, OpenTelemetry };
149
+ export { type EnrichSpan, LegacyOpenTelemetry, OpenTelemetry, type OpenTelemetryOptions, type OpenTelemetrySpanType };
package/dist/index.js CHANGED
@@ -556,6 +556,7 @@ var OpenTelemetry = class {
556
556
  var _a;
557
557
  this.tracer = (_a = options.tracer) != null ? _a : trace.getTracer("gen_ai");
558
558
  this.supplementalAttributes = normalizeSupplementalAttributes(options);
559
+ this.enrichSpan = options.enrichSpan;
559
560
  }
560
561
  getCallState(callId) {
561
562
  return this.callStates.get(callId);
@@ -563,6 +564,30 @@ var OpenTelemetry = class {
563
564
  cleanupCallState(callId) {
564
565
  this.callStates.delete(callId);
565
566
  }
567
+ getSpanAttributes({
568
+ attributes,
569
+ spanType,
570
+ operationId,
571
+ callId,
572
+ runtimeContext
573
+ }) {
574
+ var _a;
575
+ let customAttributes;
576
+ try {
577
+ customAttributes = (_a = this.enrichSpan) == null ? void 0 : _a.call(this, {
578
+ spanType,
579
+ operationId,
580
+ callId,
581
+ runtimeContext
582
+ });
583
+ } catch (e) {
584
+ customAttributes = void 0;
585
+ }
586
+ return {
587
+ ...customAttributes,
588
+ ...attributes
589
+ };
590
+ }
566
591
  executeTool({
567
592
  callId,
568
593
  toolCallId,
@@ -614,13 +639,12 @@ var OpenTelemetry = class {
614
639
  };
615
640
  const providerName = mapProviderName(event.provider);
616
641
  const operationName = mapOperationName(event.operationId);
642
+ const runtimeContext = event.runtimeContext;
617
643
  const baseSupplementalAttributes = selectSupplementalAttributes(
618
644
  telemetry,
619
645
  this.supplementalAttributes,
620
646
  {
621
- runtimeContext: getRuntimeContextAttributes(
622
- event.runtimeContext
623
- ),
647
+ runtimeContext: getRuntimeContextAttributes(runtimeContext),
624
648
  headers: getHeaderAttributes(event.headers)
625
649
  }
626
650
  );
@@ -637,8 +661,8 @@ var OpenTelemetry = class {
637
661
  "gen_ai.request.top_p": event.topP,
638
662
  "gen_ai.request.stop_sequences": event.stopSequences,
639
663
  "gen_ai.request.seed": event.seed,
640
- "gen_ai.system_instructions": event.system ? {
641
- input: () => JSON.stringify(formatSystemInstructions(event.system))
664
+ "gen_ai.system_instructions": event.instructions ? {
665
+ input: () => JSON.stringify(formatSystemInstructions(event.instructions))
642
666
  } : void 0,
643
667
  "gen_ai.input.messages": {
644
668
  input: () => JSON.stringify(
@@ -652,7 +676,13 @@ var OpenTelemetry = class {
652
676
  });
653
677
  const spanName = `${operationName} ${event.modelId}`;
654
678
  const rootSpan = this.tracer.startSpan(spanName, {
655
- attributes,
679
+ attributes: this.getSpanAttributes({
680
+ attributes,
681
+ spanType: "operation",
682
+ operationId: event.operationId,
683
+ callId: event.callId,
684
+ runtimeContext
685
+ }),
656
686
  kind: SpanKind.INTERNAL
657
687
  });
658
688
  const rootContext = trace.setSpan(context2.active(), rootSpan);
@@ -671,6 +701,7 @@ var OpenTelemetry = class {
671
701
  settings,
672
702
  provider: event.provider,
673
703
  modelId: event.modelId,
704
+ runtimeContext,
674
705
  baseSupplementalAttributes
675
706
  });
676
707
  }
@@ -736,7 +767,13 @@ var OpenTelemetry = class {
736
767
  });
737
768
  const spanName = `${operationName} ${event.modelId}`;
738
769
  const rootSpan = this.tracer.startSpan(spanName, {
739
- attributes,
770
+ attributes: this.getSpanAttributes({
771
+ attributes,
772
+ spanType: "operation",
773
+ operationId: event.operationId,
774
+ callId: event.callId,
775
+ runtimeContext: void 0
776
+ }),
740
777
  kind: SpanKind.INTERNAL
741
778
  });
742
779
  const rootContext = trace.setSpan(context2.active(), rootSpan);
@@ -755,6 +792,7 @@ var OpenTelemetry = class {
755
792
  settings,
756
793
  provider: event.provider,
757
794
  modelId: event.modelId,
795
+ runtimeContext: void 0,
758
796
  baseSupplementalAttributes
759
797
  });
760
798
  }
@@ -784,7 +822,16 @@ var OpenTelemetry = class {
784
822
  const spanName = `chat ${event.modelId}`;
785
823
  state.inferenceSpan = this.tracer.startSpan(
786
824
  spanName,
787
- { attributes, kind: SpanKind.CLIENT },
825
+ {
826
+ attributes: this.getSpanAttributes({
827
+ attributes,
828
+ spanType: "languageModel",
829
+ operationId: state.operationId,
830
+ callId: event.callId,
831
+ runtimeContext: state.runtimeContext
832
+ }),
833
+ kind: SpanKind.CLIENT
834
+ },
788
835
  state.rootContext
789
836
  );
790
837
  state.inferenceContext = trace.setSpan(
@@ -871,7 +918,13 @@ var OpenTelemetry = class {
871
918
  });
872
919
  const spanName = `embeddings ${event.modelId}`;
873
920
  const rootSpan = this.tracer.startSpan(spanName, {
874
- attributes,
921
+ attributes: this.getSpanAttributes({
922
+ attributes,
923
+ spanType: "operation",
924
+ operationId: event.operationId,
925
+ callId: event.callId,
926
+ runtimeContext: void 0
927
+ }),
875
928
  kind: SpanKind.CLIENT
876
929
  });
877
930
  const rootContext = trace.setSpan(context2.active(), rootSpan);
@@ -890,6 +943,7 @@ var OpenTelemetry = class {
890
943
  settings: { maxRetries: event.maxRetries },
891
944
  provider: event.provider,
892
945
  modelId: event.modelId,
946
+ runtimeContext: void 0,
893
947
  baseSupplementalAttributes
894
948
  });
895
949
  }
@@ -897,6 +951,7 @@ var OpenTelemetry = class {
897
951
  const state = this.getCallState(event.callId);
898
952
  if (!(state == null ? void 0 : state.rootSpan) || !state.rootContext) return;
899
953
  const { telemetry } = state;
954
+ state.runtimeContext = event.runtimeContext;
900
955
  const stepAttributes = selectAttributes(telemetry, {
901
956
  "gen_ai.operation.name": "agent_step",
902
957
  ...state.baseSupplementalAttributes,
@@ -910,7 +965,16 @@ var OpenTelemetry = class {
910
965
  });
911
966
  state.stepSpan = this.tracer.startSpan(
912
967
  `step ${event.steps.length + 1}`,
913
- { attributes: stepAttributes, kind: SpanKind.INTERNAL },
968
+ {
969
+ attributes: this.getSpanAttributes({
970
+ attributes: stepAttributes,
971
+ spanType: "step",
972
+ operationId: state.operationId,
973
+ callId: event.callId,
974
+ runtimeContext: state.runtimeContext
975
+ }),
976
+ kind: SpanKind.INTERNAL
977
+ },
914
978
  state.rootContext
915
979
  );
916
980
  state.stepContext = trace.setSpan(state.rootContext, state.stepSpan);
@@ -947,7 +1011,16 @@ var OpenTelemetry = class {
947
1011
  });
948
1012
  state.inferenceSpan = this.tracer.startSpan(
949
1013
  `chat ${event.modelId}`,
950
- { attributes: inferenceAttributes, kind: SpanKind.CLIENT },
1014
+ {
1015
+ attributes: this.getSpanAttributes({
1016
+ attributes: inferenceAttributes,
1017
+ spanType: "languageModel",
1018
+ operationId: state.operationId,
1019
+ callId: event.callId,
1020
+ runtimeContext: state.runtimeContext
1021
+ }),
1022
+ kind: SpanKind.CLIENT
1023
+ },
951
1024
  state.stepContext
952
1025
  );
953
1026
  state.inferenceContext = trace.setSpan(
@@ -1009,7 +1082,16 @@ var OpenTelemetry = class {
1009
1082
  const spanName = `execute_tool ${toolCall.toolName}`;
1010
1083
  const toolSpan = this.tracer.startSpan(
1011
1084
  spanName,
1012
- { attributes, kind: SpanKind.INTERNAL },
1085
+ {
1086
+ attributes: this.getSpanAttributes({
1087
+ attributes,
1088
+ spanType: "tool",
1089
+ operationId: state.operationId,
1090
+ callId: event.callId,
1091
+ runtimeContext: state.runtimeContext
1092
+ }),
1093
+ kind: SpanKind.INTERNAL
1094
+ },
1013
1095
  state.stepContext
1014
1096
  );
1015
1097
  const toolContext = trace.setSpan(state.stepContext, toolSpan);
@@ -1202,7 +1284,16 @@ var OpenTelemetry = class {
1202
1284
  const spanName = `embeddings ${state.modelId}`;
1203
1285
  const embedSpan = this.tracer.startSpan(
1204
1286
  spanName,
1205
- { attributes, kind: SpanKind.CLIENT },
1287
+ {
1288
+ attributes: this.getSpanAttributes({
1289
+ attributes,
1290
+ spanType: "embedding",
1291
+ operationId: state.operationId,
1292
+ callId: event.callId,
1293
+ runtimeContext: state.runtimeContext
1294
+ }),
1295
+ kind: SpanKind.CLIENT
1296
+ },
1206
1297
  state.rootContext
1207
1298
  );
1208
1299
  const embedContext = trace.setSpan(state.rootContext, embedSpan);
@@ -1266,7 +1357,13 @@ var OpenTelemetry = class {
1266
1357
  });
1267
1358
  const spanName = `rerank ${event.modelId}`;
1268
1359
  const rootSpan = this.tracer.startSpan(spanName, {
1269
- attributes,
1360
+ attributes: this.getSpanAttributes({
1361
+ attributes,
1362
+ spanType: "operation",
1363
+ operationId: event.operationId,
1364
+ callId: event.callId,
1365
+ runtimeContext: void 0
1366
+ }),
1270
1367
  kind: SpanKind.CLIENT
1271
1368
  });
1272
1369
  const rootContext = trace.setSpan(context2.active(), rootSpan);
@@ -1285,6 +1382,7 @@ var OpenTelemetry = class {
1285
1382
  settings: { maxRetries: event.maxRetries },
1286
1383
  provider: event.provider,
1287
1384
  modelId: event.modelId,
1385
+ runtimeContext: void 0,
1288
1386
  baseSupplementalAttributes
1289
1387
  });
1290
1388
  }
@@ -1315,7 +1413,16 @@ var OpenTelemetry = class {
1315
1413
  const spanName = `rerank ${state.modelId}`;
1316
1414
  const rerankSpan = this.tracer.startSpan(
1317
1415
  spanName,
1318
- { attributes, kind: SpanKind.CLIENT },
1416
+ {
1417
+ attributes: this.getSpanAttributes({
1418
+ attributes,
1419
+ spanType: "reranking",
1420
+ operationId: state.operationId,
1421
+ callId: event.callId,
1422
+ runtimeContext: state.runtimeContext
1423
+ }),
1424
+ kind: SpanKind.CLIENT
1425
+ },
1319
1426
  state.rootContext
1320
1427
  );
1321
1428
  const rerankContext = trace.setSpan(state.rootContext, rerankSpan);
@@ -1581,7 +1688,7 @@ var LegacyOpenTelemetry = class {
1581
1688
  "ai.model.id": event.modelId,
1582
1689
  "ai.prompt": {
1583
1690
  input: () => JSON.stringify({
1584
- system: event.system,
1691
+ system: event.instructions,
1585
1692
  messages: event.messages
1586
1693
  })
1587
1694
  }