@mastra/ai-sdk 1.7.1 → 1.8.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 +29 -0
- package/dist/_types/@internal_ai-sdk-v5/dist/index.d.ts +16 -217
- package/dist/_types/@internal_ai-v6/dist/index.d.ts +31 -378
- package/dist/chat-route.d.ts +6 -2
- package/dist/chat-route.d.ts.map +1 -1
- package/dist/index.cjs +401 -113
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +401 -113
- package/dist/index.js.map +1 -1
- package/dist/sse-heartbeat.d.ts +8 -0
- package/dist/sse-heartbeat.d.ts.map +1 -0
- package/dist/transformers.d.ts +13 -5
- package/dist/transformers.d.ts.map +1 -1
- package/package.json +12 -11
package/dist/index.js
CHANGED
|
@@ -9,7 +9,7 @@ import { MASTRA_RESOURCE_ID_KEY } from "@mastra/core/request-context";
|
|
|
9
9
|
import { MessageList, TripWire, aiV5ModelMessageToV2PromptMessage } from "@mastra/core/agent";
|
|
10
10
|
import { RequestContext } from "@mastra/core/di";
|
|
11
11
|
import { MessageHistory, SemanticRecall, WorkingMemory } from "@mastra/core/processors";
|
|
12
|
-
//#region ../../packages/_vendored/ai_v5/dist/dist-
|
|
12
|
+
//#region ../../packages/_vendored/ai_v5/dist/dist-BuEMdYEn.js
|
|
13
13
|
var marker$1$4 = "vercel.ai.error";
|
|
14
14
|
var symbol$1$5 = Symbol.for(marker$1$4);
|
|
15
15
|
var _a$1$5;
|
|
@@ -533,6 +533,26 @@ async function cancelResponseBody$1(response) {
|
|
|
533
533
|
await ((_a2 = response.body) == null ? void 0 : _a2.cancel());
|
|
534
534
|
} catch (e) {}
|
|
535
535
|
}
|
|
536
|
+
var initialGlobalFetch$1 = globalThis.fetch;
|
|
537
|
+
isNodeDefaultFetch$1(initialGlobalFetch$1);
|
|
538
|
+
function isNodeDefaultFetch$1(fetch) {
|
|
539
|
+
const source = Function.prototype.toString.call(fetch);
|
|
540
|
+
return source.includes("internal/deps/undici") || source.includes("lazy loading of undici");
|
|
541
|
+
}
|
|
542
|
+
function getCurrentModulePath$1() {
|
|
543
|
+
const originalPrepareStackTrace = Error.prepareStackTrace;
|
|
544
|
+
try {
|
|
545
|
+
Error.prepareStackTrace = (_error, callSites) => callSites;
|
|
546
|
+
const error = /* @__PURE__ */ new Error("Capture current module path");
|
|
547
|
+
Error.captureStackTrace(error, getCurrentModulePath$1);
|
|
548
|
+
const [caller] = error.stack;
|
|
549
|
+
const fileName = caller == null ? void 0 : caller.getFileName();
|
|
550
|
+
if (fileName == null) throw new Error("Unable to determine the current module path");
|
|
551
|
+
return fileName;
|
|
552
|
+
} finally {
|
|
553
|
+
Error.prepareStackTrace = originalPrepareStackTrace;
|
|
554
|
+
}
|
|
555
|
+
}
|
|
536
556
|
var DEFAULT_MAX_DOWNLOAD_SIZE$1 = 2 * 1024 * 1024 * 1024;
|
|
537
557
|
async function readResponseWithSizeLimit$1({ response, url, maxBytes = DEFAULT_MAX_DOWNLOAD_SIZE$1 }) {
|
|
538
558
|
const contentLength = response.headers.get("content-length");
|
|
@@ -636,11 +656,11 @@ function withUserAgentSuffix$1(headers, ...userAgentSuffixParts) {
|
|
|
636
656
|
normalizedHeaders.set("user-agent", [currentUserAgentHeader, ...userAgentSuffixParts].filter(Boolean).join(" "));
|
|
637
657
|
return Object.fromEntries(normalizedHeaders.entries());
|
|
638
658
|
}
|
|
639
|
-
var VERSION$4 = "3.0.
|
|
659
|
+
var VERSION$4 = "3.0.31";
|
|
640
660
|
var getOriginalFetch = () => globalThis.fetch;
|
|
641
|
-
var getFromApi = async ({ url, headers = {}, successfulResponseHandler, failedResponseHandler, abortSignal, fetch
|
|
661
|
+
var getFromApi = async ({ url, headers = {}, successfulResponseHandler, failedResponseHandler, abortSignal, fetch = getOriginalFetch() }) => {
|
|
642
662
|
try {
|
|
643
|
-
const response = await
|
|
663
|
+
const response = await fetch(url, {
|
|
644
664
|
method: "GET",
|
|
645
665
|
headers: withUserAgentSuffix$1(headers, `ai-sdk/provider-utils/${VERSION$4}`, getRuntimeEnvironmentUserAgent$1()),
|
|
646
666
|
signal: abortSignal
|
|
@@ -866,7 +886,7 @@ function parseJsonEventStream({ stream, schema }) {
|
|
|
866
886
|
} }));
|
|
867
887
|
}
|
|
868
888
|
var getOriginalFetch2 = () => globalThis.fetch;
|
|
869
|
-
var postJsonToApi = async ({ url, headers, body, failedResponseHandler, successfulResponseHandler, abortSignal, fetch
|
|
889
|
+
var postJsonToApi = async ({ url, headers, body, failedResponseHandler, successfulResponseHandler, abortSignal, fetch }) => postToApi({
|
|
870
890
|
url,
|
|
871
891
|
headers: {
|
|
872
892
|
"Content-Type": "application/json",
|
|
@@ -879,11 +899,11 @@ var postJsonToApi = async ({ url, headers, body, failedResponseHandler, successf
|
|
|
879
899
|
failedResponseHandler,
|
|
880
900
|
successfulResponseHandler,
|
|
881
901
|
abortSignal,
|
|
882
|
-
fetch
|
|
902
|
+
fetch
|
|
883
903
|
});
|
|
884
|
-
var postToApi = async ({ url, headers = {}, body, successfulResponseHandler, failedResponseHandler, abortSignal, fetch
|
|
904
|
+
var postToApi = async ({ url, headers = {}, body, successfulResponseHandler, failedResponseHandler, abortSignal, fetch = getOriginalFetch2() }) => {
|
|
885
905
|
try {
|
|
886
|
-
const response = await
|
|
906
|
+
const response = await fetch(url, {
|
|
887
907
|
method: "POST",
|
|
888
908
|
headers: withUserAgentSuffix$1(headers, `ai-sdk/provider-utils/${VERSION$4}`, getRuntimeEnvironmentUserAgent$1()),
|
|
889
909
|
body: body.content,
|
|
@@ -2945,7 +2965,7 @@ async function getVercelRequestId() {
|
|
|
2945
2965
|
var _a10;
|
|
2946
2966
|
return (_a10 = getContext().headers) == null ? void 0 : _a10["x-vercel-id"];
|
|
2947
2967
|
}
|
|
2948
|
-
var VERSION$2 = "2.0.
|
|
2968
|
+
var VERSION$2 = "2.0.125";
|
|
2949
2969
|
var AI_GATEWAY_PROTOCOL_VERSION = "0.0.1";
|
|
2950
2970
|
function createGatewayProvider(options = {}) {
|
|
2951
2971
|
var _a10, _b10;
|
|
@@ -4395,19 +4415,48 @@ function processUIMessageStream$1({ stream, messageMetadataSchema, dataPartSchem
|
|
|
4395
4415
|
return stream.pipeThrough(new TransformStream({ async transform(chunk, controller) {
|
|
4396
4416
|
await runUpdateMessageJob(async ({ state, write }) => {
|
|
4397
4417
|
var _a16, _b, _c, _d;
|
|
4418
|
+
function getCurrentStepParts() {
|
|
4419
|
+
const parts = state.message.parts;
|
|
4420
|
+
let currentStepStartIndex = parts.length - 1;
|
|
4421
|
+
while (currentStepStartIndex >= 0 && parts[currentStepStartIndex].type !== "step-start") currentStepStartIndex--;
|
|
4422
|
+
return parts.slice(currentStepStartIndex + 1);
|
|
4423
|
+
}
|
|
4424
|
+
function getCurrentStepToolInvocations() {
|
|
4425
|
+
return getCurrentStepParts().filter(isToolUIPart$1);
|
|
4426
|
+
}
|
|
4398
4427
|
function getToolInvocation(toolCallId) {
|
|
4399
|
-
|
|
4428
|
+
let toolInvocation = getCurrentStepToolInvocations().find((invocation) => invocation.toolCallId === toolCallId);
|
|
4429
|
+
if (toolInvocation == null) {
|
|
4430
|
+
const parts = state.message.parts;
|
|
4431
|
+
for (let i = parts.length - 1; i >= 0; i--) {
|
|
4432
|
+
const part = parts[i];
|
|
4433
|
+
if (isToolUIPart$1(part) && part.toolCallId === toolCallId) {
|
|
4434
|
+
toolInvocation = part;
|
|
4435
|
+
break;
|
|
4436
|
+
}
|
|
4437
|
+
}
|
|
4438
|
+
}
|
|
4400
4439
|
if (toolInvocation == null) throw new Error("tool-output-error must be preceded by a tool-input-available");
|
|
4401
4440
|
return toolInvocation;
|
|
4402
4441
|
}
|
|
4403
4442
|
function getDynamicToolInvocation(toolCallId) {
|
|
4404
|
-
|
|
4443
|
+
let toolInvocation = getCurrentStepParts().filter((part) => part.type === "dynamic-tool").find((invocation) => invocation.toolCallId === toolCallId);
|
|
4444
|
+
if (toolInvocation == null) {
|
|
4445
|
+
const parts = state.message.parts;
|
|
4446
|
+
for (let i = parts.length - 1; i >= 0; i--) {
|
|
4447
|
+
const part = parts[i];
|
|
4448
|
+
if (part.type === "dynamic-tool" && part.toolCallId === toolCallId) {
|
|
4449
|
+
toolInvocation = part;
|
|
4450
|
+
break;
|
|
4451
|
+
}
|
|
4452
|
+
}
|
|
4453
|
+
}
|
|
4405
4454
|
if (toolInvocation == null) throw new Error("tool-output-error must be preceded by a tool-input-available");
|
|
4406
4455
|
return toolInvocation;
|
|
4407
4456
|
}
|
|
4408
|
-
function updateToolPart(options) {
|
|
4457
|
+
function updateToolPart(options, existingPart) {
|
|
4409
4458
|
var _a17;
|
|
4410
|
-
const part =
|
|
4459
|
+
const part = existingPart != null ? existingPart : getCurrentStepParts().find((part2) => isToolUIPart$1(part2) && part2.toolCallId === options.toolCallId);
|
|
4411
4460
|
const anyOptions = options;
|
|
4412
4461
|
const anyPart = part;
|
|
4413
4462
|
if (part != null) {
|
|
@@ -4432,9 +4481,9 @@ function processUIMessageStream$1({ stream, messageMetadataSchema, dataPartSchem
|
|
|
4432
4481
|
...anyOptions.providerMetadata != null ? { callProviderMetadata: anyOptions.providerMetadata } : {}
|
|
4433
4482
|
});
|
|
4434
4483
|
}
|
|
4435
|
-
function updateDynamicToolPart(options) {
|
|
4484
|
+
function updateDynamicToolPart(options, existingPart) {
|
|
4436
4485
|
var _a17, _b2;
|
|
4437
|
-
const part =
|
|
4486
|
+
const part = existingPart != null ? existingPart : getCurrentStepParts().find((part2) => part2.type === "dynamic-tool" && part2.toolCallId === options.toolCallId);
|
|
4438
4487
|
const anyOptions = options;
|
|
4439
4488
|
const anyPart = part;
|
|
4440
4489
|
if (part != null) {
|
|
@@ -4555,7 +4604,7 @@ function processUIMessageStream$1({ stream, messageMetadataSchema, dataPartSchem
|
|
|
4555
4604
|
write();
|
|
4556
4605
|
break;
|
|
4557
4606
|
case "tool-input-start": {
|
|
4558
|
-
const toolInvocations =
|
|
4607
|
+
const toolInvocations = getCurrentStepParts().filter(isToolUIPart$1);
|
|
4559
4608
|
state.partialToolCalls[chunk.toolCallId] = {
|
|
4560
4609
|
text: "",
|
|
4561
4610
|
toolName: chunk.toolName,
|
|
@@ -4650,7 +4699,7 @@ function processUIMessageStream$1({ stream, messageMetadataSchema, dataPartSchem
|
|
|
4650
4699
|
input: toolInvocation.input,
|
|
4651
4700
|
output: chunk.output,
|
|
4652
4701
|
preliminary: chunk.preliminary
|
|
4653
|
-
});
|
|
4702
|
+
}, toolInvocation);
|
|
4654
4703
|
} else {
|
|
4655
4704
|
const toolInvocation = getToolInvocation(chunk.toolCallId);
|
|
4656
4705
|
updateToolPart({
|
|
@@ -4661,7 +4710,7 @@ function processUIMessageStream$1({ stream, messageMetadataSchema, dataPartSchem
|
|
|
4661
4710
|
output: chunk.output,
|
|
4662
4711
|
providerExecuted: chunk.providerExecuted,
|
|
4663
4712
|
preliminary: chunk.preliminary
|
|
4664
|
-
});
|
|
4713
|
+
}, toolInvocation);
|
|
4665
4714
|
}
|
|
4666
4715
|
write();
|
|
4667
4716
|
break;
|
|
@@ -4675,7 +4724,7 @@ function processUIMessageStream$1({ stream, messageMetadataSchema, dataPartSchem
|
|
|
4675
4724
|
input: toolInvocation.input,
|
|
4676
4725
|
errorText: chunk.errorText,
|
|
4677
4726
|
providerExecuted: chunk.providerExecuted
|
|
4678
|
-
});
|
|
4727
|
+
}, toolInvocation);
|
|
4679
4728
|
} else {
|
|
4680
4729
|
const toolInvocation = getToolInvocation(chunk.toolCallId);
|
|
4681
4730
|
updateToolPart({
|
|
@@ -4686,7 +4735,7 @@ function processUIMessageStream$1({ stream, messageMetadataSchema, dataPartSchem
|
|
|
4686
4735
|
rawInput: toolInvocation.rawInput,
|
|
4687
4736
|
errorText: chunk.errorText,
|
|
4688
4737
|
providerExecuted: chunk.providerExecuted
|
|
4689
|
-
});
|
|
4738
|
+
}, toolInvocation);
|
|
4690
4739
|
}
|
|
4691
4740
|
write();
|
|
4692
4741
|
break;
|
|
@@ -4977,7 +5026,7 @@ function createUIMessageStream$1({ execute, onError = () => "An error occurred."
|
|
|
4977
5026
|
});
|
|
4978
5027
|
}
|
|
4979
5028
|
//#endregion
|
|
4980
|
-
//#region ../../packages/_vendored/ai_v6/dist/dist-
|
|
5029
|
+
//#region ../../packages/_vendored/ai_v6/dist/dist-BTWHzT8H.js
|
|
4981
5030
|
var marker$1 = "vercel.ai.error";
|
|
4982
5031
|
var symbol$1 = Symbol.for(marker$1);
|
|
4983
5032
|
var _a$1;
|
|
@@ -5317,6 +5366,26 @@ var _b;
|
|
|
5317
5366
|
return AISDKError.hasMarker(error, marker$2);
|
|
5318
5367
|
}
|
|
5319
5368
|
});
|
|
5369
|
+
var initialGlobalFetch = globalThis.fetch;
|
|
5370
|
+
isNodeDefaultFetch(initialGlobalFetch);
|
|
5371
|
+
function isNodeDefaultFetch(fetch) {
|
|
5372
|
+
const source = Function.prototype.toString.call(fetch);
|
|
5373
|
+
return source.includes("internal/deps/undici") || source.includes("lazy loading of undici");
|
|
5374
|
+
}
|
|
5375
|
+
function getCurrentModulePath() {
|
|
5376
|
+
const originalPrepareStackTrace = Error.prepareStackTrace;
|
|
5377
|
+
try {
|
|
5378
|
+
Error.prepareStackTrace = (_error, callSites) => callSites;
|
|
5379
|
+
const error = /* @__PURE__ */ new Error("Capture current module path");
|
|
5380
|
+
Error.captureStackTrace(error, getCurrentModulePath);
|
|
5381
|
+
const [caller] = error.stack;
|
|
5382
|
+
const fileName = caller == null ? void 0 : caller.getFileName();
|
|
5383
|
+
if (fileName == null) throw new Error("Unable to determine the current module path");
|
|
5384
|
+
return fileName;
|
|
5385
|
+
} finally {
|
|
5386
|
+
Error.prepareStackTrace = originalPrepareStackTrace;
|
|
5387
|
+
}
|
|
5388
|
+
}
|
|
5320
5389
|
var createIdGenerator = ({ prefix, size = 16, alphabet = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz", separator = "-" } = {}) => {
|
|
5321
5390
|
const generator = () => {
|
|
5322
5391
|
const alphabetLength = alphabet.length;
|
|
@@ -7267,6 +7336,25 @@ _a16 = symbol16;
|
|
|
7267
7336
|
function asArray(value) {
|
|
7268
7337
|
return value === void 0 ? [] : Array.isArray(value) ? value : [value];
|
|
7269
7338
|
}
|
|
7339
|
+
function mergeObjects(base, overrides) {
|
|
7340
|
+
if (base === void 0 && overrides === void 0) return;
|
|
7341
|
+
if (base === void 0) return overrides;
|
|
7342
|
+
if (overrides === void 0) return base;
|
|
7343
|
+
const result = { ...base };
|
|
7344
|
+
for (const key in overrides) {
|
|
7345
|
+
if (key === "__proto__" || key === "constructor" || key === "prototype") continue;
|
|
7346
|
+
if (Object.prototype.hasOwnProperty.call(overrides, key)) {
|
|
7347
|
+
const overridesValue = overrides[key];
|
|
7348
|
+
if (overridesValue === void 0) continue;
|
|
7349
|
+
const baseValue = key in base ? base[key] : void 0;
|
|
7350
|
+
const isSourceObject = overridesValue !== null && typeof overridesValue === "object" && !Array.isArray(overridesValue) && !(overridesValue instanceof Date) && !(overridesValue instanceof RegExp);
|
|
7351
|
+
const isTargetObject = baseValue !== null && baseValue !== void 0 && typeof baseValue === "object" && !Array.isArray(baseValue) && !(baseValue instanceof Date) && !(baseValue instanceof RegExp);
|
|
7352
|
+
if (isSourceObject && isTargetObject) result[key] = mergeObjects(baseValue, overridesValue);
|
|
7353
|
+
else result[key] = overridesValue;
|
|
7354
|
+
}
|
|
7355
|
+
}
|
|
7356
|
+
return result;
|
|
7357
|
+
}
|
|
7270
7358
|
var dataContentSchema = z.union([
|
|
7271
7359
|
z.string(),
|
|
7272
7360
|
z.instanceof(Uint8Array),
|
|
@@ -7450,25 +7538,6 @@ z.union([
|
|
|
7450
7538
|
assistantModelMessageSchema,
|
|
7451
7539
|
toolModelMessageSchema
|
|
7452
7540
|
]);
|
|
7453
|
-
function mergeObjects(base, overrides) {
|
|
7454
|
-
if (base === void 0 && overrides === void 0) return;
|
|
7455
|
-
if (base === void 0) return overrides;
|
|
7456
|
-
if (overrides === void 0) return base;
|
|
7457
|
-
const result = { ...base };
|
|
7458
|
-
for (const key in overrides) {
|
|
7459
|
-
if (key === "__proto__" || key === "constructor" || key === "prototype") continue;
|
|
7460
|
-
if (Object.prototype.hasOwnProperty.call(overrides, key)) {
|
|
7461
|
-
const overridesValue = overrides[key];
|
|
7462
|
-
if (overridesValue === void 0) continue;
|
|
7463
|
-
const baseValue = key in base ? base[key] : void 0;
|
|
7464
|
-
const isSourceObject = overridesValue !== null && typeof overridesValue === "object" && !Array.isArray(overridesValue) && !(overridesValue instanceof Date) && !(overridesValue instanceof RegExp);
|
|
7465
|
-
const isTargetObject = baseValue !== null && baseValue !== void 0 && typeof baseValue === "object" && !Array.isArray(baseValue) && !(baseValue instanceof Date) && !(baseValue instanceof RegExp);
|
|
7466
|
-
if (isSourceObject && isTargetObject) result[key] = mergeObjects(baseValue, overridesValue);
|
|
7467
|
-
else result[key] = overridesValue;
|
|
7468
|
-
}
|
|
7469
|
-
}
|
|
7470
|
-
return result;
|
|
7471
|
-
}
|
|
7472
7541
|
new TextEncoder();
|
|
7473
7542
|
__export({}, {
|
|
7474
7543
|
array: () => array,
|
|
@@ -8080,8 +8149,27 @@ function processUIMessageStream({ stream, messageMetadataSchema, dataPartSchemas
|
|
|
8080
8149
|
return stream.pipeThrough(new TransformStream({ async transform(chunk, controller) {
|
|
8081
8150
|
await runUpdateMessageJob(async ({ state, write }) => {
|
|
8082
8151
|
var _a22, _b, _c, _d;
|
|
8152
|
+
function getCurrentStepParts() {
|
|
8153
|
+
const parts = state.message.parts;
|
|
8154
|
+
let currentStepStartIndex = parts.length - 1;
|
|
8155
|
+
while (currentStepStartIndex >= 0 && parts[currentStepStartIndex].type !== "step-start") currentStepStartIndex--;
|
|
8156
|
+
return parts.slice(currentStepStartIndex + 1);
|
|
8157
|
+
}
|
|
8158
|
+
function getCurrentStepToolInvocations() {
|
|
8159
|
+
return getCurrentStepParts().filter(isToolUIPart);
|
|
8160
|
+
}
|
|
8083
8161
|
function getToolInvocation(toolCallId) {
|
|
8084
|
-
|
|
8162
|
+
let toolInvocation = getCurrentStepToolInvocations().find((invocation) => invocation.toolCallId === toolCallId);
|
|
8163
|
+
if (toolInvocation == null) {
|
|
8164
|
+
const parts = state.message.parts;
|
|
8165
|
+
for (let i = parts.length - 1; i >= 0; i--) {
|
|
8166
|
+
const part = parts[i];
|
|
8167
|
+
if (isToolUIPart(part) && part.toolCallId === toolCallId) {
|
|
8168
|
+
toolInvocation = part;
|
|
8169
|
+
break;
|
|
8170
|
+
}
|
|
8171
|
+
}
|
|
8172
|
+
}
|
|
8085
8173
|
if (toolInvocation == null) throw new UIMessageStreamError({
|
|
8086
8174
|
chunkType: "tool-invocation",
|
|
8087
8175
|
chunkId: toolCallId,
|
|
@@ -8089,9 +8177,9 @@ function processUIMessageStream({ stream, messageMetadataSchema, dataPartSchemas
|
|
|
8089
8177
|
});
|
|
8090
8178
|
return toolInvocation;
|
|
8091
8179
|
}
|
|
8092
|
-
function updateToolPart(options) {
|
|
8180
|
+
function updateToolPart(options, existingPart) {
|
|
8093
8181
|
var _a23;
|
|
8094
|
-
const part =
|
|
8182
|
+
const part = existingPart != null ? existingPart : getCurrentStepParts().find((part2) => isStaticToolUIPart(part2) && part2.toolCallId === options.toolCallId);
|
|
8095
8183
|
const anyOptions = options;
|
|
8096
8184
|
const anyPart = part;
|
|
8097
8185
|
if (part != null) {
|
|
@@ -8125,9 +8213,9 @@ function processUIMessageStream({ stream, messageMetadataSchema, dataPartSchemas
|
|
|
8125
8213
|
...anyOptions.providerMetadata != null && !(options.state === "output-available" || options.state === "output-error") ? { callProviderMetadata: anyOptions.providerMetadata } : {}
|
|
8126
8214
|
});
|
|
8127
8215
|
}
|
|
8128
|
-
function updateDynamicToolPart(options) {
|
|
8216
|
+
function updateDynamicToolPart(options, existingPart) {
|
|
8129
8217
|
var _a23, _b2;
|
|
8130
|
-
const part =
|
|
8218
|
+
const part = existingPart != null ? existingPart : getCurrentStepParts().find((part2) => part2.type === "dynamic-tool" && part2.toolCallId === options.toolCallId);
|
|
8131
8219
|
const anyOptions = options;
|
|
8132
8220
|
const anyPart = part;
|
|
8133
8221
|
if (part != null) {
|
|
@@ -8282,7 +8370,7 @@ function processUIMessageStream({ stream, messageMetadataSchema, dataPartSchemas
|
|
|
8282
8370
|
write();
|
|
8283
8371
|
break;
|
|
8284
8372
|
case "tool-input-start": {
|
|
8285
|
-
const toolInvocations =
|
|
8373
|
+
const toolInvocations = getCurrentStepParts().filter(isStaticToolUIPart);
|
|
8286
8374
|
state.partialToolCalls[chunk.toolCallId] = {
|
|
8287
8375
|
text: "",
|
|
8288
8376
|
toolName: chunk.toolName,
|
|
@@ -8367,7 +8455,7 @@ function processUIMessageStream({ stream, messageMetadataSchema, dataPartSchemas
|
|
|
8367
8455
|
if (onToolCall && !chunk.providerExecuted) await onToolCall({ toolCall: chunk });
|
|
8368
8456
|
break;
|
|
8369
8457
|
case "tool-input-error": {
|
|
8370
|
-
const existingPart =
|
|
8458
|
+
const existingPart = getCurrentStepParts().filter(isToolUIPart).find((p) => p.toolCallId === chunk.toolCallId);
|
|
8371
8459
|
if (existingPart != null ? existingPart.type === "dynamic-tool" : !!chunk.dynamic) updateDynamicToolPart({
|
|
8372
8460
|
toolCallId: chunk.toolCallId,
|
|
8373
8461
|
toolName: chunk.toolName,
|
|
@@ -8421,7 +8509,7 @@ function processUIMessageStream({ stream, messageMetadataSchema, dataPartSchemas
|
|
|
8421
8509
|
providerMetadata: chunk.providerMetadata,
|
|
8422
8510
|
title: toolInvocation.title,
|
|
8423
8511
|
toolMetadata: toolInvocation.toolMetadata
|
|
8424
|
-
});
|
|
8512
|
+
}, toolInvocation);
|
|
8425
8513
|
else updateToolPart({
|
|
8426
8514
|
toolCallId: chunk.toolCallId,
|
|
8427
8515
|
toolName: getStaticToolName(toolInvocation),
|
|
@@ -8433,7 +8521,7 @@ function processUIMessageStream({ stream, messageMetadataSchema, dataPartSchemas
|
|
|
8433
8521
|
providerMetadata: chunk.providerMetadata,
|
|
8434
8522
|
title: toolInvocation.title,
|
|
8435
8523
|
toolMetadata: toolInvocation.toolMetadata
|
|
8436
|
-
});
|
|
8524
|
+
}, toolInvocation);
|
|
8437
8525
|
write();
|
|
8438
8526
|
break;
|
|
8439
8527
|
}
|
|
@@ -8449,7 +8537,7 @@ function processUIMessageStream({ stream, messageMetadataSchema, dataPartSchemas
|
|
|
8449
8537
|
providerMetadata: chunk.providerMetadata,
|
|
8450
8538
|
title: toolInvocation.title,
|
|
8451
8539
|
toolMetadata: toolInvocation.toolMetadata
|
|
8452
|
-
});
|
|
8540
|
+
}, toolInvocation);
|
|
8453
8541
|
else updateToolPart({
|
|
8454
8542
|
toolCallId: chunk.toolCallId,
|
|
8455
8543
|
toolName: getStaticToolName(toolInvocation),
|
|
@@ -8461,7 +8549,7 @@ function processUIMessageStream({ stream, messageMetadataSchema, dataPartSchemas
|
|
|
8461
8549
|
providerMetadata: chunk.providerMetadata,
|
|
8462
8550
|
title: toolInvocation.title,
|
|
8463
8551
|
toolMetadata: toolInvocation.toolMetadata
|
|
8464
|
-
});
|
|
8552
|
+
}, toolInvocation);
|
|
8465
8553
|
write();
|
|
8466
8554
|
break;
|
|
8467
8555
|
}
|
|
@@ -9316,6 +9404,7 @@ function convertFullStreamChunkToUIMessageStream({ part, messageMetadataValue, s
|
|
|
9316
9404
|
//#endregion
|
|
9317
9405
|
//#region src/transformers.ts
|
|
9318
9406
|
const PRIMITIVE_CACHE_SYMBOL = Symbol("primitive-cache");
|
|
9407
|
+
const COMPLETED_STEPS_SYMBOL = Symbol("completed-steps-cache");
|
|
9319
9408
|
function cloneWorkflowStep(step, includeOutput) {
|
|
9320
9409
|
return {
|
|
9321
9410
|
name: step.name,
|
|
@@ -9443,7 +9532,8 @@ function createAgentStreamToAISDKTransformer(convertMastraChunkToAISDK, { lastMe
|
|
|
9443
9532
|
if (transformedChunk) if (transformedChunk.type === "tool-agent") {
|
|
9444
9533
|
const payload = transformedChunk.payload;
|
|
9445
9534
|
const agentTransformed = transformAgent(payload, bufferedSteps);
|
|
9446
|
-
if (agentTransformed) controller.enqueue(
|
|
9535
|
+
if (agentTransformed) if (Array.isArray(agentTransformed)) for (const part of agentTransformed) controller.enqueue(part);
|
|
9536
|
+
else controller.enqueue(agentTransformed);
|
|
9447
9537
|
} else if (transformedChunk.type === "tool-workflow") {
|
|
9448
9538
|
const payload = transformedChunk.payload;
|
|
9449
9539
|
const workflowChunk = transformWorkflow(payload, bufferedSteps, true, void 0, void 0, convertMastraChunkToAISDK);
|
|
@@ -9526,30 +9616,7 @@ function AgentStreamToAISDKV6Transformer({ lastMessageId, sendStart = true, send
|
|
|
9526
9616
|
});
|
|
9527
9617
|
}
|
|
9528
9618
|
function ensureAgentRunState(bufferedSteps, runId) {
|
|
9529
|
-
if (!bufferedSteps.has(runId)) bufferedSteps.set(runId,
|
|
9530
|
-
id: "",
|
|
9531
|
-
object: null,
|
|
9532
|
-
finishReason: null,
|
|
9533
|
-
usage: null,
|
|
9534
|
-
warnings: [],
|
|
9535
|
-
text: "",
|
|
9536
|
-
reasoning: [],
|
|
9537
|
-
sources: [],
|
|
9538
|
-
files: [],
|
|
9539
|
-
toolCalls: [],
|
|
9540
|
-
pendingToolCalls: [],
|
|
9541
|
-
toolResults: [],
|
|
9542
|
-
request: {},
|
|
9543
|
-
response: {
|
|
9544
|
-
id: "",
|
|
9545
|
-
timestamp: /* @__PURE__ */ new Date(),
|
|
9546
|
-
modelId: "",
|
|
9547
|
-
messages: []
|
|
9548
|
-
},
|
|
9549
|
-
providerMetadata: void 0,
|
|
9550
|
-
steps: [],
|
|
9551
|
-
status: "running"
|
|
9552
|
-
});
|
|
9619
|
+
if (!bufferedSteps.has(runId)) bufferedSteps.set(runId, createAgentRunState());
|
|
9553
9620
|
return bufferedSteps.get(runId);
|
|
9554
9621
|
}
|
|
9555
9622
|
function upsertPendingToolCall(pendingToolCalls = [], toolCallId, updates) {
|
|
@@ -9585,36 +9652,109 @@ function appendPendingToolCallArgs(pendingToolCalls = [], payload) {
|
|
|
9585
9652
|
function removePendingToolCall(pendingToolCalls = [], toolCallId) {
|
|
9586
9653
|
return pendingToolCalls.filter((call) => call.toolCallId !== toolCallId);
|
|
9587
9654
|
}
|
|
9655
|
+
function createAgentResponseState() {
|
|
9656
|
+
return {
|
|
9657
|
+
id: "",
|
|
9658
|
+
timestamp: /* @__PURE__ */ new Date(),
|
|
9659
|
+
modelId: "",
|
|
9660
|
+
messages: []
|
|
9661
|
+
};
|
|
9662
|
+
}
|
|
9663
|
+
function createAgentRunState(id = "") {
|
|
9664
|
+
return {
|
|
9665
|
+
id,
|
|
9666
|
+
object: null,
|
|
9667
|
+
finishReason: null,
|
|
9668
|
+
usage: null,
|
|
9669
|
+
warnings: [],
|
|
9670
|
+
text: "",
|
|
9671
|
+
reasoning: [],
|
|
9672
|
+
sources: [],
|
|
9673
|
+
files: [],
|
|
9674
|
+
toolCalls: [],
|
|
9675
|
+
pendingToolCalls: [],
|
|
9676
|
+
toolResults: [],
|
|
9677
|
+
request: {},
|
|
9678
|
+
response: createAgentResponseState(),
|
|
9679
|
+
providerMetadata: void 0,
|
|
9680
|
+
steps: [],
|
|
9681
|
+
status: "running"
|
|
9682
|
+
};
|
|
9683
|
+
}
|
|
9684
|
+
function cloneAgentResponse(response, { includeMessages }) {
|
|
9685
|
+
if (!response) return response;
|
|
9686
|
+
return {
|
|
9687
|
+
...response,
|
|
9688
|
+
...Object.prototype.hasOwnProperty.call(response, "messages") ? { messages: includeMessages ? response.messages : [] } : {},
|
|
9689
|
+
...Object.prototype.hasOwnProperty.call(response, "dbMessages") ? { dbMessages: includeMessages ? response.dbMessages : [] } : {},
|
|
9690
|
+
...Object.prototype.hasOwnProperty.call(response, "uiMessages") ? { uiMessages: includeMessages ? response.uiMessages : [] } : {}
|
|
9691
|
+
};
|
|
9692
|
+
}
|
|
9693
|
+
function cloneAgentStep(step, { includeDetails }) {
|
|
9694
|
+
if (includeDetails) return {
|
|
9695
|
+
...step,
|
|
9696
|
+
response: cloneAgentResponse(step.response, { includeMessages: true })
|
|
9697
|
+
};
|
|
9698
|
+
return {
|
|
9699
|
+
...step,
|
|
9700
|
+
object: null,
|
|
9701
|
+
files: [],
|
|
9702
|
+
sources: [],
|
|
9703
|
+
toolCalls: [],
|
|
9704
|
+
pendingToolCalls: [],
|
|
9705
|
+
toolResults: [],
|
|
9706
|
+
dynamicToolCalls: [],
|
|
9707
|
+
dynamicToolResults: [],
|
|
9708
|
+
staticToolCalls: [],
|
|
9709
|
+
staticToolResults: [],
|
|
9710
|
+
text: "",
|
|
9711
|
+
reasoning: [],
|
|
9712
|
+
content: Array.isArray(step.content) ? [] : step.content,
|
|
9713
|
+
reasoningText: typeof step.reasoningText === "string" ? "" : step.reasoningText,
|
|
9714
|
+
response: cloneAgentResponse(step.response, { includeMessages: false })
|
|
9715
|
+
};
|
|
9716
|
+
}
|
|
9717
|
+
function serializeAgentRun(current, { includeCompletedStepDetails, includeResponseMessages }) {
|
|
9718
|
+
const { _textOffset: _to, _reasoningOffset: _ro, ...data } = current;
|
|
9719
|
+
return {
|
|
9720
|
+
...data,
|
|
9721
|
+
response: cloneAgentResponse(data.response, { includeMessages: includeResponseMessages }),
|
|
9722
|
+
steps: data.steps.map((step) => cloneAgentStep(step, { includeDetails: includeCompletedStepDetails }))
|
|
9723
|
+
};
|
|
9724
|
+
}
|
|
9725
|
+
function createAgentDataPart(args) {
|
|
9726
|
+
const { current, runId, includeCompletedStepDetails, includeResponseMessages } = args;
|
|
9727
|
+
return {
|
|
9728
|
+
type: "data-tool-agent",
|
|
9729
|
+
id: runId,
|
|
9730
|
+
data: serializeAgentRun(current, {
|
|
9731
|
+
includeCompletedStepDetails,
|
|
9732
|
+
includeResponseMessages
|
|
9733
|
+
})
|
|
9734
|
+
};
|
|
9735
|
+
}
|
|
9736
|
+
function createAgentStepDataPart(args) {
|
|
9737
|
+
const { runId, stepIndex, step } = args;
|
|
9738
|
+
return {
|
|
9739
|
+
type: "data-tool-agent-step",
|
|
9740
|
+
id: `${runId}:${stepIndex}`,
|
|
9741
|
+
data: {
|
|
9742
|
+
runId,
|
|
9743
|
+
stepIndex,
|
|
9744
|
+
step: cloneAgentStep(step, { includeDetails: true })
|
|
9745
|
+
}
|
|
9746
|
+
};
|
|
9747
|
+
}
|
|
9588
9748
|
function transformAgent(payload, bufferedSteps) {
|
|
9589
9749
|
let hasChanged = false;
|
|
9750
|
+
let completedStep = null;
|
|
9590
9751
|
switch (payload.type) {
|
|
9591
|
-
case "start":
|
|
9592
|
-
|
|
9593
|
-
|
|
9594
|
-
object: null,
|
|
9595
|
-
finishReason: null,
|
|
9596
|
-
usage: null,
|
|
9597
|
-
warnings: [],
|
|
9598
|
-
text: "",
|
|
9599
|
-
reasoning: [],
|
|
9600
|
-
sources: [],
|
|
9601
|
-
files: [],
|
|
9602
|
-
toolCalls: [],
|
|
9603
|
-
pendingToolCalls: [],
|
|
9604
|
-
toolResults: [],
|
|
9605
|
-
request: {},
|
|
9606
|
-
response: {
|
|
9607
|
-
id: "",
|
|
9608
|
-
timestamp: /* @__PURE__ */ new Date(),
|
|
9609
|
-
modelId: "",
|
|
9610
|
-
messages: []
|
|
9611
|
-
},
|
|
9612
|
-
providerMetadata: void 0,
|
|
9613
|
-
steps: [],
|
|
9614
|
-
status: "running"
|
|
9615
|
-
});
|
|
9752
|
+
case "start": {
|
|
9753
|
+
const startState = createAgentRunState(payload.payload.id);
|
|
9754
|
+
bufferedSteps.set(payload.runId, startState);
|
|
9616
9755
|
hasChanged = true;
|
|
9617
9756
|
break;
|
|
9757
|
+
}
|
|
9618
9758
|
case "tool-call-input-streaming-start": {
|
|
9619
9759
|
const toolInputStartRun = ensureAgentRunState(bufferedSteps, payload.runId);
|
|
9620
9760
|
const existing = toolInputStartRun.pendingToolCalls?.find((call) => call.toolCallId === payload.payload.toolCallId);
|
|
@@ -9745,6 +9885,7 @@ function transformAgent(payload, bufferedSteps) {
|
|
|
9745
9885
|
break;
|
|
9746
9886
|
case "step-finish": {
|
|
9747
9887
|
const stepRun = ensureAgentRunState(bufferedSteps, payload.runId);
|
|
9888
|
+
const stepIndex = stepRun.steps.length;
|
|
9748
9889
|
const { steps: _steps, _textOffset, _reasoningOffset, ...stepRunWithoutSteps } = stepRun;
|
|
9749
9890
|
const textOffset = _textOffset || 0;
|
|
9750
9891
|
const reasoningOffset = _reasoningOffset || 0;
|
|
@@ -9786,18 +9927,28 @@ function transformAgent(payload, bufferedSteps) {
|
|
|
9786
9927
|
_textOffset: stepRun.text.length,
|
|
9787
9928
|
_reasoningOffset: stepRun.reasoning.length
|
|
9788
9929
|
});
|
|
9930
|
+
completedStep = {
|
|
9931
|
+
stepIndex,
|
|
9932
|
+
step: stepResult
|
|
9933
|
+
};
|
|
9789
9934
|
hasChanged = true;
|
|
9790
9935
|
break;
|
|
9791
9936
|
}
|
|
9792
9937
|
default: break;
|
|
9793
9938
|
}
|
|
9794
9939
|
if (hasChanged) {
|
|
9795
|
-
const
|
|
9796
|
-
|
|
9797
|
-
|
|
9798
|
-
|
|
9799
|
-
|
|
9800
|
-
};
|
|
9940
|
+
const snapshot = createAgentDataPart({
|
|
9941
|
+
current: bufferedSteps.get(payload.runId),
|
|
9942
|
+
runId: payload.runId,
|
|
9943
|
+
includeCompletedStepDetails: payload.type === "finish",
|
|
9944
|
+
includeResponseMessages: payload.type === "finish"
|
|
9945
|
+
});
|
|
9946
|
+
if (completedStep) return [snapshot, createAgentStepDataPart({
|
|
9947
|
+
runId: payload.runId,
|
|
9948
|
+
stepIndex: completedStep.stepIndex,
|
|
9949
|
+
step: completedStep.step
|
|
9950
|
+
})];
|
|
9951
|
+
return snapshot;
|
|
9801
9952
|
}
|
|
9802
9953
|
return null;
|
|
9803
9954
|
}
|
|
@@ -10223,10 +10374,24 @@ function transformNetwork(payload, bufferedNetworks, isNested) {
|
|
|
10223
10374
|
const step = current.steps.find((step) => step.id === stepId);
|
|
10224
10375
|
if (!step) return null;
|
|
10225
10376
|
step[PRIMITIVE_CACHE_SYMBOL] = step[PRIMITIVE_CACHE_SYMBOL] || /* @__PURE__ */ new Map();
|
|
10377
|
+
if (payload.payload.type === "start") delete step[COMPLETED_STEPS_SYMBOL];
|
|
10226
10378
|
const result = transformAgent(payload.payload, step[PRIMITIVE_CACHE_SYMBOL]);
|
|
10227
|
-
|
|
10228
|
-
|
|
10379
|
+
const snapshot = Array.isArray(result) ? result[0] : result;
|
|
10380
|
+
if (snapshot) {
|
|
10381
|
+
const { request, response, ...data } = snapshot.data;
|
|
10382
|
+
if (Array.isArray(result)) {
|
|
10383
|
+
const { stepIndex, step: completedStepDetail } = result[1].data;
|
|
10384
|
+
step[COMPLETED_STEPS_SYMBOL] = step[COMPLETED_STEPS_SYMBOL] || /* @__PURE__ */ new Map();
|
|
10385
|
+
step[COMPLETED_STEPS_SYMBOL].set(stepIndex, completedStepDetail);
|
|
10386
|
+
}
|
|
10229
10387
|
step.task = data;
|
|
10388
|
+
const completedSteps = step[COMPLETED_STEPS_SYMBOL];
|
|
10389
|
+
if (completedSteps && completedSteps.size > 0 && Array.isArray(data.steps)) {
|
|
10390
|
+
for (const [stepIndex, completedStepDetail] of completedSteps) if (stepIndex < data.steps.length) data.steps[stepIndex] = {
|
|
10391
|
+
...data.steps[stepIndex],
|
|
10392
|
+
...completedStepDetail
|
|
10393
|
+
};
|
|
10394
|
+
}
|
|
10230
10395
|
}
|
|
10231
10396
|
bufferedNetworks.set(payload.runId, current);
|
|
10232
10397
|
return {
|
|
@@ -10350,6 +10515,124 @@ function toAISdkStream(stream, options = {
|
|
|
10350
10515
|
}));
|
|
10351
10516
|
}
|
|
10352
10517
|
//#endregion
|
|
10518
|
+
//#region src/sse-heartbeat.ts
|
|
10519
|
+
const SSE_HEARTBEAT_BYTES = new TextEncoder().encode(": heartbeat\n\n");
|
|
10520
|
+
const LF_BYTE = 10;
|
|
10521
|
+
const MAX_TIMEOUT_MS = 2147483647;
|
|
10522
|
+
/** Throws when an enabled heartbeat interval cannot be scheduled with a timer. */
|
|
10523
|
+
function assertValidHeartbeatMs(heartbeatMs) {
|
|
10524
|
+
if (heartbeatMs !== void 0 && !(heartbeatMs <= 0) && (!Number.isFinite(heartbeatMs) || heartbeatMs > MAX_TIMEOUT_MS)) throw new RangeError(`heartbeatMs must be a finite number no greater than ${MAX_TIMEOUT_MS}`);
|
|
10525
|
+
}
|
|
10526
|
+
/**
|
|
10527
|
+
* Adds periodic SSE comment heartbeats to an AI SDK response body.
|
|
10528
|
+
* AI SDK serialization uses LF-delimited frames, which this private wrapper preserves and relies on.
|
|
10529
|
+
*/
|
|
10530
|
+
function withSseHeartbeat(response, heartbeatMs) {
|
|
10531
|
+
assertValidHeartbeatMs(heartbeatMs);
|
|
10532
|
+
if (heartbeatMs === void 0 || heartbeatMs <= 0 || !response.body) return response;
|
|
10533
|
+
const reader = response.body.getReader();
|
|
10534
|
+
let heartbeatTimeout;
|
|
10535
|
+
let wakePull;
|
|
10536
|
+
let readResult;
|
|
10537
|
+
let readError;
|
|
10538
|
+
let hasReadError = false;
|
|
10539
|
+
let reading = false;
|
|
10540
|
+
let finished = false;
|
|
10541
|
+
let readerReleased = false;
|
|
10542
|
+
let atFrameBoundary = true;
|
|
10543
|
+
let lastByte;
|
|
10544
|
+
let nextHeartbeatAt = performance.now() + heartbeatMs;
|
|
10545
|
+
const clearHeartbeat = () => {
|
|
10546
|
+
if (heartbeatTimeout !== void 0) {
|
|
10547
|
+
clearTimeout(heartbeatTimeout);
|
|
10548
|
+
heartbeatTimeout = void 0;
|
|
10549
|
+
}
|
|
10550
|
+
};
|
|
10551
|
+
const releaseReader = () => {
|
|
10552
|
+
if (readerReleased) return;
|
|
10553
|
+
readerReleased = true;
|
|
10554
|
+
reader.releaseLock();
|
|
10555
|
+
};
|
|
10556
|
+
const updateFrameBoundary = (chunk) => {
|
|
10557
|
+
if (chunk.byteLength === 0) return;
|
|
10558
|
+
atFrameBoundary = chunk.byteLength === 1 ? lastByte === LF_BYTE && chunk[0] === LF_BYTE : chunk[chunk.byteLength - 2] === LF_BYTE && chunk[chunk.byteLength - 1] === LF_BYTE;
|
|
10559
|
+
lastByte = chunk[chunk.byteLength - 1];
|
|
10560
|
+
};
|
|
10561
|
+
const startRead = () => {
|
|
10562
|
+
if (reading || readResult || hasReadError || finished) return;
|
|
10563
|
+
reading = true;
|
|
10564
|
+
reader.read().then((result) => {
|
|
10565
|
+
reading = false;
|
|
10566
|
+
readResult = result;
|
|
10567
|
+
wakePull?.("read");
|
|
10568
|
+
}, (error) => {
|
|
10569
|
+
reading = false;
|
|
10570
|
+
readError = error;
|
|
10571
|
+
hasReadError = true;
|
|
10572
|
+
wakePull?.("read");
|
|
10573
|
+
});
|
|
10574
|
+
};
|
|
10575
|
+
const forwardRead = (controller) => {
|
|
10576
|
+
if (hasReadError) {
|
|
10577
|
+
finished = true;
|
|
10578
|
+
releaseReader();
|
|
10579
|
+
controller.error(readError);
|
|
10580
|
+
return;
|
|
10581
|
+
}
|
|
10582
|
+
if (!readResult) return;
|
|
10583
|
+
const result = readResult;
|
|
10584
|
+
readResult = void 0;
|
|
10585
|
+
if (result.done) {
|
|
10586
|
+
finished = true;
|
|
10587
|
+
releaseReader();
|
|
10588
|
+
controller.close();
|
|
10589
|
+
return;
|
|
10590
|
+
}
|
|
10591
|
+
updateFrameBoundary(result.value);
|
|
10592
|
+
controller.enqueue(result.value);
|
|
10593
|
+
};
|
|
10594
|
+
const stream = new ReadableStream({
|
|
10595
|
+
async pull(controller) {
|
|
10596
|
+
if (finished) return;
|
|
10597
|
+
startRead();
|
|
10598
|
+
if (readResult || hasReadError) {
|
|
10599
|
+
forwardRead(controller);
|
|
10600
|
+
return;
|
|
10601
|
+
}
|
|
10602
|
+
const next = await new Promise((resolve) => {
|
|
10603
|
+
wakePull = resolve;
|
|
10604
|
+
if (atFrameBoundary) heartbeatTimeout = setTimeout(() => resolve("heartbeat"), Math.max(0, nextHeartbeatAt - performance.now()));
|
|
10605
|
+
});
|
|
10606
|
+
wakePull = void 0;
|
|
10607
|
+
clearHeartbeat();
|
|
10608
|
+
if (finished) return;
|
|
10609
|
+
if (readResult || hasReadError) {
|
|
10610
|
+
forwardRead(controller);
|
|
10611
|
+
return;
|
|
10612
|
+
}
|
|
10613
|
+
if (next === "heartbeat") {
|
|
10614
|
+
controller.enqueue(SSE_HEARTBEAT_BYTES.slice());
|
|
10615
|
+
nextHeartbeatAt = performance.now() + heartbeatMs;
|
|
10616
|
+
}
|
|
10617
|
+
},
|
|
10618
|
+
async cancel(reason) {
|
|
10619
|
+
if (finished) return;
|
|
10620
|
+
finished = true;
|
|
10621
|
+
clearHeartbeat();
|
|
10622
|
+
try {
|
|
10623
|
+
await reader.cancel(reason);
|
|
10624
|
+
} finally {
|
|
10625
|
+
releaseReader();
|
|
10626
|
+
}
|
|
10627
|
+
}
|
|
10628
|
+
});
|
|
10629
|
+
return new Response(stream, {
|
|
10630
|
+
status: response.status,
|
|
10631
|
+
statusText: response.statusText,
|
|
10632
|
+
headers: response.headers
|
|
10633
|
+
});
|
|
10634
|
+
}
|
|
10635
|
+
//#endregion
|
|
10353
10636
|
//#region src/chat-route.ts
|
|
10354
10637
|
/**
|
|
10355
10638
|
* Collects every approval response across all assistant messages in a v6
|
|
@@ -10552,11 +10835,13 @@ async function handleChatStream({ mastra, agentId, agentVersion, params, default
|
|
|
10552
10835
|
* @param {boolean} [options.sendFinish=true] - Whether to send finish events in the stream
|
|
10553
10836
|
* @param {boolean} [options.sendReasoning=false] - Whether to include reasoning steps in the stream
|
|
10554
10837
|
* @param {boolean} [options.sendSources=false] - Whether to include source citations in the stream
|
|
10838
|
+
* @param {number} [options.heartbeatMs] - Target interval for periodic SSE comment heartbeats. Already-buffered source events and stream lifecycle signals take priority. Values up to 0 disable heartbeats. `NaN`, positive infinity, and values above 2,147,483,647 throw a `RangeError`.
|
|
10555
10839
|
* @param {(error: unknown) => string} [options.onError] - Custom error serializer streamed to the client. When omitted, errors are passed through a default serializer that strips sensitive fields (e.g. `APICallError.requestBodyValues`, which holds the system prompt) before they reach the client.
|
|
10556
10840
|
*
|
|
10557
10841
|
* @returns {ReturnType<typeof registerApiRoute>} A registered API route handler
|
|
10558
10842
|
*
|
|
10559
10843
|
* @throws {Error} When path doesn't include `:agentId` and no fixed agent is specified
|
|
10844
|
+
* @throws {RangeError} When `heartbeatMs` is `NaN`, positive infinity, or greater than 2,147,483,647
|
|
10560
10845
|
* @throws {Error} When agent ID is missing at runtime
|
|
10561
10846
|
* @throws {Error} When specified agent is not found in Mastra instance
|
|
10562
10847
|
*
|
|
@@ -10579,12 +10864,13 @@ async function handleChatStream({ mastra, agentId, agentVersion, params, default
|
|
|
10579
10864
|
* @remarks
|
|
10580
10865
|
* - The route handler expects a JSON body with a `messages` array
|
|
10581
10866
|
* - Messages should follow the format: `{ role: 'user' | 'assistant' | 'system', content: string }`
|
|
10582
|
-
* - The response is a Server-Sent Events (SSE) stream compatible with AI SDK
|
|
10867
|
+
* - The response is a Server-Sent Events (SSE) stream compatible with the selected AI SDK version
|
|
10583
10868
|
* - If both `agent` and `:agentId` are present, a warning is logged and the fixed `agent` takes precedence
|
|
10584
10869
|
* - Request context from the incoming request overrides `defaultOptions.requestContext` if both are present
|
|
10585
10870
|
*/
|
|
10586
|
-
function chatRoute({ path = "/chat/:agentId", agent, defaultOptions, experimentalTransform, version = "v5", agentVersion, sendStart = true, sendFinish = true, sendReasoning = false, sendSources = false, onError }) {
|
|
10871
|
+
function chatRoute({ path = "/chat/:agentId", agent, defaultOptions, experimentalTransform, version = "v5", agentVersion, sendStart = true, sendFinish = true, sendReasoning = false, sendSources = false, heartbeatMs, onError }) {
|
|
10587
10872
|
if (!agent && !path.includes("/:agentId")) throw new Error("Path must include :agentId to route to the correct agent or pass the agent explicitly");
|
|
10873
|
+
assertValidHeartbeatMs(heartbeatMs);
|
|
10588
10874
|
return registerApiRoute(path, {
|
|
10589
10875
|
method: "POST",
|
|
10590
10876
|
openapi: {
|
|
@@ -10713,11 +10999,13 @@ function chatRoute({ path = "/chat/:agentId", agent, defaultOptions, experimenta
|
|
|
10713
10999
|
sendSources,
|
|
10714
11000
|
onError
|
|
10715
11001
|
};
|
|
10716
|
-
|
|
11002
|
+
let response;
|
|
11003
|
+
if (version === "v6") response = createUIMessageStreamResponse({ stream: await handleChatStream({
|
|
10717
11004
|
...handlerOptions,
|
|
10718
11005
|
version: "v6"
|
|
10719
11006
|
}) });
|
|
10720
|
-
|
|
11007
|
+
else response = createUIMessageStreamResponse$1({ stream: await handleChatStream(handlerOptions) });
|
|
11008
|
+
return withSseHeartbeat(response, heartbeatMs);
|
|
10721
11009
|
}
|
|
10722
11010
|
});
|
|
10723
11011
|
}
|