@mastra/client-js 1.56.0-alpha.1 → 1.56.0-alpha.11
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/client.d.ts +3 -3
- package/dist/client.d.ts.map +1 -1
- package/dist/docs/SKILL.md +2 -2
- package/dist/docs/assets/SOURCE_MAP.json +1 -1
- package/dist/docs/references/docs-harness-agent-controller.md +11 -14
- package/dist/docs/references/docs-harness-schedules.md +8 -6
- package/dist/docs/references/docs-harness-signals.md +3 -1
- package/dist/docs/references/reference-client-js-agent-controller.md +15 -3
- package/dist/docs/references/reference-client-js-agents.md +20 -0
- package/dist/docs/references/reference-client-js-mastra-client.md +1 -1
- package/dist/docs/references/reference-client-js-observability.md +124 -9
- package/dist/docs/references/{reference-observability-tracing-trace-query.md → reference-observability-tracing-advanced-queries.md} +486 -158
- package/dist/index.cjs +913 -118
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +906 -111
- package/dist/index.js.map +1 -1
- package/dist/resources/agent-controller.d.ts +36 -26
- package/dist/resources/agent-controller.d.ts.map +1 -1
- package/dist/resources/agent.d.ts +54 -6
- package/dist/resources/agent.d.ts.map +1 -1
- package/dist/resources/base.d.ts.map +1 -1
- package/dist/resources/observability.d.ts +9 -7
- package/dist/resources/observability.d.ts.map +1 -1
- package/dist/route-types.generated.d.ts +711 -596
- package/dist/route-types.generated.d.ts.map +1 -1
- package/dist/types.d.ts +9 -9
- package/dist/types.d.ts.map +1 -1
- package/dist/utils/ai-sdk-v4/data-stream-parts.d.ts +89 -0
- package/dist/utils/ai-sdk-v4/data-stream-parts.d.ts.map +1 -0
- package/dist/utils/ai-sdk-v4/fix-json.d.ts +2 -0
- package/dist/utils/ai-sdk-v4/fix-json.d.ts.map +1 -0
- package/dist/utils/ai-sdk-v4/index.d.ts +5 -0
- package/dist/utils/ai-sdk-v4/index.d.ts.map +1 -0
- package/dist/utils/ai-sdk-v4/parse-partial-json.d.ts +6 -0
- package/dist/utils/ai-sdk-v4/parse-partial-json.d.ts.map +1 -0
- package/dist/utils/ai-sdk-v4/process-data-stream.d.ts +53 -0
- package/dist/utils/ai-sdk-v4/process-data-stream.d.ts.map +1 -0
- package/dist/utils/ai-sdk-v4/types.d.ts +93 -0
- package/dist/utils/ai-sdk-v4/types.d.ts.map +1 -0
- package/dist/utils/index.d.ts +7 -0
- package/dist/utils/index.d.ts.map +1 -1
- package/package.json +9 -11
- package/dist/_types/@ai-sdk_provider/dist/index.d.ts +0 -1587
- package/dist/_types/@ai-sdk_provider/package.json +0 -1
- package/dist/_types/@ai-sdk_provider-utils/dist/index.d.ts +0 -379
- package/dist/_types/@ai-sdk_provider-utils/package.json +0 -1
- package/dist/_types/@ai-sdk_ui-utils/dist/index.d.ts +0 -820
- package/dist/_types/@ai-sdk_ui-utils/package.json +0 -1
package/dist/index.cjs
CHANGED
|
@@ -16,16 +16,15 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
16
16
|
}
|
|
17
17
|
return to;
|
|
18
18
|
};
|
|
19
|
-
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
|
|
19
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule || !__hasOwnProp.call(mod, "default") ? __defProp(target, "default", {
|
|
20
20
|
value: mod,
|
|
21
21
|
enumerable: true
|
|
22
22
|
}) : target, mod));
|
|
23
23
|
//#endregion
|
|
24
|
-
let _ai_sdk_ui_utils = require("@ai-sdk/ui-utils");
|
|
25
24
|
let _lukeed_uuid = require("@lukeed/uuid");
|
|
26
25
|
let _mastra_core_error = require("@mastra/core/error");
|
|
27
|
-
let _mastra_schema_compat_schema = require("@mastra/schema-compat/schema");
|
|
28
26
|
let _mastra_core_request_context = require("@mastra/core/request-context");
|
|
27
|
+
let _mastra_schema_compat_schema = require("@mastra/schema-compat/schema");
|
|
29
28
|
let _mastra_schema_compat_zod_to_json = require("@mastra/schema-compat/zod-to-json");
|
|
30
29
|
let _mastra_core_a2a_client = require("@mastra/core/a2a/client");
|
|
31
30
|
let _mastra_core_a2a_v1 = require("@mastra/core/a2a/v1");
|
|
@@ -84,15 +83,16 @@ function attributesToOtlp(attrs) {
|
|
|
84
83
|
key,
|
|
85
84
|
value: { boolValue: raw }
|
|
86
85
|
});
|
|
87
|
-
else if (typeof raw === "number")
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
86
|
+
else if (typeof raw === "number") {
|
|
87
|
+
if (Number.isInteger(raw)) out.push({
|
|
88
|
+
key,
|
|
89
|
+
value: { intValue: raw }
|
|
90
|
+
});
|
|
91
|
+
else out.push({
|
|
92
|
+
key,
|
|
93
|
+
value: { doubleValue: raw }
|
|
94
|
+
});
|
|
95
|
+
} else try {
|
|
96
96
|
out.push({
|
|
97
97
|
key,
|
|
98
98
|
value: { stringValue: JSON.stringify(raw) }
|
|
@@ -401,6 +401,16 @@ function isTerminalHttpError(error) {
|
|
|
401
401
|
return typeof status === "number" && (status >= 400 && status < 500 || status === 501);
|
|
402
402
|
}
|
|
403
403
|
/**
|
|
404
|
+
* Whether an error is the server's trace query execution timeout (504 with code
|
|
405
|
+
* `TRACE_QUERY_EXECUTION_TIMEOUT`). Re-sending the same query hits the same
|
|
406
|
+
* timeout budget, so retrying only repeats an expensive database query.
|
|
407
|
+
* Plain 504s from proxies or gateways do not carry this code and stay retryable.
|
|
408
|
+
*/
|
|
409
|
+
function isTraceQueryTimeoutError(error) {
|
|
410
|
+
const { status, body } = error ?? {};
|
|
411
|
+
return status === 504 && body?.code === "TRACE_QUERY_EXECUTION_TIMEOUT";
|
|
412
|
+
}
|
|
413
|
+
/**
|
|
404
414
|
* Whether a failed resubscribe should end a long-lived subscription instead of
|
|
405
415
|
* retrying. Like {@link isTerminalHttpError}, but 408 Request Timeout and
|
|
406
416
|
* 429 Too Many Requests stay retryable because they mean "try again later".
|
|
@@ -410,6 +420,571 @@ function isTerminalReconnectError(error) {
|
|
|
410
420
|
return isTerminalHttpError(error) && status !== 408 && status !== 429;
|
|
411
421
|
}
|
|
412
422
|
//#endregion
|
|
423
|
+
//#region src/utils/ai-sdk-v4/data-stream-parts.ts
|
|
424
|
+
const dataStreamParts = [
|
|
425
|
+
{
|
|
426
|
+
code: "0",
|
|
427
|
+
name: "text",
|
|
428
|
+
parse: (value) => {
|
|
429
|
+
if (typeof value !== "string") throw new Error("\"text\" parts expect a string value.");
|
|
430
|
+
return {
|
|
431
|
+
type: "text",
|
|
432
|
+
value
|
|
433
|
+
};
|
|
434
|
+
}
|
|
435
|
+
},
|
|
436
|
+
{
|
|
437
|
+
code: "2",
|
|
438
|
+
name: "data",
|
|
439
|
+
parse: (value) => {
|
|
440
|
+
if (!Array.isArray(value)) throw new Error("\"data\" parts expect an array value.");
|
|
441
|
+
return {
|
|
442
|
+
type: "data",
|
|
443
|
+
value
|
|
444
|
+
};
|
|
445
|
+
}
|
|
446
|
+
},
|
|
447
|
+
{
|
|
448
|
+
code: "3",
|
|
449
|
+
name: "error",
|
|
450
|
+
parse: (value) => {
|
|
451
|
+
if (typeof value !== "string") throw new Error("\"error\" parts expect a string value.");
|
|
452
|
+
return {
|
|
453
|
+
type: "error",
|
|
454
|
+
value
|
|
455
|
+
};
|
|
456
|
+
}
|
|
457
|
+
},
|
|
458
|
+
{
|
|
459
|
+
code: "8",
|
|
460
|
+
name: "message_annotations",
|
|
461
|
+
parse: (value) => {
|
|
462
|
+
if (!Array.isArray(value)) throw new Error("\"message_annotations\" parts expect an array value.");
|
|
463
|
+
return {
|
|
464
|
+
type: "message_annotations",
|
|
465
|
+
value
|
|
466
|
+
};
|
|
467
|
+
}
|
|
468
|
+
},
|
|
469
|
+
{
|
|
470
|
+
code: "9",
|
|
471
|
+
name: "tool_call",
|
|
472
|
+
parse: (value) => {
|
|
473
|
+
if (value == null || typeof value !== "object" || !("toolCallId" in value) || typeof value.toolCallId !== "string" || !("toolName" in value) || typeof value.toolName !== "string" || !("args" in value) || typeof value.args !== "object") throw new Error("\"tool_call\" parts expect an object with a \"toolCallId\", \"toolName\", and \"args\" property.");
|
|
474
|
+
return {
|
|
475
|
+
type: "tool_call",
|
|
476
|
+
value
|
|
477
|
+
};
|
|
478
|
+
}
|
|
479
|
+
},
|
|
480
|
+
{
|
|
481
|
+
code: "a",
|
|
482
|
+
name: "tool_result",
|
|
483
|
+
parse: (value) => {
|
|
484
|
+
if (value == null || typeof value !== "object" || !("toolCallId" in value) || typeof value.toolCallId !== "string" || !("result" in value)) throw new Error("\"tool_result\" parts expect an object with a \"toolCallId\" and a \"result\" property.");
|
|
485
|
+
return {
|
|
486
|
+
type: "tool_result",
|
|
487
|
+
value
|
|
488
|
+
};
|
|
489
|
+
}
|
|
490
|
+
},
|
|
491
|
+
{
|
|
492
|
+
code: "b",
|
|
493
|
+
name: "tool_call_streaming_start",
|
|
494
|
+
parse: (value) => {
|
|
495
|
+
if (value == null || typeof value !== "object" || !("toolCallId" in value) || typeof value.toolCallId !== "string" || !("toolName" in value) || typeof value.toolName !== "string") throw new Error("\"tool_call_streaming_start\" parts expect an object with a \"toolCallId\" and \"toolName\" property.");
|
|
496
|
+
return {
|
|
497
|
+
type: "tool_call_streaming_start",
|
|
498
|
+
value
|
|
499
|
+
};
|
|
500
|
+
}
|
|
501
|
+
},
|
|
502
|
+
{
|
|
503
|
+
code: "c",
|
|
504
|
+
name: "tool_call_delta",
|
|
505
|
+
parse: (value) => {
|
|
506
|
+
if (value == null || typeof value !== "object" || !("toolCallId" in value) || typeof value.toolCallId !== "string" || !("argsTextDelta" in value) || typeof value.argsTextDelta !== "string") throw new Error("\"tool_call_delta\" parts expect an object with a \"toolCallId\" and \"argsTextDelta\" property.");
|
|
507
|
+
return {
|
|
508
|
+
type: "tool_call_delta",
|
|
509
|
+
value
|
|
510
|
+
};
|
|
511
|
+
}
|
|
512
|
+
},
|
|
513
|
+
{
|
|
514
|
+
code: "d",
|
|
515
|
+
name: "finish_message",
|
|
516
|
+
parse: (value) => {
|
|
517
|
+
if (value == null || typeof value !== "object" || !("finishReason" in value) || typeof value.finishReason !== "string") throw new Error("\"finish_message\" parts expect an object with a \"finishReason\" property.");
|
|
518
|
+
const result = { finishReason: value.finishReason };
|
|
519
|
+
if ("usage" in value && value.usage != null && typeof value.usage === "object" && "promptTokens" in value.usage && "completionTokens" in value.usage) result.usage = {
|
|
520
|
+
promptTokens: typeof value.usage.promptTokens === "number" ? value.usage.promptTokens : NaN,
|
|
521
|
+
completionTokens: typeof value.usage.completionTokens === "number" ? value.usage.completionTokens : NaN
|
|
522
|
+
};
|
|
523
|
+
return {
|
|
524
|
+
type: "finish_message",
|
|
525
|
+
value: result
|
|
526
|
+
};
|
|
527
|
+
}
|
|
528
|
+
},
|
|
529
|
+
{
|
|
530
|
+
code: "e",
|
|
531
|
+
name: "finish_step",
|
|
532
|
+
parse: (value) => {
|
|
533
|
+
if (value == null || typeof value !== "object" || !("finishReason" in value) || typeof value.finishReason !== "string") throw new Error("\"finish_step\" parts expect an object with a \"finishReason\" property.");
|
|
534
|
+
const result = {
|
|
535
|
+
finishReason: value.finishReason,
|
|
536
|
+
isContinued: false
|
|
537
|
+
};
|
|
538
|
+
if ("usage" in value && value.usage != null && typeof value.usage === "object" && "promptTokens" in value.usage && "completionTokens" in value.usage) result.usage = {
|
|
539
|
+
promptTokens: typeof value.usage.promptTokens === "number" ? value.usage.promptTokens : NaN,
|
|
540
|
+
completionTokens: typeof value.usage.completionTokens === "number" ? value.usage.completionTokens : NaN
|
|
541
|
+
};
|
|
542
|
+
if ("isContinued" in value && typeof value.isContinued === "boolean") result.isContinued = value.isContinued;
|
|
543
|
+
return {
|
|
544
|
+
type: "finish_step",
|
|
545
|
+
value: result
|
|
546
|
+
};
|
|
547
|
+
}
|
|
548
|
+
},
|
|
549
|
+
{
|
|
550
|
+
code: "f",
|
|
551
|
+
name: "start_step",
|
|
552
|
+
parse: (value) => {
|
|
553
|
+
if (value == null || typeof value !== "object" || !("messageId" in value) || typeof value.messageId !== "string") throw new Error("\"start_step\" parts expect an object with an \"id\" property.");
|
|
554
|
+
return {
|
|
555
|
+
type: "start_step",
|
|
556
|
+
value: { messageId: value.messageId }
|
|
557
|
+
};
|
|
558
|
+
}
|
|
559
|
+
},
|
|
560
|
+
{
|
|
561
|
+
code: "g",
|
|
562
|
+
name: "reasoning",
|
|
563
|
+
parse: (value) => {
|
|
564
|
+
if (typeof value !== "string") throw new Error("\"reasoning\" parts expect a string value.");
|
|
565
|
+
return {
|
|
566
|
+
type: "reasoning",
|
|
567
|
+
value
|
|
568
|
+
};
|
|
569
|
+
}
|
|
570
|
+
},
|
|
571
|
+
{
|
|
572
|
+
code: "h",
|
|
573
|
+
name: "source",
|
|
574
|
+
parse: (value) => {
|
|
575
|
+
if (value == null || typeof value !== "object") throw new Error("\"source\" parts expect a Source object.");
|
|
576
|
+
return {
|
|
577
|
+
type: "source",
|
|
578
|
+
value
|
|
579
|
+
};
|
|
580
|
+
}
|
|
581
|
+
},
|
|
582
|
+
{
|
|
583
|
+
code: "i",
|
|
584
|
+
name: "redacted_reasoning",
|
|
585
|
+
parse: (value) => {
|
|
586
|
+
if (value == null || typeof value !== "object" || !("data" in value) || typeof value.data !== "string") throw new Error("\"redacted_reasoning\" parts expect an object with a \"data\" property.");
|
|
587
|
+
return {
|
|
588
|
+
type: "redacted_reasoning",
|
|
589
|
+
value: { data: value.data }
|
|
590
|
+
};
|
|
591
|
+
}
|
|
592
|
+
},
|
|
593
|
+
{
|
|
594
|
+
code: "j",
|
|
595
|
+
name: "reasoning_signature",
|
|
596
|
+
parse: (value) => {
|
|
597
|
+
if (value == null || typeof value !== "object" || !("signature" in value) || typeof value.signature !== "string") throw new Error("\"reasoning_signature\" parts expect an object with a \"signature\" property.");
|
|
598
|
+
return {
|
|
599
|
+
type: "reasoning_signature",
|
|
600
|
+
value: { signature: value.signature }
|
|
601
|
+
};
|
|
602
|
+
}
|
|
603
|
+
},
|
|
604
|
+
{
|
|
605
|
+
code: "k",
|
|
606
|
+
name: "file",
|
|
607
|
+
parse: (value) => {
|
|
608
|
+
if (value == null || typeof value !== "object" || !("data" in value) || typeof value.data !== "string" || !("mimeType" in value) || typeof value.mimeType !== "string") throw new Error("\"file\" parts expect an object with a \"data\" and \"mimeType\" property.");
|
|
609
|
+
return {
|
|
610
|
+
type: "file",
|
|
611
|
+
value
|
|
612
|
+
};
|
|
613
|
+
}
|
|
614
|
+
}
|
|
615
|
+
];
|
|
616
|
+
const dataStreamPartsByCode = Object.fromEntries(dataStreamParts.map((part) => [part.code, part]));
|
|
617
|
+
Object.fromEntries(dataStreamParts.map((part) => [part.name, part.code]));
|
|
618
|
+
const validCodes = dataStreamParts.map((part) => part.code);
|
|
619
|
+
/**
|
|
620
|
+
Parses a stream part from a string.
|
|
621
|
+
|
|
622
|
+
@param line The string to parse.
|
|
623
|
+
@returns The parsed stream part.
|
|
624
|
+
@throws An error if the string cannot be parsed.
|
|
625
|
+
*/
|
|
626
|
+
const parseDataStreamPart = (line) => {
|
|
627
|
+
const firstSeparatorIndex = line.indexOf(":");
|
|
628
|
+
if (firstSeparatorIndex === -1) throw new Error("Failed to parse stream string. No separator found.");
|
|
629
|
+
const prefix = line.slice(0, firstSeparatorIndex);
|
|
630
|
+
if (!validCodes.includes(prefix)) throw new Error(`Failed to parse stream string. Invalid code ${prefix}.`);
|
|
631
|
+
const code = prefix;
|
|
632
|
+
const textValue = line.slice(firstSeparatorIndex + 1);
|
|
633
|
+
const jsonValue = JSON.parse(textValue);
|
|
634
|
+
return dataStreamPartsByCode[code].parse(jsonValue);
|
|
635
|
+
};
|
|
636
|
+
//#endregion
|
|
637
|
+
//#region src/utils/ai-sdk-v4/fix-json.ts
|
|
638
|
+
function fixJson(input) {
|
|
639
|
+
const stack = ["ROOT"];
|
|
640
|
+
let lastValidIndex = -1;
|
|
641
|
+
let literalStart = null;
|
|
642
|
+
function processValueStart(char, i, swapState) {
|
|
643
|
+
switch (char) {
|
|
644
|
+
case "\"":
|
|
645
|
+
lastValidIndex = i;
|
|
646
|
+
stack.pop();
|
|
647
|
+
stack.push(swapState);
|
|
648
|
+
stack.push("INSIDE_STRING");
|
|
649
|
+
break;
|
|
650
|
+
case "f":
|
|
651
|
+
case "t":
|
|
652
|
+
case "n":
|
|
653
|
+
lastValidIndex = i;
|
|
654
|
+
literalStart = i;
|
|
655
|
+
stack.pop();
|
|
656
|
+
stack.push(swapState);
|
|
657
|
+
stack.push("INSIDE_LITERAL");
|
|
658
|
+
break;
|
|
659
|
+
case "-":
|
|
660
|
+
stack.pop();
|
|
661
|
+
stack.push(swapState);
|
|
662
|
+
stack.push("INSIDE_NUMBER");
|
|
663
|
+
break;
|
|
664
|
+
case "0":
|
|
665
|
+
case "1":
|
|
666
|
+
case "2":
|
|
667
|
+
case "3":
|
|
668
|
+
case "4":
|
|
669
|
+
case "5":
|
|
670
|
+
case "6":
|
|
671
|
+
case "7":
|
|
672
|
+
case "8":
|
|
673
|
+
case "9":
|
|
674
|
+
lastValidIndex = i;
|
|
675
|
+
stack.pop();
|
|
676
|
+
stack.push(swapState);
|
|
677
|
+
stack.push("INSIDE_NUMBER");
|
|
678
|
+
break;
|
|
679
|
+
case "{":
|
|
680
|
+
lastValidIndex = i;
|
|
681
|
+
stack.pop();
|
|
682
|
+
stack.push(swapState);
|
|
683
|
+
stack.push("INSIDE_OBJECT_START");
|
|
684
|
+
break;
|
|
685
|
+
case "[":
|
|
686
|
+
lastValidIndex = i;
|
|
687
|
+
stack.pop();
|
|
688
|
+
stack.push(swapState);
|
|
689
|
+
stack.push("INSIDE_ARRAY_START");
|
|
690
|
+
}
|
|
691
|
+
}
|
|
692
|
+
function processAfterObjectValue(char, i) {
|
|
693
|
+
switch (char) {
|
|
694
|
+
case ",":
|
|
695
|
+
stack.pop();
|
|
696
|
+
stack.push("INSIDE_OBJECT_AFTER_COMMA");
|
|
697
|
+
break;
|
|
698
|
+
case "}":
|
|
699
|
+
lastValidIndex = i;
|
|
700
|
+
stack.pop();
|
|
701
|
+
}
|
|
702
|
+
}
|
|
703
|
+
function processAfterArrayValue(char, i) {
|
|
704
|
+
switch (char) {
|
|
705
|
+
case ",":
|
|
706
|
+
stack.pop();
|
|
707
|
+
stack.push("INSIDE_ARRAY_AFTER_COMMA");
|
|
708
|
+
break;
|
|
709
|
+
case "]":
|
|
710
|
+
lastValidIndex = i;
|
|
711
|
+
stack.pop();
|
|
712
|
+
}
|
|
713
|
+
}
|
|
714
|
+
for (let i = 0; i < input.length; i++) {
|
|
715
|
+
const char = input[i];
|
|
716
|
+
switch (stack[stack.length - 1]) {
|
|
717
|
+
case "ROOT":
|
|
718
|
+
processValueStart(char, i, "FINISH");
|
|
719
|
+
break;
|
|
720
|
+
case "INSIDE_OBJECT_START":
|
|
721
|
+
switch (char) {
|
|
722
|
+
case "\"":
|
|
723
|
+
stack.pop();
|
|
724
|
+
stack.push("INSIDE_OBJECT_KEY");
|
|
725
|
+
break;
|
|
726
|
+
case "}":
|
|
727
|
+
lastValidIndex = i;
|
|
728
|
+
stack.pop();
|
|
729
|
+
}
|
|
730
|
+
break;
|
|
731
|
+
case "INSIDE_OBJECT_AFTER_COMMA":
|
|
732
|
+
switch (char) {
|
|
733
|
+
case "\"":
|
|
734
|
+
stack.pop();
|
|
735
|
+
stack.push("INSIDE_OBJECT_KEY");
|
|
736
|
+
}
|
|
737
|
+
break;
|
|
738
|
+
case "INSIDE_OBJECT_KEY":
|
|
739
|
+
switch (char) {
|
|
740
|
+
case "\"":
|
|
741
|
+
stack.pop();
|
|
742
|
+
stack.push("INSIDE_OBJECT_AFTER_KEY");
|
|
743
|
+
}
|
|
744
|
+
break;
|
|
745
|
+
case "INSIDE_OBJECT_AFTER_KEY":
|
|
746
|
+
switch (char) {
|
|
747
|
+
case ":":
|
|
748
|
+
stack.pop();
|
|
749
|
+
stack.push("INSIDE_OBJECT_BEFORE_VALUE");
|
|
750
|
+
}
|
|
751
|
+
break;
|
|
752
|
+
case "INSIDE_OBJECT_BEFORE_VALUE":
|
|
753
|
+
processValueStart(char, i, "INSIDE_OBJECT_AFTER_VALUE");
|
|
754
|
+
break;
|
|
755
|
+
case "INSIDE_OBJECT_AFTER_VALUE":
|
|
756
|
+
processAfterObjectValue(char, i);
|
|
757
|
+
break;
|
|
758
|
+
case "INSIDE_STRING":
|
|
759
|
+
switch (char) {
|
|
760
|
+
case "\"":
|
|
761
|
+
stack.pop();
|
|
762
|
+
lastValidIndex = i;
|
|
763
|
+
break;
|
|
764
|
+
case "\\":
|
|
765
|
+
stack.push("INSIDE_STRING_ESCAPE");
|
|
766
|
+
break;
|
|
767
|
+
default: lastValidIndex = i;
|
|
768
|
+
}
|
|
769
|
+
break;
|
|
770
|
+
case "INSIDE_ARRAY_START":
|
|
771
|
+
switch (char) {
|
|
772
|
+
case "]":
|
|
773
|
+
lastValidIndex = i;
|
|
774
|
+
stack.pop();
|
|
775
|
+
break;
|
|
776
|
+
default:
|
|
777
|
+
lastValidIndex = i;
|
|
778
|
+
processValueStart(char, i, "INSIDE_ARRAY_AFTER_VALUE");
|
|
779
|
+
}
|
|
780
|
+
break;
|
|
781
|
+
case "INSIDE_ARRAY_AFTER_VALUE":
|
|
782
|
+
switch (char) {
|
|
783
|
+
case ",":
|
|
784
|
+
stack.pop();
|
|
785
|
+
stack.push("INSIDE_ARRAY_AFTER_COMMA");
|
|
786
|
+
break;
|
|
787
|
+
case "]":
|
|
788
|
+
lastValidIndex = i;
|
|
789
|
+
stack.pop();
|
|
790
|
+
break;
|
|
791
|
+
default: lastValidIndex = i;
|
|
792
|
+
}
|
|
793
|
+
break;
|
|
794
|
+
case "INSIDE_ARRAY_AFTER_COMMA":
|
|
795
|
+
processValueStart(char, i, "INSIDE_ARRAY_AFTER_VALUE");
|
|
796
|
+
break;
|
|
797
|
+
case "INSIDE_STRING_ESCAPE":
|
|
798
|
+
stack.pop();
|
|
799
|
+
lastValidIndex = i;
|
|
800
|
+
break;
|
|
801
|
+
case "INSIDE_NUMBER":
|
|
802
|
+
switch (char) {
|
|
803
|
+
case "0":
|
|
804
|
+
case "1":
|
|
805
|
+
case "2":
|
|
806
|
+
case "3":
|
|
807
|
+
case "4":
|
|
808
|
+
case "5":
|
|
809
|
+
case "6":
|
|
810
|
+
case "7":
|
|
811
|
+
case "8":
|
|
812
|
+
case "9":
|
|
813
|
+
lastValidIndex = i;
|
|
814
|
+
break;
|
|
815
|
+
case "e":
|
|
816
|
+
case "E":
|
|
817
|
+
case "-":
|
|
818
|
+
case ".": break;
|
|
819
|
+
case ",":
|
|
820
|
+
stack.pop();
|
|
821
|
+
if (stack[stack.length - 1] === "INSIDE_ARRAY_AFTER_VALUE") processAfterArrayValue(char, i);
|
|
822
|
+
if (stack[stack.length - 1] === "INSIDE_OBJECT_AFTER_VALUE") processAfterObjectValue(char, i);
|
|
823
|
+
break;
|
|
824
|
+
case "}":
|
|
825
|
+
stack.pop();
|
|
826
|
+
if (stack[stack.length - 1] === "INSIDE_OBJECT_AFTER_VALUE") processAfterObjectValue(char, i);
|
|
827
|
+
break;
|
|
828
|
+
case "]":
|
|
829
|
+
stack.pop();
|
|
830
|
+
if (stack[stack.length - 1] === "INSIDE_ARRAY_AFTER_VALUE") processAfterArrayValue(char, i);
|
|
831
|
+
break;
|
|
832
|
+
default: stack.pop();
|
|
833
|
+
}
|
|
834
|
+
break;
|
|
835
|
+
case "INSIDE_LITERAL": {
|
|
836
|
+
const partialLiteral = input.substring(literalStart, i + 1);
|
|
837
|
+
if (!"false".startsWith(partialLiteral) && !"true".startsWith(partialLiteral) && !"null".startsWith(partialLiteral)) {
|
|
838
|
+
stack.pop();
|
|
839
|
+
if (stack[stack.length - 1] === "INSIDE_OBJECT_AFTER_VALUE") processAfterObjectValue(char, i);
|
|
840
|
+
else if (stack[stack.length - 1] === "INSIDE_ARRAY_AFTER_VALUE") processAfterArrayValue(char, i);
|
|
841
|
+
} else lastValidIndex = i;
|
|
842
|
+
break;
|
|
843
|
+
}
|
|
844
|
+
}
|
|
845
|
+
}
|
|
846
|
+
let result = input.slice(0, lastValidIndex + 1);
|
|
847
|
+
for (let i = stack.length - 1; i >= 0; i--) switch (stack[i]) {
|
|
848
|
+
case "INSIDE_STRING":
|
|
849
|
+
result += "\"";
|
|
850
|
+
break;
|
|
851
|
+
case "INSIDE_OBJECT_KEY":
|
|
852
|
+
case "INSIDE_OBJECT_AFTER_KEY":
|
|
853
|
+
case "INSIDE_OBJECT_AFTER_COMMA":
|
|
854
|
+
case "INSIDE_OBJECT_START":
|
|
855
|
+
case "INSIDE_OBJECT_BEFORE_VALUE":
|
|
856
|
+
case "INSIDE_OBJECT_AFTER_VALUE":
|
|
857
|
+
result += "}";
|
|
858
|
+
break;
|
|
859
|
+
case "INSIDE_ARRAY_START":
|
|
860
|
+
case "INSIDE_ARRAY_AFTER_COMMA":
|
|
861
|
+
case "INSIDE_ARRAY_AFTER_VALUE":
|
|
862
|
+
result += "]";
|
|
863
|
+
break;
|
|
864
|
+
case "INSIDE_LITERAL": {
|
|
865
|
+
const partialLiteral = input.substring(literalStart, input.length);
|
|
866
|
+
if ("true".startsWith(partialLiteral)) result += "true".slice(partialLiteral.length);
|
|
867
|
+
else if ("false".startsWith(partialLiteral)) result += "false".slice(partialLiteral.length);
|
|
868
|
+
else if ("null".startsWith(partialLiteral)) result += "null".slice(partialLiteral.length);
|
|
869
|
+
}
|
|
870
|
+
}
|
|
871
|
+
return result;
|
|
872
|
+
}
|
|
873
|
+
//#endregion
|
|
874
|
+
//#region src/utils/ai-sdk-v4/parse-partial-json.ts
|
|
875
|
+
function tryParse(text) {
|
|
876
|
+
try {
|
|
877
|
+
return {
|
|
878
|
+
success: true,
|
|
879
|
+
value: JSON.parse(text)
|
|
880
|
+
};
|
|
881
|
+
} catch {
|
|
882
|
+
return { success: false };
|
|
883
|
+
}
|
|
884
|
+
}
|
|
885
|
+
function parsePartialJson(jsonText) {
|
|
886
|
+
if (jsonText === void 0) return {
|
|
887
|
+
value: void 0,
|
|
888
|
+
state: "undefined-input"
|
|
889
|
+
};
|
|
890
|
+
let result = tryParse(jsonText);
|
|
891
|
+
if (result.success) return {
|
|
892
|
+
value: result.value,
|
|
893
|
+
state: "successful-parse"
|
|
894
|
+
};
|
|
895
|
+
result = tryParse(fixJson(jsonText));
|
|
896
|
+
if (result.success) return {
|
|
897
|
+
value: result.value,
|
|
898
|
+
state: "repaired-parse"
|
|
899
|
+
};
|
|
900
|
+
return {
|
|
901
|
+
value: void 0,
|
|
902
|
+
state: "failed-parse"
|
|
903
|
+
};
|
|
904
|
+
}
|
|
905
|
+
//#endregion
|
|
906
|
+
//#region src/utils/ai-sdk-v4/process-data-stream.ts
|
|
907
|
+
const NEWLINE = "\n".charCodeAt(0);
|
|
908
|
+
function concatChunks(chunks, totalLength) {
|
|
909
|
+
const concatenatedChunks = new Uint8Array(totalLength);
|
|
910
|
+
let offset = 0;
|
|
911
|
+
for (const chunk of chunks) {
|
|
912
|
+
concatenatedChunks.set(chunk, offset);
|
|
913
|
+
offset += chunk.length;
|
|
914
|
+
}
|
|
915
|
+
chunks.length = 0;
|
|
916
|
+
return concatenatedChunks;
|
|
917
|
+
}
|
|
918
|
+
async function processDataStream({ stream, onTextPart, onReasoningPart, onReasoningSignaturePart, onRedactedReasoningPart, onSourcePart, onFilePart, onDataPart, onErrorPart, onToolCallStreamingStartPart, onToolCallDeltaPart, onToolCallPart, onToolResultPart, onMessageAnnotationsPart, onFinishMessagePart, onFinishStepPart, onStartStepPart }) {
|
|
919
|
+
const reader = stream.getReader();
|
|
920
|
+
const decoder = new TextDecoder();
|
|
921
|
+
const chunks = [];
|
|
922
|
+
let totalLength = 0;
|
|
923
|
+
while (true) {
|
|
924
|
+
const { value } = await reader.read();
|
|
925
|
+
if (value) {
|
|
926
|
+
chunks.push(value);
|
|
927
|
+
totalLength += value.length;
|
|
928
|
+
if (value[value.length - 1] !== NEWLINE) continue;
|
|
929
|
+
}
|
|
930
|
+
if (chunks.length === 0) break;
|
|
931
|
+
const concatenatedChunks = concatChunks(chunks, totalLength);
|
|
932
|
+
totalLength = 0;
|
|
933
|
+
const streamParts = decoder.decode(concatenatedChunks, { stream: true }).split("\n").filter((line) => line !== "").map(parseDataStreamPart);
|
|
934
|
+
for (const { type, value } of streamParts) switch (type) {
|
|
935
|
+
case "text":
|
|
936
|
+
await onTextPart?.(value);
|
|
937
|
+
break;
|
|
938
|
+
case "reasoning":
|
|
939
|
+
await onReasoningPart?.(value);
|
|
940
|
+
break;
|
|
941
|
+
case "reasoning_signature":
|
|
942
|
+
await onReasoningSignaturePart?.(value);
|
|
943
|
+
break;
|
|
944
|
+
case "redacted_reasoning":
|
|
945
|
+
await onRedactedReasoningPart?.(value);
|
|
946
|
+
break;
|
|
947
|
+
case "file":
|
|
948
|
+
await onFilePart?.(value);
|
|
949
|
+
break;
|
|
950
|
+
case "source":
|
|
951
|
+
await onSourcePart?.(value);
|
|
952
|
+
break;
|
|
953
|
+
case "data":
|
|
954
|
+
await onDataPart?.(value);
|
|
955
|
+
break;
|
|
956
|
+
case "error":
|
|
957
|
+
await onErrorPart?.(value);
|
|
958
|
+
break;
|
|
959
|
+
case "message_annotations":
|
|
960
|
+
await onMessageAnnotationsPart?.(value);
|
|
961
|
+
break;
|
|
962
|
+
case "tool_call_streaming_start":
|
|
963
|
+
await onToolCallStreamingStartPart?.(value);
|
|
964
|
+
break;
|
|
965
|
+
case "tool_call_delta":
|
|
966
|
+
await onToolCallDeltaPart?.(value);
|
|
967
|
+
break;
|
|
968
|
+
case "tool_call":
|
|
969
|
+
await onToolCallPart?.(value);
|
|
970
|
+
break;
|
|
971
|
+
case "tool_result":
|
|
972
|
+
await onToolResultPart?.(value);
|
|
973
|
+
break;
|
|
974
|
+
case "finish_message":
|
|
975
|
+
await onFinishMessagePart?.(value);
|
|
976
|
+
break;
|
|
977
|
+
case "finish_step":
|
|
978
|
+
await onFinishStepPart?.(value);
|
|
979
|
+
break;
|
|
980
|
+
case "start_step":
|
|
981
|
+
await onStartStepPart?.(value);
|
|
982
|
+
break;
|
|
983
|
+
default: throw new Error(`Unknown stream part type: ${type}`);
|
|
984
|
+
}
|
|
985
|
+
}
|
|
986
|
+
}
|
|
987
|
+
//#endregion
|
|
413
988
|
//#region src/utils/client-tool-model-output.ts
|
|
414
989
|
/**
|
|
415
990
|
* Normalize modelOutput from toModelOutput() to the AI SDK V2 tool result
|
|
@@ -642,7 +1217,7 @@ var BaseResource = class {
|
|
|
642
1217
|
} catch (error) {
|
|
643
1218
|
lastError = error;
|
|
644
1219
|
if (signal?.aborted || error?.name === "AbortError") throw error;
|
|
645
|
-
if (isTerminalHttpError(error)) throw error;
|
|
1220
|
+
if (isTerminalHttpError(error) || isTraceQueryTimeoutError(error)) throw error;
|
|
646
1221
|
if (attempt === retries) break;
|
|
647
1222
|
await new Promise((resolve, reject) => {
|
|
648
1223
|
const timer = setTimeout(() => {
|
|
@@ -663,8 +1238,16 @@ var BaseResource = class {
|
|
|
663
1238
|
};
|
|
664
1239
|
//#endregion
|
|
665
1240
|
//#region src/resources/agent.ts
|
|
666
|
-
const SIGNAL_RUNTIME_OPTIONS_TTL_MS =
|
|
1241
|
+
const SIGNAL_RUNTIME_OPTIONS_TTL_MS = 3e5;
|
|
667
1242
|
const signalRuntimeOptionsByRunId = /* @__PURE__ */ new Map();
|
|
1243
|
+
/**
|
|
1244
|
+
* Client tools a resume request can execute, keyed by run. The stream that stayed open from
|
|
1245
|
+
* before the suspension must not run those tools again, but it must run any resumed client tool
|
|
1246
|
+
* the resume request cannot execute (a server-side approve sends no client tools). Held until the
|
|
1247
|
+
* last stream of the run closes, which is after the resume request returns.
|
|
1248
|
+
*/
|
|
1249
|
+
const resumingClientToolNamesByRunKey = /* @__PURE__ */ new Map();
|
|
1250
|
+
const openStreamCountByRunKey = /* @__PURE__ */ new Map();
|
|
668
1251
|
const latestSignalRuntimeOptionsByThread = /* @__PURE__ */ new Map();
|
|
669
1252
|
const createSignalRuntimeOptionsEntry = (store, key, streamOptions) => {
|
|
670
1253
|
const timeout = setTimeout(() => store.delete(key), SIGNAL_RUNTIME_OPTIONS_TTL_MS);
|
|
@@ -857,6 +1440,49 @@ var Agent = class extends BaseResource {
|
|
|
857
1440
|
getSignalRuntimeRunKey(runId) {
|
|
858
1441
|
return `${this.options.baseUrl}|${this.apiPrefix}|${this.agentId}|${runId}`;
|
|
859
1442
|
}
|
|
1443
|
+
/**
|
|
1444
|
+
* Records that `runId` is being resumed by a request that can execute these client tools, so the
|
|
1445
|
+
* stream that is still open from before the suspension skips them. Released when the last stream
|
|
1446
|
+
* of the run closes, which is after this request returns.
|
|
1447
|
+
*/
|
|
1448
|
+
holdResumingClientTools(runId, clientTools) {
|
|
1449
|
+
const names = Object.entries(clientTools ?? {}).filter(([, tool]) => typeof tool.execute === "function").map(([name]) => name);
|
|
1450
|
+
if (names.length === 0) return () => {};
|
|
1451
|
+
const key = this.getSignalRuntimeRunKey(runId);
|
|
1452
|
+
const held = resumingClientToolNamesByRunKey.get(key) ?? /* @__PURE__ */ new Map();
|
|
1453
|
+
for (const name of names) held.set(name, (held.get(name) ?? 0) + 1);
|
|
1454
|
+
resumingClientToolNamesByRunKey.set(key, held);
|
|
1455
|
+
let released = false;
|
|
1456
|
+
return ({ force = false } = {}) => {
|
|
1457
|
+
if (released || !force && openStreamCountByRunKey.has(key)) return;
|
|
1458
|
+
released = true;
|
|
1459
|
+
const current = resumingClientToolNamesByRunKey.get(key);
|
|
1460
|
+
if (!current) return;
|
|
1461
|
+
for (const name of names) {
|
|
1462
|
+
const count = (current.get(name) ?? 1) - 1;
|
|
1463
|
+
if (count > 0) current.set(name, count);
|
|
1464
|
+
else current.delete(name);
|
|
1465
|
+
}
|
|
1466
|
+
if (current.size === 0) resumingClientToolNamesByRunKey.delete(key);
|
|
1467
|
+
};
|
|
1468
|
+
}
|
|
1469
|
+
/** Drops the held tool names when the last stream of the run closes. */
|
|
1470
|
+
trackOpenStream(runId) {
|
|
1471
|
+
const key = this.getSignalRuntimeRunKey(runId);
|
|
1472
|
+
openStreamCountByRunKey.set(key, (openStreamCountByRunKey.get(key) ?? 0) + 1);
|
|
1473
|
+
let released = false;
|
|
1474
|
+
return () => {
|
|
1475
|
+
if (released) return;
|
|
1476
|
+
released = true;
|
|
1477
|
+
const remaining = (openStreamCountByRunKey.get(key) ?? 1) - 1;
|
|
1478
|
+
if (remaining > 0) {
|
|
1479
|
+
openStreamCountByRunKey.set(key, remaining);
|
|
1480
|
+
return;
|
|
1481
|
+
}
|
|
1482
|
+
openStreamCountByRunKey.delete(key);
|
|
1483
|
+
resumingClientToolNamesByRunKey.delete(key);
|
|
1484
|
+
};
|
|
1485
|
+
}
|
|
860
1486
|
getSignalRuntimeThreadKey({ resourceId, threadId }) {
|
|
861
1487
|
if (!threadId) return void 0;
|
|
862
1488
|
return `${this.options.baseUrl}|${this.apiPrefix}|${this.agentId}|${resourceId ?? ""}|${threadId}`;
|
|
@@ -1543,7 +2169,7 @@ var Agent = class extends BaseResource {
|
|
|
1543
2169
|
replaceLastMessage
|
|
1544
2170
|
});
|
|
1545
2171
|
}
|
|
1546
|
-
await
|
|
2172
|
+
await processDataStream({
|
|
1547
2173
|
stream,
|
|
1548
2174
|
onTextPart(value) {
|
|
1549
2175
|
if (currentTextPart == null) {
|
|
@@ -1634,7 +2260,7 @@ var Agent = class extends BaseResource {
|
|
|
1634
2260
|
onToolCallDeltaPart(value) {
|
|
1635
2261
|
const partialToolCall = partialToolCalls[value.toolCallId];
|
|
1636
2262
|
partialToolCall.text += value.argsTextDelta;
|
|
1637
|
-
const { value: partialArgs } =
|
|
2263
|
+
const { value: partialArgs } = parsePartialJson(partialToolCall.text);
|
|
1638
2264
|
const invocation = {
|
|
1639
2265
|
state: "partial-call",
|
|
1640
2266
|
step: partialToolCall.step,
|
|
@@ -1649,7 +2275,7 @@ var Agent = class extends BaseResource {
|
|
|
1649
2275
|
},
|
|
1650
2276
|
async onToolCallPart(value) {
|
|
1651
2277
|
const partialToolCall = partialToolCalls[value.toolCallId];
|
|
1652
|
-
const streamedArgs = partialToolCall?.text ?
|
|
2278
|
+
const streamedArgs = partialToolCall?.text ? parsePartialJson(partialToolCall.text).value : void 0;
|
|
1653
2279
|
const toolCall = streamedArgs === void 0 ? value : {
|
|
1654
2280
|
...value,
|
|
1655
2281
|
args: streamedArgs
|
|
@@ -1764,7 +2390,7 @@ var Agent = class extends BaseResource {
|
|
|
1764
2390
|
headers: response.headers
|
|
1765
2391
|
});
|
|
1766
2392
|
streamResponse.processDataStream = async (options = {}) => {
|
|
1767
|
-
await
|
|
2393
|
+
await processDataStream({
|
|
1768
2394
|
stream: streamResponse.body,
|
|
1769
2395
|
...options
|
|
1770
2396
|
});
|
|
@@ -1888,7 +2514,7 @@ var Agent = class extends BaseResource {
|
|
|
1888
2514
|
break;
|
|
1889
2515
|
case "tool-call": {
|
|
1890
2516
|
const partialToolCall = partialToolCalls[chunk.payload.toolCallId];
|
|
1891
|
-
const streamedArgs = partialToolCall?.text ?
|
|
2517
|
+
const streamedArgs = partialToolCall?.text ? parsePartialJson(partialToolCall.text).value : void 0;
|
|
1892
2518
|
const toolCall = streamedArgs === void 0 ? chunk.payload : {
|
|
1893
2519
|
...chunk.payload,
|
|
1894
2520
|
args: streamedArgs
|
|
@@ -1947,7 +2573,7 @@ var Agent = class extends BaseResource {
|
|
|
1947
2573
|
case "tool-call-delta": {
|
|
1948
2574
|
const partialToolCall = partialToolCalls[chunk.payload.toolCallId];
|
|
1949
2575
|
partialToolCall.text += chunk.payload.argsTextDelta;
|
|
1950
|
-
const { value: partialArgs } =
|
|
2576
|
+
const { value: partialArgs } = parsePartialJson(partialToolCall.text);
|
|
1951
2577
|
const invocation = {
|
|
1952
2578
|
state: "partial-call",
|
|
1953
2579
|
step: partialToolCall.step,
|
|
@@ -1994,7 +2620,6 @@ var Agent = class extends BaseResource {
|
|
|
1994
2620
|
case "finish":
|
|
1995
2621
|
finishReason = chunk.payload?.stepResult?.reason ?? finishReason;
|
|
1996
2622
|
if (chunk.payload?.usage != null) usage = chunk.payload.usage;
|
|
1997
|
-
break;
|
|
1998
2623
|
}
|
|
1999
2624
|
}
|
|
2000
2625
|
});
|
|
@@ -2058,6 +2683,10 @@ var Agent = class extends BaseResource {
|
|
|
2058
2683
|
try {
|
|
2059
2684
|
let messages = [];
|
|
2060
2685
|
let streamRunId = processedParams.runId;
|
|
2686
|
+
let finishedHistory;
|
|
2687
|
+
let suspended = false;
|
|
2688
|
+
const resumedToolCallIds = /* @__PURE__ */ new Set();
|
|
2689
|
+
const releaseOpenStream = streamRunId ? this.trackOpenStream(streamRunId) : () => {};
|
|
2061
2690
|
const [streamForController, streamForProcessing] = response.body.tee();
|
|
2062
2691
|
const decoder = new TextDecoder();
|
|
2063
2692
|
let pendingText = "";
|
|
@@ -2065,6 +2694,13 @@ var Agent = class extends BaseResource {
|
|
|
2065
2694
|
pendingText += text;
|
|
2066
2695
|
const lines = pendingText.split("\n\n");
|
|
2067
2696
|
pendingText = isFinal ? "" : lines.pop() ?? "";
|
|
2697
|
+
for (const line of lines) {
|
|
2698
|
+
if (!line.startsWith("data: ") || !line.includes("\"type\":\"finish\"")) continue;
|
|
2699
|
+
try {
|
|
2700
|
+
const all = JSON.parse(line.slice(6))?.payload?.messages?.all;
|
|
2701
|
+
if (Array.isArray(all)) finishedHistory = all;
|
|
2702
|
+
} catch {}
|
|
2703
|
+
}
|
|
2068
2704
|
const readableLines = lines.filter((line) => line.trim() !== "[DONE]" && line.trim() !== "data: [DONE]").join("\n\n");
|
|
2069
2705
|
if (readableLines) safeEnqueue(new TextEncoder().encode(`${readableLines}\n\n`));
|
|
2070
2706
|
};
|
|
@@ -2119,6 +2755,9 @@ var Agent = class extends BaseResource {
|
|
|
2119
2755
|
});
|
|
2120
2756
|
}
|
|
2121
2757
|
const executableToolCalls = [...toolInvocationsById.values()].filter((toolCall) => {
|
|
2758
|
+
if (resumedToolCallIds.has(toolCall.toolCallId)) {
|
|
2759
|
+
if ((streamRunId ? resumingClientToolNamesByRunKey.get(this.getSignalRuntimeRunKey(streamRunId)) : void 0)?.has(toolCall.toolName)) return false;
|
|
2760
|
+
}
|
|
2122
2761
|
const clientTool = processedParams.clientTools?.[toolCall.toolName];
|
|
2123
2762
|
return Boolean(clientTool?.execute);
|
|
2124
2763
|
});
|
|
@@ -2218,12 +2857,12 @@ var Agent = class extends BaseResource {
|
|
|
2218
2857
|
role: "tool",
|
|
2219
2858
|
content: toolResultContents
|
|
2220
2859
|
};
|
|
2221
|
-
const updatedMessages = threadId ? [toolResultMessage] : [
|
|
2860
|
+
const updatedMessages = threadId ? [toolResultMessage] : (route === "resume-stream" || route === "approve-tool-call" || route === "decline-tool-call") && finishedHistory ? [...finishedHistory, toolResultMessage] : [
|
|
2222
2861
|
...Array.isArray(processedParams.messages) ? processedParams.messages : [],
|
|
2223
2862
|
...messages,
|
|
2224
2863
|
toolResultMessage
|
|
2225
2864
|
];
|
|
2226
|
-
const recursionRoute = route === "resume-stream" ? "stream" : route === "resume-stream-until-idle" ? "stream-until-idle" : route;
|
|
2865
|
+
const recursionRoute = route === "resume-stream" || route === "approve-tool-call" || route === "decline-tool-call" ? "stream" : route === "resume-stream-until-idle" ? "stream-until-idle" : route;
|
|
2227
2866
|
if (isAborted()) return;
|
|
2228
2867
|
try {
|
|
2229
2868
|
await this.processStreamResponse({
|
|
@@ -2245,6 +2884,12 @@ var Agent = class extends BaseResource {
|
|
|
2245
2884
|
},
|
|
2246
2885
|
onStreamChunk: (chunk) => {
|
|
2247
2886
|
if (!streamRunId && typeof chunk.runId === "string") streamRunId = chunk.runId;
|
|
2887
|
+
if (chunk.type === "tool-call-approval" || chunk.type === "tool-call-suspended") suspended = true;
|
|
2888
|
+
else if (suspended && chunk.type === "tool-call" && typeof chunk.payload?.toolCallId === "string") {
|
|
2889
|
+
const toolName = chunk.payload.toolName;
|
|
2890
|
+
const held = streamRunId ? resumingClientToolNamesByRunKey.get(this.getSignalRuntimeRunKey(streamRunId)) : void 0;
|
|
2891
|
+
if (typeof toolName === "string" && held?.has(toolName)) resumedToolCallIds.add(chunk.payload.toolCallId);
|
|
2892
|
+
}
|
|
2248
2893
|
},
|
|
2249
2894
|
lastMessage: void 0
|
|
2250
2895
|
}).catch(async (error) => {
|
|
@@ -2255,6 +2900,7 @@ var Agent = class extends BaseResource {
|
|
|
2255
2900
|
safeClose();
|
|
2256
2901
|
}).finally(() => {
|
|
2257
2902
|
signal?.removeEventListener("abort", onAbort);
|
|
2903
|
+
releaseOpenStream();
|
|
2258
2904
|
});
|
|
2259
2905
|
} catch (error) {
|
|
2260
2906
|
if (!isAbortError(error)) console.error("Error processing stream response:", error);
|
|
@@ -2422,12 +3068,18 @@ var Agent = class extends BaseResource {
|
|
|
2422
3068
|
}
|
|
2423
3069
|
async approveToolCall(params) {
|
|
2424
3070
|
const { requestContext, ...rest } = params;
|
|
3071
|
+
const executableClientTools = params.clientToolsResolver?.() ?? params.clientTools;
|
|
3072
|
+
const releaseHold = this.holdResumingClientTools(rest.runId, executableClientTools);
|
|
2425
3073
|
const processedParams = {
|
|
2426
3074
|
...rest,
|
|
2427
|
-
requestContext: parseClientRequestContext(requestContext)
|
|
3075
|
+
requestContext: parseClientRequestContext(requestContext),
|
|
3076
|
+
clientTools: processClientTools(executableClientTools)
|
|
2428
3077
|
};
|
|
2429
3078
|
const { readable, controller: readableController, signal } = this.createCancellableStream(params.abortSignal);
|
|
2430
|
-
const response = await this.processStreamResponse(processedParams, readableController, "approve-tool-call", signal)
|
|
3079
|
+
const response = await this.processStreamResponse(processedParams, readableController, "approve-tool-call", signal).catch((error) => {
|
|
3080
|
+
releaseHold({ force: true });
|
|
3081
|
+
throw error;
|
|
3082
|
+
});
|
|
2431
3083
|
const streamResponse = new Response(readable, {
|
|
2432
3084
|
status: response.status,
|
|
2433
3085
|
statusText: response.statusText,
|
|
@@ -2453,12 +3105,18 @@ var Agent = class extends BaseResource {
|
|
|
2453
3105
|
}
|
|
2454
3106
|
async declineToolCall(params) {
|
|
2455
3107
|
const { requestContext, ...rest } = params;
|
|
3108
|
+
const executableClientTools = params.clientToolsResolver?.() ?? params.clientTools;
|
|
3109
|
+
const releaseHold = this.holdResumingClientTools(rest.runId, executableClientTools);
|
|
2456
3110
|
const processedParams = {
|
|
2457
3111
|
...rest,
|
|
2458
|
-
requestContext: parseClientRequestContext(requestContext)
|
|
3112
|
+
requestContext: parseClientRequestContext(requestContext),
|
|
3113
|
+
clientTools: processClientTools(executableClientTools)
|
|
2459
3114
|
};
|
|
2460
3115
|
const { readable, controller: readableController, signal } = this.createCancellableStream(params.abortSignal);
|
|
2461
|
-
const response = await this.processStreamResponse(processedParams, readableController, "decline-tool-call", signal)
|
|
3116
|
+
const response = await this.processStreamResponse(processedParams, readableController, "decline-tool-call", signal).catch((error) => {
|
|
3117
|
+
releaseHold({ force: true });
|
|
3118
|
+
throw error;
|
|
3119
|
+
});
|
|
2462
3120
|
const streamResponse = new Response(readable, {
|
|
2463
3121
|
status: response.status,
|
|
2464
3122
|
statusText: response.statusText,
|
|
@@ -2518,18 +3176,23 @@ var Agent = class extends BaseResource {
|
|
|
2518
3176
|
* Used to continue execution after a suspension point (e.g., workflow suspend within an agent).
|
|
2519
3177
|
*/
|
|
2520
3178
|
async resumeStream(resumeData, options) {
|
|
3179
|
+
const executableClientTools = options.clientToolsResolver?.() ?? options.clientTools;
|
|
3180
|
+
const releaseHold = this.holdResumingClientTools(options.runId, executableClientTools);
|
|
2521
3181
|
const processedParams = {
|
|
2522
3182
|
...options,
|
|
2523
3183
|
resumeData,
|
|
2524
3184
|
requestContext: parseClientRequestContext(options.requestContext),
|
|
2525
|
-
clientTools: processClientTools(
|
|
3185
|
+
clientTools: processClientTools(executableClientTools),
|
|
2526
3186
|
structuredOutput: options.structuredOutput ? {
|
|
2527
3187
|
...options.structuredOutput,
|
|
2528
3188
|
schema: (0, _mastra_schema_compat_schema.standardSchemaToJSONSchema)((0, _mastra_schema_compat_schema.toStandardSchema)(options.structuredOutput.schema))
|
|
2529
3189
|
} : void 0
|
|
2530
3190
|
};
|
|
2531
3191
|
const { readable, controller: readableController, signal } = this.createCancellableStream(options.abortSignal);
|
|
2532
|
-
const response = await this.processStreamResponse(processedParams, readableController, "resume-stream", signal)
|
|
3192
|
+
const response = await this.processStreamResponse(processedParams, readableController, "resume-stream", signal).catch((error) => {
|
|
3193
|
+
releaseHold({ force: true });
|
|
3194
|
+
throw error;
|
|
3195
|
+
});
|
|
2533
3196
|
const streamResponse = new Response(readable, {
|
|
2534
3197
|
status: response.status,
|
|
2535
3198
|
statusText: response.statusText,
|
|
@@ -2582,18 +3245,23 @@ var Agent = class extends BaseResource {
|
|
|
2582
3245
|
* Used to continue execution after a suspension point (e.g., workflow suspend within an agent).
|
|
2583
3246
|
*/
|
|
2584
3247
|
async resumeStreamUntilIdle(resumeData, options) {
|
|
3248
|
+
const executableClientTools = options.clientToolsResolver?.() ?? options.clientTools;
|
|
3249
|
+
const releaseHold = this.holdResumingClientTools(options.runId, executableClientTools);
|
|
2585
3250
|
const processedParams = {
|
|
2586
3251
|
...options,
|
|
2587
3252
|
resumeData,
|
|
2588
3253
|
requestContext: parseClientRequestContext(options.requestContext),
|
|
2589
|
-
clientTools: processClientTools(
|
|
3254
|
+
clientTools: processClientTools(executableClientTools),
|
|
2590
3255
|
structuredOutput: options.structuredOutput ? {
|
|
2591
3256
|
...options.structuredOutput,
|
|
2592
3257
|
schema: (0, _mastra_schema_compat_schema.standardSchemaToJSONSchema)((0, _mastra_schema_compat_schema.toStandardSchema)(options.structuredOutput.schema))
|
|
2593
3258
|
} : void 0
|
|
2594
3259
|
};
|
|
2595
3260
|
const { readable, controller: readableController, signal } = this.createCancellableStream(options.abortSignal);
|
|
2596
|
-
const response = await this.processStreamResponse(processedParams, readableController, "resume-stream-until-idle", signal)
|
|
3261
|
+
const response = await this.processStreamResponse(processedParams, readableController, "resume-stream-until-idle", signal).catch((error) => {
|
|
3262
|
+
releaseHold({ force: true });
|
|
3263
|
+
throw error;
|
|
3264
|
+
});
|
|
2597
3265
|
const streamResponse = new Response(readable, {
|
|
2598
3266
|
status: response.status,
|
|
2599
3267
|
statusText: response.statusText,
|
|
@@ -2612,27 +3280,93 @@ var Agent = class extends BaseResource {
|
|
|
2612
3280
|
* Used when `requireToolApproval` is enabled with generate() to allow the agent to proceed.
|
|
2613
3281
|
*/
|
|
2614
3282
|
async approveToolCallGenerate(params) {
|
|
2615
|
-
const { requestContext, ...rest } = params;
|
|
2616
|
-
|
|
2617
|
-
|
|
2618
|
-
|
|
2619
|
-
|
|
2620
|
-
|
|
2621
|
-
|
|
2622
|
-
|
|
3283
|
+
const { requestContext, clientTools, clientToolsResolver, memory, ...rest } = params;
|
|
3284
|
+
const executableClientTools = clientToolsResolver?.() ?? clientTools;
|
|
3285
|
+
const releaseHold = this.holdResumingClientTools(rest.runId, executableClientTools);
|
|
3286
|
+
let response;
|
|
3287
|
+
try {
|
|
3288
|
+
response = await this.request(`/agents/${this.agentId}/approve-tool-call-generate`, {
|
|
3289
|
+
method: "POST",
|
|
3290
|
+
body: {
|
|
3291
|
+
...rest,
|
|
3292
|
+
requestContext: parseClientRequestContext(requestContext),
|
|
3293
|
+
clientTools: processClientTools(executableClientTools)
|
|
3294
|
+
}
|
|
3295
|
+
});
|
|
3296
|
+
} catch (error) {
|
|
3297
|
+
releaseHold({ force: true });
|
|
3298
|
+
throw error;
|
|
3299
|
+
}
|
|
3300
|
+
try {
|
|
3301
|
+
return await this.continueResumedGenerate(response, {
|
|
3302
|
+
requestContext,
|
|
3303
|
+
clientTools: executableClientTools,
|
|
3304
|
+
clientToolsResolver,
|
|
3305
|
+
memory
|
|
3306
|
+
});
|
|
3307
|
+
} finally {
|
|
3308
|
+
releaseHold();
|
|
3309
|
+
}
|
|
2623
3310
|
}
|
|
2624
3311
|
/**
|
|
2625
3312
|
* Declines a pending tool call and returns the complete response (non-streaming).
|
|
2626
3313
|
* Used when `requireToolApproval` is enabled with generate() to prevent tool execution.
|
|
2627
3314
|
*/
|
|
2628
3315
|
async declineToolCallGenerate(params) {
|
|
2629
|
-
const { requestContext, ...rest } = params;
|
|
2630
|
-
|
|
2631
|
-
|
|
2632
|
-
|
|
2633
|
-
|
|
2634
|
-
|
|
2635
|
-
|
|
3316
|
+
const { requestContext, clientTools, clientToolsResolver, memory, ...rest } = params;
|
|
3317
|
+
const executableClientTools = clientToolsResolver?.() ?? clientTools;
|
|
3318
|
+
const releaseHold = this.holdResumingClientTools(rest.runId, executableClientTools);
|
|
3319
|
+
let response;
|
|
3320
|
+
try {
|
|
3321
|
+
response = await this.request(`/agents/${this.agentId}/decline-tool-call-generate`, {
|
|
3322
|
+
method: "POST",
|
|
3323
|
+
body: {
|
|
3324
|
+
...rest,
|
|
3325
|
+
requestContext: parseClientRequestContext(requestContext),
|
|
3326
|
+
clientTools: processClientTools(executableClientTools)
|
|
3327
|
+
}
|
|
3328
|
+
});
|
|
3329
|
+
} catch (error) {
|
|
3330
|
+
releaseHold({ force: true });
|
|
3331
|
+
throw error;
|
|
3332
|
+
}
|
|
3333
|
+
try {
|
|
3334
|
+
return await this.continueResumedGenerate(response, {
|
|
3335
|
+
requestContext,
|
|
3336
|
+
clientTools: executableClientTools,
|
|
3337
|
+
clientToolsResolver,
|
|
3338
|
+
memory
|
|
3339
|
+
});
|
|
3340
|
+
} finally {
|
|
3341
|
+
releaseHold();
|
|
3342
|
+
}
|
|
3343
|
+
}
|
|
3344
|
+
/**
|
|
3345
|
+
* Runs executable client tools the model called after an approval decision and continues on
|
|
3346
|
+
* /generate, like generate() does. With memory the continuation sends only the new messages to the
|
|
3347
|
+
* thread. Without memory it re-sends the conversation up to the last user turn, because the resume
|
|
3348
|
+
* routes keep the earlier history server-side and drop it once the run finishes.
|
|
3349
|
+
*/
|
|
3350
|
+
async continueResumedGenerate(response, { requestContext, clientTools, clientToolsResolver, memory }) {
|
|
3351
|
+
if (response.finishReason !== "tool-calls") return response;
|
|
3352
|
+
const context = requestContext === void 0 || requestContext instanceof _mastra_core_request_context.RequestContext ? requestContext : new _mastra_core_request_context.RequestContext(Object.entries(requestContext));
|
|
3353
|
+
const threadId = typeof memory?.thread === "string" ? memory.thread : memory?.thread?.id;
|
|
3354
|
+
const history = response.messages ?? [];
|
|
3355
|
+
const priorTurns = history.slice(0, history.findLastIndex((message) => message.role === "user") + 1);
|
|
3356
|
+
return executeToolCallAndRespond({
|
|
3357
|
+
response,
|
|
3358
|
+
params: {
|
|
3359
|
+
messages: threadId ? [] : priorTurns,
|
|
3360
|
+
clientTools: clientToolsResolver?.() ?? clientTools,
|
|
3361
|
+
clientToolsResolver,
|
|
3362
|
+
requestContext: context,
|
|
3363
|
+
memory
|
|
3364
|
+
},
|
|
3365
|
+
agentId: this.agentId,
|
|
3366
|
+
resourceId: memory?.resource,
|
|
3367
|
+
threadId,
|
|
3368
|
+
requestContext: context,
|
|
3369
|
+
respondFn: (messages, options) => this.generate(messages, options)
|
|
2636
3370
|
});
|
|
2637
3371
|
}
|
|
2638
3372
|
/**
|
|
@@ -3830,7 +4564,8 @@ async function verifyAgentCardSignatureIfPresent(agentCard, options) {
|
|
|
3830
4564
|
index
|
|
3831
4565
|
});
|
|
3832
4566
|
if (!verificationKey) throw new Error("No verification key was provided for Agent Card signature verification");
|
|
3833
|
-
|
|
4567
|
+
const importedKey = await importVerificationKey(verificationKey, protectedHeader.alg);
|
|
4568
|
+
await (0, jose.compactVerify)(compactJws, importedKey, { algorithms: allowedAlgorithms });
|
|
3834
4569
|
return agentCard;
|
|
3835
4570
|
} catch (error) {
|
|
3836
4571
|
verificationErrors.push(error instanceof Error ? error.message : "Unknown verification failure");
|
|
@@ -4574,10 +5309,10 @@ var Observability = class extends BaseResource {
|
|
|
4574
5309
|
});
|
|
4575
5310
|
}
|
|
4576
5311
|
/**
|
|
4577
|
-
* Queries thread
|
|
5312
|
+
* Queries full-history thread rows using a trace or thread activity window.
|
|
4578
5313
|
*
|
|
4579
|
-
* @param params - Thread query with its
|
|
4580
|
-
* @returns Matching thread
|
|
5314
|
+
* @param params - Thread query with its qualification window, filters and pagination
|
|
5315
|
+
* @returns Matching thread rows. Legacy requests retain their identity-only response.
|
|
4581
5316
|
*/
|
|
4582
5317
|
queryTraceThreads(params) {
|
|
4583
5318
|
return this.request("/observability/threads/query", {
|
|
@@ -6162,48 +6897,40 @@ function hydrateEventTimestamps(event) {
|
|
|
6162
6897
|
return isKnownParsedEvent(event) ? hydrateKnownEvent(event) : event;
|
|
6163
6898
|
}
|
|
6164
6899
|
/**
|
|
6165
|
-
* A session
|
|
6166
|
-
* get-or-create on the server, so re-creating the same
|
|
6167
|
-
*
|
|
6168
|
-
*
|
|
6169
|
-
*
|
|
6170
|
-
* two sessions with the same resourceId but different scopes have their own
|
|
6171
|
-
* run loop, thread binding, and mode/model/state (e.g. one session per git
|
|
6172
|
-
* worktree, with the worktree path as the scope). The scope travels on every
|
|
6173
|
-
* request as a `sessionScope` query param.
|
|
6900
|
+
* A session addressed by its `sessionId` within one agent controller. Sessions
|
|
6901
|
+
* are get-or-create on the server, so re-creating the same sessionId resumes
|
|
6902
|
+
* the existing conversation rather than forking it. Many sessions can work on
|
|
6903
|
+
* one `resourceId` (whose threads and memory they use); each has its own run
|
|
6904
|
+
* loop, thread binding, and mode/model/state.
|
|
6174
6905
|
*/
|
|
6175
6906
|
var AgentControllerSession = class extends BaseResource {
|
|
6176
6907
|
controllerId;
|
|
6177
|
-
|
|
6178
|
-
|
|
6179
|
-
constructor(options, controllerId, resourceId, scope) {
|
|
6908
|
+
sessionId;
|
|
6909
|
+
constructor(options, controllerId, sessionId) {
|
|
6180
6910
|
super(options);
|
|
6181
6911
|
this.controllerId = controllerId;
|
|
6182
|
-
this.
|
|
6183
|
-
this.scope = scope;
|
|
6912
|
+
this.sessionId = sessionId;
|
|
6184
6913
|
}
|
|
6185
6914
|
base() {
|
|
6186
|
-
return `/agent-controller/${encodeURIComponent(this.controllerId)}/sessions/${encodeURIComponent(this.
|
|
6187
|
-
}
|
|
6188
|
-
/** Append this session's scope (if any) as a `sessionScope` query param. */
|
|
6189
|
-
url(path) {
|
|
6190
|
-
if (this.scope === void 0) return path;
|
|
6191
|
-
return `${path}${path.includes("?") ? "&" : "?"}sessionScope=${encodeURIComponent(this.scope)}`;
|
|
6915
|
+
return `/agent-controller/${encodeURIComponent(this.controllerId)}/sessions/${encodeURIComponent(this.sessionId)}`;
|
|
6192
6916
|
}
|
|
6193
6917
|
/**
|
|
6194
|
-
* Create or resume this session.
|
|
6195
|
-
*
|
|
6196
|
-
*
|
|
6197
|
-
*
|
|
6918
|
+
* Create or resume this session. `resourceId` names whose threads and memory
|
|
6919
|
+
* the session works on. Without it the server resumes the session on the
|
|
6920
|
+
* resource it already has (the live session's, or the resource of the thread
|
|
6921
|
+
* with the session's id), falling back to the sessionId. Pass `tags` to scope
|
|
6922
|
+
* initial thread selection — a thread is a resume candidate only when its
|
|
6923
|
+
* metadata matches every tag. Pass `threadId` to bind the session to one
|
|
6924
|
+
* exact thread, creating it with that id when it does not exist.
|
|
6198
6925
|
*/
|
|
6199
6926
|
create(options) {
|
|
6200
6927
|
return this.request(`/agent-controller/${encodeURIComponent(this.controllerId)}/sessions`, {
|
|
6201
6928
|
method: "POST",
|
|
6202
6929
|
body: {
|
|
6203
|
-
resourceId:
|
|
6930
|
+
resourceId: options?.resourceId,
|
|
6931
|
+
sessionId: this.sessionId,
|
|
6204
6932
|
tags: options?.tags,
|
|
6205
|
-
threadId: options?.threadId
|
|
6206
|
-
sessionScope: this.scope
|
|
6933
|
+
threadId: options?.threadId
|
|
6207
6934
|
}
|
|
6208
6935
|
});
|
|
6209
6936
|
}
|
|
@@ -6229,10 +6956,12 @@ var AgentControllerSession = class extends BaseResource {
|
|
|
6229
6956
|
delayMs: finiteOr(options.reconnect.delayMs, 1e3),
|
|
6230
6957
|
maxDelayMs: finiteOr(options.reconnect.maxDelayMs, 3e4)
|
|
6231
6958
|
} : null;
|
|
6959
|
+
const idleTimeoutMs = finiteOr(options.idleTimeoutMs, 6e4);
|
|
6232
6960
|
/** Exponential backoff for the Nth (1-based) retry of an outage streak. */
|
|
6233
6961
|
const backoffDelay = (attempt) => reconnectOptions ? Math.min(reconnectOptions.delayMs * 2 ** (attempt - 1), reconnectOptions.maxDelayMs) : 0;
|
|
6234
6962
|
let cancelled = false;
|
|
6235
6963
|
let currentReader = null;
|
|
6964
|
+
let currentAbort = null;
|
|
6236
6965
|
let reconnectTimer;
|
|
6237
6966
|
let delayResolve;
|
|
6238
6967
|
const settleDelay = () => {
|
|
@@ -6248,8 +6977,39 @@ var AgentControllerSession = class extends BaseResource {
|
|
|
6248
6977
|
delayResolve = resolve;
|
|
6249
6978
|
reconnectTimer = setTimeout(settleDelay, ms);
|
|
6250
6979
|
});
|
|
6980
|
+
const idleTimeoutError = () => {
|
|
6981
|
+
const error = /* @__PURE__ */ new Error(`Agent controller session stream received no data for ${idleTimeoutMs}ms`);
|
|
6982
|
+
error.name = "AgentControllerStreamIdleError";
|
|
6983
|
+
return error;
|
|
6984
|
+
};
|
|
6251
6985
|
const requestStream = async () => {
|
|
6252
|
-
const
|
|
6986
|
+
const abort = new AbortController();
|
|
6987
|
+
currentAbort = abort;
|
|
6988
|
+
let openTimer;
|
|
6989
|
+
const request = this.request(`${this.base()}/stream`, {
|
|
6990
|
+
stream: true,
|
|
6991
|
+
signal: abort.signal
|
|
6992
|
+
});
|
|
6993
|
+
request.then((response) => {
|
|
6994
|
+
if (abort.signal.aborted) response.body?.cancel().catch(() => {});
|
|
6995
|
+
}).catch(() => {});
|
|
6996
|
+
let response;
|
|
6997
|
+
try {
|
|
6998
|
+
if (idleTimeoutMs > 0) response = await Promise.race([request, new Promise((_resolve, reject) => {
|
|
6999
|
+
openTimer = setTimeout(() => {
|
|
7000
|
+
const error = idleTimeoutError();
|
|
7001
|
+
abort.abort(error);
|
|
7002
|
+
reject(error);
|
|
7003
|
+
}, idleTimeoutMs);
|
|
7004
|
+
})]);
|
|
7005
|
+
else response = await request;
|
|
7006
|
+
} finally {
|
|
7007
|
+
clearTimeout(openTimer);
|
|
7008
|
+
}
|
|
7009
|
+
if (abort.signal.aborted) {
|
|
7010
|
+
response.body?.cancel().catch(() => {});
|
|
7011
|
+
throw abort.signal.reason;
|
|
7012
|
+
}
|
|
6253
7013
|
if (!response.body) throw new Error("No response body for agent controller session stream");
|
|
6254
7014
|
return response;
|
|
6255
7015
|
};
|
|
@@ -6275,12 +7035,40 @@ var AgentControllerSession = class extends BaseResource {
|
|
|
6275
7035
|
const pump = async (response) => {
|
|
6276
7036
|
const reader = response.body.getReader();
|
|
6277
7037
|
currentReader = reader;
|
|
7038
|
+
const abort = currentAbort;
|
|
6278
7039
|
const decoder = new TextDecoder();
|
|
6279
7040
|
let buffer = "";
|
|
7041
|
+
let idleTimer;
|
|
7042
|
+
let timedOut = false;
|
|
7043
|
+
const armIdleTimer = () => {
|
|
7044
|
+
if (idleTimeoutMs <= 0) return;
|
|
7045
|
+
clearTimeout(idleTimer);
|
|
7046
|
+
idleTimer = setTimeout(() => {
|
|
7047
|
+
timedOut = true;
|
|
7048
|
+
reader.cancel(idleTimeoutError()).catch(() => {});
|
|
7049
|
+
abort?.abort(idleTimeoutError());
|
|
7050
|
+
}, idleTimeoutMs);
|
|
7051
|
+
};
|
|
6280
7052
|
try {
|
|
7053
|
+
armIdleTimer();
|
|
6281
7054
|
while (!cancelled) {
|
|
6282
|
-
|
|
7055
|
+
let chunk;
|
|
7056
|
+
try {
|
|
7057
|
+
chunk = await reader.read();
|
|
7058
|
+
} catch (error) {
|
|
7059
|
+
if (timedOut && !cancelled) return {
|
|
7060
|
+
kind: "transport_error",
|
|
7061
|
+
error: idleTimeoutError()
|
|
7062
|
+
};
|
|
7063
|
+
throw error;
|
|
7064
|
+
}
|
|
7065
|
+
if (timedOut && !cancelled) return {
|
|
7066
|
+
kind: "transport_error",
|
|
7067
|
+
error: idleTimeoutError()
|
|
7068
|
+
};
|
|
7069
|
+
const { done, value } = chunk;
|
|
6283
7070
|
if (done) return cancelled ? { kind: "cancelled" } : { kind: "done" };
|
|
7071
|
+
armIdleTimer();
|
|
6284
7072
|
if (cancelled) return { kind: "cancelled" };
|
|
6285
7073
|
buffer += decoder.decode(value, { stream: true });
|
|
6286
7074
|
let separator;
|
|
@@ -6314,7 +7102,9 @@ var AgentControllerSession = class extends BaseResource {
|
|
|
6314
7102
|
error
|
|
6315
7103
|
};
|
|
6316
7104
|
} finally {
|
|
7105
|
+
clearTimeout(idleTimer);
|
|
6317
7106
|
if (currentReader === reader) currentReader = null;
|
|
7107
|
+
if (currentAbort === abort) currentAbort = null;
|
|
6318
7108
|
reader.cancel().catch(() => {});
|
|
6319
7109
|
}
|
|
6320
7110
|
};
|
|
@@ -6391,6 +7181,7 @@ var AgentControllerSession = class extends BaseResource {
|
|
|
6391
7181
|
cancelled = true;
|
|
6392
7182
|
settleDelay();
|
|
6393
7183
|
currentReader?.cancel().catch(() => {});
|
|
7184
|
+
currentAbort?.abort();
|
|
6394
7185
|
} };
|
|
6395
7186
|
}
|
|
6396
7187
|
/**
|
|
@@ -6405,7 +7196,7 @@ var AgentControllerSession = class extends BaseResource {
|
|
|
6405
7196
|
files: void 0
|
|
6406
7197
|
} : message;
|
|
6407
7198
|
const requestContext = parseClientRequestContext(options?.requestContext);
|
|
6408
|
-
await this.request(
|
|
7199
|
+
await this.request(`${this.base()}/messages`, {
|
|
6409
7200
|
method: "POST",
|
|
6410
7201
|
body: {
|
|
6411
7202
|
message: content,
|
|
@@ -6416,7 +7207,7 @@ var AgentControllerSession = class extends BaseResource {
|
|
|
6416
7207
|
}
|
|
6417
7208
|
/** Abort the in-flight run for this session. */
|
|
6418
7209
|
async abort() {
|
|
6419
|
-
await this.request(
|
|
7210
|
+
await this.request(`${this.base()}/abort`, { method: "POST" });
|
|
6420
7211
|
}
|
|
6421
7212
|
/**
|
|
6422
7213
|
* Approve or decline a pending tool call (`tool_approval_required`). Resolves
|
|
@@ -6424,12 +7215,13 @@ var AgentControllerSession = class extends BaseResource {
|
|
|
6424
7215
|
*/
|
|
6425
7216
|
async approveTool(toolCallId, approved, options) {
|
|
6426
7217
|
const requestContext = parseClientRequestContext(options?.requestContext);
|
|
6427
|
-
return this.request(
|
|
7218
|
+
return this.request(`${this.base()}/tool-approval`, {
|
|
6428
7219
|
method: "POST",
|
|
6429
7220
|
retries: 0,
|
|
6430
7221
|
body: {
|
|
6431
7222
|
toolCallId,
|
|
6432
7223
|
approved,
|
|
7224
|
+
...options?.alwaysAllowCategory ? { alwaysAllowCategory: true } : {},
|
|
6433
7225
|
...requestContext ? { requestContext } : {}
|
|
6434
7226
|
}
|
|
6435
7227
|
});
|
|
@@ -6441,7 +7233,7 @@ var AgentControllerSession = class extends BaseResource {
|
|
|
6441
7233
|
*/
|
|
6442
7234
|
async respondToToolSuspension(toolCallId, resumeData, options) {
|
|
6443
7235
|
const requestContext = parseClientRequestContext(options?.requestContext);
|
|
6444
|
-
return this.request(
|
|
7236
|
+
return this.request(`${this.base()}/tool-suspension`, {
|
|
6445
7237
|
method: "POST",
|
|
6446
7238
|
retries: 0,
|
|
6447
7239
|
body: {
|
|
@@ -6461,7 +7253,7 @@ var AgentControllerSession = class extends BaseResource {
|
|
|
6461
7253
|
files: void 0
|
|
6462
7254
|
} : message;
|
|
6463
7255
|
const requestContext = parseClientRequestContext(options?.requestContext);
|
|
6464
|
-
await this.request(
|
|
7256
|
+
await this.request(`${this.base()}/steer`, {
|
|
6465
7257
|
method: "POST",
|
|
6466
7258
|
body: {
|
|
6467
7259
|
message: content,
|
|
@@ -6473,18 +7265,18 @@ var AgentControllerSession = class extends BaseResource {
|
|
|
6473
7265
|
/** Get the current mode, model, and thread (for initial UI hydration). */
|
|
6474
7266
|
state(options) {
|
|
6475
7267
|
const path = options?.threadId ? `${this.base()}?threadId=${encodeURIComponent(options.threadId)}` : this.base();
|
|
6476
|
-
return this.request(
|
|
7268
|
+
return this.request(path);
|
|
6477
7269
|
}
|
|
6478
7270
|
/** Merge key-value pairs into the session state. Existing keys not in the payload are preserved. */
|
|
6479
7271
|
async setState(updates) {
|
|
6480
|
-
await this.request(
|
|
7272
|
+
await this.request(`${this.base()}/state`, {
|
|
6481
7273
|
method: "PUT",
|
|
6482
7274
|
body: { state: updates }
|
|
6483
7275
|
});
|
|
6484
7276
|
}
|
|
6485
7277
|
/** Switch the active mode (e.g. `build`, `plan`). */
|
|
6486
7278
|
async switchMode(modeId) {
|
|
6487
|
-
await this.request(
|
|
7279
|
+
await this.request(`${this.base()}/mode`, {
|
|
6488
7280
|
method: "POST",
|
|
6489
7281
|
body: { modeId }
|
|
6490
7282
|
});
|
|
@@ -6494,7 +7286,7 @@ var AgentControllerSession = class extends BaseResource {
|
|
|
6494
7286
|
* `thinkingLevel` is provided it is applied and persisted with the model.
|
|
6495
7287
|
*/
|
|
6496
7288
|
async switchModel(modelId, { thinkingLevel } = {}) {
|
|
6497
|
-
await this.request(
|
|
7289
|
+
await this.request(`${this.base()}/model`, {
|
|
6498
7290
|
method: "POST",
|
|
6499
7291
|
body: thinkingLevel !== void 0 ? {
|
|
6500
7292
|
modelId,
|
|
@@ -6515,36 +7307,36 @@ var AgentControllerSession = class extends BaseResource {
|
|
|
6515
7307
|
if (opts.limit != null) params.set("limit", String(opts.limit));
|
|
6516
7308
|
if (opts.tags && Object.keys(opts.tags).length > 0) params.set("tags", JSON.stringify(opts.tags));
|
|
6517
7309
|
const query = params.toString() ? `?${params.toString()}` : "";
|
|
6518
|
-
return (await this.request(
|
|
7310
|
+
return (await this.request(`${this.base()}/threads${query}`)).threads;
|
|
6519
7311
|
}
|
|
6520
7312
|
/** Switch the session to an existing thread (rebinds stream + state). */
|
|
6521
7313
|
async switchThread(threadId) {
|
|
6522
|
-
await this.request(
|
|
7314
|
+
await this.request(`${this.base()}/thread`, {
|
|
6523
7315
|
method: "POST",
|
|
6524
7316
|
body: { threadId }
|
|
6525
7317
|
});
|
|
6526
7318
|
}
|
|
6527
7319
|
/** Create a new thread (unbinds previous, binds the new one). */
|
|
6528
7320
|
async createThread(title) {
|
|
6529
|
-
return this.request(
|
|
7321
|
+
return this.request(`${this.base()}/threads`, {
|
|
6530
7322
|
method: "POST",
|
|
6531
7323
|
body: { title }
|
|
6532
7324
|
});
|
|
6533
7325
|
}
|
|
6534
7326
|
/** Delete a thread. If it's the active thread the session unbinds. */
|
|
6535
7327
|
async deleteThread(threadId) {
|
|
6536
|
-
await this.request(
|
|
7328
|
+
await this.request(`${this.base()}/threads/${encodeURIComponent(threadId)}`, { method: "DELETE" });
|
|
6537
7329
|
}
|
|
6538
7330
|
/** Rename a thread. */
|
|
6539
7331
|
async renameThread(threadId, title) {
|
|
6540
|
-
await this.request(
|
|
7332
|
+
await this.request(`${this.base()}/threads/${encodeURIComponent(threadId)}`, {
|
|
6541
7333
|
method: "PUT",
|
|
6542
7334
|
body: { title }
|
|
6543
7335
|
});
|
|
6544
7336
|
}
|
|
6545
7337
|
/** Clone a thread (and its messages). The session binds to the clone. */
|
|
6546
7338
|
async cloneThread(options) {
|
|
6547
|
-
return this.request(
|
|
7339
|
+
return this.request(`${this.base()}/threads/clone`, {
|
|
6548
7340
|
method: "POST",
|
|
6549
7341
|
body: options ?? {}
|
|
6550
7342
|
});
|
|
@@ -6565,7 +7357,7 @@ var AgentControllerSession = class extends BaseResource {
|
|
|
6565
7357
|
if (include) queryParams.set("include", JSON.stringify(include));
|
|
6566
7358
|
}
|
|
6567
7359
|
const query = queryParams.toString();
|
|
6568
|
-
const body = await this.request(
|
|
7360
|
+
const body = await this.request(`${this.base()}/threads/${encodeURIComponent(threadId)}/messages${query ? `?${query}` : ""}`);
|
|
6569
7361
|
const messages = body.messages.map(hydrateMessage);
|
|
6570
7362
|
if (legacy) return messages;
|
|
6571
7363
|
return {
|
|
@@ -6584,7 +7376,7 @@ var AgentControllerSession = class extends BaseResource {
|
|
|
6584
7376
|
files: void 0
|
|
6585
7377
|
} : message;
|
|
6586
7378
|
const requestContext = parseClientRequestContext(options?.requestContext);
|
|
6587
|
-
await this.request(
|
|
7379
|
+
await this.request(`${this.base()}/follow-up`, {
|
|
6588
7380
|
method: "POST",
|
|
6589
7381
|
body: {
|
|
6590
7382
|
message: content,
|
|
@@ -6595,26 +7387,26 @@ var AgentControllerSession = class extends BaseResource {
|
|
|
6595
7387
|
}
|
|
6596
7388
|
/** Get the observational memory record for this session's thread. */
|
|
6597
7389
|
async getOMRecord() {
|
|
6598
|
-
return (await this.request(
|
|
7390
|
+
return (await this.request(`${this.base()}/om`)).record;
|
|
6599
7391
|
}
|
|
6600
7392
|
/** Change the session's resource identity. */
|
|
6601
7393
|
async setResourceId(newResourceId) {
|
|
6602
|
-
await this.request(
|
|
7394
|
+
await this.request(`${this.base()}/resource`, {
|
|
6603
7395
|
method: "POST",
|
|
6604
7396
|
body: { newResourceId }
|
|
6605
7397
|
});
|
|
6606
7398
|
}
|
|
6607
7399
|
/** Get known resource IDs for this session. */
|
|
6608
7400
|
async getResourceIds() {
|
|
6609
|
-
return (await this.request(
|
|
7401
|
+
return (await this.request(`${this.base()}/resources`)).resourceIds;
|
|
6610
7402
|
}
|
|
6611
7403
|
/** Get the current goal for this session's thread. */
|
|
6612
7404
|
async getGoal() {
|
|
6613
|
-
return (await this.request(
|
|
7405
|
+
return (await this.request(`${this.base()}/goal`)).goal;
|
|
6614
7406
|
}
|
|
6615
7407
|
/** Set a new goal objective. The agent's in-loop judge evaluates progress after each turn. */
|
|
6616
7408
|
async setGoal(objective, options) {
|
|
6617
|
-
return (await this.request(
|
|
7409
|
+
return (await this.request(`${this.base()}/goal`, {
|
|
6618
7410
|
method: "POST",
|
|
6619
7411
|
body: {
|
|
6620
7412
|
objective,
|
|
@@ -6624,22 +7416,22 @@ var AgentControllerSession = class extends BaseResource {
|
|
|
6624
7416
|
}
|
|
6625
7417
|
/** Update goal options (judge model, max runs, status). */
|
|
6626
7418
|
async updateGoal(options) {
|
|
6627
|
-
return (await this.request(
|
|
7419
|
+
return (await this.request(`${this.base()}/goal`, {
|
|
6628
7420
|
method: "PUT",
|
|
6629
7421
|
body: options
|
|
6630
7422
|
})).goal;
|
|
6631
7423
|
}
|
|
6632
7424
|
/** Clear the current goal. */
|
|
6633
7425
|
async clearGoal() {
|
|
6634
|
-
await this.request(
|
|
7426
|
+
await this.request(`${this.base()}/goal`, { method: "DELETE" });
|
|
6635
7427
|
}
|
|
6636
7428
|
/** Get the current permission rules (per-category and per-tool policies). */
|
|
6637
7429
|
async getPermissions() {
|
|
6638
|
-
return this.request(
|
|
7430
|
+
return this.request(`${this.base()}/permissions`);
|
|
6639
7431
|
}
|
|
6640
7432
|
/** Set the approval policy for a tool category. */
|
|
6641
7433
|
async setPermissionForCategory(category, policy) {
|
|
6642
|
-
await this.request(
|
|
7434
|
+
await this.request(`${this.base()}/permissions/category`, {
|
|
6643
7435
|
method: "PUT",
|
|
6644
7436
|
body: {
|
|
6645
7437
|
category,
|
|
@@ -6649,7 +7441,7 @@ var AgentControllerSession = class extends BaseResource {
|
|
|
6649
7441
|
}
|
|
6650
7442
|
/** Set the approval policy for a specific tool. */
|
|
6651
7443
|
async setPermissionForTool(toolName, policy) {
|
|
6652
|
-
await this.request(
|
|
7444
|
+
await this.request(`${this.base()}/permissions/tool`, {
|
|
6653
7445
|
method: "PUT",
|
|
6654
7446
|
body: {
|
|
6655
7447
|
toolName,
|
|
@@ -6663,7 +7455,7 @@ var AgentControllerSession = class extends BaseResource {
|
|
|
6663
7455
|
* or is persisted for later.
|
|
6664
7456
|
*/
|
|
6665
7457
|
async sendNotification(input) {
|
|
6666
|
-
return this.request(
|
|
7458
|
+
return this.request(`${this.base()}/notifications`, {
|
|
6667
7459
|
method: "POST",
|
|
6668
7460
|
body: input
|
|
6669
7461
|
});
|
|
@@ -6696,12 +7488,11 @@ var AgentController = class extends BaseResource {
|
|
|
6696
7488
|
return this.request(`${this.basePath()}/workspace`);
|
|
6697
7489
|
}
|
|
6698
7490
|
/**
|
|
6699
|
-
*
|
|
6700
|
-
*
|
|
6701
|
-
* (e.g. one session per git worktree, with the worktree path as the scope).
|
|
7491
|
+
* Address the session with this `sessionId`. Sessions created without an
|
|
7492
|
+
* explicit id are addressed by their `resourceId`.
|
|
6702
7493
|
*/
|
|
6703
|
-
session(
|
|
6704
|
-
return new AgentControllerSession(this.options, this.controllerId,
|
|
7494
|
+
session(sessionId) {
|
|
7495
|
+
return new AgentControllerSession(this.options, this.controllerId, sessionId);
|
|
6705
7496
|
}
|
|
6706
7497
|
};
|
|
6707
7498
|
/** Pull the plain text out of an assistant message's nested content parts. */
|
|
@@ -6775,7 +7566,7 @@ var MastraClient = class extends BaseResource {
|
|
|
6775
7566
|
}
|
|
6776
7567
|
/**
|
|
6777
7568
|
* Scopes to an agent controller hosted on the connected Mastra instance. Use
|
|
6778
|
-
* `getAgentController(id).session(
|
|
7569
|
+
* `getAgentController(id).session(sessionId)` to create/resume a session,
|
|
6779
7570
|
* stream its events, and send messages.
|
|
6780
7571
|
* @param controllerId - The id the agent controller is registered under on Mastra
|
|
6781
7572
|
*/
|
|
@@ -7026,8 +7817,10 @@ var MastraClient = class extends BaseResource {
|
|
|
7026
7817
|
if (logLevel) searchParams.set("logLevel", logLevel);
|
|
7027
7818
|
if (page !== void 0) searchParams.set("page", String(page));
|
|
7028
7819
|
if (perPage !== void 0) searchParams.set("perPage", String(perPage));
|
|
7029
|
-
if (_filters)
|
|
7030
|
-
|
|
7820
|
+
if (_filters) {
|
|
7821
|
+
if (Array.isArray(_filters)) for (const filter of _filters) searchParams.append("filters", filter);
|
|
7822
|
+
else searchParams.set("filters", _filters);
|
|
7823
|
+
}
|
|
7031
7824
|
if (searchParams.size) return this.request(`/logs?${searchParams}`);
|
|
7032
7825
|
else return this.request(`/logs`);
|
|
7033
7826
|
}
|
|
@@ -7047,8 +7840,10 @@ var MastraClient = class extends BaseResource {
|
|
|
7047
7840
|
if (logLevel) searchParams.set("logLevel", logLevel);
|
|
7048
7841
|
if (page !== void 0) searchParams.set("page", String(page));
|
|
7049
7842
|
if (perPage !== void 0) searchParams.set("perPage", String(perPage));
|
|
7050
|
-
if (_filters)
|
|
7051
|
-
|
|
7843
|
+
if (_filters) {
|
|
7844
|
+
if (Array.isArray(_filters)) for (const filter of _filters) searchParams.append("filters", filter);
|
|
7845
|
+
else searchParams.set("filters", _filters);
|
|
7846
|
+
}
|
|
7052
7847
|
if (searchParams.size) return this.request(`/logs/${runId}?${searchParams}`);
|
|
7053
7848
|
else return this.request(`/logs/${runId}`);
|
|
7054
7849
|
}
|
|
@@ -7296,7 +8091,7 @@ var MastraClient = class extends BaseResource {
|
|
|
7296
8091
|
getTraceQueryValues(params, options) {
|
|
7297
8092
|
return this.observability.getTraceQueryValues(params, options);
|
|
7298
8093
|
}
|
|
7299
|
-
/** Queries thread
|
|
8094
|
+
/** Queries full-history thread rows using a trace or thread activity window. */
|
|
7300
8095
|
queryTraceThreads(params) {
|
|
7301
8096
|
return this.observability.queryTraceThreads(params);
|
|
7302
8097
|
}
|