@ai-sdk/workflow 0.0.0-bf6e4b15-20260402200305
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 +52 -0
- package/LICENSE +13 -0
- package/README.md +62 -0
- package/dist/index.d.mts +739 -0
- package/dist/index.mjs +1261 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +77 -0
- package/src/do-stream-step.ts +329 -0
- package/src/index.ts +37 -0
- package/src/providers/mock-function-wrapper.ts +11 -0
- package/src/providers/mock.ts +123 -0
- package/src/serializable-schema.ts +81 -0
- package/src/stream-iterator.ts +46 -0
- package/src/stream-text-iterator.ts +444 -0
- package/src/telemetry.ts +199 -0
- package/src/test/agent-e2e-workflows.ts +507 -0
- package/src/test/calculate-workflow.ts +19 -0
- package/src/to-ui-message-chunk.ts +214 -0
- package/src/types.ts +11 -0
- package/src/workflow-agent.ts +1647 -0
- package/src/workflow-chat-transport.ts +359 -0
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
import { generateId, type ToolSet, type UIMessageChunk } from 'ai';
|
|
2
|
+
import type { Experimental_ModelCallStreamPart as ModelCallStreamPart } from 'ai';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Convert a single ModelCallStreamPart to a UIMessageChunk.
|
|
6
|
+
* Returns undefined for parts that don't map to UI chunks.
|
|
7
|
+
*/
|
|
8
|
+
export function toUIMessageChunk(
|
|
9
|
+
part: ModelCallStreamPart<ToolSet>,
|
|
10
|
+
): UIMessageChunk | undefined {
|
|
11
|
+
switch (part.type) {
|
|
12
|
+
case 'text-start':
|
|
13
|
+
return {
|
|
14
|
+
type: 'text-start',
|
|
15
|
+
id: part.id,
|
|
16
|
+
...(part.providerMetadata != null
|
|
17
|
+
? { providerMetadata: part.providerMetadata }
|
|
18
|
+
: {}),
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
case 'text-delta':
|
|
22
|
+
return {
|
|
23
|
+
type: 'text-delta',
|
|
24
|
+
id: part.id,
|
|
25
|
+
delta: part.text,
|
|
26
|
+
...(part.providerMetadata != null
|
|
27
|
+
? { providerMetadata: part.providerMetadata }
|
|
28
|
+
: {}),
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
case 'text-end':
|
|
32
|
+
return {
|
|
33
|
+
type: 'text-end',
|
|
34
|
+
id: part.id,
|
|
35
|
+
...(part.providerMetadata != null
|
|
36
|
+
? { providerMetadata: part.providerMetadata }
|
|
37
|
+
: {}),
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
case 'reasoning-start':
|
|
41
|
+
return {
|
|
42
|
+
type: 'reasoning-start',
|
|
43
|
+
id: part.id,
|
|
44
|
+
...(part.providerMetadata != null
|
|
45
|
+
? { providerMetadata: part.providerMetadata }
|
|
46
|
+
: {}),
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
case 'reasoning-delta':
|
|
50
|
+
return {
|
|
51
|
+
type: 'reasoning-delta',
|
|
52
|
+
id: part.id,
|
|
53
|
+
delta: part.text,
|
|
54
|
+
...(part.providerMetadata != null
|
|
55
|
+
? { providerMetadata: part.providerMetadata }
|
|
56
|
+
: {}),
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
case 'reasoning-end':
|
|
60
|
+
return {
|
|
61
|
+
type: 'reasoning-end',
|
|
62
|
+
id: part.id,
|
|
63
|
+
...(part.providerMetadata != null
|
|
64
|
+
? { providerMetadata: part.providerMetadata }
|
|
65
|
+
: {}),
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
case 'file': {
|
|
69
|
+
const file = part.file;
|
|
70
|
+
// GeneratedFile.base64 always has data (lazy-converted from Uint8Array if needed)
|
|
71
|
+
return {
|
|
72
|
+
type: 'file',
|
|
73
|
+
mediaType: file.mediaType,
|
|
74
|
+
url: `data:${file.mediaType};base64,${file.base64}`,
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
case 'source': {
|
|
79
|
+
if (part.sourceType === 'url') {
|
|
80
|
+
return {
|
|
81
|
+
type: 'source-url',
|
|
82
|
+
sourceId: part.id,
|
|
83
|
+
url: part.url,
|
|
84
|
+
title: part.title,
|
|
85
|
+
...(part.providerMetadata != null
|
|
86
|
+
? { providerMetadata: part.providerMetadata }
|
|
87
|
+
: {}),
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
if (part.sourceType === 'document') {
|
|
91
|
+
return {
|
|
92
|
+
type: 'source-document',
|
|
93
|
+
sourceId: part.id,
|
|
94
|
+
mediaType: part.mediaType,
|
|
95
|
+
title: part.title,
|
|
96
|
+
filename: part.filename,
|
|
97
|
+
...(part.providerMetadata != null
|
|
98
|
+
? { providerMetadata: part.providerMetadata }
|
|
99
|
+
: {}),
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
return undefined;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
case 'tool-input-start':
|
|
106
|
+
return {
|
|
107
|
+
type: 'tool-input-start',
|
|
108
|
+
toolCallId: part.id,
|
|
109
|
+
toolName: part.toolName,
|
|
110
|
+
...(part.providerExecuted != null
|
|
111
|
+
? { providerExecuted: part.providerExecuted }
|
|
112
|
+
: {}),
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
case 'tool-input-delta':
|
|
116
|
+
return {
|
|
117
|
+
type: 'tool-input-delta',
|
|
118
|
+
toolCallId: part.id,
|
|
119
|
+
inputTextDelta: part.delta,
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
case 'tool-call': {
|
|
123
|
+
// parseToolCall adds invalid/error at runtime for failed parses
|
|
124
|
+
const toolCallPart = part as typeof part & {
|
|
125
|
+
invalid?: boolean;
|
|
126
|
+
error?: unknown;
|
|
127
|
+
};
|
|
128
|
+
if (toolCallPart.invalid) {
|
|
129
|
+
return {
|
|
130
|
+
type: 'tool-input-error',
|
|
131
|
+
toolCallId: toolCallPart.toolCallId,
|
|
132
|
+
toolName: toolCallPart.toolName,
|
|
133
|
+
input: toolCallPart.input,
|
|
134
|
+
errorText:
|
|
135
|
+
toolCallPart.error instanceof Error
|
|
136
|
+
? toolCallPart.error.message
|
|
137
|
+
: String(toolCallPart.error ?? 'Invalid tool call'),
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
return {
|
|
141
|
+
type: 'tool-input-available',
|
|
142
|
+
toolCallId: part.toolCallId,
|
|
143
|
+
toolName: part.toolName,
|
|
144
|
+
input: part.input,
|
|
145
|
+
...(part.providerExecuted != null
|
|
146
|
+
? { providerExecuted: part.providerExecuted }
|
|
147
|
+
: {}),
|
|
148
|
+
...(part.providerMetadata != null
|
|
149
|
+
? { providerMetadata: part.providerMetadata }
|
|
150
|
+
: {}),
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
case 'tool-result':
|
|
155
|
+
return {
|
|
156
|
+
type: 'tool-output-available',
|
|
157
|
+
toolCallId: part.toolCallId,
|
|
158
|
+
output: part.output,
|
|
159
|
+
};
|
|
160
|
+
|
|
161
|
+
case 'tool-error':
|
|
162
|
+
return {
|
|
163
|
+
type: 'tool-output-error',
|
|
164
|
+
toolCallId: part.toolCallId,
|
|
165
|
+
errorText:
|
|
166
|
+
part.error instanceof Error ? part.error.message : String(part.error),
|
|
167
|
+
};
|
|
168
|
+
|
|
169
|
+
case 'error': {
|
|
170
|
+
const error = part.error;
|
|
171
|
+
return {
|
|
172
|
+
type: 'error',
|
|
173
|
+
errorText: error instanceof Error ? error.message : String(error),
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// These don't produce UI chunks
|
|
178
|
+
case 'tool-input-end':
|
|
179
|
+
case 'model-call-start':
|
|
180
|
+
case 'model-call-response-metadata':
|
|
181
|
+
case 'model-call-end':
|
|
182
|
+
case 'raw':
|
|
183
|
+
return undefined;
|
|
184
|
+
|
|
185
|
+
default:
|
|
186
|
+
return undefined;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* Create a TransformStream that converts ModelCallStreamPart to UIMessageChunk.
|
|
192
|
+
* Wraps toUIMessageChunk with start/start-step/finish-step lifecycle chunks.
|
|
193
|
+
*/
|
|
194
|
+
export function createModelCallToUIChunkTransform(): TransformStream<
|
|
195
|
+
ModelCallStreamPart<ToolSet>,
|
|
196
|
+
UIMessageChunk
|
|
197
|
+
> {
|
|
198
|
+
return new TransformStream<ModelCallStreamPart<ToolSet>, UIMessageChunk>({
|
|
199
|
+
start: controller => {
|
|
200
|
+
controller.enqueue({ type: 'start', messageId: generateId() });
|
|
201
|
+
controller.enqueue({ type: 'start-step' });
|
|
202
|
+
},
|
|
203
|
+
flush: controller => {
|
|
204
|
+
controller.enqueue({ type: 'finish-step' });
|
|
205
|
+
controller.enqueue({ type: 'finish' });
|
|
206
|
+
},
|
|
207
|
+
transform: (part, controller) => {
|
|
208
|
+
const uiChunk = toUIMessageChunk(part);
|
|
209
|
+
if (uiChunk) {
|
|
210
|
+
controller.enqueue(uiChunk);
|
|
211
|
+
}
|
|
212
|
+
},
|
|
213
|
+
});
|
|
214
|
+
}
|
package/src/types.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared types for AI SDK V4.
|
|
3
|
+
*/
|
|
4
|
+
import type { LanguageModelV4 } from '@ai-sdk/provider';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Language model type for AI SDK V4.
|
|
8
|
+
*
|
|
9
|
+
* This is a simple alias for LanguageModelV4 from @ai-sdk/provider.
|
|
10
|
+
*/
|
|
11
|
+
export type CompatibleLanguageModel = LanguageModelV4;
|