@ai-sdk/workflow 1.0.0-canary.72 → 1.0.0-canary.73
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 +8 -0
- package/dist/index.mjs +21 -19
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -3
- package/src/providers/mock.ts +8 -8
- package/src/to-ui-message-chunk.ts +8 -8
- package/src/workflow-chat-transport.ts +15 -13
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ai-sdk/workflow",
|
|
3
|
-
"version": "1.0.0-canary.
|
|
3
|
+
"version": "1.0.0-canary.73",
|
|
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.20.0",
|
|
30
30
|
"@ai-sdk/provider": "4.0.0-canary.17",
|
|
31
|
-
"ai": "
|
|
32
|
-
"
|
|
31
|
+
"@ai-sdk/provider-utils": "5.0.0-canary.44",
|
|
32
|
+
"ai": "7.0.0-canary.156"
|
|
33
33
|
},
|
|
34
34
|
"devDependencies": {
|
|
35
35
|
"@types/node": "22.19.19",
|
package/src/providers/mock.ts
CHANGED
|
@@ -47,13 +47,13 @@ export function mockTextModel(text: string) {
|
|
|
47
47
|
export function mockSequenceModel(responses: MockResponseDescriptor[]) {
|
|
48
48
|
return mockProvider({
|
|
49
49
|
doStream: async (options: any) => {
|
|
50
|
-
const
|
|
50
|
+
const responseIndex = Math.min(
|
|
51
51
|
options.prompt.filter((m: any) => m.role === 'assistant').length,
|
|
52
52
|
responses.length - 1,
|
|
53
53
|
);
|
|
54
|
-
const
|
|
54
|
+
const selectedResponse = responses[responseIndex];
|
|
55
55
|
const parts =
|
|
56
|
-
|
|
56
|
+
selectedResponse.type === 'text'
|
|
57
57
|
? [
|
|
58
58
|
{ type: 'stream-start', warnings: [] },
|
|
59
59
|
{
|
|
@@ -63,7 +63,7 @@ export function mockSequenceModel(responses: MockResponseDescriptor[]) {
|
|
|
63
63
|
timestamp: new Date(),
|
|
64
64
|
},
|
|
65
65
|
{ type: 'text-start', id: '1' },
|
|
66
|
-
{ type: 'text-delta', id: '1', delta:
|
|
66
|
+
{ type: 'text-delta', id: '1', delta: selectedResponse.text },
|
|
67
67
|
{ type: 'text-end', id: '1' },
|
|
68
68
|
{
|
|
69
69
|
type: 'finish',
|
|
@@ -84,9 +84,9 @@ export function mockSequenceModel(responses: MockResponseDescriptor[]) {
|
|
|
84
84
|
},
|
|
85
85
|
{
|
|
86
86
|
type: 'tool-call',
|
|
87
|
-
toolCallId: `call-${
|
|
88
|
-
toolName:
|
|
89
|
-
input:
|
|
87
|
+
toolCallId: `call-${responseIndex + 1}`,
|
|
88
|
+
toolName: selectedResponse.toolName,
|
|
89
|
+
input: selectedResponse.input,
|
|
90
90
|
},
|
|
91
91
|
{
|
|
92
92
|
type: 'finish',
|
|
@@ -100,7 +100,7 @@ export function mockSequenceModel(responses: MockResponseDescriptor[]) {
|
|
|
100
100
|
return {
|
|
101
101
|
stream: new ReadableStream({
|
|
102
102
|
start(c) {
|
|
103
|
-
for (const
|
|
103
|
+
for (const streamPart of parts as any[]) c.enqueue(streamPart);
|
|
104
104
|
c.close();
|
|
105
105
|
},
|
|
106
106
|
}),
|
|
@@ -191,20 +191,20 @@ export function toUIMessageChunk(
|
|
|
191
191
|
// standard ModelCallStreamPart types but are written by the
|
|
192
192
|
// WorkflowAgent between tool execution and the next model step
|
|
193
193
|
// to ensure proper message splitting in convertToModelMessages.
|
|
194
|
-
const
|
|
195
|
-
if (
|
|
194
|
+
const passthroughPart = part as any;
|
|
195
|
+
if (passthroughPart.type === 'tool-approval-request') {
|
|
196
196
|
return {
|
|
197
197
|
type: 'tool-approval-request',
|
|
198
|
-
approvalId:
|
|
199
|
-
toolCallId:
|
|
198
|
+
approvalId: passthroughPart.approvalId,
|
|
199
|
+
toolCallId: passthroughPart.toolCallId,
|
|
200
200
|
} as UIMessageChunk;
|
|
201
201
|
}
|
|
202
202
|
if (
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
203
|
+
passthroughPart.type === 'finish-step' ||
|
|
204
|
+
passthroughPart.type === 'start-step' ||
|
|
205
|
+
passthroughPart.type === 'tool-output-denied'
|
|
206
206
|
) {
|
|
207
|
-
return
|
|
207
|
+
return passthroughPart as UIMessageChunk;
|
|
208
208
|
}
|
|
209
209
|
return undefined;
|
|
210
210
|
}
|
|
@@ -216,7 +216,7 @@ export class WorkflowChatTransport<
|
|
|
216
216
|
: undefined;
|
|
217
217
|
|
|
218
218
|
const url = requestConfig?.api ?? this.api;
|
|
219
|
-
const
|
|
219
|
+
const response = await this.fetch(url, {
|
|
220
220
|
method: 'POST',
|
|
221
221
|
body: JSON.stringify(
|
|
222
222
|
requestConfig?.body ?? { messages, ...options.body },
|
|
@@ -226,13 +226,13 @@ export class WorkflowChatTransport<
|
|
|
226
226
|
signal: abortSignal,
|
|
227
227
|
});
|
|
228
228
|
|
|
229
|
-
if (!
|
|
229
|
+
if (!response.ok || !response.body) {
|
|
230
230
|
throw new Error(
|
|
231
|
-
`Failed to fetch chat: ${
|
|
231
|
+
`Failed to fetch chat: ${response.status} ${await response.text()}`,
|
|
232
232
|
);
|
|
233
233
|
}
|
|
234
234
|
|
|
235
|
-
const workflowRunId =
|
|
235
|
+
const workflowRunId = response.headers.get('x-workflow-run-id');
|
|
236
236
|
if (!workflowRunId) {
|
|
237
237
|
throw new Error(
|
|
238
238
|
'Workflow run ID not found in "x-workflow-run-id" response header',
|
|
@@ -242,12 +242,12 @@ export class WorkflowChatTransport<
|
|
|
242
242
|
// Notify the caller that the chat POST request was sent.
|
|
243
243
|
// This is useful for tracking the chat history on the client
|
|
244
244
|
// side and allows for inspecting response headers.
|
|
245
|
-
await this.onChatSendMessage?.(
|
|
245
|
+
await this.onChatSendMessage?.(response, options);
|
|
246
246
|
|
|
247
247
|
// Flush the initial stream until the end or an error occurs
|
|
248
248
|
try {
|
|
249
249
|
const chunkStream = parseJsonEventStream({
|
|
250
|
-
stream:
|
|
250
|
+
stream: response.body,
|
|
251
251
|
schema: uiMessageChunkSchema,
|
|
252
252
|
});
|
|
253
253
|
for await (const chunk of createAsyncIterableStream(chunkStream)) {
|
|
@@ -292,8 +292,8 @@ export class WorkflowChatTransport<
|
|
|
292
292
|
async reconnectToStream(
|
|
293
293
|
options: ReconnectToStreamOptions & ChatRequestOptions,
|
|
294
294
|
): Promise<ReadableStream<UIMessageChunk> | null> {
|
|
295
|
-
const
|
|
296
|
-
return convertAsyncIteratorToReadableStream(
|
|
295
|
+
const reconnectIterator = this.reconnectToStreamIterator(options);
|
|
296
|
+
return convertAsyncIteratorToReadableStream(reconnectIterator);
|
|
297
297
|
}
|
|
298
298
|
|
|
299
299
|
private async *reconnectToStreamIterator(
|
|
@@ -344,15 +344,15 @@ export class WorkflowChatTransport<
|
|
|
344
344
|
: chunkIndex;
|
|
345
345
|
|
|
346
346
|
const url = `${baseUrl}?startIndex=${startIndex}`;
|
|
347
|
-
const
|
|
347
|
+
const response = await this.fetch(url, {
|
|
348
348
|
headers: requestConfig?.headers,
|
|
349
349
|
credentials: requestConfig?.credentials,
|
|
350
350
|
signal: options.abortSignal,
|
|
351
351
|
});
|
|
352
352
|
|
|
353
|
-
if (!
|
|
353
|
+
if (!response.ok || !response.body) {
|
|
354
354
|
throw new Error(
|
|
355
|
-
`Failed to fetch chat: ${
|
|
355
|
+
`Failed to fetch chat: ${response.status} ${await response.text()}`,
|
|
356
356
|
);
|
|
357
357
|
}
|
|
358
358
|
|
|
@@ -365,7 +365,9 @@ export class WorkflowChatTransport<
|
|
|
365
365
|
// resume from (explicitStartIndex + chunks received).
|
|
366
366
|
chunkIndex = explicitStartIndex;
|
|
367
367
|
} else if (useExplicitStartIndex && explicitStartIndex < 0) {
|
|
368
|
-
const tailIndexHeader =
|
|
368
|
+
const tailIndexHeader = response.headers.get(
|
|
369
|
+
'x-workflow-stream-tail-index',
|
|
370
|
+
);
|
|
369
371
|
const tailIndex =
|
|
370
372
|
tailIndexHeader !== null ? parseInt(tailIndexHeader, 10) : NaN;
|
|
371
373
|
|
|
@@ -389,7 +391,7 @@ export class WorkflowChatTransport<
|
|
|
389
391
|
|
|
390
392
|
try {
|
|
391
393
|
const chunkStream = parseJsonEventStream({
|
|
392
|
-
stream:
|
|
394
|
+
stream: response.body,
|
|
393
395
|
schema: uiMessageChunkSchema,
|
|
394
396
|
});
|
|
395
397
|
for await (const chunk of createAsyncIterableStream(chunkStream)) {
|