@ai-sdk/workflow 2.0.32 → 2.0.34

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/dist/index.d.ts CHANGED
@@ -1,7 +1,8 @@
1
1
  import { LanguageModelV4, LanguageModelV4CallOptions, SharedV4ProviderOptions, LanguageModelV4Prompt, LanguageModelV4StreamPart } from '@ai-sdk/provider';
2
2
  import { Context, HasRequiredKey, InferToolSetContext, InferToolInput, InferToolContext, InferToolOutput } from '@ai-sdk/provider-utils';
3
- import { ToolSet, Experimental_LanguageModelStreamPart, LanguageModel, Instructions, ToolChoice, TelemetryOptions as TelemetryOptions$1, StopCondition, ActiveTools, LanguageModelResponseMetadata, LanguageModelUsage, FinishReason, ToolCallRepairFunction, Experimental_SandboxSession, ModelMessage, StepResult, GenerateTextOnStepEndCallback, UIMessage, InferUITools, UIMessageChunk, ChatTransport, PrepareSendMessagesRequest, PrepareReconnectToStreamRequest, ChatRequestOptions } from 'ai';
3
+ import { ToolSet, Experimental_LanguageModelStreamPart, LanguageModel, Instructions, ToolChoice, TelemetryOptions as TelemetryOptions$1, StopCondition, ActiveTools, LanguageModelResponseMetadata, LanguageModelUsage, FinishReason, ToolCallRepairFunction, Experimental_SandboxSession, ModelMessage, StepResult, GenerateTextOnStepEndCallback, UIMessage, InferUITools, UIMessageChunk } from 'ai';
4
4
  export { Output, ToolCallRepairFunction } from 'ai';
5
+ export { ReconnectToStreamOptions, SendMessagesOptions, WorkflowChatTransport, WorkflowChatTransportOptions } from './client.js';
5
6
 
6
7
  type ModelCallStreamPart<TTools extends ToolSet = ToolSet> = Experimental_LanguageModelStreamPart<TTools> | {
7
8
  type: 'tool-approval-request';
@@ -1114,163 +1115,6 @@ declare function createModelCallToUIChunkTransform({ uiStartIndex, }?: {
1114
1115
  uiStartIndex?: number;
1115
1116
  }): TransformStream<ModelCallStreamPart<ToolSet>, UIMessageChunk>;
1116
1117
 
1117
- interface SendMessagesOptions<UI_MESSAGE extends UIMessage> {
1118
- trigger: 'submit-message' | 'regenerate-message';
1119
- chatId: string;
1120
- messageId?: string;
1121
- messages: UI_MESSAGE[];
1122
- abortSignal?: AbortSignal;
1123
- }
1124
- interface ReconnectToStreamOptions {
1125
- chatId: string;
1126
- abortSignal?: AbortSignal;
1127
- /**
1128
- * Override the `startIndex` for this reconnection.
1129
- * Negative values read from the end when the server's durable stream and
1130
- * tail-index header use the same UIMessageChunk index space.
1131
- * When omitted, falls back to the constructor's `initialStartIndex`.
1132
- */
1133
- startIndex?: number;
1134
- }
1135
- type OnChatSendMessage<UI_MESSAGE extends UIMessage> = (response: Response, options: SendMessagesOptions<UI_MESSAGE>) => void | Promise<void>;
1136
- type OnChatEnd = ({ chatId, chunkIndex, }: {
1137
- chatId: string;
1138
- chunkIndex: number;
1139
- }) => void | Promise<void>;
1140
- /**
1141
- * Configuration options for the WorkflowChatTransport.
1142
- *
1143
- * @template UI_MESSAGE - The type of UI messages being sent and received,
1144
- * must extend the UIMessage interface from the AI SDK.
1145
- */
1146
- interface WorkflowChatTransportOptions<UI_MESSAGE extends UIMessage> {
1147
- /**
1148
- * API endpoint for chat requests
1149
- * Defaults to /api/chat if not provided
1150
- */
1151
- api?: string;
1152
- /**
1153
- * Custom fetch implementation to use for HTTP requests.
1154
- * Defaults to the global fetch function if not provided.
1155
- */
1156
- fetch?: typeof fetch;
1157
- /**
1158
- * Callback invoked after successfully sending messages to the chat endpoint.
1159
- * Useful for tracking chat history and inspecting response headers.
1160
- *
1161
- * @param response - The HTTP response object from the chat endpoint
1162
- * @param options - The original options passed to sendMessages
1163
- */
1164
- onChatSendMessage?: OnChatSendMessage<UI_MESSAGE>;
1165
- /**
1166
- * Callback invoked when a chat stream ends (receives a "finish" chunk).
1167
- * Useful for cleanup operations or state updates.
1168
- *
1169
- * @param chatId - The ID of the chat that ended
1170
- * @param chunkIndex - The total number of chunks received
1171
- */
1172
- onChatEnd?: OnChatEnd;
1173
- /**
1174
- * Maximum number of consecutive errors allowed during reconnection attempts.
1175
- * Defaults to 3 if not provided.
1176
- */
1177
- maxConsecutiveErrors?: number;
1178
- /**
1179
- * Default `startIndex` to use when reconnecting to a stream without a known
1180
- * chunk position (i.e. the initial reconnection, not a retry).
1181
- * Negative values read from the end of a durable UIMessageChunk stream (e.g.
1182
- * `-10` fetches the last 10 chunks), which is useful for resuming a chat UI
1183
- * after a page refresh without replaying the full conversation. Raw
1184
- * ModelCallStreamPart streams do not support negative UI chunk indexes.
1185
- *
1186
- * Can be overridden per-call via `ReconnectToStreamOptions.startIndex`.
1187
- *
1188
- * Defaults to `0` (replay from the beginning).
1189
- */
1190
- initialStartIndex?: number;
1191
- /**
1192
- * Function to prepare the request for sending messages.
1193
- * Allows customizing the API endpoint, headers, credentials, and body.
1194
- */
1195
- prepareSendMessagesRequest?: PrepareSendMessagesRequest<UI_MESSAGE>;
1196
- /**
1197
- * Function to prepare the request for reconnecting to a stream.
1198
- * Allows customizing the API endpoint, headers, and credentials.
1199
- */
1200
- prepareReconnectToStreamRequest?: PrepareReconnectToStreamRequest;
1201
- }
1202
- /**
1203
- * A transport implementation for managing chat workflows with support for
1204
- * streaming responses and automatic reconnection to interrupted streams.
1205
- *
1206
- * This class implements the ChatTransport interface from the AI SDK and provides
1207
- * reliable message streaming with automatic recovery from network interruptions
1208
- * or function timeouts.
1209
- *
1210
- * @template UI_MESSAGE - The type of UI messages being sent and received,
1211
- * must extend the UIMessage interface from the AI SDK.
1212
- *
1213
- * @implements {ChatTransport<UI_MESSAGE>}
1214
- */
1215
- declare class WorkflowChatTransport<UI_MESSAGE extends UIMessage> implements ChatTransport<UI_MESSAGE> {
1216
- private readonly api;
1217
- private readonly fetch;
1218
- private readonly onChatSendMessage?;
1219
- private readonly onChatEnd?;
1220
- private readonly maxConsecutiveErrors;
1221
- private readonly initialStartIndex;
1222
- private readonly prepareSendMessagesRequest?;
1223
- private readonly prepareReconnectToStreamRequest?;
1224
- /**
1225
- * Creates a new WorkflowChatTransport instance.
1226
- *
1227
- * @param options - Configuration options for the transport
1228
- * @param options.api - API endpoint for chat requests (defaults to '/api/chat')
1229
- * @param options.fetch - Custom fetch implementation (defaults to global fetch)
1230
- * @param options.onChatSendMessage - Callback after sending messages
1231
- * @param options.onChatEnd - Callback when chat stream ends
1232
- * @param options.maxConsecutiveErrors - Maximum consecutive errors for reconnection
1233
- * @param options.prepareSendMessagesRequest - Function to prepare send messages request
1234
- * @param options.prepareReconnectToStreamRequest - Function to prepare reconnect request
1235
- */
1236
- constructor(options?: WorkflowChatTransportOptions<UI_MESSAGE>);
1237
- /**
1238
- * Sends messages to the chat endpoint and returns a stream of response chunks.
1239
- *
1240
- * This method handles the entire chat lifecycle including:
1241
- * - Sending messages to the /api/chat endpoint
1242
- * - Streaming response chunks
1243
- * - Automatic reconnection if the stream is interrupted
1244
- *
1245
- * @param options - Options for sending messages
1246
- * @param options.trigger - The type of message submission ('submit-message' or 'regenerate-message')
1247
- * @param options.chatId - Unique identifier for this chat session
1248
- * @param options.messageId - Optional message ID for tracking specific messages
1249
- * @param options.messages - Array of UI messages to send
1250
- * @param options.abortSignal - Optional AbortSignal to cancel the request
1251
- *
1252
- * @returns A ReadableStream of UIMessageChunk objects containing the response
1253
- * @throws Error if the fetch request fails or returns a non-OK status
1254
- */
1255
- sendMessages(options: SendMessagesOptions<UI_MESSAGE> & ChatRequestOptions): Promise<ReadableStream<UIMessageChunk>>;
1256
- private sendMessagesIterator;
1257
- /**
1258
- * Reconnects to an existing chat stream that was previously interrupted.
1259
- *
1260
- * This method is useful for resuming a chat session after network issues,
1261
- * page refreshes, or Vercel Function timeouts.
1262
- *
1263
- * @param options - Options for reconnecting to the stream
1264
- * @param options.chatId - The chat ID to reconnect to
1265
- *
1266
- * @returns A ReadableStream of UIMessageChunk objects
1267
- * @throws Error if the reconnection request fails or returns a non-OK status
1268
- */
1269
- reconnectToStream(options: ReconnectToStreamOptions & ChatRequestOptions): Promise<ReadableStream<UIMessageChunk> | null>;
1270
- private reconnectToStreamIterator;
1271
- private onFinish;
1272
- }
1273
-
1274
1118
  /**
1275
1119
  * Normalizes the part framing of a UI message stream so it is always
1276
1120
  * well-formed for the AI SDK's stream consumer (`processUIMessageStream`,
@@ -1323,4 +1167,4 @@ declare class WorkflowChatTransport<UI_MESSAGE extends UIMessage> implements Cha
1323
1167
  */
1324
1168
  declare function normalizeUIMessageStreamParts(source: AsyncIterable<UIMessageChunk>): AsyncGenerator<UIMessageChunk>;
1325
1169
 
1326
- export { type CompatibleLanguageModel, type DownloadFunction, type GenerationSettings, type InferWorkflowAgentTools, type InferWorkflowAgentUIMessage, type ModelCallStreamPart, type OutputSpecification, type PrepareCallCallback, type PrepareCallOptions, type PrepareCallResult, type PrepareStepCallback, type PrepareStepInfo, type PrepareStepResult, type ProviderOptions, type ReconnectToStreamOptions, type SendMessagesOptions, type StreamTextTransform, type TelemetryOptions, WorkflowAgent, type WorkflowAgentOnAbortCallback, type WorkflowAgentOnEndCallback, type WorkflowAgentOnErrorCallback, type WorkflowAgentOnFinishCallback, type WorkflowAgentOnStartCallback, type WorkflowAgentOnStepEndCallback, type WorkflowAgentOnStepFinishCallback, type WorkflowAgentOnStepStartCallback, type WorkflowAgentOnToolExecutionEndCallback, type WorkflowAgentOnToolExecutionStartCallback, type WorkflowAgentOptions, type WorkflowAgentStreamOptions, type WorkflowAgentStreamResult, type WorkflowAgentToolExecutionEndEvent, type WorkflowAgentToolExecutionStartEvent, WorkflowChatTransport, type WorkflowChatTransportOptions, type WorkflowToolApprovalSecret, createModelCallToUIChunkTransform, normalizeUIMessageStreamParts, toUIMessageChunk };
1170
+ export { type CompatibleLanguageModel, type DownloadFunction, type GenerationSettings, type InferWorkflowAgentTools, type InferWorkflowAgentUIMessage, type ModelCallStreamPart, type OutputSpecification, type PrepareCallCallback, type PrepareCallOptions, type PrepareCallResult, type PrepareStepCallback, type PrepareStepInfo, type PrepareStepResult, type ProviderOptions, type StreamTextTransform, type TelemetryOptions, WorkflowAgent, type WorkflowAgentOnAbortCallback, type WorkflowAgentOnEndCallback, type WorkflowAgentOnErrorCallback, type WorkflowAgentOnFinishCallback, type WorkflowAgentOnStartCallback, type WorkflowAgentOnStepEndCallback, type WorkflowAgentOnStepFinishCallback, type WorkflowAgentOnStepStartCallback, type WorkflowAgentOnToolExecutionEndCallback, type WorkflowAgentOnToolExecutionStartCallback, type WorkflowAgentOptions, type WorkflowAgentStreamOptions, type WorkflowAgentStreamResult, type WorkflowAgentToolExecutionEndEvent, type WorkflowAgentToolExecutionStartEvent, type WorkflowToolApprovalSecret, createModelCallToUIChunkTransform, normalizeUIMessageStreamParts, toUIMessageChunk };
package/dist/index.js CHANGED
@@ -1,3 +1,7 @@
1
+ import {
2
+ WorkflowChatTransport,
3
+ normalizeUIMessageStreamParts
4
+ } from "./chunk-FJHDNS6E.js";
1
5
  import "./chunk-UAWBPTDW.js";
2
6
 
3
7
  // src/workflow-agent.ts
@@ -22,6 +26,7 @@ import {
22
26
  validateApprovedToolApprovals,
23
27
  verifyToolApprovalSignature
24
28
  } from "ai/internal";
29
+ import { getWorkflowMetadata } from "workflow";
25
30
 
26
31
  // src/add-tool-results-to-conversation.ts
27
32
  function addToolResultsToConversation({
@@ -1500,9 +1505,10 @@ var WorkflowAgent = class {
1500
1505
  });
1501
1506
  const download = effectiveDownloadFromPrepare;
1502
1507
  const sandbox = (_n = options.experimental_sandbox) != null ? _n : this.experimentalSandbox;
1508
+ const abortSignalTimeout = isInWorkflow() ? void 0 : options.timeout;
1503
1509
  const effectiveAbortSignal = mergeAbortSignals(
1504
1510
  (_o = options.abortSignal) != null ? _o : effectiveGenerationSettings.abortSignal,
1505
- options.timeout
1511
+ abortSignalTimeout
1506
1512
  );
1507
1513
  const timeoutAt = options.timeout == null ? void 0 : Date.now() + options.timeout;
1508
1514
  const mergedOnToolExecutionStart = mergeCallbacks(
@@ -2648,6 +2654,14 @@ async function writeApprovalToolResults(writable, approvedResults, deniedResults
2648
2654
  writer.releaseLock();
2649
2655
  }
2650
2656
  }
2657
+ function isInWorkflow() {
2658
+ try {
2659
+ getWorkflowMetadata();
2660
+ return true;
2661
+ } catch (e) {
2662
+ return false;
2663
+ }
2664
+ }
2651
2665
  function aggregateUsage(steps) {
2652
2666
  var _a, _b, _c, _d;
2653
2667
  let inputTokens = 0;
@@ -2968,365 +2982,6 @@ function createModelCallToUIChunkTransform({
2968
2982
  }
2969
2983
  });
2970
2984
  }
2971
-
2972
- // src/workflow-chat-transport.ts
2973
- import {
2974
- parseJsonEventStream,
2975
- uiMessageChunkSchema
2976
- } from "ai";
2977
- import {
2978
- convertAsyncIteratorToReadableStream,
2979
- getErrorMessage as getErrorMessage2
2980
- } from "@ai-sdk/provider-utils";
2981
- import { createAsyncIterableStream } from "ai/internal";
2982
-
2983
- // src/normalize-ui-message-stream.ts
2984
- var newPartFrameState = () => ({
2985
- open: /* @__PURE__ */ new Set(),
2986
- ended: /* @__PURE__ */ new Set()
2987
- });
2988
- function* repairPart(kind, id, chunk, state, startType) {
2989
- if (kind === "start") {
2990
- if (state.open.has(id) || state.ended.has(id)) {
2991
- return;
2992
- }
2993
- state.open.add(id);
2994
- yield chunk;
2995
- return;
2996
- }
2997
- if (state.ended.has(id)) {
2998
- return;
2999
- }
3000
- if (!state.open.has(id)) {
3001
- state.open.add(id);
3002
- yield { type: startType, id };
3003
- }
3004
- if (kind === "end") {
3005
- state.open.delete(id);
3006
- state.ended.add(id);
3007
- }
3008
- yield chunk;
3009
- }
3010
- async function* normalizeUIMessageStreamParts(source) {
3011
- const text = newPartFrameState();
3012
- const reasoning = newPartFrameState();
3013
- for await (const chunk of source) {
3014
- switch (chunk.type) {
3015
- case "reset-step":
3016
- text.open.clear();
3017
- text.ended.clear();
3018
- reasoning.open.clear();
3019
- reasoning.ended.clear();
3020
- yield chunk;
3021
- break;
3022
- case "finish-step":
3023
- text.ended.clear();
3024
- reasoning.ended.clear();
3025
- yield chunk;
3026
- break;
3027
- case "text-start":
3028
- yield* repairPart("start", chunk.id, chunk, text, "text-start");
3029
- break;
3030
- case "text-delta":
3031
- yield* repairPart("delta", chunk.id, chunk, text, "text-start");
3032
- break;
3033
- case "text-end":
3034
- yield* repairPart("end", chunk.id, chunk, text, "text-start");
3035
- break;
3036
- case "reasoning-start":
3037
- yield* repairPart(
3038
- "start",
3039
- chunk.id,
3040
- chunk,
3041
- reasoning,
3042
- "reasoning-start"
3043
- );
3044
- break;
3045
- case "reasoning-delta":
3046
- yield* repairPart(
3047
- "delta",
3048
- chunk.id,
3049
- chunk,
3050
- reasoning,
3051
- "reasoning-start"
3052
- );
3053
- break;
3054
- case "reasoning-end":
3055
- yield* repairPart("end", chunk.id, chunk, reasoning, "reasoning-start");
3056
- break;
3057
- default:
3058
- yield chunk;
3059
- }
3060
- }
3061
- }
3062
-
3063
- // src/workflow-chat-transport.ts
3064
- function createOrphanFilter() {
3065
- const seenStartedIds = /* @__PURE__ */ new Set();
3066
- const seenStartedToolCallIds = /* @__PURE__ */ new Set();
3067
- let warnedOnce = false;
3068
- function warnOnce(orphanKind, orphanRef) {
3069
- if (warnedOnce) return;
3070
- warnedOnce = true;
3071
- console.warn(
3072
- `[WorkflowChatTransport] Dropping orphan UI chunk (${orphanKind} for id "${orphanRef}") on resume \u2014 the resume position landed mid-part. The dropped chunk(s) reference a part whose start chunk wasn't in the resumed window. To preserve the full message, configure your stream endpoint to rewind to a step boundary before returning the readable. See: https://workflow.dev/docs/ai/resumable-streams#mid-part-resumes`
3073
- );
3074
- }
3075
- function shouldDrop(chunk) {
3076
- switch (chunk.type) {
3077
- case "reset-step":
3078
- seenStartedIds.clear();
3079
- seenStartedToolCallIds.clear();
3080
- return false;
3081
- case "text-start":
3082
- case "reasoning-start":
3083
- seenStartedIds.add(chunk.id);
3084
- return false;
3085
- case "tool-input-start":
3086
- // `tool-input-available` / `tool-input-error` are self-contained: the
3087
- // AI SDK creates the tool part from them directly (non-streamed tool
3088
- // calls are emitted as a bare `tool-input-available`), so they must
3089
- // never be dropped. They also carry the full input, so they recover a
3090
- // tool call whose `tool-input-start` fell outside the resumed window.
3091
- case "tool-input-available":
3092
- case "tool-input-error":
3093
- seenStartedToolCallIds.add(chunk.toolCallId);
3094
- return false;
3095
- case "text-delta":
3096
- case "text-end":
3097
- case "reasoning-delta":
3098
- case "reasoning-end":
3099
- if (seenStartedIds.has(chunk.id)) return false;
3100
- warnOnce(chunk.type, chunk.id);
3101
- return true;
3102
- case "tool-input-delta":
3103
- case "tool-approval-request":
3104
- case "tool-output-available":
3105
- case "tool-output-error":
3106
- case "tool-output-denied":
3107
- if (seenStartedToolCallIds.has(chunk.toolCallId)) return false;
3108
- warnOnce(chunk.type, chunk.toolCallId);
3109
- return true;
3110
- default:
3111
- return false;
3112
- }
3113
- }
3114
- return { shouldDrop };
3115
- }
3116
- var WorkflowChatTransport = class {
3117
- /**
3118
- * Creates a new WorkflowChatTransport instance.
3119
- *
3120
- * @param options - Configuration options for the transport
3121
- * @param options.api - API endpoint for chat requests (defaults to '/api/chat')
3122
- * @param options.fetch - Custom fetch implementation (defaults to global fetch)
3123
- * @param options.onChatSendMessage - Callback after sending messages
3124
- * @param options.onChatEnd - Callback when chat stream ends
3125
- * @param options.maxConsecutiveErrors - Maximum consecutive errors for reconnection
3126
- * @param options.prepareSendMessagesRequest - Function to prepare send messages request
3127
- * @param options.prepareReconnectToStreamRequest - Function to prepare reconnect request
3128
- */
3129
- constructor(options = {}) {
3130
- var _a, _b, _c, _d;
3131
- this.api = (_a = options.api) != null ? _a : "/api/chat";
3132
- this.fetch = (_b = options.fetch) != null ? _b : fetch.bind(globalThis);
3133
- this.onChatSendMessage = options.onChatSendMessage;
3134
- this.onChatEnd = options.onChatEnd;
3135
- this.maxConsecutiveErrors = (_c = options.maxConsecutiveErrors) != null ? _c : 3;
3136
- this.initialStartIndex = (_d = options.initialStartIndex) != null ? _d : 0;
3137
- this.prepareSendMessagesRequest = options.prepareSendMessagesRequest;
3138
- this.prepareReconnectToStreamRequest = options.prepareReconnectToStreamRequest;
3139
- }
3140
- /**
3141
- * Sends messages to the chat endpoint and returns a stream of response chunks.
3142
- *
3143
- * This method handles the entire chat lifecycle including:
3144
- * - Sending messages to the /api/chat endpoint
3145
- * - Streaming response chunks
3146
- * - Automatic reconnection if the stream is interrupted
3147
- *
3148
- * @param options - Options for sending messages
3149
- * @param options.trigger - The type of message submission ('submit-message' or 'regenerate-message')
3150
- * @param options.chatId - Unique identifier for this chat session
3151
- * @param options.messageId - Optional message ID for tracking specific messages
3152
- * @param options.messages - Array of UI messages to send
3153
- * @param options.abortSignal - Optional AbortSignal to cancel the request
3154
- *
3155
- * @returns A ReadableStream of UIMessageChunk objects containing the response
3156
- * @throws Error if the fetch request fails or returns a non-OK status
3157
- */
3158
- async sendMessages(options) {
3159
- return convertAsyncIteratorToReadableStream(
3160
- normalizeUIMessageStreamParts(this.sendMessagesIterator(options))
3161
- );
3162
- }
3163
- async *sendMessagesIterator(options) {
3164
- var _a, _b, _c;
3165
- const { chatId, messages, abortSignal, trigger, messageId } = options;
3166
- let gotFinish = false;
3167
- let chunkIndex = 0;
3168
- const requestConfig = this.prepareSendMessagesRequest ? await this.prepareSendMessagesRequest({
3169
- id: chatId,
3170
- messages,
3171
- requestMetadata: options.metadata,
3172
- body: options.body,
3173
- credentials: void 0,
3174
- headers: options.headers,
3175
- api: this.api,
3176
- trigger,
3177
- messageId
3178
- }) : void 0;
3179
- const url = (_a = requestConfig == null ? void 0 : requestConfig.api) != null ? _a : this.api;
3180
- const response = await this.fetch(url, {
3181
- method: "POST",
3182
- body: JSON.stringify(
3183
- (_b = requestConfig == null ? void 0 : requestConfig.body) != null ? _b : { messages, ...options.body }
3184
- ),
3185
- headers: requestConfig == null ? void 0 : requestConfig.headers,
3186
- credentials: requestConfig == null ? void 0 : requestConfig.credentials,
3187
- signal: abortSignal
3188
- });
3189
- if (!response.ok || !response.body) {
3190
- throw new Error(
3191
- `Failed to fetch chat: ${response.status} ${await response.text()}`
3192
- );
3193
- }
3194
- const workflowRunId = response.headers.get("x-workflow-run-id");
3195
- if (!workflowRunId) {
3196
- throw new Error(
3197
- 'Workflow run ID not found in "x-workflow-run-id" response header'
3198
- );
3199
- }
3200
- await ((_c = this.onChatSendMessage) == null ? void 0 : _c.call(this, response, options));
3201
- try {
3202
- const chunkStream = parseJsonEventStream({
3203
- stream: response.body,
3204
- schema: uiMessageChunkSchema
3205
- });
3206
- for await (const chunk of createAsyncIterableStream(chunkStream)) {
3207
- if (!chunk.success) {
3208
- throw chunk.error;
3209
- }
3210
- chunkIndex++;
3211
- yield chunk.value;
3212
- if (chunk.value.type === "finish") {
3213
- gotFinish = true;
3214
- }
3215
- }
3216
- } catch (error) {
3217
- console.error("Error in chat POST stream", error);
3218
- }
3219
- if (gotFinish) {
3220
- await this.onFinish(gotFinish, { chatId, chunkIndex });
3221
- } else {
3222
- yield* this.reconnectToStreamIterator(options, workflowRunId, chunkIndex);
3223
- }
3224
- }
3225
- /**
3226
- * Reconnects to an existing chat stream that was previously interrupted.
3227
- *
3228
- * This method is useful for resuming a chat session after network issues,
3229
- * page refreshes, or Vercel Function timeouts.
3230
- *
3231
- * @param options - Options for reconnecting to the stream
3232
- * @param options.chatId - The chat ID to reconnect to
3233
- *
3234
- * @returns A ReadableStream of UIMessageChunk objects
3235
- * @throws Error if the reconnection request fails or returns a non-OK status
3236
- */
3237
- async reconnectToStream(options) {
3238
- const reconnectIterator = normalizeUIMessageStreamParts(
3239
- this.reconnectToStreamIterator(options)
3240
- );
3241
- return convertAsyncIteratorToReadableStream(reconnectIterator);
3242
- }
3243
- async *reconnectToStreamIterator(options, workflowRunId, initialChunkIndex = 0) {
3244
- var _a, _b;
3245
- let chunkIndex = initialChunkIndex;
3246
- const explicitStartIndex = (_a = options.startIndex) != null ? _a : this.initialStartIndex;
3247
- let useExplicitStartIndex = initialChunkIndex === 0 && explicitStartIndex !== 0;
3248
- const defaultApi = `${this.api}/${encodeURIComponent(workflowRunId != null ? workflowRunId : options.chatId)}/stream`;
3249
- const requestConfig = this.prepareReconnectToStreamRequest ? await this.prepareReconnectToStreamRequest({
3250
- id: options.chatId,
3251
- requestMetadata: options.metadata,
3252
- body: void 0,
3253
- credentials: void 0,
3254
- headers: void 0,
3255
- api: defaultApi
3256
- }) : void 0;
3257
- const baseUrl = (_b = requestConfig == null ? void 0 : requestConfig.api) != null ? _b : defaultApi;
3258
- let gotFinish = false;
3259
- let consecutiveErrors = 0;
3260
- let replayFromStart = false;
3261
- const orphanFilter = useExplicitStartIndex && explicitStartIndex < 0 ? createOrphanFilter() : null;
3262
- while (!gotFinish) {
3263
- const startIndex = useExplicitStartIndex ? explicitStartIndex : replayFromStart ? 0 : chunkIndex;
3264
- const url = `${baseUrl}?startIndex=${startIndex}`;
3265
- const response = await this.fetch(url, {
3266
- headers: requestConfig == null ? void 0 : requestConfig.headers,
3267
- credentials: requestConfig == null ? void 0 : requestConfig.credentials,
3268
- signal: options.abortSignal
3269
- });
3270
- if (!response.ok || !response.body) {
3271
- throw new Error(
3272
- `Failed to fetch chat: ${response.status} ${await response.text()}`
3273
- );
3274
- }
3275
- if (useExplicitStartIndex && explicitStartIndex > 0) {
3276
- chunkIndex = explicitStartIndex;
3277
- } else if (useExplicitStartIndex && explicitStartIndex < 0) {
3278
- const tailIndexHeader = response.headers.get(
3279
- "x-workflow-stream-tail-index"
3280
- );
3281
- const tailIndex = tailIndexHeader !== null ? parseInt(tailIndexHeader, 10) : NaN;
3282
- if (!Number.isNaN(tailIndex)) {
3283
- chunkIndex = Math.max(0, tailIndex + 1 + explicitStartIndex);
3284
- } else {
3285
- console.warn(
3286
- `[WorkflowChatTransport] Negative initialStartIndex is configured (${explicitStartIndex}) but the reconnection endpoint did not return a valid "x-workflow-stream-tail-index" header. Retries will replay the stream from the beginning. See: https://workflow.dev/docs/ai/resumable-streams#resuming-from-the-end-of-the-stream`
3287
- );
3288
- replayFromStart = true;
3289
- }
3290
- }
3291
- useExplicitStartIndex = false;
3292
- try {
3293
- const chunkStream = parseJsonEventStream({
3294
- stream: response.body,
3295
- schema: uiMessageChunkSchema
3296
- });
3297
- for await (const chunk of createAsyncIterableStream(chunkStream)) {
3298
- if (!chunk.success) {
3299
- throw chunk.error;
3300
- }
3301
- chunkIndex++;
3302
- if (orphanFilter == null ? void 0 : orphanFilter.shouldDrop(chunk.value)) continue;
3303
- yield chunk.value;
3304
- if (chunk.value.type === "finish") {
3305
- gotFinish = true;
3306
- }
3307
- }
3308
- consecutiveErrors = 0;
3309
- } catch (error) {
3310
- console.error("Error in chat GET reconnectToStream", error);
3311
- consecutiveErrors++;
3312
- if (consecutiveErrors >= this.maxConsecutiveErrors) {
3313
- throw new Error(
3314
- `Failed to reconnect after ${this.maxConsecutiveErrors} consecutive errors. Last error: ${getErrorMessage2(error)}`
3315
- );
3316
- }
3317
- }
3318
- }
3319
- await this.onFinish(gotFinish, { chatId: options.chatId, chunkIndex });
3320
- }
3321
- async onFinish(gotFinish, { chatId, chunkIndex }) {
3322
- var _a;
3323
- if (gotFinish) {
3324
- await ((_a = this.onChatEnd) == null ? void 0 : _a.call(this, { chatId, chunkIndex }));
3325
- } else {
3326
- throw new Error("No finish chunk received");
3327
- }
3328
- }
3329
- };
3330
2985
  export {
3331
2986
  Output,
3332
2987
  WorkflowAgent,