@mastra/ai-sdk 1.0.0-beta.4 → 1.0.0-beta.6

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,10 +1,10 @@
1
- export { chatRoute } from './chat-route.js';
2
- export type { chatRouteOptions } from './chat-route.js';
3
- export { workflowRoute } from './workflow-route.js';
4
- export type { WorkflowRouteOptions } from './workflow-route.js';
1
+ export { chatRoute, handleChatStream } from './chat-route.js';
2
+ export type { chatRouteOptions, ChatStreamHandlerParams, ChatStreamHandlerOptions } from './chat-route.js';
3
+ export { workflowRoute, handleWorkflowStream } from './workflow-route.js';
4
+ export type { WorkflowRouteOptions, WorkflowStreamHandlerParams, WorkflowStreamHandlerOptions } from './workflow-route.js';
5
5
  export type { WorkflowDataPart } from './transformers.js';
6
- export { networkRoute } from './network-route.js';
7
- export type { NetworkRouteOptions } from './network-route.js';
6
+ export { networkRoute, handleNetworkStream } from './network-route.js';
7
+ export type { NetworkRouteOptions, NetworkStreamHandlerParams, NetworkStreamHandlerOptions } from './network-route.js';
8
8
  export type { NetworkDataPart } from './transformers.js';
9
9
  export type { AgentDataPart } from './transformers.js';
10
10
  export { toAISdkV5Stream as toAISdkStream } from './convert-streams.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,YAAY,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AACrD,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,YAAY,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAC7D,YAAY,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AACvD,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,YAAY,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAC3D,YAAY,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACtD,YAAY,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAEpD,OAAO,EAAE,eAAe,IAAI,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAGrE,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,EAAE,gBAAgB,EAAE,uBAAuB,EAAE,wBAAwB,EAAE,MAAM,cAAc,CAAC;AACxG,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,eAAe,IAAI,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAGrE,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC"}
package/dist/index.js CHANGED
@@ -8,6 +8,31 @@ import { DefaultGeneratedFile, DefaultGeneratedFileWithType } from '@mastra/core
8
8
  var isDataChunkType = (chunk) => {
9
9
  return chunk && typeof chunk === "object" && "type" in chunk && chunk.type?.startsWith("data-");
10
10
  };
11
+ var isMastraTextStreamChunk = (chunk) => {
12
+ return chunk && typeof chunk === "object" && "type" in chunk && typeof chunk.type === "string" && [
13
+ "text-start",
14
+ "text-delta",
15
+ "text-end",
16
+ "reasoning-start",
17
+ "reasoning-delta",
18
+ "reasoning-end",
19
+ "file",
20
+ "source",
21
+ "tool-input-start",
22
+ "tool-input-delta",
23
+ "tool-call",
24
+ "tool-result",
25
+ "tool-error",
26
+ "error",
27
+ "start-step",
28
+ "finish-step",
29
+ "start",
30
+ "finish",
31
+ "abort",
32
+ "tool-input-end",
33
+ "raw"
34
+ ].includes(chunk.type);
35
+ };
11
36
  function safeParseErrorObject(obj) {
12
37
  if (typeof obj !== "object" || obj === null) {
13
38
  return String(obj);
@@ -490,7 +515,9 @@ function convertFullStreamChunkToUIMessageStream({
490
515
 
491
516
  // src/transformers.ts
492
517
  var PRIMITIVE_CACHE_SYMBOL = Symbol("primitive-cache");
493
- function WorkflowStreamToAISDKTransformer() {
518
+ function WorkflowStreamToAISDKTransformer({
519
+ includeTextStreamParts
520
+ } = {}) {
494
521
  const bufferedWorkflows = /* @__PURE__ */ new Map();
495
522
  return new TransformStream({
496
523
  start(controller) {
@@ -504,7 +531,7 @@ function WorkflowStreamToAISDKTransformer() {
504
531
  });
505
532
  },
506
533
  transform(chunk, controller) {
507
- const transformed = transformWorkflow(chunk, bufferedWorkflows);
534
+ const transformed = transformWorkflow(chunk, bufferedWorkflows, false, includeTextStreamParts);
508
535
  if (transformed) controller.enqueue(transformed);
509
536
  }
510
537
  });
@@ -725,7 +752,7 @@ function transformAgent(payload, bufferedSteps) {
725
752
  }
726
753
  return null;
727
754
  }
728
- function transformWorkflow(payload, bufferedWorkflows, isNested) {
755
+ function transformWorkflow(payload, bufferedWorkflows, isNested, includeTextStreamParts) {
729
756
  switch (payload.type) {
730
757
  case "workflow-start":
731
758
  bufferedWorkflows.set(payload.runId, {
@@ -820,6 +847,16 @@ function transformWorkflow(payload, bufferedWorkflows, isNested) {
820
847
  }
821
848
  case "workflow-step-output": {
822
849
  const output = payload.payload.output;
850
+ if (includeTextStreamParts && output && isMastraTextStreamChunk(output)) {
851
+ const part = convertMastraChunkToAISDKv5({ chunk: output, mode: "stream" });
852
+ const transformedChunk = convertFullStreamChunkToUIMessageStream({
853
+ part,
854
+ onError(error) {
855
+ return safeParseErrorObject(error);
856
+ }
857
+ });
858
+ return transformedChunk;
859
+ }
823
860
  if (output && isDataChunkType(output)) {
824
861
  if (!("data" in output)) {
825
862
  throw new Error(
@@ -1120,7 +1157,7 @@ function transformNetwork(payload, bufferedNetworks, isNested) {
1120
1157
  }
1121
1158
  step[PRIMITIVE_CACHE_SYMBOL] = step[PRIMITIVE_CACHE_SYMBOL] || /* @__PURE__ */ new Map();
1122
1159
  const result = transformWorkflow(payload.payload, step[PRIMITIVE_CACHE_SYMBOL]);
1123
- if (result) {
1160
+ if (result && "data" in result) {
1124
1161
  const data = result.data;
1125
1162
  step.task = data;
1126
1163
  if (data.name && step.task) {
@@ -1171,7 +1208,10 @@ function toAISdkV5Stream(stream, options = {
1171
1208
  }) {
1172
1209
  const from = options?.from;
1173
1210
  if (from === "workflow") {
1174
- return stream.pipeThrough(WorkflowStreamToAISDKTransformer());
1211
+ const includeTextStreamParts = options?.includeTextStreamParts ?? true;
1212
+ return stream.pipeThrough(
1213
+ WorkflowStreamToAISDKTransformer({ includeTextStreamParts })
1214
+ );
1175
1215
  }
1176
1216
  if (from === "network") {
1177
1217
  return stream.pipeThrough(AgentNetworkToAISDKTransformer());
@@ -1191,6 +1231,57 @@ function toAISdkV5Stream(stream, options = {
1191
1231
  }
1192
1232
 
1193
1233
  // src/chat-route.ts
1234
+ async function handleChatStream({
1235
+ mastra,
1236
+ agentId,
1237
+ params,
1238
+ defaultOptions,
1239
+ sendStart = true,
1240
+ sendFinish = true,
1241
+ sendReasoning = false,
1242
+ sendSources = false
1243
+ }) {
1244
+ const { messages, resumeData, runId, requestContext, ...rest } = params;
1245
+ if (resumeData && !runId) {
1246
+ throw new Error("runId is required when resumeData is provided");
1247
+ }
1248
+ const agentObj = mastra.getAgentById(agentId);
1249
+ if (!agentObj) {
1250
+ throw new Error(`Agent ${agentId} not found`);
1251
+ }
1252
+ if (!Array.isArray(messages)) {
1253
+ throw new Error("Messages must be an array of UIMessage objects");
1254
+ }
1255
+ const mergedOptions = {
1256
+ ...defaultOptions,
1257
+ ...rest,
1258
+ ...runId && { runId },
1259
+ requestContext: requestContext || defaultOptions?.requestContext
1260
+ };
1261
+ const result = resumeData ? await agentObj.resumeStream(resumeData, mergedOptions) : await agentObj.stream(messages, mergedOptions);
1262
+ let lastMessageId;
1263
+ if (messages.length) {
1264
+ const lastMessage = messages[messages.length - 1];
1265
+ if (lastMessage?.role === "assistant") {
1266
+ lastMessageId = lastMessage.id;
1267
+ }
1268
+ }
1269
+ return createUIMessageStream({
1270
+ originalMessages: messages,
1271
+ execute: async ({ writer }) => {
1272
+ for await (const part of toAISdkV5Stream(result, {
1273
+ from: "agent",
1274
+ lastMessageId,
1275
+ sendStart,
1276
+ sendFinish,
1277
+ sendReasoning,
1278
+ sendSources
1279
+ })) {
1280
+ writer.write(part);
1281
+ }
1282
+ }
1283
+ });
1284
+ }
1194
1285
  function chatRoute({
1195
1286
  path = "/chat/:agentId",
1196
1287
  agent,
@@ -1227,6 +1318,14 @@ function chatRoute({
1227
1318
  schema: {
1228
1319
  type: "object",
1229
1320
  properties: {
1321
+ resumeData: {
1322
+ type: "object",
1323
+ description: "Resume data for the agent"
1324
+ },
1325
+ runId: {
1326
+ type: "string",
1327
+ description: "The run ID required when resuming an agent execution"
1328
+ },
1230
1329
  messages: {
1231
1330
  type: "array",
1232
1331
  description: "Array of messages in the conversation",
@@ -1297,9 +1396,9 @@ function chatRoute({
1297
1396
  }
1298
1397
  },
1299
1398
  handler: async (c) => {
1300
- const { messages, ...rest } = await c.req.json();
1399
+ const params = await c.req.json();
1301
1400
  const mastra = c.get("mastra");
1302
- const requestContext = c.get("requestContext");
1401
+ const contextRequestContext = c.get("requestContext");
1303
1402
  let agentToUse = agent;
1304
1403
  if (!agent) {
1305
1404
  const agentId = c.req.param("agentId");
@@ -1310,39 +1409,24 @@ function chatRoute({
1310
1409
  `Fixed agent ID was set together with an agentId path parameter. This can lead to unexpected behavior.`
1311
1410
  );
1312
1411
  }
1313
- if (requestContext && defaultOptions?.requestContext) {
1412
+ if (contextRequestContext && defaultOptions?.requestContext) {
1314
1413
  mastra.getLogger()?.warn(`"requestContext" set in the route options will be overridden by the request's "requestContext".`);
1315
1414
  }
1316
1415
  if (!agentToUse) {
1317
1416
  throw new Error("Agent ID is required");
1318
1417
  }
1319
- const agentObj = mastra.getAgentById(agentToUse);
1320
- if (!agentObj) {
1321
- throw new Error(`Agent ${agentToUse} not found`);
1322
- }
1323
- const result = await agentObj.stream(messages, {
1324
- ...defaultOptions,
1325
- ...rest,
1326
- requestContext: requestContext || defaultOptions?.requestContext
1327
- });
1328
- let lastMessageId;
1329
- if (messages.length > 0 && messages[messages.length - 1].role === "assistant") {
1330
- lastMessageId = messages[messages.length - 1].id;
1331
- }
1332
- const uiMessageStream = createUIMessageStream({
1333
- originalMessages: messages,
1334
- execute: async ({ writer }) => {
1335
- for await (const part of toAISdkV5Stream(result, {
1336
- from: "agent",
1337
- lastMessageId,
1338
- sendStart,
1339
- sendFinish,
1340
- sendReasoning,
1341
- sendSources
1342
- })) {
1343
- writer.write(part);
1344
- }
1345
- }
1418
+ const uiMessageStream = await handleChatStream({
1419
+ mastra,
1420
+ agentId: agentToUse,
1421
+ params: {
1422
+ ...params,
1423
+ requestContext: contextRequestContext || params.requestContext
1424
+ },
1425
+ defaultOptions,
1426
+ sendStart,
1427
+ sendFinish,
1428
+ sendReasoning,
1429
+ sendSources
1346
1430
  });
1347
1431
  return createUIMessageStreamResponse({
1348
1432
  stream: uiMessageStream
@@ -1350,9 +1434,31 @@ function chatRoute({
1350
1434
  }
1351
1435
  });
1352
1436
  }
1437
+ async function handleWorkflowStream({
1438
+ mastra,
1439
+ workflowId,
1440
+ params,
1441
+ includeTextStreamParts = true
1442
+ }) {
1443
+ const { runId, resourceId, inputData, resumeData, requestContext, ...rest } = params;
1444
+ const workflowObj = mastra.getWorkflowById(workflowId);
1445
+ if (!workflowObj) {
1446
+ throw new Error(`Workflow ${workflowId} not found`);
1447
+ }
1448
+ const run = await workflowObj.createRun({ runId, resourceId, ...rest });
1449
+ const stream = resumeData ? run.resumeStream({ resumeData, ...rest, requestContext }) : run.stream({ inputData, ...rest, requestContext });
1450
+ return createUIMessageStream({
1451
+ execute: async ({ writer }) => {
1452
+ for await (const part of toAISdkV5Stream(stream, { from: "workflow", includeTextStreamParts })) {
1453
+ writer.write(part);
1454
+ }
1455
+ }
1456
+ });
1457
+ }
1353
1458
  function workflowRoute({
1354
1459
  path = "/api/workflows/:workflowId/stream",
1355
- workflow
1460
+ workflow,
1461
+ includeTextStreamParts = true
1356
1462
  }) {
1357
1463
  if (!workflow && !path.includes("/:workflowId")) {
1358
1464
  throw new Error("Path must include :workflowId to route to the correct workflow or pass the workflow explicitly");
@@ -1403,9 +1509,9 @@ function workflowRoute({
1403
1509
  }
1404
1510
  },
1405
1511
  handler: async (c) => {
1406
- const { runId, resourceId, inputData, resumeData, ...rest } = await c.req.json();
1512
+ const params = await c.req.json();
1407
1513
  const mastra = c.get("mastra");
1408
- const requestContext = c.get("requestContext");
1514
+ const contextRequestContext = c.get("requestContext");
1409
1515
  let workflowToUse = workflow;
1410
1516
  if (!workflow) {
1411
1517
  const workflowId = c.req.param("workflowId");
@@ -1419,28 +1525,47 @@ function workflowRoute({
1419
1525
  if (!workflowToUse) {
1420
1526
  throw new Error("Workflow ID is required");
1421
1527
  }
1422
- const workflowObj = mastra.getWorkflowById(workflowToUse);
1423
- if (!workflowObj) {
1424
- throw new Error(`Workflow ${workflowToUse} not found`);
1425
- }
1426
- if (requestContext && rest.requestContext) {
1528
+ if (contextRequestContext && params.requestContext) {
1427
1529
  mastra.getLogger()?.warn(
1428
1530
  `"requestContext" from the request body will be ignored because "requestContext" is already set in the route options.`
1429
1531
  );
1430
1532
  }
1431
- const run = await workflowObj.createRun({ runId, resourceId, ...rest });
1432
- const stream = resumeData ? run.resumeStream({ resumeData, ...rest, requestContext: requestContext || rest.requestContext }) : run.stream({ inputData, ...rest, requestContext: requestContext || rest.requestContext });
1433
- const uiMessageStream = createUIMessageStream({
1434
- execute: async ({ writer }) => {
1435
- for await (const part of toAISdkV5Stream(stream, { from: "workflow" })) {
1436
- writer.write(part);
1437
- }
1438
- }
1533
+ const uiMessageStream = await handleWorkflowStream({
1534
+ mastra,
1535
+ workflowId: workflowToUse,
1536
+ params: {
1537
+ ...params,
1538
+ requestContext: contextRequestContext || params.requestContext
1539
+ },
1540
+ includeTextStreamParts
1439
1541
  });
1440
1542
  return createUIMessageStreamResponse({ stream: uiMessageStream });
1441
1543
  }
1442
1544
  });
1443
1545
  }
1546
+ async function handleNetworkStream({
1547
+ mastra,
1548
+ agentId,
1549
+ params,
1550
+ defaultOptions
1551
+ }) {
1552
+ const { messages, ...rest } = params;
1553
+ const agentObj = mastra.getAgentById(agentId);
1554
+ if (!agentObj) {
1555
+ throw new Error(`Agent ${agentId} not found`);
1556
+ }
1557
+ const result = await agentObj.network(messages, {
1558
+ ...defaultOptions,
1559
+ ...rest
1560
+ });
1561
+ return createUIMessageStream({
1562
+ execute: async ({ writer }) => {
1563
+ for await (const part of toAISdkV5Stream(result, { from: "network" })) {
1564
+ writer.write(part);
1565
+ }
1566
+ }
1567
+ });
1568
+ }
1444
1569
  function networkRoute({
1445
1570
  path = "/network/:agentId",
1446
1571
  agent,
@@ -1501,7 +1626,7 @@ function networkRoute({
1501
1626
  }
1502
1627
  },
1503
1628
  handler: async (c) => {
1504
- const { messages, ...rest } = await c.req.json();
1629
+ const params = await c.req.json();
1505
1630
  const mastra = c.get("mastra");
1506
1631
  let agentToUse = agent;
1507
1632
  if (!agent) {
@@ -1516,20 +1641,11 @@ function networkRoute({
1516
1641
  if (!agentToUse) {
1517
1642
  throw new Error("Agent ID is required");
1518
1643
  }
1519
- const agentObj = mastra.getAgentById(agentToUse);
1520
- if (!agentObj) {
1521
- throw new Error(`Agent ${agentToUse} not found`);
1522
- }
1523
- const result = await agentObj.network(messages, {
1524
- ...defaultOptions,
1525
- ...rest
1526
- });
1527
- const uiMessageStream = createUIMessageStream({
1528
- execute: async ({ writer }) => {
1529
- for await (const part of toAISdkV5Stream(result, { from: "network" })) {
1530
- writer.write(part);
1531
- }
1532
- }
1644
+ const uiMessageStream = await handleNetworkStream({
1645
+ mastra,
1646
+ agentId: agentToUse,
1647
+ params,
1648
+ defaultOptions
1533
1649
  });
1534
1650
  return createUIMessageStreamResponse({ stream: uiMessageStream });
1535
1651
  }
@@ -1543,6 +1659,6 @@ function toAISdkFormat() {
1543
1659
  );
1544
1660
  }
1545
1661
 
1546
- export { chatRoute, networkRoute, toAISdkFormat, toAISdkV5Stream as toAISdkStream, workflowRoute };
1662
+ export { chatRoute, handleChatStream, handleNetworkStream, handleWorkflowStream, networkRoute, toAISdkFormat, toAISdkV5Stream as toAISdkStream, workflowRoute };
1547
1663
  //# sourceMappingURL=index.js.map
1548
1664
  //# sourceMappingURL=index.js.map