@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.
@@ -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;