@mastra/ai-sdk 0.2.7 → 0.3.1

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 CHANGED
@@ -1,5 +1,80 @@
1
1
  # @mastra/ai-sdk
2
2
 
3
+ ## 0.3.1
4
+
5
+ ### Patch Changes
6
+
7
+ - Added support for tripwire data chunks in streaming responses. ([#10291](https://github.com/mastra-ai/mastra/pull/10291))
8
+
9
+ Tripwire chunks allow the AI SDK to emit special data events when certain conditions are triggered during stream processing. These chunks include a `tripwireReason` field explaining why the tripwire was activated.
10
+
11
+ #### Usage
12
+
13
+ When converting Mastra chunks to AI SDK v5 format, tripwire chunks are now automatically handled:
14
+
15
+ ```typescript
16
+ // Tripwire chunks are converted to data-tripwire format
17
+ const chunk = {
18
+ type: 'tripwire',
19
+ payload: { tripwireReason: 'Rate limit approaching' }
20
+ };
21
+
22
+ // Converts to:
23
+ {
24
+ type: 'data-tripwire',
25
+ data: { tripwireReason: 'Rate limit approaching' }
26
+ }
27
+ ```
28
+
29
+ - Updated dependencies [[`7491cc0`](https://github.com/mastra-ai/mastra/commit/7491cc0350b2ba067f98c4915bf607119bd0150f), [`0d10ac7`](https://github.com/mastra-ai/mastra/commit/0d10ac7b8efa03c2f0c330eb2520148bfa6091e9), [`e3e899c`](https://github.com/mastra-ai/mastra/commit/e3e899c650f4c435445303bd97a66f5840a52a1e)]:
30
+ - @mastra/core@0.24.3
31
+
32
+ ## 0.3.1-alpha.0
33
+
34
+ ### Patch Changes
35
+
36
+ - Added support for tripwire data chunks in streaming responses. ([#10291](https://github.com/mastra-ai/mastra/pull/10291))
37
+
38
+ Tripwire chunks allow the AI SDK to emit special data events when certain conditions are triggered during stream processing. These chunks include a `tripwireReason` field explaining why the tripwire was activated.
39
+
40
+ #### Usage
41
+
42
+ When converting Mastra chunks to AI SDK v5 format, tripwire chunks are now automatically handled:
43
+
44
+ ```typescript
45
+ // Tripwire chunks are converted to data-tripwire format
46
+ const chunk = {
47
+ type: 'tripwire',
48
+ payload: { tripwireReason: 'Rate limit approaching' }
49
+ };
50
+
51
+ // Converts to:
52
+ {
53
+ type: 'data-tripwire',
54
+ data: { tripwireReason: 'Rate limit approaching' }
55
+ }
56
+ ```
57
+
58
+ - Updated dependencies [[`7491cc0`](https://github.com/mastra-ai/mastra/commit/7491cc0350b2ba067f98c4915bf607119bd0150f), [`0d10ac7`](https://github.com/mastra-ai/mastra/commit/0d10ac7b8efa03c2f0c330eb2520148bfa6091e9), [`e3e899c`](https://github.com/mastra-ai/mastra/commit/e3e899c650f4c435445303bd97a66f5840a52a1e)]:
59
+ - @mastra/core@0.24.3-alpha.0
60
+
61
+ ## 0.3.0
62
+
63
+ ### Minor Changes
64
+
65
+ - Add sendStart, sendFinish, sendReasoning, and sendSources options to toAISdkV5Stream function, allowing fine-grained control over which message chunks are included in the converted stream. Previously, these values were hardcoded in the transformer. ([#10250](https://github.com/mastra-ai/mastra/pull/10250))
66
+
67
+ BREAKING CHANGE: AgentStreamToAISDKTransformer now accepts an options object instead of a single lastMessageId parameter
68
+
69
+ Also, add sendStart, sendFinish, sendReasoning, and sendSources parameters to
70
+ chatRoute function, enabling fine-grained control over which chunks are
71
+ included in the AI SDK stream output.
72
+
73
+ ### Patch Changes
74
+
75
+ - Updated dependencies [[`eebb7bb`](https://github.com/mastra-ai/mastra/commit/eebb7bb407c57342a3be3a2efbe68c696589feeb), [`c6e6d07`](https://github.com/mastra-ai/mastra/commit/c6e6d071ecf346a80dceab410af2c567c7e66a57), [`0e6df8f`](https://github.com/mastra-ai/mastra/commit/0e6df8f66340992cb1b319834657deb17368de52), [`6295fd7`](https://github.com/mastra-ai/mastra/commit/6295fd783d49075d5bf2c18ff9486e94d36aaa56), [`d813cf7`](https://github.com/mastra-ai/mastra/commit/d813cf7251695d85cc60469058384ffa74974484)]:
76
+ - @mastra/core@0.24.2
77
+
3
78
  ## 0.2.7
4
79
 
5
80
  ### Patch Changes
@@ -9,6 +9,56 @@ export type chatRouteOptions<OUTPUT extends OutputSchema = undefined> = {
9
9
  } | {
10
10
  path: string;
11
11
  agent: string;
12
- });
13
- export declare function chatRoute<OUTPUT extends OutputSchema = undefined>({ path, agent, defaultOptions, }: chatRouteOptions<OUTPUT>): ReturnType<typeof registerApiRoute>;
12
+ }) & {
13
+ sendStart?: boolean;
14
+ sendFinish?: boolean;
15
+ sendReasoning?: boolean;
16
+ sendSources?: boolean;
17
+ };
18
+ /**
19
+ * Creates a chat route handler for streaming agent conversations using the AI SDK format.
20
+ *
21
+ * This function registers an HTTP POST endpoint that accepts messages, executes an agent,
22
+ * and streams the response back to the client in AI SDK v5 compatible format.
23
+ * *
24
+ * @param {chatRouteOptions} options - Configuration options for the chat route
25
+ * @param {string} [options.path='/chat/:agentId'] - The route path. Include `:agentId` for dynamic routing
26
+ * @param {string} [options.agent] - Fixed agent ID when not using dynamic routing
27
+ * @param {AgentExecutionOptions} [options.defaultOptions] - Default options passed to agent execution
28
+ * @param {boolean} [options.sendStart=true] - Whether to send start events in the stream
29
+ * @param {boolean} [options.sendFinish=true] - Whether to send finish events in the stream
30
+ * @param {boolean} [options.sendReasoning=false] - Whether to include reasoning steps in the stream
31
+ * @param {boolean} [options.sendSources=false] - Whether to include source citations in the stream
32
+ *
33
+ * @returns {ReturnType<typeof registerApiRoute>} A registered API route handler
34
+ *
35
+ * @throws {Error} When path doesn't include `:agentId` and no fixed agent is specified
36
+ * @throws {Error} When agent ID is missing at runtime
37
+ * @throws {Error} When specified agent is not found in Mastra instance
38
+ *
39
+ * @example
40
+ * // Dynamic agent routing
41
+ * chatRoute({
42
+ * path: '/chat/:agentId',
43
+ * sendReasoning: true,
44
+ * });
45
+ *
46
+ * @example
47
+ * // Fixed agent with custom path
48
+ * chatRoute({
49
+ * path: '/api/support-chat',
50
+ * agent: 'support-agent',
51
+ * defaultOptions: {
52
+ * maxSteps: 5,
53
+ * },
54
+ * });
55
+ *
56
+ * @remarks
57
+ * - The route handler expects a JSON body with a `messages` array
58
+ * - Messages should follow the format: `{ role: 'user' | 'assistant' | 'system', content: string }`
59
+ * - The response is a Server-Sent Events (SSE) stream compatible with AI SDK v5
60
+ * - If both `agent` and `:agentId` are present, a warning is logged and the fixed `agent` takes precedence
61
+ * - Request context from the incoming request overrides `defaultOptions.requestContext` if both are present
62
+ */
63
+ export declare function chatRoute<OUTPUT extends OutputSchema = undefined>({ path, agent, defaultOptions, sendStart, sendFinish, sendReasoning, sendSources, }: chatRouteOptions<OUTPUT>): ReturnType<typeof registerApiRoute>;
14
64
  //# sourceMappingURL=chat-route.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"chat-route.d.ts","sourceRoot":"","sources":["../src/chat-route.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAEhE,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAIxD,MAAM,MAAM,gBAAgB,CAAC,MAAM,SAAS,YAAY,GAAG,SAAS,IAAI;IACtE,cAAc,CAAC,EAAE,qBAAqB,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACzD,GAAG,CACA;IACE,IAAI,EAAE,GAAG,MAAM,WAAW,MAAM,EAAE,CAAC;IACnC,KAAK,CAAC,EAAE,KAAK,CAAC;CACf,GACD;IACE,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACf,CACJ,CAAC;AAEF,wBAAgB,SAAS,CAAC,MAAM,SAAS,YAAY,GAAG,SAAS,EAAE,EACjE,IAAuB,EACvB,KAAK,EACL,cAAc,GACf,EAAE,gBAAgB,CAAC,MAAM,CAAC,GAAG,UAAU,CAAC,OAAO,gBAAgB,CAAC,CA6JhE"}
1
+ {"version":3,"file":"chat-route.d.ts","sourceRoot":"","sources":["../src/chat-route.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAEhE,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAIxD,MAAM,MAAM,gBAAgB,CAAC,MAAM,SAAS,YAAY,GAAG,SAAS,IAAI;IACtE,cAAc,CAAC,EAAE,qBAAqB,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACzD,GAAG,CACA;IACE,IAAI,EAAE,GAAG,MAAM,WAAW,MAAM,EAAE,CAAC;IACnC,KAAK,CAAC,EAAE,KAAK,CAAC;CACf,GACD;IACE,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACf,CACJ,GAAG;IACA,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB,CAAC;AAEJ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4CG;AACH,wBAAgB,SAAS,CAAC,MAAM,SAAS,YAAY,GAAG,SAAS,EAAE,EACjE,IAAuB,EACvB,KAAK,EACL,cAAc,EACd,SAAgB,EAChB,UAAiB,EACjB,aAAqB,EACrB,WAAmB,GACpB,EAAE,gBAAgB,CAAC,MAAM,CAAC,GAAG,UAAU,CAAC,OAAO,gBAAgB,CAAC,CAoKhE"}
package/dist/helpers.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import type { ChunkType } from '@mastra/core';
2
2
  import type { PartialSchemaOutput, OutputSchema, DataChunkType } from '@mastra/core/stream';
3
3
  import type { InferUIMessageChunk, ObjectStreamPart, TextStreamPart, ToolSet, UIMessage } from 'ai';
4
- export type OutputChunkType<OUTPUT extends OutputSchema = undefined> = TextStreamPart<ToolSet> | ObjectStreamPart<PartialSchemaOutput<OUTPUT>> | undefined;
4
+ export type OutputChunkType<OUTPUT extends OutputSchema = undefined> = TextStreamPart<ToolSet> | ObjectStreamPart<PartialSchemaOutput<OUTPUT>> | DataChunkType | undefined;
5
5
  export type ToolAgentChunkType = {
6
6
  type: 'tool-agent';
7
7
  toolCallId: string;
@@ -1 +1 @@
1
- {"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../src/helpers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAE9C,OAAO,KAAK,EAAE,mBAAmB,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAE5F,OAAO,KAAK,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,cAAc,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,IAAI,CAAC;AAGpG,MAAM,MAAM,eAAe,CAAC,MAAM,SAAS,YAAY,GAAG,SAAS,IAC/D,cAAc,CAAC,OAAO,CAAC,GACvB,gBAAgB,CAAC,mBAAmB,CAAC,MAAM,CAAC,CAAC,GAC7C,SAAS,CAAC;AAEd,MAAM,MAAM,kBAAkB,GAAG;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,GAAG,CAAA;CAAE,CAAC;AAC1F,MAAM,MAAM,qBAAqB,GAAG;IAAE,IAAI,EAAE,eAAe,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,GAAG,CAAA;CAAE,CAAC;AAChG,MAAM,MAAM,oBAAoB,GAAG;IAAE,IAAI,EAAE,cAAc,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,GAAG,CAAA;CAAE,CAAC;AAE9F,wBAAgB,2BAA2B,CAAC,MAAM,SAAS,YAAY,GAAG,SAAS,EAAE,EACnF,KAAK,EACL,IAAe,GAChB,EAAE;IACD,KAAK,EAAE,SAAS,CAAC,MAAM,CAAC,CAAC;IACzB,IAAI,CAAC,EAAE,UAAU,GAAG,QAAQ,CAAC;CAC9B,GAAG,eAAe,CAAC,MAAM,CAAC,CAqN1B;AAED,wBAAgB,uCAAuC,CAAC,UAAU,SAAS,SAAS,EAAE,EACpF,IAAI,EACJ,oBAAoB,EACpB,aAAa,EACb,WAAW,EACX,OAAO,EACP,SAAS,EACT,UAAU,EACV,iBAAiB,GAClB,EAAE;IAED,IAAI,EAAE,cAAc,CAAC,OAAO,CAAC,GAAG,aAAa,GAAG;QAAE,IAAI,EAAE,aAAa,CAAC;QAAC,UAAU,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,GAAG,CAAA;KAAE,CAAC;IACzG,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,OAAO,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,MAAM,CAAC;IACpC,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B,GAAG,mBAAmB,CAAC,UAAU,CAAC,GAAG,kBAAkB,GAAG,qBAAqB,GAAG,oBAAoB,GAAG,SAAS,CAwOlH"}
1
+ {"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../src/helpers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAE9C,OAAO,KAAK,EAAE,mBAAmB,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAE5F,OAAO,KAAK,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,cAAc,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,IAAI,CAAC;AAGpG,MAAM,MAAM,eAAe,CAAC,MAAM,SAAS,YAAY,GAAG,SAAS,IAC/D,cAAc,CAAC,OAAO,CAAC,GACvB,gBAAgB,CAAC,mBAAmB,CAAC,MAAM,CAAC,CAAC,GAC7C,aAAa,GACb,SAAS,CAAC;AAEd,MAAM,MAAM,kBAAkB,GAAG;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,GAAG,CAAA;CAAE,CAAC;AAC1F,MAAM,MAAM,qBAAqB,GAAG;IAAE,IAAI,EAAE,eAAe,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,GAAG,CAAA;CAAE,CAAC;AAChG,MAAM,MAAM,oBAAoB,GAAG;IAAE,IAAI,EAAE,cAAc,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,GAAG,CAAA;CAAE,CAAC;AAE9F,wBAAgB,2BAA2B,CAAC,MAAM,SAAS,YAAY,GAAG,SAAS,EAAE,EACnF,KAAK,EACL,IAAe,GAChB,EAAE;IACD,KAAK,EAAE,SAAS,CAAC,MAAM,CAAC,CAAC;IACzB,IAAI,CAAC,EAAE,UAAU,GAAG,QAAQ,CAAC;CAC9B,GAAG,eAAe,CAAC,MAAM,CAAC,CAiP1B;AAED,wBAAgB,uCAAuC,CAAC,UAAU,SAAS,SAAS,EAAE,EACpF,IAAI,EACJ,oBAAoB,EACpB,aAAa,EACb,WAAW,EACX,OAAO,EACP,SAAS,EACT,UAAU,EACV,iBAAiB,GAClB,EAAE;IAED,IAAI,EAAE,cAAc,CAAC,OAAO,CAAC,GAAG,aAAa,GAAG;QAAE,IAAI,EAAE,aAAa,CAAC;QAAC,UAAU,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,GAAG,CAAA;KAAE,CAAC;IACzG,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,OAAO,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,MAAM,CAAC;IACpC,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B,GAAG,mBAAmB,CAAC,UAAU,CAAC,GAAG,kBAAkB,GAAG,qBAAqB,GAAG,oBAAoB,GAAG,SAAS,CAwOlH"}
package/dist/index.cjs CHANGED
@@ -126,6 +126,28 @@ function convertMastraChunkToAISDKv5({
126
126
  toolName: chunk.payload.toolName,
127
127
  input: chunk.payload.args
128
128
  };
129
+ case "tool-call-approval":
130
+ return {
131
+ type: "data-tool-call-approval",
132
+ id: chunk.payload.toolCallId,
133
+ data: {
134
+ runId: chunk.runId,
135
+ toolCallId: chunk.payload.toolCallId,
136
+ toolName: chunk.payload.toolName,
137
+ args: chunk.payload.args
138
+ }
139
+ };
140
+ case "tool-call-suspended":
141
+ return {
142
+ type: "data-tool-call-suspended",
143
+ id: chunk.payload.toolCallId,
144
+ data: {
145
+ runId: chunk.runId,
146
+ toolCallId: chunk.payload.toolCallId,
147
+ toolName: chunk.payload.toolName,
148
+ suspendPayload: chunk.payload.suspendPayload
149
+ }
150
+ };
129
151
  case "tool-call-input-streaming-start":
130
152
  return {
131
153
  type: "tool-input-start",
@@ -216,6 +238,13 @@ function convertMastraChunkToAISDKv5({
216
238
  type: "object",
217
239
  object: chunk.object
218
240
  };
241
+ case "tripwire":
242
+ return {
243
+ type: "data-tripwire",
244
+ data: {
245
+ tripwireReason: chunk.payload.tripwireReason
246
+ }
247
+ };
219
248
  default:
220
249
  if (chunk.type && "payload" in chunk && chunk.payload) {
221
250
  return {
@@ -271,6 +300,14 @@ function convertFullStreamChunkToUIMessageStream({
271
300
  };
272
301
  }
273
302
  case "reasoning-delta": {
303
+ if (sendReasoning) {
304
+ return {
305
+ type: "reasoning-delta",
306
+ id: part.id,
307
+ delta: part.text,
308
+ ...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {}
309
+ };
310
+ }
274
311
  return;
275
312
  }
276
313
  case "reasoning-end": {
@@ -288,6 +325,25 @@ function convertFullStreamChunkToUIMessageStream({
288
325
  };
289
326
  }
290
327
  case "source": {
328
+ if (sendSources && part.sourceType === "url") {
329
+ return {
330
+ type: "source-url",
331
+ sourceId: part.id,
332
+ url: part.url,
333
+ title: part.title,
334
+ ...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {}
335
+ };
336
+ }
337
+ if (sendSources && part.sourceType === "document") {
338
+ return {
339
+ type: "source-document",
340
+ sourceId: part.id,
341
+ mediaType: part.mediaType,
342
+ title: part.title,
343
+ filename: part.filename,
344
+ ...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {}
345
+ };
346
+ }
291
347
  return;
292
348
  }
293
349
  case "tool-input-start": {
@@ -378,21 +434,23 @@ function convertFullStreamChunkToUIMessageStream({
378
434
  return { type: "finish-step" };
379
435
  }
380
436
  case "start": {
381
- {
437
+ if (sendStart) {
382
438
  return {
383
439
  type: "start",
384
440
  ...messageMetadataValue != null ? { messageMetadata: messageMetadataValue } : {},
385
441
  ...responseMessageId != null ? { messageId: responseMessageId } : {}
386
442
  };
387
443
  }
444
+ return;
388
445
  }
389
446
  case "finish": {
390
- {
447
+ if (sendFinish) {
391
448
  return {
392
449
  type: "finish",
393
450
  ...messageMetadataValue != null ? { messageMetadata: messageMetadataValue } : {}
394
451
  };
395
452
  }
453
+ return;
396
454
  }
397
455
  case "abort": {
398
456
  return part;
@@ -457,17 +515,31 @@ function AgentNetworkToAISDKTransformer() {
457
515
  }
458
516
  });
459
517
  }
460
- function AgentStreamToAISDKTransformer(lastMessageId) {
518
+ function AgentStreamToAISDKTransformer({
519
+ lastMessageId,
520
+ sendStart,
521
+ sendFinish,
522
+ sendReasoning,
523
+ sendSources
524
+ }) {
461
525
  let bufferedSteps = /* @__PURE__ */ new Map();
526
+ let tripwireOccurred = false;
527
+ let finishEventSent = false;
462
528
  return new TransformStream({
463
529
  transform(chunk, controller) {
530
+ if (chunk.type === "tripwire") {
531
+ tripwireOccurred = true;
532
+ }
533
+ if (chunk.type === "finish") {
534
+ finishEventSent = true;
535
+ }
464
536
  const part = convertMastraChunkToAISDKv5({ chunk, mode: "stream" });
465
537
  const transformedChunk = convertFullStreamChunkToUIMessageStream({
466
538
  part,
467
- sendReasoning: false,
468
- sendSources: false,
469
- sendStart: true,
470
- sendFinish: true,
539
+ sendReasoning,
540
+ sendSources,
541
+ sendStart,
542
+ sendFinish,
471
543
  responseMessageId: lastMessageId,
472
544
  onError() {
473
545
  return "Error";
@@ -490,6 +562,14 @@ function AgentStreamToAISDKTransformer(lastMessageId) {
490
562
  controller.enqueue(transformedChunk);
491
563
  }
492
564
  }
565
+ },
566
+ flush(controller) {
567
+ if (tripwireOccurred && !finishEventSent && sendFinish) {
568
+ controller.enqueue({
569
+ type: "finish",
570
+ finishReason: "other"
571
+ });
572
+ }
493
573
  }
494
574
  });
495
575
  }
@@ -976,7 +1056,11 @@ function transformNetwork(payload, bufferedNetworks, isNested) {
976
1056
  }
977
1057
 
978
1058
  // src/to-ai-sdk-format.ts
979
- function toAISdkFormat(stream, options = { from: "agent" }) {
1059
+ function toAISdkFormat(stream, options = {
1060
+ from: "agent",
1061
+ sendStart: true,
1062
+ sendFinish: true
1063
+ }) {
980
1064
  const from = options?.from;
981
1065
  if (from === "workflow") {
982
1066
  return stream.pipeThrough(WorkflowStreamToAISDKTransformer());
@@ -985,14 +1069,26 @@ function toAISdkFormat(stream, options = { from: "agent" }) {
985
1069
  return stream.pipeThrough(AgentNetworkToAISDKTransformer());
986
1070
  }
987
1071
  const agentReadable = "fullStream" in stream ? stream.fullStream : stream;
988
- return agentReadable.pipeThrough(AgentStreamToAISDKTransformer(options?.lastMessageId));
1072
+ return agentReadable.pipeThrough(
1073
+ AgentStreamToAISDKTransformer({
1074
+ lastMessageId: options?.lastMessageId,
1075
+ sendStart: options?.sendStart,
1076
+ sendFinish: options?.sendFinish,
1077
+ sendReasoning: options?.sendReasoning,
1078
+ sendSources: options?.sendSources
1079
+ })
1080
+ );
989
1081
  }
990
1082
 
991
1083
  // src/chat-route.ts
992
1084
  function chatRoute({
993
1085
  path = "/chat/:agentId",
994
1086
  agent,
995
- defaultOptions
1087
+ defaultOptions,
1088
+ sendStart = true,
1089
+ sendFinish = true,
1090
+ sendReasoning = false,
1091
+ sendSources = false
996
1092
  }) {
997
1093
  if (!agent && !path.includes("/:agentId")) {
998
1094
  throw new Error("Path must include :agentId to route to the correct agent or pass the agent explicitly");
@@ -1126,7 +1222,14 @@ function chatRoute({
1126
1222
  const uiMessageStream = ai.createUIMessageStream({
1127
1223
  originalMessages: messages,
1128
1224
  execute: async ({ writer }) => {
1129
- for await (const part of toAISdkFormat(result, { from: "agent", lastMessageId })) {
1225
+ for await (const part of toAISdkFormat(result, {
1226
+ from: "agent",
1227
+ lastMessageId,
1228
+ sendStart,
1229
+ sendFinish,
1230
+ sendReasoning,
1231
+ sendSources
1232
+ })) {
1130
1233
  writer.write(part);
1131
1234
  }
1132
1235
  }
@@ -1170,7 +1273,7 @@ function workflowRoute({
1170
1273
  resourceId: { type: "string" },
1171
1274
  inputData: { type: "object", additionalProperties: true },
1172
1275
  resumeData: { type: "object", additionalProperties: true },
1173
- requestContext: { type: "object", additionalProperties: true },
1276
+ runtimeContext: { type: "object", additionalProperties: true },
1174
1277
  tracingOptions: { type: "object", additionalProperties: true },
1175
1278
  step: { type: "string" }
1176
1279
  }