@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 CHANGED
@@ -1,5 +1,14 @@
1
1
  # @ai-sdk/otel
2
2
 
3
+ ## 1.0.111
4
+
5
+ ### Patch Changes
6
+
7
+ - 31d24ce: feat: add telemetry support to `experimental_evaluate`
8
+ - Updated dependencies [31d24ce]
9
+ - Updated dependencies [a65bfd9]
10
+ - ai@7.0.111
11
+
3
12
  ## 1.0.110
4
13
 
5
14
  ### Patch Changes
package/dist/index.d.ts CHANGED
@@ -1,9 +1,9 @@
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, GenerateTextAbortEvent, Output } from 'ai';
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, Experimental_EvaluateStartEvent, Experimental_EvaluateEndEvent, Experimental_EvaluationModelCallStartEvent, Experimental_EvaluationModelCallEndEvent, GenerateTextAbortEvent, Output } from 'ai';
2
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';
6
+ type OpenTelemetrySpanType = 'operation' | 'step' | 'languageModel' | 'tool' | 'embedding' | 'reranking' | 'experimental_evaluation';
7
7
  type EnrichSpan = (options: {
8
8
  spanType: OpenTelemetrySpanType;
9
9
  operationId: string;
@@ -36,6 +36,10 @@ type OpenTelemetryOptions = {
36
36
  * Emit reranking input documents and output ranking.
37
37
  */
38
38
  reranking?: boolean;
39
+ /**
40
+ * Emit evaluation state, questions, and answers.
41
+ */
42
+ experimental_evaluation?: boolean;
39
43
  /**
40
44
  * Emit runtime context values.
41
45
  */
@@ -105,6 +109,12 @@ declare class OpenTelemetry implements Telemetry {
105
109
  private onRerankOperationEnd;
106
110
  onRerankStart(event: RerankingModelCallStartEvent): void;
107
111
  onRerankEnd(event: RerankingModelCallEndEvent): void;
112
+ private onEvaluateOperationStart;
113
+ private onEvaluateOperationEnd;
114
+ experimental_onEvaluateStart(event: InferTelemetryEvent<Experimental_EvaluateStartEvent>): void;
115
+ experimental_onEvaluateEnd(event: Experimental_EvaluateEndEvent): void;
116
+ experimental_onEvaluationModelCallStart(event: Experimental_EvaluationModelCallStartEvent): void;
117
+ experimental_onEvaluationModelCallEnd(event: Experimental_EvaluationModelCallEndEvent): void;
108
118
  onAbort(event: GenerateTextAbortEvent<ToolSet>): void;
109
119
  onError(error: unknown): void;
110
120
  }
@@ -162,6 +172,12 @@ declare class LegacyOpenTelemetry implements Telemetry {
162
172
  private onRerankOperationEnd;
163
173
  onRerankStart(event: RerankingModelCallStartEvent): void;
164
174
  onRerankEnd(event: RerankingModelCallEndEvent): void;
175
+ private onEvaluateOperationStart;
176
+ private onEvaluateOperationEnd;
177
+ experimental_onEvaluateStart(event: InferTelemetryEvent<Experimental_EvaluateStartEvent>): void;
178
+ experimental_onEvaluateEnd(event: Experimental_EvaluateEndEvent): void;
179
+ experimental_onEvaluationModelCallStart(event: Experimental_EvaluationModelCallStartEvent): void;
180
+ experimental_onEvaluationModelCallEnd(event: Experimental_EvaluationModelCallEndEvent): void;
165
181
  onAbort(event: GenerateTextAbortEvent<ToolSet>): void;
166
182
  onError(error: unknown): void;
167
183
  }
package/dist/index.js CHANGED
@@ -569,23 +569,25 @@ var disabledSupplementalAttributes = {
569
569
  providerMetadata: false,
570
570
  embedding: false,
571
571
  reranking: false,
572
+ experimental_evaluation: false,
572
573
  runtimeContext: false,
573
574
  headers: false,
574
575
  toolChoice: false,
575
576
  schema: false
576
577
  };
577
578
  function normalizeSupplementalAttributes(options) {
578
- var _a, _b, _c, _d, _e, _f, _g, _h;
579
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i;
579
580
  return {
580
581
  ...disabledSupplementalAttributes,
581
582
  usage: (_a = options.usage) != null ? _a : false,
582
583
  providerMetadata: (_b = options.providerMetadata) != null ? _b : false,
583
584
  embedding: (_c = options.embedding) != null ? _c : false,
584
585
  reranking: (_d = options.reranking) != null ? _d : false,
585
- runtimeContext: (_e = options.runtimeContext) != null ? _e : false,
586
- headers: (_f = options.headers) != null ? _f : false,
587
- toolChoice: (_g = options.toolChoice) != null ? _g : false,
588
- schema: (_h = options.schema) != null ? _h : false
586
+ experimental_evaluation: (_e = options.experimental_evaluation) != null ? _e : false,
587
+ runtimeContext: (_f = options.runtimeContext) != null ? _f : false,
588
+ headers: (_g = options.headers) != null ? _g : false,
589
+ toolChoice: (_h = options.toolChoice) != null ? _h : false,
590
+ schema: (_i = options.schema) != null ? _i : false
589
591
  };
590
592
  }
591
593
  function getRuntimeContextAttributes(context4) {
@@ -810,6 +812,7 @@ var OpenTelemetry = class {
810
812
  inferenceContext: void 0,
811
813
  embedSpans: /* @__PURE__ */ new Map(),
812
814
  rerankSpan: void 0,
815
+ evaluationSpan: void 0,
813
816
  toolSpans: /* @__PURE__ */ new Map(),
814
817
  settings,
815
818
  provider: event.provider,
@@ -901,6 +904,7 @@ var OpenTelemetry = class {
901
904
  inferenceContext: void 0,
902
905
  embedSpans: /* @__PURE__ */ new Map(),
903
906
  rerankSpan: void 0,
907
+ evaluationSpan: void 0,
904
908
  toolSpans: /* @__PURE__ */ new Map(),
905
909
  settings,
906
910
  provider: event.provider,
@@ -1063,6 +1067,7 @@ var OpenTelemetry = class {
1063
1067
  inferenceContext: void 0,
1064
1068
  embedSpans: /* @__PURE__ */ new Map(),
1065
1069
  rerankSpan: void 0,
1070
+ evaluationSpan: void 0,
1066
1071
  toolSpans: /* @__PURE__ */ new Map(),
1067
1072
  settings: { maxRetries: event.maxRetries },
1068
1073
  provider: event.provider,
@@ -1602,6 +1607,7 @@ var OpenTelemetry = class {
1602
1607
  inferenceContext: void 0,
1603
1608
  embedSpans: /* @__PURE__ */ new Map(),
1604
1609
  rerankSpan: void 0,
1610
+ evaluationSpan: void 0,
1605
1611
  toolSpans: /* @__PURE__ */ new Map(),
1606
1612
  settings: { maxRetries: event.maxRetries },
1607
1613
  provider: event.provider,
@@ -1670,6 +1676,162 @@ var OpenTelemetry = class {
1670
1676
  span.end();
1671
1677
  state.rerankSpan = void 0;
1672
1678
  }
1679
+ onEvaluateOperationStart(event) {
1680
+ const telemetry = {
1681
+ recordInputs: event.recordInputs,
1682
+ recordOutputs: event.recordOutputs,
1683
+ functionId: event.functionId
1684
+ };
1685
+ const runtimeContext = event.runtimeContext;
1686
+ const baseSupplementalAttributes = selectSupplementalAttributes(
1687
+ telemetry,
1688
+ this.supplementalAttributes,
1689
+ {
1690
+ runtimeContext: getRuntimeContextAttributes(runtimeContext),
1691
+ headers: getHeaderAttributes(event.headers)
1692
+ }
1693
+ );
1694
+ const attributes = selectAttributes(telemetry, {
1695
+ "gen_ai.operation.name": "evaluate",
1696
+ "gen_ai.provider.name": mapProviderName(event.provider),
1697
+ "gen_ai.request.model": event.modelId,
1698
+ ...baseSupplementalAttributes,
1699
+ ...selectSupplementalAttributes(telemetry, this.supplementalAttributes, {
1700
+ experimental_evaluation: {
1701
+ "ai.evaluation.state": {
1702
+ input: () => JSON.stringify(event.state)
1703
+ },
1704
+ "ai.evaluation.questions": {
1705
+ input: () => JSON.stringify(event.questions)
1706
+ }
1707
+ }
1708
+ })
1709
+ });
1710
+ const rootSpan = this.tracer.startSpan(`evaluate ${event.modelId}`, {
1711
+ attributes: this.getSpanAttributes({
1712
+ attributes,
1713
+ spanType: "operation",
1714
+ operationId: event.operationId,
1715
+ callId: event.callId,
1716
+ runtimeContext
1717
+ }),
1718
+ kind: SpanKind.CLIENT
1719
+ });
1720
+ const rootContext = trace.setSpan(context2.active(), rootSpan);
1721
+ this.callStates.set(event.callId, {
1722
+ operationId: event.operationId,
1723
+ telemetry,
1724
+ rootSpan,
1725
+ rootContext,
1726
+ stepSpan: void 0,
1727
+ stepContext: void 0,
1728
+ inferenceSpan: void 0,
1729
+ inferenceContext: void 0,
1730
+ embedSpans: /* @__PURE__ */ new Map(),
1731
+ rerankSpan: void 0,
1732
+ evaluationSpan: void 0,
1733
+ toolSpans: /* @__PURE__ */ new Map(),
1734
+ settings: { maxRetries: event.maxRetries },
1735
+ provider: event.provider,
1736
+ modelId: event.modelId,
1737
+ runtimeContext,
1738
+ baseSupplementalAttributes
1739
+ });
1740
+ }
1741
+ onEvaluateOperationEnd(event) {
1742
+ const state = this.getCallState(event.callId);
1743
+ if (!(state == null ? void 0 : state.rootSpan)) return;
1744
+ state.rootSpan.setAttributes(
1745
+ selectSupplementalAttributes(
1746
+ state.telemetry,
1747
+ this.supplementalAttributes,
1748
+ {
1749
+ experimental_evaluation: {
1750
+ "ai.evaluation.answers": {
1751
+ output: () => JSON.stringify(event.answers)
1752
+ }
1753
+ }
1754
+ }
1755
+ )
1756
+ );
1757
+ state.rootSpan.end();
1758
+ this.cleanupCallState(event.callId);
1759
+ }
1760
+ experimental_onEvaluateStart(event) {
1761
+ this.onEvaluateOperationStart(event);
1762
+ }
1763
+ experimental_onEvaluateEnd(event) {
1764
+ this.onEvaluateOperationEnd(event);
1765
+ }
1766
+ experimental_onEvaluationModelCallStart(event) {
1767
+ const state = this.getCallState(event.callId);
1768
+ if (!(state == null ? void 0 : state.rootSpan) || !state.rootContext) return;
1769
+ const attributes = selectAttributes(state.telemetry, {
1770
+ "gen_ai.operation.name": "evaluate",
1771
+ "gen_ai.provider.name": mapProviderName(state.provider),
1772
+ "gen_ai.request.model": state.modelId,
1773
+ ...state.baseSupplementalAttributes,
1774
+ ...selectSupplementalAttributes(
1775
+ state.telemetry,
1776
+ this.supplementalAttributes,
1777
+ {
1778
+ experimental_evaluation: {
1779
+ "ai.evaluation.state": {
1780
+ input: () => JSON.stringify(event.state)
1781
+ },
1782
+ "ai.evaluation.questions": {
1783
+ input: () => JSON.stringify(event.questions)
1784
+ }
1785
+ }
1786
+ }
1787
+ )
1788
+ });
1789
+ const span = this.tracer.startSpan(
1790
+ `evaluate ${state.modelId}`,
1791
+ {
1792
+ attributes: this.getSpanAttributes({
1793
+ attributes,
1794
+ spanType: "experimental_evaluation",
1795
+ operationId: event.operationId,
1796
+ callId: event.callId,
1797
+ runtimeContext: state.runtimeContext
1798
+ }),
1799
+ kind: SpanKind.CLIENT
1800
+ },
1801
+ state.rootContext
1802
+ );
1803
+ state.evaluationSpan = {
1804
+ span,
1805
+ context: trace.setSpan(state.rootContext, span)
1806
+ };
1807
+ }
1808
+ experimental_onEvaluationModelCallEnd(event) {
1809
+ var _a, _b;
1810
+ const state = this.getCallState(event.callId);
1811
+ if (!(state == null ? void 0 : state.evaluationSpan)) return;
1812
+ state.evaluationSpan.span.setAttributes(
1813
+ selectAttributes(state.telemetry, {
1814
+ "gen_ai.usage.input_tokens": (_a = event.usage) == null ? void 0 : _a.inputTokens,
1815
+ "gen_ai.usage.output_tokens": (_b = event.usage) == null ? void 0 : _b.outputTokens,
1816
+ ...selectSupplementalAttributes(
1817
+ state.telemetry,
1818
+ this.supplementalAttributes,
1819
+ {
1820
+ experimental_evaluation: {
1821
+ "ai.evaluation.answers": {
1822
+ output: () => JSON.stringify(event.answers)
1823
+ }
1824
+ },
1825
+ providerMetadata: {
1826
+ "ai.response.providerMetadata": event.providerMetadata ? JSON.stringify(event.providerMetadata) : void 0
1827
+ }
1828
+ }
1829
+ )
1830
+ })
1831
+ );
1832
+ state.evaluationSpan.span.end();
1833
+ state.evaluationSpan = void 0;
1834
+ }
1673
1835
  onAbort(event) {
1674
1836
  const state = this.getCallState(event.callId);
1675
1837
  if (!(state == null ? void 0 : state.rootSpan)) return;
@@ -1695,6 +1857,10 @@ var OpenTelemetry = class {
1695
1857
  state.rerankSpan.span.end();
1696
1858
  state.rerankSpan = void 0;
1697
1859
  }
1860
+ if (state.evaluationSpan) {
1861
+ state.evaluationSpan.span.end();
1862
+ state.evaluationSpan = void 0;
1863
+ }
1698
1864
  state.rootSpan.end();
1699
1865
  this.cleanupCallState(event.callId);
1700
1866
  }
@@ -1732,6 +1898,11 @@ var OpenTelemetry = class {
1732
1898
  state.rerankSpan.span.end();
1733
1899
  state.rerankSpan = void 0;
1734
1900
  }
1901
+ if (state.evaluationSpan) {
1902
+ recordErrorOnSpan(state.evaluationSpan.span, actualError);
1903
+ state.evaluationSpan.span.end();
1904
+ state.evaluationSpan = void 0;
1905
+ }
1735
1906
  recordErrorOnSpan(state.rootSpan, actualError);
1736
1907
  state.rootSpan.end();
1737
1908
  this.cleanupCallState(event.callId);
@@ -1971,6 +2142,7 @@ var LegacyOpenTelemetry = class {
1971
2142
  stepContext: void 0,
1972
2143
  embedSpans: /* @__PURE__ */ new Map(),
1973
2144
  rerankSpan: void 0,
2145
+ evaluationSpan: void 0,
1974
2146
  toolSpans: /* @__PURE__ */ new Map(),
1975
2147
  baseTelemetryAttributes,
1976
2148
  settings
@@ -2027,6 +2199,7 @@ var LegacyOpenTelemetry = class {
2027
2199
  stepContext: void 0,
2028
2200
  embedSpans: /* @__PURE__ */ new Map(),
2029
2201
  rerankSpan: void 0,
2202
+ evaluationSpan: void 0,
2030
2203
  toolSpans: /* @__PURE__ */ new Map(),
2031
2204
  baseTelemetryAttributes,
2032
2205
  settings
@@ -2154,6 +2327,7 @@ var LegacyOpenTelemetry = class {
2154
2327
  stepContext: void 0,
2155
2328
  embedSpans: /* @__PURE__ */ new Map(),
2156
2329
  rerankSpan: void 0,
2330
+ evaluationSpan: void 0,
2157
2331
  toolSpans: /* @__PURE__ */ new Map(),
2158
2332
  baseTelemetryAttributes,
2159
2333
  settings
@@ -2529,6 +2703,7 @@ var LegacyOpenTelemetry = class {
2529
2703
  stepContext: void 0,
2530
2704
  embedSpans: /* @__PURE__ */ new Map(),
2531
2705
  rerankSpan: void 0,
2706
+ evaluationSpan: void 0,
2532
2707
  toolSpans: /* @__PURE__ */ new Map(),
2533
2708
  baseTelemetryAttributes,
2534
2709
  settings
@@ -2578,6 +2753,110 @@ var LegacyOpenTelemetry = class {
2578
2753
  span.end();
2579
2754
  state.rerankSpan = void 0;
2580
2755
  }
2756
+ onEvaluateOperationStart(event) {
2757
+ const telemetry = {
2758
+ recordInputs: event.recordInputs,
2759
+ recordOutputs: event.recordOutputs,
2760
+ functionId: event.functionId
2761
+ };
2762
+ const settings = {
2763
+ maxRetries: event.maxRetries
2764
+ };
2765
+ const baseTelemetryAttributes = getBaseTelemetryAttributes({
2766
+ model: { provider: event.provider, modelId: event.modelId },
2767
+ headers: event.headers,
2768
+ settings,
2769
+ context: event.runtimeContext
2770
+ });
2771
+ const attributes = selectAttributes2(telemetry, {
2772
+ ...assembleOperationName({ operationId: event.operationId, telemetry }),
2773
+ ...baseTelemetryAttributes,
2774
+ "ai.evaluation.state": {
2775
+ input: () => JSON.stringify(event.state)
2776
+ },
2777
+ "ai.evaluation.questions": {
2778
+ input: () => JSON.stringify(event.questions)
2779
+ }
2780
+ });
2781
+ const rootSpan = this.tracer.startSpan(event.operationId, { attributes });
2782
+ const rootContext = trace2.setSpan(context3.active(), rootSpan);
2783
+ this.callStates.set(event.callId, {
2784
+ operationId: event.operationId,
2785
+ telemetry,
2786
+ rootSpan,
2787
+ rootContext,
2788
+ stepSpan: void 0,
2789
+ stepContext: void 0,
2790
+ embedSpans: /* @__PURE__ */ new Map(),
2791
+ rerankSpan: void 0,
2792
+ evaluationSpan: void 0,
2793
+ toolSpans: /* @__PURE__ */ new Map(),
2794
+ baseTelemetryAttributes,
2795
+ settings
2796
+ });
2797
+ }
2798
+ onEvaluateOperationEnd(event) {
2799
+ const state = this.getCallState(event.callId);
2800
+ if (!(state == null ? void 0 : state.rootSpan)) return;
2801
+ state.rootSpan.setAttributes(
2802
+ selectAttributes2(state.telemetry, {
2803
+ "ai.evaluation.answers": {
2804
+ output: () => JSON.stringify(event.answers)
2805
+ }
2806
+ })
2807
+ );
2808
+ state.rootSpan.end();
2809
+ this.cleanupCallState(event.callId);
2810
+ }
2811
+ experimental_onEvaluateStart(event) {
2812
+ this.onEvaluateOperationStart(event);
2813
+ }
2814
+ experimental_onEvaluateEnd(event) {
2815
+ this.onEvaluateOperationEnd(event);
2816
+ }
2817
+ experimental_onEvaluationModelCallStart(event) {
2818
+ const state = this.getCallState(event.callId);
2819
+ if (!(state == null ? void 0 : state.rootSpan) || !state.rootContext) return;
2820
+ const attributes = selectAttributes2(state.telemetry, {
2821
+ ...assembleOperationName({
2822
+ operationId: event.operationId,
2823
+ telemetry: state.telemetry
2824
+ }),
2825
+ ...state.baseTelemetryAttributes,
2826
+ "ai.evaluation.state": {
2827
+ input: () => JSON.stringify(event.state)
2828
+ },
2829
+ "ai.evaluation.questions": {
2830
+ input: () => JSON.stringify(event.questions)
2831
+ }
2832
+ });
2833
+ const span = this.tracer.startSpan(
2834
+ event.operationId,
2835
+ { attributes },
2836
+ state.rootContext
2837
+ );
2838
+ state.evaluationSpan = {
2839
+ span,
2840
+ context: trace2.setSpan(state.rootContext, span)
2841
+ };
2842
+ }
2843
+ experimental_onEvaluationModelCallEnd(event) {
2844
+ var _a, _b;
2845
+ const state = this.getCallState(event.callId);
2846
+ if (!(state == null ? void 0 : state.evaluationSpan)) return;
2847
+ state.evaluationSpan.span.setAttributes(
2848
+ selectAttributes2(state.telemetry, {
2849
+ "ai.evaluation.answers": {
2850
+ output: () => JSON.stringify(event.answers)
2851
+ },
2852
+ "ai.usage.inputTokens": (_a = event.usage) == null ? void 0 : _a.inputTokens,
2853
+ "ai.usage.outputTokens": (_b = event.usage) == null ? void 0 : _b.outputTokens,
2854
+ "ai.response.providerMetadata": event.providerMetadata ? JSON.stringify(event.providerMetadata) : void 0
2855
+ })
2856
+ );
2857
+ state.evaluationSpan.span.end();
2858
+ state.evaluationSpan = void 0;
2859
+ }
2581
2860
  onAbort(event) {
2582
2861
  const state = this.getCallState(event.callId);
2583
2862
  if (!(state == null ? void 0 : state.rootSpan)) return;
@@ -2598,6 +2877,10 @@ var LegacyOpenTelemetry = class {
2598
2877
  state.rerankSpan.span.end();
2599
2878
  state.rerankSpan = void 0;
2600
2879
  }
2880
+ if (state.evaluationSpan) {
2881
+ state.evaluationSpan.span.end();
2882
+ state.evaluationSpan = void 0;
2883
+ }
2601
2884
  state.rootSpan.end();
2602
2885
  this.cleanupCallState(event.callId);
2603
2886
  }
@@ -2622,6 +2905,11 @@ var LegacyOpenTelemetry = class {
2622
2905
  state.rerankSpan.span.end();
2623
2906
  state.rerankSpan = void 0;
2624
2907
  }
2908
+ if (state.evaluationSpan) {
2909
+ recordSpanError(state.evaluationSpan.span, actualError);
2910
+ state.evaluationSpan.span.end();
2911
+ state.evaluationSpan = void 0;
2912
+ }
2625
2913
  recordSpanError(state.rootSpan, actualError);
2626
2914
  state.rootSpan.end();
2627
2915
  this.cleanupCallState(event.callId);