@mastra/ai-sdk 0.0.0-fix-thread-list-20251105222841 → 0.0.0-fix-issue-10434-concurrent-write-corruption-20251124213939
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 +193 -3
- package/dist/chat-route.d.ts +52 -2
- package/dist/chat-route.d.ts.map +1 -1
- package/dist/convert-messages.d.ts +1 -1
- package/dist/convert-messages.d.ts.map +1 -1
- package/dist/convert-streams.d.ts +63 -1
- package/dist/convert-streams.d.ts.map +1 -1
- package/dist/helpers.d.ts +1 -1
- package/dist/helpers.d.ts.map +1 -1
- package/dist/index.cjs +155 -16
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +155 -16
- package/dist/index.js.map +1 -1
- package/dist/transformers.d.ts +10 -2
- package/dist/transformers.d.ts.map +1 -1
- package/dist/workflow-route.d.ts.map +1 -1
- package/package.json +8 -6
package/dist/index.js
CHANGED
|
@@ -138,6 +138,28 @@ function convertMastraChunkToAISDKv5({
|
|
|
138
138
|
toolName: chunk.payload.toolName,
|
|
139
139
|
input: chunk.payload.args
|
|
140
140
|
};
|
|
141
|
+
case "tool-call-approval":
|
|
142
|
+
return {
|
|
143
|
+
type: "data-tool-call-approval",
|
|
144
|
+
id: chunk.payload.toolCallId,
|
|
145
|
+
data: {
|
|
146
|
+
runId: chunk.runId,
|
|
147
|
+
toolCallId: chunk.payload.toolCallId,
|
|
148
|
+
toolName: chunk.payload.toolName,
|
|
149
|
+
args: chunk.payload.args
|
|
150
|
+
}
|
|
151
|
+
};
|
|
152
|
+
case "tool-call-suspended":
|
|
153
|
+
return {
|
|
154
|
+
type: "data-tool-call-suspended",
|
|
155
|
+
id: chunk.payload.toolCallId,
|
|
156
|
+
data: {
|
|
157
|
+
runId: chunk.runId,
|
|
158
|
+
toolCallId: chunk.payload.toolCallId,
|
|
159
|
+
toolName: chunk.payload.toolName,
|
|
160
|
+
suspendPayload: chunk.payload.suspendPayload
|
|
161
|
+
}
|
|
162
|
+
};
|
|
141
163
|
case "tool-call-input-streaming-start":
|
|
142
164
|
return {
|
|
143
165
|
type: "tool-input-start",
|
|
@@ -228,6 +250,13 @@ function convertMastraChunkToAISDKv5({
|
|
|
228
250
|
type: "object",
|
|
229
251
|
object: chunk.object
|
|
230
252
|
};
|
|
253
|
+
case "tripwire":
|
|
254
|
+
return {
|
|
255
|
+
type: "data-tripwire",
|
|
256
|
+
data: {
|
|
257
|
+
tripwireReason: chunk.payload.tripwireReason
|
|
258
|
+
}
|
|
259
|
+
};
|
|
231
260
|
default:
|
|
232
261
|
if (chunk.type && "payload" in chunk && chunk.payload) {
|
|
233
262
|
return {
|
|
@@ -283,6 +312,14 @@ function convertFullStreamChunkToUIMessageStream({
|
|
|
283
312
|
};
|
|
284
313
|
}
|
|
285
314
|
case "reasoning-delta": {
|
|
315
|
+
if (sendReasoning) {
|
|
316
|
+
return {
|
|
317
|
+
type: "reasoning-delta",
|
|
318
|
+
id: part.id,
|
|
319
|
+
delta: part.text,
|
|
320
|
+
...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {}
|
|
321
|
+
};
|
|
322
|
+
}
|
|
286
323
|
return;
|
|
287
324
|
}
|
|
288
325
|
case "reasoning-end": {
|
|
@@ -300,6 +337,25 @@ function convertFullStreamChunkToUIMessageStream({
|
|
|
300
337
|
};
|
|
301
338
|
}
|
|
302
339
|
case "source": {
|
|
340
|
+
if (sendSources && part.sourceType === "url") {
|
|
341
|
+
return {
|
|
342
|
+
type: "source-url",
|
|
343
|
+
sourceId: part.id,
|
|
344
|
+
url: part.url,
|
|
345
|
+
title: part.title,
|
|
346
|
+
...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {}
|
|
347
|
+
};
|
|
348
|
+
}
|
|
349
|
+
if (sendSources && part.sourceType === "document") {
|
|
350
|
+
return {
|
|
351
|
+
type: "source-document",
|
|
352
|
+
sourceId: part.id,
|
|
353
|
+
mediaType: part.mediaType,
|
|
354
|
+
title: part.title,
|
|
355
|
+
filename: part.filename,
|
|
356
|
+
...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {}
|
|
357
|
+
};
|
|
358
|
+
}
|
|
303
359
|
return;
|
|
304
360
|
}
|
|
305
361
|
case "tool-input-start": {
|
|
@@ -357,6 +413,14 @@ function convertFullStreamChunkToUIMessageStream({
|
|
|
357
413
|
toolCallId: part.toolCallId,
|
|
358
414
|
payload: part.output
|
|
359
415
|
};
|
|
416
|
+
} else if (isDataChunkType(part.output)) {
|
|
417
|
+
if (!("data" in part.output)) {
|
|
418
|
+
throw new Error(
|
|
419
|
+
`UI Messages require a data property when using data- prefixed chunks
|
|
420
|
+
${JSON.stringify(part)}`
|
|
421
|
+
);
|
|
422
|
+
}
|
|
423
|
+
return part.output;
|
|
360
424
|
}
|
|
361
425
|
return;
|
|
362
426
|
}
|
|
@@ -382,21 +446,23 @@ function convertFullStreamChunkToUIMessageStream({
|
|
|
382
446
|
return { type: "finish-step" };
|
|
383
447
|
}
|
|
384
448
|
case "start": {
|
|
385
|
-
{
|
|
449
|
+
if (sendStart) {
|
|
386
450
|
return {
|
|
387
451
|
type: "start",
|
|
388
452
|
...messageMetadataValue != null ? { messageMetadata: messageMetadataValue } : {},
|
|
389
453
|
...responseMessageId != null ? { messageId: responseMessageId } : {}
|
|
390
454
|
};
|
|
391
455
|
}
|
|
456
|
+
return;
|
|
392
457
|
}
|
|
393
458
|
case "finish": {
|
|
394
|
-
{
|
|
459
|
+
if (sendFinish) {
|
|
395
460
|
return {
|
|
396
461
|
type: "finish",
|
|
397
462
|
...messageMetadataValue != null ? { messageMetadata: messageMetadataValue } : {}
|
|
398
463
|
};
|
|
399
464
|
}
|
|
465
|
+
return;
|
|
400
466
|
}
|
|
401
467
|
case "abort": {
|
|
402
468
|
return part;
|
|
@@ -461,20 +527,37 @@ function AgentNetworkToAISDKTransformer() {
|
|
|
461
527
|
}
|
|
462
528
|
});
|
|
463
529
|
}
|
|
464
|
-
function AgentStreamToAISDKTransformer(
|
|
530
|
+
function AgentStreamToAISDKTransformer({
|
|
531
|
+
lastMessageId,
|
|
532
|
+
sendStart,
|
|
533
|
+
sendFinish,
|
|
534
|
+
sendReasoning,
|
|
535
|
+
sendSources,
|
|
536
|
+
messageMetadata,
|
|
537
|
+
onError
|
|
538
|
+
}) {
|
|
465
539
|
let bufferedSteps = /* @__PURE__ */ new Map();
|
|
540
|
+
let tripwireOccurred = false;
|
|
541
|
+
let finishEventSent = false;
|
|
466
542
|
return new TransformStream({
|
|
467
543
|
transform(chunk, controller) {
|
|
544
|
+
if (chunk.type === "tripwire") {
|
|
545
|
+
tripwireOccurred = true;
|
|
546
|
+
}
|
|
547
|
+
if (chunk.type === "finish") {
|
|
548
|
+
finishEventSent = true;
|
|
549
|
+
}
|
|
468
550
|
const part = convertMastraChunkToAISDKv5({ chunk, mode: "stream" });
|
|
469
551
|
const transformedChunk = convertFullStreamChunkToUIMessageStream({
|
|
470
552
|
part,
|
|
471
|
-
sendReasoning
|
|
472
|
-
sendSources
|
|
473
|
-
|
|
474
|
-
|
|
553
|
+
sendReasoning,
|
|
554
|
+
sendSources,
|
|
555
|
+
messageMetadataValue: messageMetadata?.({ part }),
|
|
556
|
+
sendStart,
|
|
557
|
+
sendFinish,
|
|
475
558
|
responseMessageId: lastMessageId,
|
|
476
559
|
onError(error) {
|
|
477
|
-
return safeParseErrorObject(error);
|
|
560
|
+
return onError ? onError(error) : safeParseErrorObject(error);
|
|
478
561
|
}
|
|
479
562
|
});
|
|
480
563
|
if (transformedChunk) {
|
|
@@ -494,6 +577,14 @@ function AgentStreamToAISDKTransformer(lastMessageId) {
|
|
|
494
577
|
controller.enqueue(transformedChunk);
|
|
495
578
|
}
|
|
496
579
|
}
|
|
580
|
+
},
|
|
581
|
+
flush(controller) {
|
|
582
|
+
if (tripwireOccurred && !finishEventSent && sendFinish) {
|
|
583
|
+
controller.enqueue({
|
|
584
|
+
type: "finish",
|
|
585
|
+
finishReason: "other"
|
|
586
|
+
});
|
|
587
|
+
}
|
|
497
588
|
}
|
|
498
589
|
});
|
|
499
590
|
}
|
|
@@ -726,6 +817,19 @@ function transformWorkflow(payload, bufferedWorkflows, isNested) {
|
|
|
726
817
|
}
|
|
727
818
|
};
|
|
728
819
|
}
|
|
820
|
+
case "workflow-step-output": {
|
|
821
|
+
const output = payload.payload.output;
|
|
822
|
+
if (output && isDataChunkType(output)) {
|
|
823
|
+
if (!("data" in output)) {
|
|
824
|
+
throw new Error(
|
|
825
|
+
`UI Messages require a data property when using data- prefixed chunks
|
|
826
|
+
${JSON.stringify(output)}`
|
|
827
|
+
);
|
|
828
|
+
}
|
|
829
|
+
return output;
|
|
830
|
+
}
|
|
831
|
+
return null;
|
|
832
|
+
}
|
|
729
833
|
default: {
|
|
730
834
|
if (isDataChunkType(payload)) {
|
|
731
835
|
if (!("data" in payload)) {
|
|
@@ -980,7 +1084,11 @@ function transformNetwork(payload, bufferedNetworks, isNested) {
|
|
|
980
1084
|
}
|
|
981
1085
|
|
|
982
1086
|
// src/convert-streams.ts
|
|
983
|
-
function toAISdkV5Stream(stream, options = {
|
|
1087
|
+
function toAISdkV5Stream(stream, options = {
|
|
1088
|
+
from: "agent",
|
|
1089
|
+
sendStart: true,
|
|
1090
|
+
sendFinish: true
|
|
1091
|
+
}) {
|
|
984
1092
|
const from = options?.from;
|
|
985
1093
|
if (from === "workflow") {
|
|
986
1094
|
return stream.pipeThrough(WorkflowStreamToAISDKTransformer());
|
|
@@ -989,14 +1097,28 @@ function toAISdkV5Stream(stream, options = { from: "agent" }) {
|
|
|
989
1097
|
return stream.pipeThrough(AgentNetworkToAISDKTransformer());
|
|
990
1098
|
}
|
|
991
1099
|
const agentReadable = "fullStream" in stream ? stream.fullStream : stream;
|
|
992
|
-
return agentReadable.pipeThrough(
|
|
1100
|
+
return agentReadable.pipeThrough(
|
|
1101
|
+
AgentStreamToAISDKTransformer({
|
|
1102
|
+
lastMessageId: options?.lastMessageId,
|
|
1103
|
+
sendStart: options?.sendStart,
|
|
1104
|
+
sendFinish: options?.sendFinish,
|
|
1105
|
+
sendReasoning: options?.sendReasoning,
|
|
1106
|
+
sendSources: options?.sendSources,
|
|
1107
|
+
messageMetadata: options?.messageMetadata,
|
|
1108
|
+
onError: options?.onError
|
|
1109
|
+
})
|
|
1110
|
+
);
|
|
993
1111
|
}
|
|
994
1112
|
|
|
995
1113
|
// src/chat-route.ts
|
|
996
1114
|
function chatRoute({
|
|
997
1115
|
path = "/chat/:agentId",
|
|
998
1116
|
agent,
|
|
999
|
-
defaultOptions
|
|
1117
|
+
defaultOptions,
|
|
1118
|
+
sendStart = true,
|
|
1119
|
+
sendFinish = true,
|
|
1120
|
+
sendReasoning = false,
|
|
1121
|
+
sendSources = false
|
|
1000
1122
|
}) {
|
|
1001
1123
|
if (!agent && !path.includes("/:agentId")) {
|
|
1002
1124
|
throw new Error("Path must include :agentId to route to the correct agent or pass the agent explicitly");
|
|
@@ -1130,7 +1252,14 @@ function chatRoute({
|
|
|
1130
1252
|
const uiMessageStream = createUIMessageStream({
|
|
1131
1253
|
originalMessages: messages,
|
|
1132
1254
|
execute: async ({ writer }) => {
|
|
1133
|
-
for await (const part of toAISdkV5Stream(result, {
|
|
1255
|
+
for await (const part of toAISdkV5Stream(result, {
|
|
1256
|
+
from: "agent",
|
|
1257
|
+
lastMessageId,
|
|
1258
|
+
sendStart,
|
|
1259
|
+
sendFinish,
|
|
1260
|
+
sendReasoning,
|
|
1261
|
+
sendSources
|
|
1262
|
+
})) {
|
|
1134
1263
|
writer.write(part);
|
|
1135
1264
|
}
|
|
1136
1265
|
}
|
|
@@ -1170,9 +1299,13 @@ function workflowRoute({
|
|
|
1170
1299
|
schema: {
|
|
1171
1300
|
type: "object",
|
|
1172
1301
|
properties: {
|
|
1302
|
+
runId: { type: "string" },
|
|
1303
|
+
resourceId: { type: "string" },
|
|
1173
1304
|
inputData: { type: "object", additionalProperties: true },
|
|
1305
|
+
resumeData: { type: "object", additionalProperties: true },
|
|
1174
1306
|
requestContext: { type: "object", additionalProperties: true },
|
|
1175
|
-
tracingOptions: { type: "object", additionalProperties: true }
|
|
1307
|
+
tracingOptions: { type: "object", additionalProperties: true },
|
|
1308
|
+
step: { type: "string" }
|
|
1176
1309
|
}
|
|
1177
1310
|
}
|
|
1178
1311
|
}
|
|
@@ -1190,8 +1323,9 @@ function workflowRoute({
|
|
|
1190
1323
|
}
|
|
1191
1324
|
},
|
|
1192
1325
|
handler: async (c) => {
|
|
1193
|
-
const { inputData, resumeData, ...rest } = await c.req.json();
|
|
1326
|
+
const { runId, resourceId, inputData, resumeData, ...rest } = await c.req.json();
|
|
1194
1327
|
const mastra = c.get("mastra");
|
|
1328
|
+
const requestContext = c.get("requestContext");
|
|
1195
1329
|
let workflowToUse = workflow;
|
|
1196
1330
|
if (!workflow) {
|
|
1197
1331
|
const workflowId = c.req.param("workflowId");
|
|
@@ -1209,8 +1343,13 @@ function workflowRoute({
|
|
|
1209
1343
|
if (!workflowObj) {
|
|
1210
1344
|
throw new Error(`Workflow ${workflowToUse} not found`);
|
|
1211
1345
|
}
|
|
1212
|
-
|
|
1213
|
-
|
|
1346
|
+
if (requestContext && rest.requestContext) {
|
|
1347
|
+
mastra.getLogger()?.warn(
|
|
1348
|
+
`"requestContext" from the request body will be ignored because "requestContext" is already set in the route options.`
|
|
1349
|
+
);
|
|
1350
|
+
}
|
|
1351
|
+
const run = await workflowObj.createRun({ runId, resourceId, ...rest });
|
|
1352
|
+
const stream = resumeData ? run.resumeStream({ resumeData, ...rest, requestContext: requestContext || rest.requestContext }) : run.stream({ inputData, ...rest, requestContext: requestContext || rest.requestContext });
|
|
1214
1353
|
const uiMessageStream = createUIMessageStream({
|
|
1215
1354
|
execute: async ({ writer }) => {
|
|
1216
1355
|
for await (const part of toAISdkV5Stream(stream, { from: "workflow" })) {
|