@mastra/ai-sdk 0.2.7 → 1.0.0-alpha.0

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,22 @@
1
1
  # @mastra/ai-sdk
2
2
 
3
+ ## 1.0.0-alpha.0
4
+
5
+ ### Major Changes
6
+
7
+ - 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))
8
+
9
+ BREAKING CHANGE: AgentStreamToAISDKTransformer now accepts an options object instead of a single lastMessageId parameter
10
+
11
+ Also, add sendStart, sendFinish, sendReasoning, and sendSources parameters to
12
+ chatRoute function, enabling fine-grained control over which chunks are
13
+ included in the AI SDK stream output.
14
+
15
+ ### Patch Changes
16
+
17
+ - 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)]:
18
+ - @mastra/core@0.24.2-alpha.0
19
+
3
20
  ## 0.2.7
4
21
 
5
22
  ### 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/index.cjs CHANGED
@@ -271,6 +271,14 @@ function convertFullStreamChunkToUIMessageStream({
271
271
  };
272
272
  }
273
273
  case "reasoning-delta": {
274
+ if (sendReasoning) {
275
+ return {
276
+ type: "reasoning-delta",
277
+ id: part.id,
278
+ delta: part.text,
279
+ ...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {}
280
+ };
281
+ }
274
282
  return;
275
283
  }
276
284
  case "reasoning-end": {
@@ -288,6 +296,25 @@ function convertFullStreamChunkToUIMessageStream({
288
296
  };
289
297
  }
290
298
  case "source": {
299
+ if (sendSources && part.sourceType === "url") {
300
+ return {
301
+ type: "source-url",
302
+ sourceId: part.id,
303
+ url: part.url,
304
+ title: part.title,
305
+ ...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {}
306
+ };
307
+ }
308
+ if (sendSources && part.sourceType === "document") {
309
+ return {
310
+ type: "source-document",
311
+ sourceId: part.id,
312
+ mediaType: part.mediaType,
313
+ title: part.title,
314
+ filename: part.filename,
315
+ ...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {}
316
+ };
317
+ }
291
318
  return;
292
319
  }
293
320
  case "tool-input-start": {
@@ -378,21 +405,23 @@ function convertFullStreamChunkToUIMessageStream({
378
405
  return { type: "finish-step" };
379
406
  }
380
407
  case "start": {
381
- {
408
+ if (sendStart) {
382
409
  return {
383
410
  type: "start",
384
411
  ...messageMetadataValue != null ? { messageMetadata: messageMetadataValue } : {},
385
412
  ...responseMessageId != null ? { messageId: responseMessageId } : {}
386
413
  };
387
414
  }
415
+ return;
388
416
  }
389
417
  case "finish": {
390
- {
418
+ if (sendFinish) {
391
419
  return {
392
420
  type: "finish",
393
421
  ...messageMetadataValue != null ? { messageMetadata: messageMetadataValue } : {}
394
422
  };
395
423
  }
424
+ return;
396
425
  }
397
426
  case "abort": {
398
427
  return part;
@@ -457,17 +486,23 @@ function AgentNetworkToAISDKTransformer() {
457
486
  }
458
487
  });
459
488
  }
460
- function AgentStreamToAISDKTransformer(lastMessageId) {
489
+ function AgentStreamToAISDKTransformer({
490
+ lastMessageId,
491
+ sendStart,
492
+ sendFinish,
493
+ sendReasoning,
494
+ sendSources
495
+ }) {
461
496
  let bufferedSteps = /* @__PURE__ */ new Map();
462
497
  return new TransformStream({
463
498
  transform(chunk, controller) {
464
499
  const part = convertMastraChunkToAISDKv5({ chunk, mode: "stream" });
465
500
  const transformedChunk = convertFullStreamChunkToUIMessageStream({
466
501
  part,
467
- sendReasoning: false,
468
- sendSources: false,
469
- sendStart: true,
470
- sendFinish: true,
502
+ sendReasoning,
503
+ sendSources,
504
+ sendStart,
505
+ sendFinish,
471
506
  responseMessageId: lastMessageId,
472
507
  onError() {
473
508
  return "Error";
@@ -976,7 +1011,11 @@ function transformNetwork(payload, bufferedNetworks, isNested) {
976
1011
  }
977
1012
 
978
1013
  // src/to-ai-sdk-format.ts
979
- function toAISdkFormat(stream, options = { from: "agent" }) {
1014
+ function toAISdkFormat(stream, options = {
1015
+ from: "agent",
1016
+ sendStart: true,
1017
+ sendFinish: true
1018
+ }) {
980
1019
  const from = options?.from;
981
1020
  if (from === "workflow") {
982
1021
  return stream.pipeThrough(WorkflowStreamToAISDKTransformer());
@@ -985,14 +1024,26 @@ function toAISdkFormat(stream, options = { from: "agent" }) {
985
1024
  return stream.pipeThrough(AgentNetworkToAISDKTransformer());
986
1025
  }
987
1026
  const agentReadable = "fullStream" in stream ? stream.fullStream : stream;
988
- return agentReadable.pipeThrough(AgentStreamToAISDKTransformer(options?.lastMessageId));
1027
+ return agentReadable.pipeThrough(
1028
+ AgentStreamToAISDKTransformer({
1029
+ lastMessageId: options?.lastMessageId,
1030
+ sendStart: options?.sendStart,
1031
+ sendFinish: options?.sendFinish,
1032
+ sendReasoning: options?.sendReasoning,
1033
+ sendSources: options?.sendSources
1034
+ })
1035
+ );
989
1036
  }
990
1037
 
991
1038
  // src/chat-route.ts
992
1039
  function chatRoute({
993
1040
  path = "/chat/:agentId",
994
1041
  agent,
995
- defaultOptions
1042
+ defaultOptions,
1043
+ sendStart = true,
1044
+ sendFinish = true,
1045
+ sendReasoning = false,
1046
+ sendSources = false
996
1047
  }) {
997
1048
  if (!agent && !path.includes("/:agentId")) {
998
1049
  throw new Error("Path must include :agentId to route to the correct agent or pass the agent explicitly");
@@ -1126,7 +1177,14 @@ function chatRoute({
1126
1177
  const uiMessageStream = ai.createUIMessageStream({
1127
1178
  originalMessages: messages,
1128
1179
  execute: async ({ writer }) => {
1129
- for await (const part of toAISdkFormat(result, { from: "agent", lastMessageId })) {
1180
+ for await (const part of toAISdkFormat(result, {
1181
+ from: "agent",
1182
+ lastMessageId,
1183
+ sendStart,
1184
+ sendFinish,
1185
+ sendReasoning,
1186
+ sendSources
1187
+ })) {
1130
1188
  writer.write(part);
1131
1189
  }
1132
1190
  }
@@ -1170,7 +1228,7 @@ function workflowRoute({
1170
1228
  resourceId: { type: "string" },
1171
1229
  inputData: { type: "object", additionalProperties: true },
1172
1230
  resumeData: { type: "object", additionalProperties: true },
1173
- requestContext: { type: "object", additionalProperties: true },
1231
+ runtimeContext: { type: "object", additionalProperties: true },
1174
1232
  tracingOptions: { type: "object", additionalProperties: true },
1175
1233
  step: { type: "string" }
1176
1234
  }