@mastra/ai-sdk 1.4.0 → 1.4.1-alpha.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/dist/index.d.ts CHANGED
@@ -2,7 +2,7 @@ export { chatRoute, handleChatStream } from './chat-route.js';
2
2
  export type { chatRouteOptions, ChatStreamHandlerParams, ChatStreamHandlerOptions, AgentVersionOptions, } from './chat-route.js';
3
3
  export { workflowRoute, handleWorkflowStream } from './workflow-route.js';
4
4
  export type { WorkflowRouteOptions, WorkflowStreamHandlerParams, WorkflowStreamHandlerOptions } from './workflow-route.js';
5
- export type { WorkflowDataPart } from './transformers.js';
5
+ export type { WorkflowDataPart, WorkflowStepDataPart } from './transformers.js';
6
6
  export { networkRoute, handleNetworkStream } from './network-route.js';
7
7
  export type { NetworkRouteOptions, NetworkStreamHandlerParams, NetworkStreamHandlerOptions } from './network-route.js';
8
8
  export type { NetworkDataPart } from './transformers.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAC3D,YAAY,EACV,gBAAgB,EAChB,uBAAuB,EACvB,wBAAwB,EACxB,mBAAmB,GACpB,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AACvE,YAAY,EAAE,oBAAoB,EAAE,2BAA2B,EAAE,4BAA4B,EAAE,MAAM,kBAAkB,CAAC;AACxH,YAAY,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AACvD,OAAO,EAAE,YAAY,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AACpE,YAAY,EAAE,mBAAmB,EAAE,0BAA0B,EAAE,2BAA2B,EAAE,MAAM,iBAAiB,CAAC;AACpH,YAAY,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACtD,YAAY,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAEpD,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAGnE,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,YAAY,EAAE,iBAAiB,EAAE,uBAAuB,EAAE,+BAA+B,EAAE,MAAM,cAAc,CAAC;AAGhH,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAC3D,YAAY,EACV,gBAAgB,EAChB,uBAAuB,EACvB,wBAAwB,EACxB,mBAAmB,GACpB,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AACvE,YAAY,EAAE,oBAAoB,EAAE,2BAA2B,EAAE,4BAA4B,EAAE,MAAM,kBAAkB,CAAC;AACxH,YAAY,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AAC7E,OAAO,EAAE,YAAY,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AACpE,YAAY,EAAE,mBAAmB,EAAE,0BAA0B,EAAE,2BAA2B,EAAE,MAAM,iBAAiB,CAAC;AACpH,YAAY,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACtD,YAAY,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAEpD,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAGnE,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,YAAY,EAAE,iBAAiB,EAAE,uBAAuB,EAAE,+BAA+B,EAAE,MAAM,cAAc,CAAC;AAGhH,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC"}
package/dist/index.js CHANGED
@@ -11595,6 +11595,7 @@ var isWorkflowExecutionDataChunkType = (chunk) => {
11595
11595
  };
11596
11596
 
11597
11597
  // src/helpers.ts
11598
+ var APPROVAL_ID_SEPARATOR = "::";
11598
11599
  function toAISDKFinishReason(reason) {
11599
11600
  if (reason === "tripwire" || reason === "retry") {
11600
11601
  return "other";
@@ -11931,6 +11932,27 @@ function convertMastraChunkToAISDKv6({
11931
11932
  chunk,
11932
11933
  mode = "stream"
11933
11934
  }) {
11935
+ if (chunk.type === "tool-call-approval") {
11936
+ return [
11937
+ {
11938
+ type: "tool-approval-request",
11939
+ approvalId: `${chunk.runId}${APPROVAL_ID_SEPARATOR}${chunk.payload.toolCallId}`,
11940
+ toolCallId: chunk.payload.toolCallId
11941
+ },
11942
+ {
11943
+ type: "data-tool-call-approval",
11944
+ id: chunk.payload.toolCallId,
11945
+ data: {
11946
+ state: "data-tool-call-approval",
11947
+ runId: chunk.runId,
11948
+ toolCallId: chunk.payload.toolCallId,
11949
+ toolName: chunk.payload.toolName,
11950
+ args: chunk.payload.args,
11951
+ resumeSchema: chunk.payload.resumeSchema
11952
+ }
11953
+ }
11954
+ ];
11955
+ }
11934
11956
  return convertMastraChunkToAISDKBase({
11935
11957
  chunk,
11936
11958
  mode,
@@ -12061,6 +12083,13 @@ function convertFullStreamChunkToUIMessageStream({
12061
12083
  ...part.dynamic != null ? { dynamic: part.dynamic } : {}
12062
12084
  };
12063
12085
  }
12086
+ case "tool-approval-request": {
12087
+ return {
12088
+ type: "tool-approval-request",
12089
+ approvalId: part.approvalId,
12090
+ toolCallId: part.toolCallId
12091
+ };
12092
+ }
12064
12093
  case "tool-result": {
12065
12094
  return {
12066
12095
  type: "tool-output-available",
@@ -12169,6 +12198,45 @@ function convertFullStreamChunkToUIMessageStream({
12169
12198
 
12170
12199
  // src/transformers.ts
12171
12200
  var PRIMITIVE_CACHE_SYMBOL = /* @__PURE__ */ Symbol("primitive-cache");
12201
+ function cloneWorkflowStep(step, includeOutput) {
12202
+ return {
12203
+ name: step.name,
12204
+ status: step.status,
12205
+ input: step.input,
12206
+ output: includeOutput ? step.output : null,
12207
+ suspendPayload: step.suspendPayload,
12208
+ resumePayload: step.resumePayload
12209
+ };
12210
+ }
12211
+ function serializeWorkflowSteps(steps, { includeOutputs }) {
12212
+ return Object.fromEntries(Object.entries(steps).map(([id, step]) => [id, cloneWorkflowStep(step, includeOutputs)]));
12213
+ }
12214
+ function createWorkflowDataPart(args) {
12215
+ const { current, isNested, runId, status, includeOutputs = false, output = null } = args;
12216
+ return {
12217
+ type: isNested ? "data-tool-workflow" : "data-workflow",
12218
+ id: runId,
12219
+ data: {
12220
+ name: current.name,
12221
+ status,
12222
+ steps: serializeWorkflowSteps(current.steps, { includeOutputs }),
12223
+ output
12224
+ }
12225
+ };
12226
+ }
12227
+ function createWorkflowStepDataPart(args) {
12228
+ const { current, isNested, runId, status, stepId } = args;
12229
+ return {
12230
+ type: isNested ? "data-tool-workflow-step" : "data-workflow-step",
12231
+ id: `${runId}:${stepId}`,
12232
+ data: {
12233
+ name: current.name,
12234
+ status,
12235
+ stepId,
12236
+ step: cloneWorkflowStep(current.steps[stepId], true)
12237
+ }
12238
+ };
12239
+ }
12172
12240
  function createWorkflowStreamToAISDKTransformer(convertMastraChunkToAISDK, {
12173
12241
  includeTextStreamParts,
12174
12242
  sendReasoning,
@@ -12198,7 +12266,15 @@ function createWorkflowStreamToAISDKTransformer(convertMastraChunkToAISDK, {
12198
12266
  },
12199
12267
  convertMastraChunkToAISDK
12200
12268
  );
12201
- if (transformed) controller.enqueue(transformed);
12269
+ if (transformed) {
12270
+ if (Array.isArray(transformed)) {
12271
+ for (const item of transformed) {
12272
+ controller.enqueue(item);
12273
+ }
12274
+ } else {
12275
+ controller.enqueue(transformed);
12276
+ }
12277
+ }
12202
12278
  }
12203
12279
  });
12204
12280
  }
@@ -12286,41 +12362,64 @@ function createAgentStreamToAISDKTransformer(convertMastraChunkToAISDK, {
12286
12362
  });
12287
12363
  }
12288
12364
  const part = convertMastraChunkToAISDK({ chunk, mode: "stream" });
12289
- const transformedChunk = convertFullStreamChunkToUIMessageStream({
12290
- part,
12291
- sendReasoning,
12292
- sendSources,
12293
- messageMetadataValue: part ? messageMetadata?.({ part }) : void 0,
12294
- sendStart,
12295
- sendFinish,
12296
- responseMessageId: lastMessageId,
12297
- onError(error) {
12298
- return onError ? onError(error) : safeParseErrorObject(error);
12365
+ const enqueueTransformedPart = (p) => {
12366
+ const transformedChunk = convertFullStreamChunkToUIMessageStream({
12367
+ part: p,
12368
+ sendReasoning,
12369
+ sendSources,
12370
+ messageMetadataValue: p ? messageMetadata?.({ part: p }) : void 0,
12371
+ sendStart,
12372
+ sendFinish,
12373
+ responseMessageId: lastMessageId,
12374
+ onError(error) {
12375
+ return onError ? onError(error) : safeParseErrorObject(error);
12376
+ }
12377
+ });
12378
+ if (transformedChunk) {
12379
+ if (transformedChunk.type === "tool-agent") {
12380
+ const payload = transformedChunk.payload;
12381
+ const agentTransformed = transformAgent(payload, bufferedSteps);
12382
+ if (agentTransformed) controller.enqueue(agentTransformed);
12383
+ } else if (transformedChunk.type === "tool-workflow") {
12384
+ const payload = transformedChunk.payload;
12385
+ const workflowChunk = transformWorkflow(
12386
+ payload,
12387
+ bufferedSteps,
12388
+ true,
12389
+ void 0,
12390
+ void 0,
12391
+ convertMastraChunkToAISDK
12392
+ );
12393
+ if (workflowChunk) {
12394
+ if (Array.isArray(workflowChunk)) {
12395
+ for (const item of workflowChunk) {
12396
+ controller.enqueue(item);
12397
+ }
12398
+ } else {
12399
+ controller.enqueue(workflowChunk);
12400
+ }
12401
+ }
12402
+ } else if (transformedChunk.type === "tool-network") {
12403
+ const payload = transformedChunk.payload;
12404
+ const networkChunk = transformNetwork(payload, bufferedSteps, true);
12405
+ if (Array.isArray(networkChunk)) {
12406
+ for (const c of networkChunk) {
12407
+ if (c) controller.enqueue(c);
12408
+ }
12409
+ } else if (networkChunk) {
12410
+ controller.enqueue(networkChunk);
12411
+ }
12412
+ } else {
12413
+ controller.enqueue(transformedChunk);
12414
+ }
12299
12415
  }
12300
- });
12301
- if (transformedChunk) {
12302
- if (transformedChunk.type === "tool-agent") {
12303
- const payload = transformedChunk.payload;
12304
- const agentTransformed = transformAgent(payload, bufferedSteps);
12305
- if (agentTransformed) controller.enqueue(agentTransformed);
12306
- } else if (transformedChunk.type === "tool-workflow") {
12307
- const payload = transformedChunk.payload;
12308
- const workflowChunk = transformWorkflow(
12309
- payload,
12310
- bufferedSteps,
12311
- true,
12312
- void 0,
12313
- void 0,
12314
- convertMastraChunkToAISDK
12315
- );
12316
- if (workflowChunk) controller.enqueue(workflowChunk);
12317
- } else if (transformedChunk.type === "tool-network") {
12318
- const payload = transformedChunk.payload;
12319
- const networkChunk = transformNetwork(payload, bufferedSteps, true);
12320
- if (networkChunk) controller.enqueue(networkChunk);
12321
- } else {
12322
- controller.enqueue(transformedChunk);
12416
+ };
12417
+ if (Array.isArray(part)) {
12418
+ for (const p of part) {
12419
+ enqueueTransformedPart(p);
12323
12420
  }
12421
+ } else {
12422
+ enqueueTransformedPart(part);
12324
12423
  }
12325
12424
  },
12326
12425
  flush(controller) {
@@ -12573,16 +12672,12 @@ function transformWorkflow(payload, bufferedWorkflows, isNested, includeTextStre
12573
12672
  name: payload.payload.workflowId,
12574
12673
  steps: {}
12575
12674
  });
12576
- return {
12577
- type: isNested ? "data-tool-workflow" : "data-workflow",
12578
- id: payload.runId,
12579
- data: {
12580
- name: bufferedWorkflows.get(payload.runId).name,
12581
- status: "running",
12582
- steps: bufferedWorkflows.get(payload.runId).steps,
12583
- output: null
12584
- }
12585
- };
12675
+ return createWorkflowDataPart({
12676
+ current: bufferedWorkflows.get(payload.runId),
12677
+ isNested,
12678
+ runId: payload.runId,
12679
+ status: "running"
12680
+ });
12586
12681
  case "workflow-step-start": {
12587
12682
  const current = bufferedWorkflows.get(payload.runId) || { name: "", steps: {} };
12588
12683
  current.steps[payload.payload.id] = {
@@ -12594,16 +12689,12 @@ function transformWorkflow(payload, bufferedWorkflows, isNested, includeTextStre
12594
12689
  resumePayload: null
12595
12690
  };
12596
12691
  bufferedWorkflows.set(payload.runId, current);
12597
- return {
12598
- type: isNested ? "data-tool-workflow" : "data-workflow",
12599
- id: payload.runId,
12600
- data: {
12601
- name: current.name,
12602
- status: "running",
12603
- steps: current.steps,
12604
- output: null
12605
- }
12606
- };
12692
+ return createWorkflowDataPart({
12693
+ current,
12694
+ isNested,
12695
+ runId: payload.runId,
12696
+ status: "running"
12697
+ });
12607
12698
  }
12608
12699
  case "workflow-step-result": {
12609
12700
  const current = bufferedWorkflows.get(payload.runId);
@@ -12613,16 +12704,21 @@ function transformWorkflow(payload, bufferedWorkflows, isNested, includeTextStre
12613
12704
  status: payload.payload.status,
12614
12705
  output: payload.payload.output ?? null
12615
12706
  };
12616
- return {
12617
- type: isNested ? "data-tool-workflow" : "data-workflow",
12618
- id: payload.runId,
12619
- data: {
12620
- name: current.name,
12707
+ return [
12708
+ createWorkflowDataPart({
12709
+ current,
12710
+ isNested,
12711
+ runId: payload.runId,
12712
+ status: "running"
12713
+ }),
12714
+ createWorkflowStepDataPart({
12715
+ current,
12716
+ isNested,
12717
+ runId: payload.runId,
12621
12718
  status: "running",
12622
- steps: current.steps,
12623
- output: null
12624
- }
12625
- };
12719
+ stepId: payload.payload.id
12720
+ })
12721
+ ];
12626
12722
  }
12627
12723
  case "workflow-step-suspended": {
12628
12724
  const current = bufferedWorkflows.get(payload.runId);
@@ -12634,35 +12730,50 @@ function transformWorkflow(payload, bufferedWorkflows, isNested, includeTextStre
12634
12730
  resumePayload: payload.payload.resumePayload ?? null,
12635
12731
  output: null
12636
12732
  };
12637
- return {
12638
- type: isNested ? "data-tool-workflow" : "data-workflow",
12639
- id: payload.runId,
12640
- data: {
12641
- name: current.name,
12733
+ return [
12734
+ createWorkflowDataPart({
12735
+ current,
12736
+ isNested,
12737
+ runId: payload.runId,
12738
+ status: "suspended"
12739
+ }),
12740
+ createWorkflowStepDataPart({
12741
+ current,
12742
+ isNested,
12743
+ runId: payload.runId,
12642
12744
  status: "suspended",
12643
- steps: current.steps,
12644
- output: null
12645
- }
12646
- };
12745
+ stepId: payload.payload.id
12746
+ })
12747
+ ];
12647
12748
  }
12648
12749
  case "workflow-finish": {
12649
12750
  const current = bufferedWorkflows.get(payload.runId);
12650
12751
  if (!current) return null;
12651
- return {
12652
- type: isNested ? "data-tool-workflow" : "data-workflow",
12653
- id: payload.runId,
12654
- data: {
12655
- name: current.name,
12656
- steps: current.steps,
12657
- output: payload.payload.output ?? null,
12658
- status: payload.payload.workflowStatus
12659
- }
12660
- };
12752
+ return createWorkflowDataPart({
12753
+ current,
12754
+ isNested,
12755
+ runId: payload.runId,
12756
+ status: payload.payload.workflowStatus,
12757
+ includeOutputs: true,
12758
+ output: payload.payload.output ?? null
12759
+ });
12661
12760
  }
12662
12761
  case "workflow-step-output": {
12663
12762
  const output = payload.payload.output;
12664
12763
  if (includeTextStreamParts && output && isMastraTextStreamChunk(output)) {
12665
12764
  const part = convertMastraChunkToAISDK({ chunk: output, mode: "stream" });
12765
+ if (Array.isArray(part)) {
12766
+ return part.map(
12767
+ (p) => convertFullStreamChunkToUIMessageStream({
12768
+ part: p,
12769
+ sendReasoning: streamOptions?.sendReasoning,
12770
+ sendSources: streamOptions?.sendSources,
12771
+ onError(error) {
12772
+ return safeParseErrorObject(error);
12773
+ }
12774
+ })
12775
+ ).filter(Boolean);
12776
+ }
12666
12777
  const transformedChunk = convertFullStreamChunkToUIMessageStream({
12667
12778
  part,
12668
12779
  sendReasoning: streamOptions?.sendReasoning,
@@ -13030,15 +13141,16 @@ function transformNetwork(payload, bufferedNetworks, isNested) {
13030
13141
  }
13031
13142
  step[PRIMITIVE_CACHE_SYMBOL] = step[PRIMITIVE_CACHE_SYMBOL] || /* @__PURE__ */ new Map();
13032
13143
  const result = transformWorkflow(payload.payload, step[PRIMITIVE_CACHE_SYMBOL]);
13033
- if (result && "data" in result) {
13034
- const data = result.data;
13144
+ const workflowResult = Array.isArray(result) ? result.find((item) => item?.type === "data-workflow" || item?.type === "data-tool-workflow") : result;
13145
+ if (workflowResult && "data" in workflowResult) {
13146
+ const data = workflowResult.data;
13035
13147
  step.task = data;
13036
13148
  if (data.name && step.task) {
13037
13149
  step.task.id = data.name;
13038
13150
  }
13039
13151
  }
13040
13152
  bufferedNetworks.set(payload.runId, current);
13041
- return {
13153
+ const networkChunk = {
13042
13154
  type: isNested ? "data-tool-network" : "data-network",
13043
13155
  id: payload.runId,
13044
13156
  data: {
@@ -13046,6 +13158,10 @@ function transformNetwork(payload, bufferedNetworks, isNested) {
13046
13158
  status: "running"
13047
13159
  }
13048
13160
  };
13161
+ if (Array.isArray(result)) {
13162
+ return [networkChunk, ...result.filter((r) => r != null)];
13163
+ }
13164
+ return networkChunk;
13049
13165
  }
13050
13166
  if (isDataChunkType(payload)) {
13051
13167
  if (!("data" in payload)) {
@@ -13160,6 +13276,32 @@ function toAISdkStream(stream, options = {
13160
13276
  }
13161
13277
 
13162
13278
  // src/chat-route.ts
13279
+ function extractV6NativeApproval(messages) {
13280
+ let lastAssistantMsg;
13281
+ for (let i = messages.length - 1; i >= 0; i--) {
13282
+ const message = messages[i];
13283
+ if (message.role === "assistant") {
13284
+ lastAssistantMsg = message;
13285
+ break;
13286
+ }
13287
+ }
13288
+ if (!lastAssistantMsg) return null;
13289
+ for (const part of lastAssistantMsg.parts ?? []) {
13290
+ if (!isToolUIPart2(part) || part.state !== "approval-responded") continue;
13291
+ const lastSep = part.approval.id.lastIndexOf(APPROVAL_ID_SEPARATOR);
13292
+ if (lastSep === -1) continue;
13293
+ const runId = part.approval.id.slice(0, lastSep);
13294
+ if (!runId) continue;
13295
+ return {
13296
+ resumeData: {
13297
+ approved: part.approval.approved,
13298
+ ...part.approval.reason != null ? { reason: part.approval.reason } : {}
13299
+ },
13300
+ runId
13301
+ };
13302
+ }
13303
+ return null;
13304
+ }
13163
13305
  async function handleChatStream({
13164
13306
  mastra,
13165
13307
  agentId,
@@ -13185,6 +13327,9 @@ async function handleChatStream({
13185
13327
  if (!Array.isArray(messages)) {
13186
13328
  throw new Error("Messages must be an array of UIMessage objects");
13187
13329
  }
13330
+ const nativeApproval = version === "v6" && !resumeData ? extractV6NativeApproval(messages) : null;
13331
+ const effectiveResumeData = nativeApproval?.resumeData ?? resumeData;
13332
+ const effectiveRunId = nativeApproval?.runId ?? runId;
13188
13333
  let lastMessageId;
13189
13334
  let messagesToSend = messages;
13190
13335
  if (messages.length > 0) {
@@ -13206,11 +13351,11 @@ async function handleChatStream({
13206
13351
  const baseOptions = {
13207
13352
  ...defaultOptionsRest,
13208
13353
  ...restOptions,
13209
- ...runId && { runId },
13354
+ ...effectiveRunId && { runId: effectiveRunId },
13210
13355
  requestContext: requestContext || defaultOptions3?.requestContext,
13211
13356
  ...Object.keys(mergedProviderOptions).length > 0 && { providerOptions: mergedProviderOptions }
13212
13357
  };
13213
- const result = resumeData ? structuredOutput ? await agentObj.resumeStream(resumeData, { ...baseOptions, structuredOutput }) : await agentObj.resumeStream(resumeData, baseOptions) : structuredOutput ? await agentObj.stream(messagesToSend, { ...baseOptions, structuredOutput }) : await agentObj.stream(messagesToSend, baseOptions);
13358
+ const result = effectiveResumeData ? structuredOutput ? await agentObj.resumeStream(effectiveResumeData, { ...baseOptions, structuredOutput }) : await agentObj.resumeStream(effectiveResumeData, baseOptions) : structuredOutput ? await agentObj.stream(messagesToSend, { ...baseOptions, structuredOutput }) : await agentObj.stream(messagesToSend, baseOptions);
13214
13359
  if (version === "v6") {
13215
13360
  return createUIMessageStream2({
13216
13361
  originalMessages: messages,