@ai-sdk/otel 1.0.0-beta.13 → 1.0.0-beta.130
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 +934 -0
- package/README.md +119 -0
- package/dist/index.d.ts +139 -22
- package/dist/index.js +1800 -168
- package/dist/index.js.map +1 -1
- package/package.json +16 -13
- package/src/assemble-operation-name.ts +2 -2
- package/src/gen-ai-format-messages.ts +644 -0
- package/src/get-base-telemetry-attributes.ts +8 -15
- package/src/get-tracer.ts +1 -1
- package/src/index.ts +7 -1
- package/src/{open-telemetry-integration.ts → legacy-open-telemetry.ts} +211 -147
- package/src/mock-tracer.ts +1 -1
- package/src/noop-tracer.ts +1 -1
- package/src/open-telemetry.ts +1336 -0
- package/src/record-span.ts +3 -4
- package/src/sanitize-attribute-value.ts +53 -0
- package/src/select-attributes.ts +65 -0
- package/src/select-telemetry-attributes.ts +3 -3
- package/src/stringify-for-telemetry.ts +23 -5
- package/src/supplemental-attributes.ts +201 -0
- package/dist/index.d.mts +0 -52
- package/dist/index.mjs +0 -845
- package/dist/index.mjs.map +0 -1
package/README.md
ADDED
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
# AI SDK - OpenTelemetry
|
|
2
|
+
|
|
3
|
+
The **OpenTelemetry integration** for the [AI SDK](https://ai-sdk.dev/docs)
|
|
4
|
+
collects tracing spans for AI SDK calls and sends them through your configured
|
|
5
|
+
OpenTelemetry setup.
|
|
6
|
+
|
|
7
|
+
## Setup
|
|
8
|
+
|
|
9
|
+
The OpenTelemetry integration is available in the `@ai-sdk/otel` module. You can
|
|
10
|
+
install it with
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
npm i @ai-sdk/otel
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## Skill for Coding Agents
|
|
17
|
+
|
|
18
|
+
If you use coding agents such as Claude Code or Cursor, we highly recommend
|
|
19
|
+
adding the AI SDK skill to your repository:
|
|
20
|
+
|
|
21
|
+
```shell
|
|
22
|
+
npx skills add vercel/ai
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Usage
|
|
26
|
+
|
|
27
|
+
Register the telemetry integration once at application startup with
|
|
28
|
+
`registerTelemetry()`:
|
|
29
|
+
|
|
30
|
+
```ts
|
|
31
|
+
import { OpenTelemetry } from '@ai-sdk/otel';
|
|
32
|
+
import { registerTelemetry } from 'ai';
|
|
33
|
+
|
|
34
|
+
registerTelemetry(new OpenTelemetry());
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
For Next.js applications, place this in `instrumentation.ts` alongside your
|
|
38
|
+
OpenTelemetry provider setup. For Node.js applications, register it at the top
|
|
39
|
+
level of your entry file.
|
|
40
|
+
|
|
41
|
+
Once registered, AI SDK calls emit telemetry events by default:
|
|
42
|
+
|
|
43
|
+
```ts
|
|
44
|
+
import { generateText } from 'ai';
|
|
45
|
+
|
|
46
|
+
const result = await generateText({
|
|
47
|
+
model: 'openai/gpt-5.4',
|
|
48
|
+
prompt: 'Write a vegetarian lasagna recipe for 4 people.',
|
|
49
|
+
telemetry: {
|
|
50
|
+
functionId: 'recipe-generator',
|
|
51
|
+
},
|
|
52
|
+
});
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
You can opt out for an individual call with `telemetry.isEnabled`:
|
|
56
|
+
|
|
57
|
+
```ts
|
|
58
|
+
const result = await generateText({
|
|
59
|
+
model: 'openai/gpt-5.4',
|
|
60
|
+
prompt: 'Write a vegetarian lasagna recipe for 4 people.',
|
|
61
|
+
telemetry: {
|
|
62
|
+
isEnabled: false,
|
|
63
|
+
},
|
|
64
|
+
});
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## OpenTelemetry
|
|
68
|
+
|
|
69
|
+
`OpenTelemetry` is the recommended integration. It emits spans that follow the
|
|
70
|
+
[OpenTelemetry GenAI Semantic Conventions](https://opentelemetry.io/docs/specs/semconv/gen-ai/).
|
|
71
|
+
|
|
72
|
+
You can pass a custom tracer when you want to use a specific `TracerProvider`:
|
|
73
|
+
|
|
74
|
+
```ts
|
|
75
|
+
import { OpenTelemetry } from '@ai-sdk/otel';
|
|
76
|
+
import { registerTelemetry } from 'ai';
|
|
77
|
+
|
|
78
|
+
registerTelemetry(
|
|
79
|
+
new OpenTelemetry({
|
|
80
|
+
tracer: tracerProvider.getTracer('gen_ai'),
|
|
81
|
+
}),
|
|
82
|
+
);
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
You can also add custom attributes to spans with `enrichSpan`:
|
|
86
|
+
|
|
87
|
+
```ts
|
|
88
|
+
import { OpenTelemetry } from '@ai-sdk/otel';
|
|
89
|
+
import { registerTelemetry } from 'ai';
|
|
90
|
+
|
|
91
|
+
registerTelemetry(
|
|
92
|
+
new OpenTelemetry({
|
|
93
|
+
enrichSpan: ({ spanType, operationId, callId }) => ({
|
|
94
|
+
'my_app.span_type': spanType,
|
|
95
|
+
'my_app.operation_id': operationId,
|
|
96
|
+
'my_app.call_id': callId,
|
|
97
|
+
}),
|
|
98
|
+
}),
|
|
99
|
+
);
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
## Legacy Telemetry
|
|
103
|
+
|
|
104
|
+
`LegacyOpenTelemetry` emits the older AI SDK-specific span format with `ai.*`
|
|
105
|
+
attributes. Use it when an existing observability integration depends on the
|
|
106
|
+
legacy span shape:
|
|
107
|
+
|
|
108
|
+
```ts
|
|
109
|
+
import { LegacyOpenTelemetry } from '@ai-sdk/otel';
|
|
110
|
+
import { registerTelemetry } from 'ai';
|
|
111
|
+
|
|
112
|
+
registerTelemetry(new LegacyOpenTelemetry());
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
## Documentation
|
|
116
|
+
|
|
117
|
+
Please check out the
|
|
118
|
+
[AI SDK telemetry documentation](https://ai-sdk.dev/docs/ai-sdk-core/telemetry)
|
|
119
|
+
for more information.
|
package/dist/index.d.ts
CHANGED
|
@@ -1,13 +1,120 @@
|
|
|
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';
|
|
2
|
+
import { Attributes, Tracer } from '@opentelemetry/api';
|
|
1
3
|
import { LanguageModelV4Prompt } from '@ai-sdk/provider';
|
|
2
|
-
import {
|
|
3
|
-
import { TelemetryIntegration, OnStartEvent, ToolSet, OutputInterface, ObjectOnStartEvent, EmbedOnStartEvent, RerankOnStartEvent, ObjectOnStepStartEvent, ObjectOnStepFinishEvent, GenerationContext, OnStepStartEvent, OnToolCallStartEvent, OnToolCallFinishEvent, OnStepFinishEvent, OnFinishEvent, ObjectOnFinishEvent, EmbedOnFinishEvent, RerankOnFinishEvent, EmbedStartEvent, EmbedFinishEvent, RerankStartEvent, RerankFinishEvent, OnChunkEvent } from 'ai';
|
|
4
|
+
import { Context } from '@ai-sdk/provider-utils';
|
|
4
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;
|
|
13
|
+
type OpenTelemetryOptions = {
|
|
14
|
+
/**
|
|
15
|
+
* The tracer to use for the telemetry data.
|
|
16
|
+
*/
|
|
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;
|
|
23
|
+
/**
|
|
24
|
+
* Emit AI SDK usage details that are not represented by GenAI SemConv.
|
|
25
|
+
*/
|
|
26
|
+
usage?: boolean;
|
|
27
|
+
/**
|
|
28
|
+
* Emit provider metadata on response spans.
|
|
29
|
+
*/
|
|
30
|
+
providerMetadata?: boolean;
|
|
31
|
+
/**
|
|
32
|
+
* Emit embedding input and output values.
|
|
33
|
+
*/
|
|
34
|
+
embedding?: boolean;
|
|
35
|
+
/**
|
|
36
|
+
* Emit reranking input documents and output ranking.
|
|
37
|
+
*/
|
|
38
|
+
reranking?: boolean;
|
|
39
|
+
/**
|
|
40
|
+
* Emit runtime context values.
|
|
41
|
+
*/
|
|
42
|
+
runtimeContext?: boolean;
|
|
43
|
+
/**
|
|
44
|
+
* Emit request headers.
|
|
45
|
+
*/
|
|
46
|
+
headers?: boolean;
|
|
47
|
+
/**
|
|
48
|
+
* Emit selected tool choice information.
|
|
49
|
+
*/
|
|
50
|
+
toolChoice?: boolean;
|
|
51
|
+
/**
|
|
52
|
+
* Emit object generation schema information.
|
|
53
|
+
*/
|
|
54
|
+
schema?: boolean;
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
interface OtelStepStartEvent$1 extends GenerateTextStepStartEvent<ToolSet> {
|
|
58
|
+
readonly stepToolChoice?: unknown;
|
|
59
|
+
}
|
|
60
|
+
declare class OpenTelemetry implements Telemetry {
|
|
61
|
+
private readonly callStates;
|
|
62
|
+
private readonly tracer;
|
|
63
|
+
private readonly supplementalAttributes;
|
|
64
|
+
private readonly enrichSpan;
|
|
65
|
+
constructor(options?: OpenTelemetryOptions);
|
|
66
|
+
private getCallState;
|
|
67
|
+
private cleanupCallState;
|
|
68
|
+
private getSpanAttributes;
|
|
69
|
+
executeTool<T>({ callId, toolCallId, execute, }: {
|
|
70
|
+
callId: string;
|
|
71
|
+
toolCallId: string;
|
|
72
|
+
execute: () => PromiseLike<T>;
|
|
73
|
+
}): PromiseLike<T>;
|
|
74
|
+
/**
|
|
75
|
+
* Runs the provider `doGenerate`/`doStream` call with the active model-call
|
|
76
|
+
* context.
|
|
77
|
+
*/
|
|
78
|
+
executeLanguageModelCall<T>({ callId, execute, }: {
|
|
79
|
+
callId: string;
|
|
80
|
+
execute: () => PromiseLike<T>;
|
|
81
|
+
}): PromiseLike<T>;
|
|
82
|
+
onStart(event: InferTelemetryEvent<GenerateTextStartEvent> | InferTelemetryEvent<GenerateObjectStartEvent> | InferTelemetryEvent<EmbedStartEvent> | InferTelemetryEvent<RerankStartEvent>): void;
|
|
83
|
+
private onGenerateStart;
|
|
84
|
+
private onObjectOperationStart;
|
|
85
|
+
/** @deprecated */
|
|
86
|
+
onObjectStepStart(event: GenerateObjectStepStartEvent): void;
|
|
87
|
+
/** @deprecated */
|
|
88
|
+
onObjectStepEnd(event: GenerateObjectStepEndEvent): void;
|
|
89
|
+
private onEmbedOperationStart;
|
|
90
|
+
onStepStart(event: OtelStepStartEvent$1): void;
|
|
91
|
+
onLanguageModelCallStart(event: LanguageModelCallStartEvent): void;
|
|
92
|
+
onLanguageModelCallEnd(event: LanguageModelCallEndEvent<ToolSet>): void;
|
|
93
|
+
onToolExecutionStart(event: ToolExecutionStartEvent<ToolSet>): void;
|
|
94
|
+
onToolExecutionEnd(event: ToolExecutionEndEvent<ToolSet>): void;
|
|
95
|
+
onStepEnd(event: GenerateTextStepEndEvent<ToolSet>): void;
|
|
96
|
+
/** @deprecated Use `onStepEnd` instead. */
|
|
97
|
+
onStepFinish(event: GenerateTextStepEndEvent<ToolSet>): void;
|
|
98
|
+
onEnd(event: GenerateTextEndEvent<ToolSet> | GenerateObjectEndEvent<unknown> | EmbedEndEvent | RerankEndEvent): void;
|
|
99
|
+
private onGenerateEnd;
|
|
100
|
+
private onObjectOperationEnd;
|
|
101
|
+
private onEmbedOperationEnd;
|
|
102
|
+
onEmbedStart(event: EmbeddingModelCallStartEvent): void;
|
|
103
|
+
onEmbedEnd(event: EmbeddingModelCallEndEvent): void;
|
|
104
|
+
private onRerankOperationStart;
|
|
105
|
+
private onRerankOperationEnd;
|
|
106
|
+
onRerankStart(event: RerankingModelCallStartEvent): void;
|
|
107
|
+
onRerankEnd(event: RerankingModelCallEndEvent): void;
|
|
108
|
+
onAbort(event: GenerateTextAbortEvent<ToolSet>): void;
|
|
109
|
+
onError(error: unknown): void;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
interface OtelStepStartEvent<TOOLS extends ToolSet = ToolSet, RUNTIME_CONTEXT extends Context = Context, OUTPUT extends Output.Output = Output.Output> extends GenerateTextStepStartEvent<TOOLS, RUNTIME_CONTEXT, OUTPUT> {
|
|
6
113
|
readonly promptMessages?: LanguageModelV4Prompt;
|
|
7
114
|
readonly stepTools?: ReadonlyArray<Record<string, unknown>>;
|
|
8
115
|
readonly stepToolChoice?: unknown;
|
|
9
116
|
}
|
|
10
|
-
declare class
|
|
117
|
+
declare class LegacyOpenTelemetry implements Telemetry {
|
|
11
118
|
private readonly callStates;
|
|
12
119
|
/**
|
|
13
120
|
* The tracer to use for the telemetry data.
|
|
@@ -23,30 +130,40 @@ declare class OpenTelemetryIntegration implements TelemetryIntegration {
|
|
|
23
130
|
toolCallId: string;
|
|
24
131
|
execute: () => PromiseLike<T>;
|
|
25
132
|
}): PromiseLike<T>;
|
|
26
|
-
|
|
133
|
+
/**
|
|
134
|
+
* Runs the provider `doGenerate`/`doStream` call with the active legacy
|
|
135
|
+
* model-call context.
|
|
136
|
+
*/
|
|
137
|
+
executeLanguageModelCall<T>({ callId, execute, }: {
|
|
138
|
+
callId: string;
|
|
139
|
+
execute: () => PromiseLike<T>;
|
|
140
|
+
}): PromiseLike<T>;
|
|
141
|
+
onStart(event: InferTelemetryEvent<GenerateTextStartEvent> | InferTelemetryEvent<GenerateObjectStartEvent> | InferTelemetryEvent<EmbedStartEvent> | InferTelemetryEvent<RerankStartEvent>): void;
|
|
27
142
|
private onGenerateStart;
|
|
28
143
|
private onObjectOperationStart;
|
|
29
144
|
/** @deprecated */
|
|
30
|
-
onObjectStepStart(event:
|
|
145
|
+
onObjectStepStart(event: GenerateObjectStepStartEvent): void;
|
|
31
146
|
/** @deprecated */
|
|
32
|
-
|
|
147
|
+
onObjectStepEnd(event: GenerateObjectStepEndEvent): void;
|
|
33
148
|
private onEmbedOperationStart;
|
|
34
|
-
onStepStart(event: OtelStepStartEvent
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
private
|
|
42
|
-
|
|
43
|
-
|
|
149
|
+
onStepStart(event: OtelStepStartEvent): void;
|
|
150
|
+
onToolExecutionStart(event: ToolExecutionStartEvent<ToolSet>): void;
|
|
151
|
+
onToolExecutionEnd(event: ToolExecutionEndEvent<ToolSet>): void;
|
|
152
|
+
onStepEnd(event: GenerateTextStepEndEvent<ToolSet>): void;
|
|
153
|
+
/** @deprecated Use `onStepEnd` instead. */
|
|
154
|
+
onStepFinish(event: GenerateTextStepEndEvent<ToolSet>): void;
|
|
155
|
+
onEnd(event: GenerateTextEndEvent<ToolSet> | GenerateObjectEndEvent<unknown> | EmbedEndEvent | RerankEndEvent): void;
|
|
156
|
+
private onGenerateEnd;
|
|
157
|
+
private onObjectOperationEnd;
|
|
158
|
+
private onEmbedOperationEnd;
|
|
159
|
+
onEmbedStart(event: EmbeddingModelCallStartEvent): void;
|
|
160
|
+
onEmbedEnd(event: EmbeddingModelCallEndEvent): void;
|
|
44
161
|
private onRerankOperationStart;
|
|
45
|
-
private
|
|
46
|
-
onRerankStart(event:
|
|
47
|
-
|
|
48
|
-
|
|
162
|
+
private onRerankOperationEnd;
|
|
163
|
+
onRerankStart(event: RerankingModelCallStartEvent): void;
|
|
164
|
+
onRerankEnd(event: RerankingModelCallEndEvent): void;
|
|
165
|
+
onAbort(event: GenerateTextAbortEvent<ToolSet>): void;
|
|
49
166
|
onError(error: unknown): void;
|
|
50
167
|
}
|
|
51
168
|
|
|
52
|
-
export {
|
|
169
|
+
export { type EnrichSpan, LegacyOpenTelemetry, OpenTelemetry, type OpenTelemetryOptions, type OpenTelemetrySpanType };
|