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