@ai-sdk/workflow 2.0.0 → 2.0.3

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ai-sdk/workflow",
3
- "version": "2.0.0",
3
+ "version": "2.0.3",
4
4
  "type": "module",
5
5
  "description": "WorkflowAgent for building AI agents with AI SDK",
6
6
  "license": "Apache-2.0",
@@ -29,7 +29,7 @@
29
29
  "ajv": "^8.20.0",
30
30
  "@ai-sdk/provider": "4.0.7",
31
31
  "@ai-sdk/provider-utils": "5.0.28",
32
- "ai": "7.0.70"
32
+ "ai": "7.0.73"
33
33
  },
34
34
  "devDependencies": {
35
35
  "@types/node": "22.19.19",
@@ -214,24 +214,50 @@ export function toUIMessageChunk(
214
214
  /**
215
215
  * Create a TransformStream that converts ModelCallStreamPart to UIMessageChunk.
216
216
  * Wraps toUIMessageChunk with start/start-step/finish-step lifecycle chunks.
217
+ *
218
+ * When resuming a stream, provide `uiStartIndex` and replay the source
219
+ * ModelCallStreamPart stream from index 0. The transform will omit the UI
220
+ * chunks that the client has already received. Raw model stream parts and UI
221
+ * message chunks do not have a one-to-one relationship, so a UI chunk index
222
+ * must not be used as the source stream's start index.
217
223
  */
218
- export function createModelCallToUIChunkTransform(): TransformStream<
219
- ModelCallStreamPart<ToolSet>,
220
- UIMessageChunk
221
- > {
224
+ export function createModelCallToUIChunkTransform({
225
+ uiStartIndex = 0,
226
+ }: {
227
+ /**
228
+ * Number of transformed UIMessageChunks to omit from the output.
229
+ * Must be a non-negative safe integer.
230
+ */
231
+ uiStartIndex?: number;
232
+ } = {}): TransformStream<ModelCallStreamPart<ToolSet>, UIMessageChunk> {
233
+ if (!Number.isSafeInteger(uiStartIndex) || uiStartIndex < 0) {
234
+ throw new RangeError('uiStartIndex must be a non-negative safe integer');
235
+ }
236
+
237
+ let uiChunkIndex = 0;
238
+
239
+ const enqueue = (
240
+ controller: TransformStreamDefaultController<UIMessageChunk>,
241
+ chunk: UIMessageChunk,
242
+ ) => {
243
+ if (uiChunkIndex++ >= uiStartIndex) {
244
+ controller.enqueue(chunk);
245
+ }
246
+ };
247
+
222
248
  return new TransformStream<ModelCallStreamPart<ToolSet>, UIMessageChunk>({
223
249
  start: controller => {
224
- controller.enqueue({ type: 'start' });
225
- controller.enqueue({ type: 'start-step' });
250
+ enqueue(controller, { type: 'start' });
251
+ enqueue(controller, { type: 'start-step' });
226
252
  },
227
253
  flush: controller => {
228
- controller.enqueue({ type: 'finish-step' });
229
- controller.enqueue({ type: 'finish' });
254
+ enqueue(controller, { type: 'finish-step' });
255
+ enqueue(controller, { type: 'finish' });
230
256
  },
231
257
  transform: (part, controller) => {
232
258
  const uiChunk = toUIMessageChunk(part);
233
259
  if (uiChunk) {
234
- controller.enqueue(uiChunk);
260
+ enqueue(controller, uiChunk);
235
261
  }
236
262
  },
237
263
  });
@@ -113,7 +113,8 @@ export interface ReconnectToStreamOptions {
113
113
  abortSignal?: AbortSignal;
114
114
  /**
115
115
  * Override the `startIndex` for this reconnection.
116
- * Negative values read from the end of the stream.
116
+ * Negative values read from the end when the server's durable stream and
117
+ * tail-index header use the same UIMessageChunk index space.
117
118
  * When omitted, falls back to the constructor's `initialStartIndex`.
118
119
  */
119
120
  startIndex?: number;
@@ -178,9 +179,10 @@ export interface WorkflowChatTransportOptions<UI_MESSAGE extends UIMessage> {
178
179
  /**
179
180
  * Default `startIndex` to use when reconnecting to a stream without a known
180
181
  * chunk position (i.e. the initial reconnection, not a retry).
181
- * Negative values read from the end of the stream (e.g. `-10` fetches the
182
- * last 10 chunks), which is useful for resuming a chat UI after a page
183
- * refresh without replaying the full conversation.
182
+ * Negative values read from the end of a durable UIMessageChunk stream (e.g.
183
+ * `-10` fetches the last 10 chunks), which is useful for resuming a chat UI
184
+ * after a page refresh without replaying the full conversation. Raw
185
+ * ModelCallStreamPart streams do not support negative UI chunk indexes.
184
186
  *
185
187
  * Can be overridden per-call via `ReconnectToStreamOptions.startIndex`.
186
188
  *