@ai-sdk/workflow 1.0.0-beta.2 → 1.0.0-beta.21
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 +139 -0
- package/dist/index.d.mts +128 -38
- package/dist/index.mjs +98 -97
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -3
- package/src/do-stream-step.ts +10 -25
- package/src/index.ts +5 -4
- package/src/providers/mock.ts +79 -92
- package/src/stream-text-iterator.ts +22 -47
- package/src/telemetry.ts +5 -5
- package/src/workflow-agent.ts +430 -317
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ai-sdk/workflow",
|
|
3
|
-
"version": "1.0.0-beta.
|
|
3
|
+
"version": "1.0.0-beta.21",
|
|
4
4
|
"description": "WorkflowAgent for building AI agents with AI SDK",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -28,8 +28,8 @@
|
|
|
28
28
|
"dependencies": {
|
|
29
29
|
"ajv": "^8.18.0",
|
|
30
30
|
"@ai-sdk/provider": "4.0.0-beta.12",
|
|
31
|
-
"@ai-sdk/provider-utils": "5.0.0-beta.
|
|
32
|
-
"ai": "7.0.0-beta.
|
|
31
|
+
"@ai-sdk/provider-utils": "5.0.0-beta.22",
|
|
32
|
+
"ai": "7.0.0-beta.106"
|
|
33
33
|
},
|
|
34
34
|
"devDependencies": {
|
|
35
35
|
"@types/node": "20.17.24",
|
package/src/do-stream-step.ts
CHANGED
|
@@ -16,12 +16,11 @@ import {
|
|
|
16
16
|
type ToolSet,
|
|
17
17
|
} from 'ai';
|
|
18
18
|
import { gateway } from 'ai';
|
|
19
|
-
import type { ProviderOptions,
|
|
19
|
+
import type { ProviderOptions, TelemetryOptions } from './workflow-agent.js';
|
|
20
20
|
import {
|
|
21
21
|
resolveSerializableTools,
|
|
22
22
|
type SerializableToolDef,
|
|
23
23
|
} from './serializable-schema.js';
|
|
24
|
-
import type { CompatibleLanguageModel } from './types.js';
|
|
25
24
|
|
|
26
25
|
export type { Experimental_LanguageModelStreamPart as ModelCallStreamPart } from 'ai';
|
|
27
26
|
|
|
@@ -55,7 +54,7 @@ export interface DoStreamStepOptions {
|
|
|
55
54
|
providerOptions?: ProviderOptions;
|
|
56
55
|
toolChoice?: ToolChoice<ToolSet>;
|
|
57
56
|
includeRawChunks?: boolean;
|
|
58
|
-
experimental_telemetry?:
|
|
57
|
+
experimental_telemetry?: TelemetryOptions;
|
|
59
58
|
repairToolCall?: ToolCallRepairFunction<ToolSet>;
|
|
60
59
|
responseFormat?: LanguageModelV4CallOptions['responseFormat'];
|
|
61
60
|
}
|
|
@@ -87,10 +86,7 @@ export interface StreamFinish {
|
|
|
87
86
|
|
|
88
87
|
export async function doStreamStep(
|
|
89
88
|
conversationPrompt: LanguageModelV4Prompt,
|
|
90
|
-
modelInit:
|
|
91
|
-
| string
|
|
92
|
-
| CompatibleLanguageModel
|
|
93
|
-
| (() => Promise<CompatibleLanguageModel>),
|
|
89
|
+
modelInit: LanguageModel,
|
|
94
90
|
writable?: WritableStream<ModelCallStreamPart<ToolSet>>,
|
|
95
91
|
serializedTools?: Record<string, SerializableToolDef>,
|
|
96
92
|
options?: DoStreamStepOptions,
|
|
@@ -98,22 +94,10 @@ export async function doStreamStep(
|
|
|
98
94
|
'use step';
|
|
99
95
|
|
|
100
96
|
// Resolve model inside step (must happen here for serialization boundary)
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
model = await modelInit();
|
|
106
|
-
} else if (
|
|
107
|
-
typeof modelInit === 'object' &&
|
|
108
|
-
modelInit !== null &&
|
|
109
|
-
'modelId' in modelInit
|
|
110
|
-
) {
|
|
111
|
-
model = modelInit;
|
|
112
|
-
} else {
|
|
113
|
-
throw new Error(
|
|
114
|
-
'Invalid "model initialization" argument. Must be a string, a LanguageModel instance, or a function that returns a LanguageModel instance.',
|
|
115
|
-
);
|
|
116
|
-
}
|
|
97
|
+
const model: LanguageModel =
|
|
98
|
+
typeof modelInit === 'string'
|
|
99
|
+
? gateway.languageModel(modelInit)
|
|
100
|
+
: modelInit;
|
|
117
101
|
|
|
118
102
|
// Reconstruct tools from serializable definitions with Ajv validation.
|
|
119
103
|
// Tools are serialized before crossing the step boundary because zod schemas
|
|
@@ -126,7 +110,7 @@ export async function doStreamStep(
|
|
|
126
110
|
// model.doStream(), retry logic, and stream part transformation
|
|
127
111
|
// (tool call parsing, finish reason mapping, file wrapping).
|
|
128
112
|
const { stream: modelStream } = await streamModelCall({
|
|
129
|
-
model
|
|
113
|
+
model,
|
|
130
114
|
// streamModelCall expects Prompt (ModelMessage[]) but we pass the
|
|
131
115
|
// pre-converted LanguageModelV4Prompt. standardizePrompt inside
|
|
132
116
|
// streamModelCall handles both formats.
|
|
@@ -257,7 +241,8 @@ export async function doStreamStep(
|
|
|
257
241
|
},
|
|
258
242
|
functionId: undefined,
|
|
259
243
|
metadata: undefined,
|
|
260
|
-
|
|
244
|
+
runtimeContext: undefined,
|
|
245
|
+
toolsContext: {},
|
|
261
246
|
content: [
|
|
262
247
|
...(text ? [{ type: 'text' as const, text }] : []),
|
|
263
248
|
...toolCalls
|
package/src/index.ts
CHANGED
|
@@ -17,11 +17,12 @@ export {
|
|
|
17
17
|
type PrepareStepInfo,
|
|
18
18
|
type PrepareStepResult,
|
|
19
19
|
type ProviderOptions,
|
|
20
|
-
type
|
|
21
|
-
type
|
|
22
|
-
type
|
|
20
|
+
type WorkflowAgentOnAbortCallback,
|
|
21
|
+
type WorkflowAgentOnErrorCallback,
|
|
22
|
+
type WorkflowAgentOnFinishCallback,
|
|
23
|
+
type WorkflowAgentOnStepFinishCallback,
|
|
23
24
|
type StreamTextTransform,
|
|
24
|
-
type
|
|
25
|
+
type TelemetryOptions,
|
|
25
26
|
type ToolCallRepairFunction,
|
|
26
27
|
type WorkflowAgentOnStartCallback,
|
|
27
28
|
type WorkflowAgentOnStepStartCallback,
|
package/src/providers/mock.ts
CHANGED
|
@@ -6,19 +6,55 @@ export type MockResponseDescriptor =
|
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* Mock model that returns a fixed text response.
|
|
9
|
-
* Same 'use step' pattern as real providers (anthropic, openai, etc.).
|
|
10
|
-
* Only captures `text` (string) — fully serializable across step boundary.
|
|
11
9
|
*/
|
|
12
10
|
export function mockTextModel(text: string) {
|
|
13
|
-
return
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
11
|
+
return mockProvider({
|
|
12
|
+
doStream: async () => ({
|
|
13
|
+
stream: new ReadableStream({
|
|
14
|
+
start(c) {
|
|
15
|
+
for (const v of [
|
|
16
|
+
{ type: 'stream-start', warnings: [] },
|
|
17
|
+
{
|
|
18
|
+
type: 'response-metadata',
|
|
19
|
+
id: 'r',
|
|
20
|
+
modelId: 'mock',
|
|
21
|
+
timestamp: new Date(),
|
|
22
|
+
},
|
|
23
|
+
{ type: 'text-start', id: '1' },
|
|
24
|
+
{ type: 'text-delta', id: '1', delta: text },
|
|
25
|
+
{ type: 'text-end', id: '1' },
|
|
26
|
+
{
|
|
27
|
+
type: 'finish',
|
|
28
|
+
finishReason: { unified: 'stop', raw: 'stop' },
|
|
29
|
+
usage: {
|
|
30
|
+
inputTokens: { total: 5, noCache: 5 },
|
|
31
|
+
outputTokens: { total: 10, text: 10 },
|
|
32
|
+
},
|
|
33
|
+
},
|
|
34
|
+
] as any[])
|
|
35
|
+
c.enqueue(v);
|
|
36
|
+
c.close();
|
|
37
|
+
},
|
|
38
|
+
}),
|
|
39
|
+
}),
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Mock model that plays through a sequence of responses.
|
|
45
|
+
* Determines which response to return by counting assistant messages in the prompt.
|
|
46
|
+
*/
|
|
47
|
+
export function mockSequenceModel(responses: MockResponseDescriptor[]) {
|
|
48
|
+
return mockProvider({
|
|
49
|
+
doStream: async (options: any) => {
|
|
50
|
+
const idx = Math.min(
|
|
51
|
+
options.prompt.filter((m: any) => m.role === 'assistant').length,
|
|
52
|
+
responses.length - 1,
|
|
53
|
+
);
|
|
54
|
+
const r = responses[idx];
|
|
55
|
+
const parts =
|
|
56
|
+
r.type === 'text'
|
|
57
|
+
? [
|
|
22
58
|
{ type: 'stream-start', warnings: [] },
|
|
23
59
|
{
|
|
24
60
|
type: 'response-metadata',
|
|
@@ -27,7 +63,7 @@ export function mockTextModel(text: string) {
|
|
|
27
63
|
timestamp: new Date(),
|
|
28
64
|
},
|
|
29
65
|
{ type: 'text-start', id: '1' },
|
|
30
|
-
{ type: 'text-delta', id: '1', delta:
|
|
66
|
+
{ type: 'text-delta', id: '1', delta: r.text },
|
|
31
67
|
{ type: 'text-end', id: '1' },
|
|
32
68
|
{
|
|
33
69
|
type: 'finish',
|
|
@@ -37,87 +73,38 @@ export function mockTextModel(text: string) {
|
|
|
37
73
|
outputTokens: { total: 10, text: 10 },
|
|
38
74
|
},
|
|
39
75
|
},
|
|
40
|
-
]
|
|
41
|
-
|
|
76
|
+
]
|
|
77
|
+
: [
|
|
78
|
+
{ type: 'stream-start', warnings: [] },
|
|
79
|
+
{
|
|
80
|
+
type: 'response-metadata',
|
|
81
|
+
id: 'r',
|
|
82
|
+
modelId: 'mock',
|
|
83
|
+
timestamp: new Date(),
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
type: 'tool-call',
|
|
87
|
+
toolCallId: `call-${idx + 1}`,
|
|
88
|
+
toolName: r.toolName,
|
|
89
|
+
input: r.input,
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
type: 'finish',
|
|
93
|
+
finishReason: { unified: 'tool-calls', raw: undefined },
|
|
94
|
+
usage: {
|
|
95
|
+
inputTokens: { total: 5, noCache: 5 },
|
|
96
|
+
outputTokens: { total: 10, text: 10 },
|
|
97
|
+
},
|
|
98
|
+
},
|
|
99
|
+
];
|
|
100
|
+
return {
|
|
101
|
+
stream: new ReadableStream({
|
|
102
|
+
start(c) {
|
|
103
|
+
for (const p of parts as any[]) c.enqueue(p);
|
|
42
104
|
c.close();
|
|
43
105
|
},
|
|
44
106
|
}),
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
};
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
/**
|
|
51
|
-
* Mock model that plays through a sequence of responses.
|
|
52
|
-
* Determines which response to return by counting assistant messages in the prompt.
|
|
53
|
-
* Only captures `responses` (array of plain objects) — fully serializable.
|
|
54
|
-
*/
|
|
55
|
-
export function mockSequenceModel(responses: MockResponseDescriptor[]) {
|
|
56
|
-
return async () => {
|
|
57
|
-
'use step';
|
|
58
|
-
// Bind closure var at step body level so SWC plugin detects it
|
|
59
|
-
const _responses = responses;
|
|
60
|
-
return mockProvider({
|
|
61
|
-
doStream: async (options: any) => {
|
|
62
|
-
const idx = Math.min(
|
|
63
|
-
options.prompt.filter((m: any) => m.role === 'assistant').length,
|
|
64
|
-
_responses.length - 1,
|
|
65
|
-
);
|
|
66
|
-
const r = _responses[idx];
|
|
67
|
-
const parts =
|
|
68
|
-
r.type === 'text'
|
|
69
|
-
? [
|
|
70
|
-
{ type: 'stream-start', warnings: [] },
|
|
71
|
-
{
|
|
72
|
-
type: 'response-metadata',
|
|
73
|
-
id: 'r',
|
|
74
|
-
modelId: 'mock',
|
|
75
|
-
timestamp: new Date(),
|
|
76
|
-
},
|
|
77
|
-
{ type: 'text-start', id: '1' },
|
|
78
|
-
{ type: 'text-delta', id: '1', delta: r.text },
|
|
79
|
-
{ type: 'text-end', id: '1' },
|
|
80
|
-
{
|
|
81
|
-
type: 'finish',
|
|
82
|
-
finishReason: { unified: 'stop', raw: 'stop' },
|
|
83
|
-
usage: {
|
|
84
|
-
inputTokens: { total: 5, noCache: 5 },
|
|
85
|
-
outputTokens: { total: 10, text: 10 },
|
|
86
|
-
},
|
|
87
|
-
},
|
|
88
|
-
]
|
|
89
|
-
: [
|
|
90
|
-
{ type: 'stream-start', warnings: [] },
|
|
91
|
-
{
|
|
92
|
-
type: 'response-metadata',
|
|
93
|
-
id: 'r',
|
|
94
|
-
modelId: 'mock',
|
|
95
|
-
timestamp: new Date(),
|
|
96
|
-
},
|
|
97
|
-
{
|
|
98
|
-
type: 'tool-call',
|
|
99
|
-
toolCallId: `call-${idx + 1}`,
|
|
100
|
-
toolName: r.toolName,
|
|
101
|
-
input: r.input,
|
|
102
|
-
},
|
|
103
|
-
{
|
|
104
|
-
type: 'finish',
|
|
105
|
-
finishReason: { unified: 'tool-calls', raw: undefined },
|
|
106
|
-
usage: {
|
|
107
|
-
inputTokens: { total: 5, noCache: 5 },
|
|
108
|
-
outputTokens: { total: 10, text: 10 },
|
|
109
|
-
},
|
|
110
|
-
},
|
|
111
|
-
];
|
|
112
|
-
return {
|
|
113
|
-
stream: new ReadableStream({
|
|
114
|
-
start(c) {
|
|
115
|
-
for (const p of parts as any[]) c.enqueue(p);
|
|
116
|
-
c.close();
|
|
117
|
-
},
|
|
118
|
-
}),
|
|
119
|
-
};
|
|
120
|
-
},
|
|
121
|
-
});
|
|
122
|
-
};
|
|
107
|
+
};
|
|
108
|
+
},
|
|
109
|
+
});
|
|
123
110
|
}
|
|
@@ -3,14 +3,15 @@ import type {
|
|
|
3
3
|
LanguageModelV4Prompt,
|
|
4
4
|
LanguageModelV4ToolResultPart,
|
|
5
5
|
} from '@ai-sdk/provider';
|
|
6
|
-
import
|
|
7
|
-
Experimental_LanguageModelStreamPart as ModelCallStreamPart,
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
ToolCallRepairFunction,
|
|
12
|
-
ToolChoice,
|
|
13
|
-
ToolSet,
|
|
6
|
+
import {
|
|
7
|
+
type Experimental_LanguageModelStreamPart as ModelCallStreamPart,
|
|
8
|
+
type LanguageModel,
|
|
9
|
+
type ModelMessage,
|
|
10
|
+
type StepResult,
|
|
11
|
+
type ToolCallRepairFunction,
|
|
12
|
+
type ToolChoice,
|
|
13
|
+
type ToolSet,
|
|
14
|
+
experimental_filterActiveTools as filterActiveTools,
|
|
14
15
|
} from 'ai';
|
|
15
16
|
import {
|
|
16
17
|
doStreamStep,
|
|
@@ -22,11 +23,11 @@ import { serializeToolSet } from './serializable-schema.js';
|
|
|
22
23
|
import type {
|
|
23
24
|
GenerationSettings,
|
|
24
25
|
PrepareStepCallback,
|
|
25
|
-
|
|
26
|
-
|
|
26
|
+
WorkflowAgentOnErrorCallback,
|
|
27
|
+
WorkflowAgentOnStepFinishCallback,
|
|
28
|
+
TelemetryOptions,
|
|
27
29
|
WorkflowAgentOnStepStartCallback,
|
|
28
30
|
} from './workflow-agent.js';
|
|
29
|
-
import type { CompatibleLanguageModel } from './types.js';
|
|
30
31
|
|
|
31
32
|
// Re-export for consumers
|
|
32
33
|
export type { ProviderExecutedToolResult } from './do-stream-step.js';
|
|
@@ -55,7 +56,6 @@ export async function* streamTextIterator({
|
|
|
55
56
|
writable,
|
|
56
57
|
model,
|
|
57
58
|
stopConditions,
|
|
58
|
-
maxSteps,
|
|
59
59
|
onStepFinish,
|
|
60
60
|
onStepStart,
|
|
61
61
|
onError,
|
|
@@ -71,20 +71,16 @@ export async function* streamTextIterator({
|
|
|
71
71
|
prompt: LanguageModelV4Prompt;
|
|
72
72
|
tools: ToolSet;
|
|
73
73
|
writable?: WritableStream<ModelCallStreamPart<ToolSet>>;
|
|
74
|
-
model:
|
|
75
|
-
| string
|
|
76
|
-
| CompatibleLanguageModel
|
|
77
|
-
| (() => Promise<CompatibleLanguageModel>);
|
|
74
|
+
model: LanguageModel;
|
|
78
75
|
stopConditions?: ModelStopCondition[] | ModelStopCondition;
|
|
79
|
-
|
|
80
|
-
onStepFinish?: StreamTextOnStepFinishCallback<any, any>;
|
|
76
|
+
onStepFinish?: WorkflowAgentOnStepFinishCallback<any>;
|
|
81
77
|
onStepStart?: WorkflowAgentOnStepStartCallback;
|
|
82
|
-
onError?:
|
|
78
|
+
onError?: WorkflowAgentOnErrorCallback;
|
|
83
79
|
prepareStep?: PrepareStepCallback<any>;
|
|
84
80
|
generationSettings?: GenerationSettings;
|
|
85
81
|
toolChoice?: ToolChoice<ToolSet>;
|
|
86
82
|
experimental_context?: unknown;
|
|
87
|
-
experimental_telemetry?:
|
|
83
|
+
experimental_telemetry?: TelemetryOptions;
|
|
88
84
|
includeRawChunks?: boolean;
|
|
89
85
|
repairToolCall?: ToolCallRepairFunction<ToolSet>;
|
|
90
86
|
responseFormat?: LanguageModelV4CallOptions['responseFormat'];
|
|
@@ -94,10 +90,7 @@ export async function* streamTextIterator({
|
|
|
94
90
|
LanguageModelV4ToolResultPart[]
|
|
95
91
|
> {
|
|
96
92
|
let conversationPrompt = [...prompt]; // Create a mutable copy
|
|
97
|
-
let currentModel:
|
|
98
|
-
| string
|
|
99
|
-
| CompatibleLanguageModel
|
|
100
|
-
| (() => Promise<CompatibleLanguageModel>) = model;
|
|
93
|
+
let currentModel: LanguageModel = model;
|
|
101
94
|
let currentGenerationSettings = generationSettings ?? {};
|
|
102
95
|
let currentToolChoice = toolChoice;
|
|
103
96
|
let currentContext = experimental_context;
|
|
@@ -110,16 +103,7 @@ export async function* streamTextIterator({
|
|
|
110
103
|
let lastStep: StepResult<any, any> | undefined;
|
|
111
104
|
let lastStepWasToolCalls = false;
|
|
112
105
|
|
|
113
|
-
// Default maxSteps to Infinity to preserve backwards compatibility
|
|
114
|
-
// (agent loops until completion unless explicitly limited)
|
|
115
|
-
const effectiveMaxSteps = maxSteps ?? Infinity;
|
|
116
|
-
|
|
117
106
|
while (!done) {
|
|
118
|
-
// Check if we've exceeded the maximum number of steps
|
|
119
|
-
if (stepNumber >= effectiveMaxSteps) {
|
|
120
|
-
break;
|
|
121
|
-
}
|
|
122
|
-
|
|
123
107
|
// Check for abort signal
|
|
124
108
|
if (currentGenerationSettings.abortSignal?.aborted) {
|
|
125
109
|
break;
|
|
@@ -248,6 +232,7 @@ export async function* streamTextIterator({
|
|
|
248
232
|
stepNumber,
|
|
249
233
|
model: currentModel,
|
|
250
234
|
messages: conversationPrompt as unknown as ModelMessage[],
|
|
235
|
+
steps: [...steps],
|
|
251
236
|
});
|
|
252
237
|
}
|
|
253
238
|
|
|
@@ -255,7 +240,10 @@ export async function* streamTextIterator({
|
|
|
255
240
|
// Filter tools if activeTools is specified
|
|
256
241
|
const effectiveTools =
|
|
257
242
|
currentActiveTools && currentActiveTools.length > 0
|
|
258
|
-
?
|
|
243
|
+
? (filterActiveTools({
|
|
244
|
+
tools,
|
|
245
|
+
activeTools: currentActiveTools,
|
|
246
|
+
}) ?? tools)
|
|
259
247
|
: tools;
|
|
260
248
|
|
|
261
249
|
// Serialize tools before crossing the step boundary — zod schemas
|
|
@@ -399,19 +387,6 @@ export async function* streamTextIterator({
|
|
|
399
387
|
return conversationPrompt;
|
|
400
388
|
}
|
|
401
389
|
|
|
402
|
-
/**
|
|
403
|
-
* Filter a tool set to only include the specified active tools.
|
|
404
|
-
*/
|
|
405
|
-
function filterToolSet(tools: ToolSet, activeTools: string[]): ToolSet {
|
|
406
|
-
const filtered: ToolSet = {};
|
|
407
|
-
for (const toolName of activeTools) {
|
|
408
|
-
if (toolName in tools) {
|
|
409
|
-
filtered[toolName] = tools[toolName];
|
|
410
|
-
}
|
|
411
|
-
}
|
|
412
|
-
return filtered;
|
|
413
|
-
}
|
|
414
|
-
|
|
415
390
|
/**
|
|
416
391
|
* Strip OpenAI's itemId from providerMetadata (requires reasoning items we don't preserve).
|
|
417
392
|
* Preserves all other provider metadata (e.g., Gemini's thoughtSignature).
|
package/src/telemetry.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { TelemetryOptions } from './workflow-agent.js';
|
|
2
2
|
|
|
3
3
|
// Minimal OTel type shims so we don't depend on @opentelemetry/api at compile time.
|
|
4
4
|
type Attributes = Record<string, unknown>;
|
|
@@ -62,7 +62,7 @@ async function ensureOtelApi(): Promise<OtelApi | null> {
|
|
|
62
62
|
* Returns a no-op–equivalent `null` when telemetry is disabled, so callers
|
|
63
63
|
* don't need a separate init step.
|
|
64
64
|
*/
|
|
65
|
-
function getTracer(telemetry?:
|
|
65
|
+
function getTracer(telemetry?: TelemetryOptions): Tracer | null {
|
|
66
66
|
if (!telemetry?.isEnabled || !otelApi) return null;
|
|
67
67
|
if (telemetry.tracer) return telemetry.tracer as Tracer;
|
|
68
68
|
return otelApi.trace.getTracer('ai');
|
|
@@ -76,7 +76,7 @@ function getTracer(telemetry?: TelemetrySettings): Tracer | null {
|
|
|
76
76
|
*/
|
|
77
77
|
function assembleOperationName(
|
|
78
78
|
operationId: string,
|
|
79
|
-
telemetry?:
|
|
79
|
+
telemetry?: TelemetryOptions,
|
|
80
80
|
): Attributes {
|
|
81
81
|
return {
|
|
82
82
|
'operation.name': `${operationId}${
|
|
@@ -94,7 +94,7 @@ function assembleOperationName(
|
|
|
94
94
|
*/
|
|
95
95
|
function buildAttributes(
|
|
96
96
|
operationId: string,
|
|
97
|
-
telemetry:
|
|
97
|
+
telemetry: TelemetryOptions | undefined,
|
|
98
98
|
extra?: Attributes,
|
|
99
99
|
): Attributes {
|
|
100
100
|
if (!telemetry?.isEnabled) return {};
|
|
@@ -154,7 +154,7 @@ function recordErrorOnSpan(span: Span, error: unknown): void {
|
|
|
154
154
|
*/
|
|
155
155
|
export async function recordSpan<T>(options: {
|
|
156
156
|
name: string;
|
|
157
|
-
telemetry?:
|
|
157
|
+
telemetry?: TelemetryOptions;
|
|
158
158
|
attributes?: Attributes;
|
|
159
159
|
fn: (span?: Span) => PromiseLike<T> | T;
|
|
160
160
|
}): Promise<T> {
|