@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.js
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
import { parsePartialJson, processDataStream } from "@ai-sdk/ui-utils";
|
|
2
1
|
import { v4 } from "@lukeed/uuid";
|
|
3
2
|
import { getErrorFromUnknown } from "@mastra/core/error";
|
|
4
|
-
import { standardSchemaToJSONSchema, toStandardSchema } from "@mastra/schema-compat/schema";
|
|
5
3
|
import { RequestContext, RequestContext as RequestContext$1 } from "@mastra/core/request-context";
|
|
4
|
+
import { standardSchemaToJSONSchema, toStandardSchema } from "@mastra/schema-compat/schema";
|
|
6
5
|
import { zodToJsonSchema } from "@mastra/schema-compat/zod-to-json";
|
|
7
6
|
import { MastraA2AError } from "@mastra/core/a2a/client";
|
|
8
7
|
import { AgentCard, CancelTaskRequest, DeleteTaskPushNotificationConfigRequest, GetTaskPushNotificationConfigRequest, GetTaskRequest, ListTaskPushNotificationConfigsRequest, ListTaskPushNotificationConfigsResponse, ListTasksRequest, ListTasksResponse, SendMessageRequest, SendMessageResponse, StreamResponse, SubscribeToTaskRequest, Task, TaskPushNotificationConfig } from "@mastra/core/a2a/v1";
|
|
@@ -60,15 +59,16 @@ function attributesToOtlp(attrs) {
|
|
|
60
59
|
key,
|
|
61
60
|
value: { boolValue: raw }
|
|
62
61
|
});
|
|
63
|
-
else if (typeof raw === "number")
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
62
|
+
else if (typeof raw === "number") {
|
|
63
|
+
if (Number.isInteger(raw)) out.push({
|
|
64
|
+
key,
|
|
65
|
+
value: { intValue: raw }
|
|
66
|
+
});
|
|
67
|
+
else out.push({
|
|
68
|
+
key,
|
|
69
|
+
value: { doubleValue: raw }
|
|
70
|
+
});
|
|
71
|
+
} else try {
|
|
72
72
|
out.push({
|
|
73
73
|
key,
|
|
74
74
|
value: { stringValue: JSON.stringify(raw) }
|
|
@@ -377,6 +377,16 @@ function isTerminalHttpError(error) {
|
|
|
377
377
|
return typeof status === "number" && (status >= 400 && status < 500 || status === 501);
|
|
378
378
|
}
|
|
379
379
|
/**
|
|
380
|
+
* Whether an error is the server's trace query execution timeout (504 with code
|
|
381
|
+
* `TRACE_QUERY_EXECUTION_TIMEOUT`). Re-sending the same query hits the same
|
|
382
|
+
* timeout budget, so retrying only repeats an expensive database query.
|
|
383
|
+
* Plain 504s from proxies or gateways do not carry this code and stay retryable.
|
|
384
|
+
*/
|
|
385
|
+
function isTraceQueryTimeoutError(error) {
|
|
386
|
+
const { status, body } = error ?? {};
|
|
387
|
+
return status === 504 && body?.code === "TRACE_QUERY_EXECUTION_TIMEOUT";
|
|
388
|
+
}
|
|
389
|
+
/**
|
|
380
390
|
* Whether a failed resubscribe should end a long-lived subscription instead of
|
|
381
391
|
* retrying. Like {@link isTerminalHttpError}, but 408 Request Timeout and
|
|
382
392
|
* 429 Too Many Requests stay retryable because they mean "try again later".
|
|
@@ -386,6 +396,571 @@ function isTerminalReconnectError(error) {
|
|
|
386
396
|
return isTerminalHttpError(error) && status !== 408 && status !== 429;
|
|
387
397
|
}
|
|
388
398
|
//#endregion
|
|
399
|
+
//#region src/utils/ai-sdk-v4/data-stream-parts.ts
|
|
400
|
+
const dataStreamParts = [
|
|
401
|
+
{
|
|
402
|
+
code: "0",
|
|
403
|
+
name: "text",
|
|
404
|
+
parse: (value) => {
|
|
405
|
+
if (typeof value !== "string") throw new Error("\"text\" parts expect a string value.");
|
|
406
|
+
return {
|
|
407
|
+
type: "text",
|
|
408
|
+
value
|
|
409
|
+
};
|
|
410
|
+
}
|
|
411
|
+
},
|
|
412
|
+
{
|
|
413
|
+
code: "2",
|
|
414
|
+
name: "data",
|
|
415
|
+
parse: (value) => {
|
|
416
|
+
if (!Array.isArray(value)) throw new Error("\"data\" parts expect an array value.");
|
|
417
|
+
return {
|
|
418
|
+
type: "data",
|
|
419
|
+
value
|
|
420
|
+
};
|
|
421
|
+
}
|
|
422
|
+
},
|
|
423
|
+
{
|
|
424
|
+
code: "3",
|
|
425
|
+
name: "error",
|
|
426
|
+
parse: (value) => {
|
|
427
|
+
if (typeof value !== "string") throw new Error("\"error\" parts expect a string value.");
|
|
428
|
+
return {
|
|
429
|
+
type: "error",
|
|
430
|
+
value
|
|
431
|
+
};
|
|
432
|
+
}
|
|
433
|
+
},
|
|
434
|
+
{
|
|
435
|
+
code: "8",
|
|
436
|
+
name: "message_annotations",
|
|
437
|
+
parse: (value) => {
|
|
438
|
+
if (!Array.isArray(value)) throw new Error("\"message_annotations\" parts expect an array value.");
|
|
439
|
+
return {
|
|
440
|
+
type: "message_annotations",
|
|
441
|
+
value
|
|
442
|
+
};
|
|
443
|
+
}
|
|
444
|
+
},
|
|
445
|
+
{
|
|
446
|
+
code: "9",
|
|
447
|
+
name: "tool_call",
|
|
448
|
+
parse: (value) => {
|
|
449
|
+
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.");
|
|
450
|
+
return {
|
|
451
|
+
type: "tool_call",
|
|
452
|
+
value
|
|
453
|
+
};
|
|
454
|
+
}
|
|
455
|
+
},
|
|
456
|
+
{
|
|
457
|
+
code: "a",
|
|
458
|
+
name: "tool_result",
|
|
459
|
+
parse: (value) => {
|
|
460
|
+
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.");
|
|
461
|
+
return {
|
|
462
|
+
type: "tool_result",
|
|
463
|
+
value
|
|
464
|
+
};
|
|
465
|
+
}
|
|
466
|
+
},
|
|
467
|
+
{
|
|
468
|
+
code: "b",
|
|
469
|
+
name: "tool_call_streaming_start",
|
|
470
|
+
parse: (value) => {
|
|
471
|
+
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.");
|
|
472
|
+
return {
|
|
473
|
+
type: "tool_call_streaming_start",
|
|
474
|
+
value
|
|
475
|
+
};
|
|
476
|
+
}
|
|
477
|
+
},
|
|
478
|
+
{
|
|
479
|
+
code: "c",
|
|
480
|
+
name: "tool_call_delta",
|
|
481
|
+
parse: (value) => {
|
|
482
|
+
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.");
|
|
483
|
+
return {
|
|
484
|
+
type: "tool_call_delta",
|
|
485
|
+
value
|
|
486
|
+
};
|
|
487
|
+
}
|
|
488
|
+
},
|
|
489
|
+
{
|
|
490
|
+
code: "d",
|
|
491
|
+
name: "finish_message",
|
|
492
|
+
parse: (value) => {
|
|
493
|
+
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.");
|
|
494
|
+
const result = { finishReason: value.finishReason };
|
|
495
|
+
if ("usage" in value && value.usage != null && typeof value.usage === "object" && "promptTokens" in value.usage && "completionTokens" in value.usage) result.usage = {
|
|
496
|
+
promptTokens: typeof value.usage.promptTokens === "number" ? value.usage.promptTokens : NaN,
|
|
497
|
+
completionTokens: typeof value.usage.completionTokens === "number" ? value.usage.completionTokens : NaN
|
|
498
|
+
};
|
|
499
|
+
return {
|
|
500
|
+
type: "finish_message",
|
|
501
|
+
value: result
|
|
502
|
+
};
|
|
503
|
+
}
|
|
504
|
+
},
|
|
505
|
+
{
|
|
506
|
+
code: "e",
|
|
507
|
+
name: "finish_step",
|
|
508
|
+
parse: (value) => {
|
|
509
|
+
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.");
|
|
510
|
+
const result = {
|
|
511
|
+
finishReason: value.finishReason,
|
|
512
|
+
isContinued: false
|
|
513
|
+
};
|
|
514
|
+
if ("usage" in value && value.usage != null && typeof value.usage === "object" && "promptTokens" in value.usage && "completionTokens" in value.usage) result.usage = {
|
|
515
|
+
promptTokens: typeof value.usage.promptTokens === "number" ? value.usage.promptTokens : NaN,
|
|
516
|
+
completionTokens: typeof value.usage.completionTokens === "number" ? value.usage.completionTokens : NaN
|
|
517
|
+
};
|
|
518
|
+
if ("isContinued" in value && typeof value.isContinued === "boolean") result.isContinued = value.isContinued;
|
|
519
|
+
return {
|
|
520
|
+
type: "finish_step",
|
|
521
|
+
value: result
|
|
522
|
+
};
|
|
523
|
+
}
|
|
524
|
+
},
|
|
525
|
+
{
|
|
526
|
+
code: "f",
|
|
527
|
+
name: "start_step",
|
|
528
|
+
parse: (value) => {
|
|
529
|
+
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.");
|
|
530
|
+
return {
|
|
531
|
+
type: "start_step",
|
|
532
|
+
value: { messageId: value.messageId }
|
|
533
|
+
};
|
|
534
|
+
}
|
|
535
|
+
},
|
|
536
|
+
{
|
|
537
|
+
code: "g",
|
|
538
|
+
name: "reasoning",
|
|
539
|
+
parse: (value) => {
|
|
540
|
+
if (typeof value !== "string") throw new Error("\"reasoning\" parts expect a string value.");
|
|
541
|
+
return {
|
|
542
|
+
type: "reasoning",
|
|
543
|
+
value
|
|
544
|
+
};
|
|
545
|
+
}
|
|
546
|
+
},
|
|
547
|
+
{
|
|
548
|
+
code: "h",
|
|
549
|
+
name: "source",
|
|
550
|
+
parse: (value) => {
|
|
551
|
+
if (value == null || typeof value !== "object") throw new Error("\"source\" parts expect a Source object.");
|
|
552
|
+
return {
|
|
553
|
+
type: "source",
|
|
554
|
+
value
|
|
555
|
+
};
|
|
556
|
+
}
|
|
557
|
+
},
|
|
558
|
+
{
|
|
559
|
+
code: "i",
|
|
560
|
+
name: "redacted_reasoning",
|
|
561
|
+
parse: (value) => {
|
|
562
|
+
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.");
|
|
563
|
+
return {
|
|
564
|
+
type: "redacted_reasoning",
|
|
565
|
+
value: { data: value.data }
|
|
566
|
+
};
|
|
567
|
+
}
|
|
568
|
+
},
|
|
569
|
+
{
|
|
570
|
+
code: "j",
|
|
571
|
+
name: "reasoning_signature",
|
|
572
|
+
parse: (value) => {
|
|
573
|
+
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.");
|
|
574
|
+
return {
|
|
575
|
+
type: "reasoning_signature",
|
|
576
|
+
value: { signature: value.signature }
|
|
577
|
+
};
|
|
578
|
+
}
|
|
579
|
+
},
|
|
580
|
+
{
|
|
581
|
+
code: "k",
|
|
582
|
+
name: "file",
|
|
583
|
+
parse: (value) => {
|
|
584
|
+
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.");
|
|
585
|
+
return {
|
|
586
|
+
type: "file",
|
|
587
|
+
value
|
|
588
|
+
};
|
|
589
|
+
}
|
|
590
|
+
}
|
|
591
|
+
];
|
|
592
|
+
const dataStreamPartsByCode = Object.fromEntries(dataStreamParts.map((part) => [part.code, part]));
|
|
593
|
+
Object.fromEntries(dataStreamParts.map((part) => [part.name, part.code]));
|
|
594
|
+
const validCodes = dataStreamParts.map((part) => part.code);
|
|
595
|
+
/**
|
|
596
|
+
Parses a stream part from a string.
|
|
597
|
+
|
|
598
|
+
@param line The string to parse.
|
|
599
|
+
@returns The parsed stream part.
|
|
600
|
+
@throws An error if the string cannot be parsed.
|
|
601
|
+
*/
|
|
602
|
+
const parseDataStreamPart = (line) => {
|
|
603
|
+
const firstSeparatorIndex = line.indexOf(":");
|
|
604
|
+
if (firstSeparatorIndex === -1) throw new Error("Failed to parse stream string. No separator found.");
|
|
605
|
+
const prefix = line.slice(0, firstSeparatorIndex);
|
|
606
|
+
if (!validCodes.includes(prefix)) throw new Error(`Failed to parse stream string. Invalid code ${prefix}.`);
|
|
607
|
+
const code = prefix;
|
|
608
|
+
const textValue = line.slice(firstSeparatorIndex + 1);
|
|
609
|
+
const jsonValue = JSON.parse(textValue);
|
|
610
|
+
return dataStreamPartsByCode[code].parse(jsonValue);
|
|
611
|
+
};
|
|
612
|
+
//#endregion
|
|
613
|
+
//#region src/utils/ai-sdk-v4/fix-json.ts
|
|
614
|
+
function fixJson(input) {
|
|
615
|
+
const stack = ["ROOT"];
|
|
616
|
+
let lastValidIndex = -1;
|
|
617
|
+
let literalStart = null;
|
|
618
|
+
function processValueStart(char, i, swapState) {
|
|
619
|
+
switch (char) {
|
|
620
|
+
case "\"":
|
|
621
|
+
lastValidIndex = i;
|
|
622
|
+
stack.pop();
|
|
623
|
+
stack.push(swapState);
|
|
624
|
+
stack.push("INSIDE_STRING");
|
|
625
|
+
break;
|
|
626
|
+
case "f":
|
|
627
|
+
case "t":
|
|
628
|
+
case "n":
|
|
629
|
+
lastValidIndex = i;
|
|
630
|
+
literalStart = i;
|
|
631
|
+
stack.pop();
|
|
632
|
+
stack.push(swapState);
|
|
633
|
+
stack.push("INSIDE_LITERAL");
|
|
634
|
+
break;
|
|
635
|
+
case "-":
|
|
636
|
+
stack.pop();
|
|
637
|
+
stack.push(swapState);
|
|
638
|
+
stack.push("INSIDE_NUMBER");
|
|
639
|
+
break;
|
|
640
|
+
case "0":
|
|
641
|
+
case "1":
|
|
642
|
+
case "2":
|
|
643
|
+
case "3":
|
|
644
|
+
case "4":
|
|
645
|
+
case "5":
|
|
646
|
+
case "6":
|
|
647
|
+
case "7":
|
|
648
|
+
case "8":
|
|
649
|
+
case "9":
|
|
650
|
+
lastValidIndex = i;
|
|
651
|
+
stack.pop();
|
|
652
|
+
stack.push(swapState);
|
|
653
|
+
stack.push("INSIDE_NUMBER");
|
|
654
|
+
break;
|
|
655
|
+
case "{":
|
|
656
|
+
lastValidIndex = i;
|
|
657
|
+
stack.pop();
|
|
658
|
+
stack.push(swapState);
|
|
659
|
+
stack.push("INSIDE_OBJECT_START");
|
|
660
|
+
break;
|
|
661
|
+
case "[":
|
|
662
|
+
lastValidIndex = i;
|
|
663
|
+
stack.pop();
|
|
664
|
+
stack.push(swapState);
|
|
665
|
+
stack.push("INSIDE_ARRAY_START");
|
|
666
|
+
}
|
|
667
|
+
}
|
|
668
|
+
function processAfterObjectValue(char, i) {
|
|
669
|
+
switch (char) {
|
|
670
|
+
case ",":
|
|
671
|
+
stack.pop();
|
|
672
|
+
stack.push("INSIDE_OBJECT_AFTER_COMMA");
|
|
673
|
+
break;
|
|
674
|
+
case "}":
|
|
675
|
+
lastValidIndex = i;
|
|
676
|
+
stack.pop();
|
|
677
|
+
}
|
|
678
|
+
}
|
|
679
|
+
function processAfterArrayValue(char, i) {
|
|
680
|
+
switch (char) {
|
|
681
|
+
case ",":
|
|
682
|
+
stack.pop();
|
|
683
|
+
stack.push("INSIDE_ARRAY_AFTER_COMMA");
|
|
684
|
+
break;
|
|
685
|
+
case "]":
|
|
686
|
+
lastValidIndex = i;
|
|
687
|
+
stack.pop();
|
|
688
|
+
}
|
|
689
|
+
}
|
|
690
|
+
for (let i = 0; i < input.length; i++) {
|
|
691
|
+
const char = input[i];
|
|
692
|
+
switch (stack[stack.length - 1]) {
|
|
693
|
+
case "ROOT":
|
|
694
|
+
processValueStart(char, i, "FINISH");
|
|
695
|
+
break;
|
|
696
|
+
case "INSIDE_OBJECT_START":
|
|
697
|
+
switch (char) {
|
|
698
|
+
case "\"":
|
|
699
|
+
stack.pop();
|
|
700
|
+
stack.push("INSIDE_OBJECT_KEY");
|
|
701
|
+
break;
|
|
702
|
+
case "}":
|
|
703
|
+
lastValidIndex = i;
|
|
704
|
+
stack.pop();
|
|
705
|
+
}
|
|
706
|
+
break;
|
|
707
|
+
case "INSIDE_OBJECT_AFTER_COMMA":
|
|
708
|
+
switch (char) {
|
|
709
|
+
case "\"":
|
|
710
|
+
stack.pop();
|
|
711
|
+
stack.push("INSIDE_OBJECT_KEY");
|
|
712
|
+
}
|
|
713
|
+
break;
|
|
714
|
+
case "INSIDE_OBJECT_KEY":
|
|
715
|
+
switch (char) {
|
|
716
|
+
case "\"":
|
|
717
|
+
stack.pop();
|
|
718
|
+
stack.push("INSIDE_OBJECT_AFTER_KEY");
|
|
719
|
+
}
|
|
720
|
+
break;
|
|
721
|
+
case "INSIDE_OBJECT_AFTER_KEY":
|
|
722
|
+
switch (char) {
|
|
723
|
+
case ":":
|
|
724
|
+
stack.pop();
|
|
725
|
+
stack.push("INSIDE_OBJECT_BEFORE_VALUE");
|
|
726
|
+
}
|
|
727
|
+
break;
|
|
728
|
+
case "INSIDE_OBJECT_BEFORE_VALUE":
|
|
729
|
+
processValueStart(char, i, "INSIDE_OBJECT_AFTER_VALUE");
|
|
730
|
+
break;
|
|
731
|
+
case "INSIDE_OBJECT_AFTER_VALUE":
|
|
732
|
+
processAfterObjectValue(char, i);
|
|
733
|
+
break;
|
|
734
|
+
case "INSIDE_STRING":
|
|
735
|
+
switch (char) {
|
|
736
|
+
case "\"":
|
|
737
|
+
stack.pop();
|
|
738
|
+
lastValidIndex = i;
|
|
739
|
+
break;
|
|
740
|
+
case "\\":
|
|
741
|
+
stack.push("INSIDE_STRING_ESCAPE");
|
|
742
|
+
break;
|
|
743
|
+
default: lastValidIndex = i;
|
|
744
|
+
}
|
|
745
|
+
break;
|
|
746
|
+
case "INSIDE_ARRAY_START":
|
|
747
|
+
switch (char) {
|
|
748
|
+
case "]":
|
|
749
|
+
lastValidIndex = i;
|
|
750
|
+
stack.pop();
|
|
751
|
+
break;
|
|
752
|
+
default:
|
|
753
|
+
lastValidIndex = i;
|
|
754
|
+
processValueStart(char, i, "INSIDE_ARRAY_AFTER_VALUE");
|
|
755
|
+
}
|
|
756
|
+
break;
|
|
757
|
+
case "INSIDE_ARRAY_AFTER_VALUE":
|
|
758
|
+
switch (char) {
|
|
759
|
+
case ",":
|
|
760
|
+
stack.pop();
|
|
761
|
+
stack.push("INSIDE_ARRAY_AFTER_COMMA");
|
|
762
|
+
break;
|
|
763
|
+
case "]":
|
|
764
|
+
lastValidIndex = i;
|
|
765
|
+
stack.pop();
|
|
766
|
+
break;
|
|
767
|
+
default: lastValidIndex = i;
|
|
768
|
+
}
|
|
769
|
+
break;
|
|
770
|
+
case "INSIDE_ARRAY_AFTER_COMMA":
|
|
771
|
+
processValueStart(char, i, "INSIDE_ARRAY_AFTER_VALUE");
|
|
772
|
+
break;
|
|
773
|
+
case "INSIDE_STRING_ESCAPE":
|
|
774
|
+
stack.pop();
|
|
775
|
+
lastValidIndex = i;
|
|
776
|
+
break;
|
|
777
|
+
case "INSIDE_NUMBER":
|
|
778
|
+
switch (char) {
|
|
779
|
+
case "0":
|
|
780
|
+
case "1":
|
|
781
|
+
case "2":
|
|
782
|
+
case "3":
|
|
783
|
+
case "4":
|
|
784
|
+
case "5":
|
|
785
|
+
case "6":
|
|
786
|
+
case "7":
|
|
787
|
+
case "8":
|
|
788
|
+
case "9":
|
|
789
|
+
lastValidIndex = i;
|
|
790
|
+
break;
|
|
791
|
+
case "e":
|
|
792
|
+
case "E":
|
|
793
|
+
case "-":
|
|
794
|
+
case ".": break;
|
|
795
|
+
case ",":
|
|
796
|
+
stack.pop();
|
|
797
|
+
if (stack[stack.length - 1] === "INSIDE_ARRAY_AFTER_VALUE") processAfterArrayValue(char, i);
|
|
798
|
+
if (stack[stack.length - 1] === "INSIDE_OBJECT_AFTER_VALUE") processAfterObjectValue(char, i);
|
|
799
|
+
break;
|
|
800
|
+
case "}":
|
|
801
|
+
stack.pop();
|
|
802
|
+
if (stack[stack.length - 1] === "INSIDE_OBJECT_AFTER_VALUE") processAfterObjectValue(char, i);
|
|
803
|
+
break;
|
|
804
|
+
case "]":
|
|
805
|
+
stack.pop();
|
|
806
|
+
if (stack[stack.length - 1] === "INSIDE_ARRAY_AFTER_VALUE") processAfterArrayValue(char, i);
|
|
807
|
+
break;
|
|
808
|
+
default: stack.pop();
|
|
809
|
+
}
|
|
810
|
+
break;
|
|
811
|
+
case "INSIDE_LITERAL": {
|
|
812
|
+
const partialLiteral = input.substring(literalStart, i + 1);
|
|
813
|
+
if (!"false".startsWith(partialLiteral) && !"true".startsWith(partialLiteral) && !"null".startsWith(partialLiteral)) {
|
|
814
|
+
stack.pop();
|
|
815
|
+
if (stack[stack.length - 1] === "INSIDE_OBJECT_AFTER_VALUE") processAfterObjectValue(char, i);
|
|
816
|
+
else if (stack[stack.length - 1] === "INSIDE_ARRAY_AFTER_VALUE") processAfterArrayValue(char, i);
|
|
817
|
+
} else lastValidIndex = i;
|
|
818
|
+
break;
|
|
819
|
+
}
|
|
820
|
+
}
|
|
821
|
+
}
|
|
822
|
+
let result = input.slice(0, lastValidIndex + 1);
|
|
823
|
+
for (let i = stack.length - 1; i >= 0; i--) switch (stack[i]) {
|
|
824
|
+
case "INSIDE_STRING":
|
|
825
|
+
result += "\"";
|
|
826
|
+
break;
|
|
827
|
+
case "INSIDE_OBJECT_KEY":
|
|
828
|
+
case "INSIDE_OBJECT_AFTER_KEY":
|
|
829
|
+
case "INSIDE_OBJECT_AFTER_COMMA":
|
|
830
|
+
case "INSIDE_OBJECT_START":
|
|
831
|
+
case "INSIDE_OBJECT_BEFORE_VALUE":
|
|
832
|
+
case "INSIDE_OBJECT_AFTER_VALUE":
|
|
833
|
+
result += "}";
|
|
834
|
+
break;
|
|
835
|
+
case "INSIDE_ARRAY_START":
|
|
836
|
+
case "INSIDE_ARRAY_AFTER_COMMA":
|
|
837
|
+
case "INSIDE_ARRAY_AFTER_VALUE":
|
|
838
|
+
result += "]";
|
|
839
|
+
break;
|
|
840
|
+
case "INSIDE_LITERAL": {
|
|
841
|
+
const partialLiteral = input.substring(literalStart, input.length);
|
|
842
|
+
if ("true".startsWith(partialLiteral)) result += "true".slice(partialLiteral.length);
|
|
843
|
+
else if ("false".startsWith(partialLiteral)) result += "false".slice(partialLiteral.length);
|
|
844
|
+
else if ("null".startsWith(partialLiteral)) result += "null".slice(partialLiteral.length);
|
|
845
|
+
}
|
|
846
|
+
}
|
|
847
|
+
return result;
|
|
848
|
+
}
|
|
849
|
+
//#endregion
|
|
850
|
+
//#region src/utils/ai-sdk-v4/parse-partial-json.ts
|
|
851
|
+
function tryParse(text) {
|
|
852
|
+
try {
|
|
853
|
+
return {
|
|
854
|
+
success: true,
|
|
855
|
+
value: JSON.parse(text)
|
|
856
|
+
};
|
|
857
|
+
} catch {
|
|
858
|
+
return { success: false };
|
|
859
|
+
}
|
|
860
|
+
}
|
|
861
|
+
function parsePartialJson(jsonText) {
|
|
862
|
+
if (jsonText === void 0) return {
|
|
863
|
+
value: void 0,
|
|
864
|
+
state: "undefined-input"
|
|
865
|
+
};
|
|
866
|
+
let result = tryParse(jsonText);
|
|
867
|
+
if (result.success) return {
|
|
868
|
+
value: result.value,
|
|
869
|
+
state: "successful-parse"
|
|
870
|
+
};
|
|
871
|
+
result = tryParse(fixJson(jsonText));
|
|
872
|
+
if (result.success) return {
|
|
873
|
+
value: result.value,
|
|
874
|
+
state: "repaired-parse"
|
|
875
|
+
};
|
|
876
|
+
return {
|
|
877
|
+
value: void 0,
|
|
878
|
+
state: "failed-parse"
|
|
879
|
+
};
|
|
880
|
+
}
|
|
881
|
+
//#endregion
|
|
882
|
+
//#region src/utils/ai-sdk-v4/process-data-stream.ts
|
|
883
|
+
const NEWLINE = "\n".charCodeAt(0);
|
|
884
|
+
function concatChunks(chunks, totalLength) {
|
|
885
|
+
const concatenatedChunks = new Uint8Array(totalLength);
|
|
886
|
+
let offset = 0;
|
|
887
|
+
for (const chunk of chunks) {
|
|
888
|
+
concatenatedChunks.set(chunk, offset);
|
|
889
|
+
offset += chunk.length;
|
|
890
|
+
}
|
|
891
|
+
chunks.length = 0;
|
|
892
|
+
return concatenatedChunks;
|
|
893
|
+
}
|
|
894
|
+
async function processDataStream({ stream, onTextPart, onReasoningPart, onReasoningSignaturePart, onRedactedReasoningPart, onSourcePart, onFilePart, onDataPart, onErrorPart, onToolCallStreamingStartPart, onToolCallDeltaPart, onToolCallPart, onToolResultPart, onMessageAnnotationsPart, onFinishMessagePart, onFinishStepPart, onStartStepPart }) {
|
|
895
|
+
const reader = stream.getReader();
|
|
896
|
+
const decoder = new TextDecoder();
|
|
897
|
+
const chunks = [];
|
|
898
|
+
let totalLength = 0;
|
|
899
|
+
while (true) {
|
|
900
|
+
const { value } = await reader.read();
|
|
901
|
+
if (value) {
|
|
902
|
+
chunks.push(value);
|
|
903
|
+
totalLength += value.length;
|
|
904
|
+
if (value[value.length - 1] !== NEWLINE) continue;
|
|
905
|
+
}
|
|
906
|
+
if (chunks.length === 0) break;
|
|
907
|
+
const concatenatedChunks = concatChunks(chunks, totalLength);
|
|
908
|
+
totalLength = 0;
|
|
909
|
+
const streamParts = decoder.decode(concatenatedChunks, { stream: true }).split("\n").filter((line) => line !== "").map(parseDataStreamPart);
|
|
910
|
+
for (const { type, value } of streamParts) switch (type) {
|
|
911
|
+
case "text":
|
|
912
|
+
await onTextPart?.(value);
|
|
913
|
+
break;
|
|
914
|
+
case "reasoning":
|
|
915
|
+
await onReasoningPart?.(value);
|
|
916
|
+
break;
|
|
917
|
+
case "reasoning_signature":
|
|
918
|
+
await onReasoningSignaturePart?.(value);
|
|
919
|
+
break;
|
|
920
|
+
case "redacted_reasoning":
|
|
921
|
+
await onRedactedReasoningPart?.(value);
|
|
922
|
+
break;
|
|
923
|
+
case "file":
|
|
924
|
+
await onFilePart?.(value);
|
|
925
|
+
break;
|
|
926
|
+
case "source":
|
|
927
|
+
await onSourcePart?.(value);
|
|
928
|
+
break;
|
|
929
|
+
case "data":
|
|
930
|
+
await onDataPart?.(value);
|
|
931
|
+
break;
|
|
932
|
+
case "error":
|
|
933
|
+
await onErrorPart?.(value);
|
|
934
|
+
break;
|
|
935
|
+
case "message_annotations":
|
|
936
|
+
await onMessageAnnotationsPart?.(value);
|
|
937
|
+
break;
|
|
938
|
+
case "tool_call_streaming_start":
|
|
939
|
+
await onToolCallStreamingStartPart?.(value);
|
|
940
|
+
break;
|
|
941
|
+
case "tool_call_delta":
|
|
942
|
+
await onToolCallDeltaPart?.(value);
|
|
943
|
+
break;
|
|
944
|
+
case "tool_call":
|
|
945
|
+
await onToolCallPart?.(value);
|
|
946
|
+
break;
|
|
947
|
+
case "tool_result":
|
|
948
|
+
await onToolResultPart?.(value);
|
|
949
|
+
break;
|
|
950
|
+
case "finish_message":
|
|
951
|
+
await onFinishMessagePart?.(value);
|
|
952
|
+
break;
|
|
953
|
+
case "finish_step":
|
|
954
|
+
await onFinishStepPart?.(value);
|
|
955
|
+
break;
|
|
956
|
+
case "start_step":
|
|
957
|
+
await onStartStepPart?.(value);
|
|
958
|
+
break;
|
|
959
|
+
default: throw new Error(`Unknown stream part type: ${type}`);
|
|
960
|
+
}
|
|
961
|
+
}
|
|
962
|
+
}
|
|
963
|
+
//#endregion
|
|
389
964
|
//#region src/utils/client-tool-model-output.ts
|
|
390
965
|
/**
|
|
391
966
|
* Normalize modelOutput from toModelOutput() to the AI SDK V2 tool result
|
|
@@ -618,7 +1193,7 @@ var BaseResource = class {
|
|
|
618
1193
|
} catch (error) {
|
|
619
1194
|
lastError = error;
|
|
620
1195
|
if (signal?.aborted || error?.name === "AbortError") throw error;
|
|
621
|
-
if (isTerminalHttpError(error)) throw error;
|
|
1196
|
+
if (isTerminalHttpError(error) || isTraceQueryTimeoutError(error)) throw error;
|
|
622
1197
|
if (attempt === retries) break;
|
|
623
1198
|
await new Promise((resolve, reject) => {
|
|
624
1199
|
const timer = setTimeout(() => {
|
|
@@ -639,8 +1214,16 @@ var BaseResource = class {
|
|
|
639
1214
|
};
|
|
640
1215
|
//#endregion
|
|
641
1216
|
//#region src/resources/agent.ts
|
|
642
|
-
const SIGNAL_RUNTIME_OPTIONS_TTL_MS =
|
|
1217
|
+
const SIGNAL_RUNTIME_OPTIONS_TTL_MS = 3e5;
|
|
643
1218
|
const signalRuntimeOptionsByRunId = /* @__PURE__ */ new Map();
|
|
1219
|
+
/**
|
|
1220
|
+
* Client tools a resume request can execute, keyed by run. The stream that stayed open from
|
|
1221
|
+
* before the suspension must not run those tools again, but it must run any resumed client tool
|
|
1222
|
+
* the resume request cannot execute (a server-side approve sends no client tools). Held until the
|
|
1223
|
+
* last stream of the run closes, which is after the resume request returns.
|
|
1224
|
+
*/
|
|
1225
|
+
const resumingClientToolNamesByRunKey = /* @__PURE__ */ new Map();
|
|
1226
|
+
const openStreamCountByRunKey = /* @__PURE__ */ new Map();
|
|
644
1227
|
const latestSignalRuntimeOptionsByThread = /* @__PURE__ */ new Map();
|
|
645
1228
|
const createSignalRuntimeOptionsEntry = (store, key, streamOptions) => {
|
|
646
1229
|
const timeout = setTimeout(() => store.delete(key), SIGNAL_RUNTIME_OPTIONS_TTL_MS);
|
|
@@ -833,6 +1416,49 @@ var Agent = class extends BaseResource {
|
|
|
833
1416
|
getSignalRuntimeRunKey(runId) {
|
|
834
1417
|
return `${this.options.baseUrl}|${this.apiPrefix}|${this.agentId}|${runId}`;
|
|
835
1418
|
}
|
|
1419
|
+
/**
|
|
1420
|
+
* Records that `runId` is being resumed by a request that can execute these client tools, so the
|
|
1421
|
+
* stream that is still open from before the suspension skips them. Released when the last stream
|
|
1422
|
+
* of the run closes, which is after this request returns.
|
|
1423
|
+
*/
|
|
1424
|
+
holdResumingClientTools(runId, clientTools) {
|
|
1425
|
+
const names = Object.entries(clientTools ?? {}).filter(([, tool]) => typeof tool.execute === "function").map(([name]) => name);
|
|
1426
|
+
if (names.length === 0) return () => {};
|
|
1427
|
+
const key = this.getSignalRuntimeRunKey(runId);
|
|
1428
|
+
const held = resumingClientToolNamesByRunKey.get(key) ?? /* @__PURE__ */ new Map();
|
|
1429
|
+
for (const name of names) held.set(name, (held.get(name) ?? 0) + 1);
|
|
1430
|
+
resumingClientToolNamesByRunKey.set(key, held);
|
|
1431
|
+
let released = false;
|
|
1432
|
+
return ({ force = false } = {}) => {
|
|
1433
|
+
if (released || !force && openStreamCountByRunKey.has(key)) return;
|
|
1434
|
+
released = true;
|
|
1435
|
+
const current = resumingClientToolNamesByRunKey.get(key);
|
|
1436
|
+
if (!current) return;
|
|
1437
|
+
for (const name of names) {
|
|
1438
|
+
const count = (current.get(name) ?? 1) - 1;
|
|
1439
|
+
if (count > 0) current.set(name, count);
|
|
1440
|
+
else current.delete(name);
|
|
1441
|
+
}
|
|
1442
|
+
if (current.size === 0) resumingClientToolNamesByRunKey.delete(key);
|
|
1443
|
+
};
|
|
1444
|
+
}
|
|
1445
|
+
/** Drops the held tool names when the last stream of the run closes. */
|
|
1446
|
+
trackOpenStream(runId) {
|
|
1447
|
+
const key = this.getSignalRuntimeRunKey(runId);
|
|
1448
|
+
openStreamCountByRunKey.set(key, (openStreamCountByRunKey.get(key) ?? 0) + 1);
|
|
1449
|
+
let released = false;
|
|
1450
|
+
return () => {
|
|
1451
|
+
if (released) return;
|
|
1452
|
+
released = true;
|
|
1453
|
+
const remaining = (openStreamCountByRunKey.get(key) ?? 1) - 1;
|
|
1454
|
+
if (remaining > 0) {
|
|
1455
|
+
openStreamCountByRunKey.set(key, remaining);
|
|
1456
|
+
return;
|
|
1457
|
+
}
|
|
1458
|
+
openStreamCountByRunKey.delete(key);
|
|
1459
|
+
resumingClientToolNamesByRunKey.delete(key);
|
|
1460
|
+
};
|
|
1461
|
+
}
|
|
836
1462
|
getSignalRuntimeThreadKey({ resourceId, threadId }) {
|
|
837
1463
|
if (!threadId) return void 0;
|
|
838
1464
|
return `${this.options.baseUrl}|${this.apiPrefix}|${this.agentId}|${resourceId ?? ""}|${threadId}`;
|
|
@@ -1970,7 +2596,6 @@ var Agent = class extends BaseResource {
|
|
|
1970
2596
|
case "finish":
|
|
1971
2597
|
finishReason = chunk.payload?.stepResult?.reason ?? finishReason;
|
|
1972
2598
|
if (chunk.payload?.usage != null) usage = chunk.payload.usage;
|
|
1973
|
-
break;
|
|
1974
2599
|
}
|
|
1975
2600
|
}
|
|
1976
2601
|
});
|
|
@@ -2034,6 +2659,10 @@ var Agent = class extends BaseResource {
|
|
|
2034
2659
|
try {
|
|
2035
2660
|
let messages = [];
|
|
2036
2661
|
let streamRunId = processedParams.runId;
|
|
2662
|
+
let finishedHistory;
|
|
2663
|
+
let suspended = false;
|
|
2664
|
+
const resumedToolCallIds = /* @__PURE__ */ new Set();
|
|
2665
|
+
const releaseOpenStream = streamRunId ? this.trackOpenStream(streamRunId) : () => {};
|
|
2037
2666
|
const [streamForController, streamForProcessing] = response.body.tee();
|
|
2038
2667
|
const decoder = new TextDecoder();
|
|
2039
2668
|
let pendingText = "";
|
|
@@ -2041,6 +2670,13 @@ var Agent = class extends BaseResource {
|
|
|
2041
2670
|
pendingText += text;
|
|
2042
2671
|
const lines = pendingText.split("\n\n");
|
|
2043
2672
|
pendingText = isFinal ? "" : lines.pop() ?? "";
|
|
2673
|
+
for (const line of lines) {
|
|
2674
|
+
if (!line.startsWith("data: ") || !line.includes("\"type\":\"finish\"")) continue;
|
|
2675
|
+
try {
|
|
2676
|
+
const all = JSON.parse(line.slice(6))?.payload?.messages?.all;
|
|
2677
|
+
if (Array.isArray(all)) finishedHistory = all;
|
|
2678
|
+
} catch {}
|
|
2679
|
+
}
|
|
2044
2680
|
const readableLines = lines.filter((line) => line.trim() !== "[DONE]" && line.trim() !== "data: [DONE]").join("\n\n");
|
|
2045
2681
|
if (readableLines) safeEnqueue(new TextEncoder().encode(`${readableLines}\n\n`));
|
|
2046
2682
|
};
|
|
@@ -2095,6 +2731,9 @@ var Agent = class extends BaseResource {
|
|
|
2095
2731
|
});
|
|
2096
2732
|
}
|
|
2097
2733
|
const executableToolCalls = [...toolInvocationsById.values()].filter((toolCall) => {
|
|
2734
|
+
if (resumedToolCallIds.has(toolCall.toolCallId)) {
|
|
2735
|
+
if ((streamRunId ? resumingClientToolNamesByRunKey.get(this.getSignalRuntimeRunKey(streamRunId)) : void 0)?.has(toolCall.toolName)) return false;
|
|
2736
|
+
}
|
|
2098
2737
|
const clientTool = processedParams.clientTools?.[toolCall.toolName];
|
|
2099
2738
|
return Boolean(clientTool?.execute);
|
|
2100
2739
|
});
|
|
@@ -2194,12 +2833,12 @@ var Agent = class extends BaseResource {
|
|
|
2194
2833
|
role: "tool",
|
|
2195
2834
|
content: toolResultContents
|
|
2196
2835
|
};
|
|
2197
|
-
const updatedMessages = threadId ? [toolResultMessage] : [
|
|
2836
|
+
const updatedMessages = threadId ? [toolResultMessage] : (route === "resume-stream" || route === "approve-tool-call" || route === "decline-tool-call") && finishedHistory ? [...finishedHistory, toolResultMessage] : [
|
|
2198
2837
|
...Array.isArray(processedParams.messages) ? processedParams.messages : [],
|
|
2199
2838
|
...messages,
|
|
2200
2839
|
toolResultMessage
|
|
2201
2840
|
];
|
|
2202
|
-
const recursionRoute = route === "resume-stream" ? "stream" : route === "resume-stream-until-idle" ? "stream-until-idle" : route;
|
|
2841
|
+
const recursionRoute = route === "resume-stream" || route === "approve-tool-call" || route === "decline-tool-call" ? "stream" : route === "resume-stream-until-idle" ? "stream-until-idle" : route;
|
|
2203
2842
|
if (isAborted()) return;
|
|
2204
2843
|
try {
|
|
2205
2844
|
await this.processStreamResponse({
|
|
@@ -2221,6 +2860,12 @@ var Agent = class extends BaseResource {
|
|
|
2221
2860
|
},
|
|
2222
2861
|
onStreamChunk: (chunk) => {
|
|
2223
2862
|
if (!streamRunId && typeof chunk.runId === "string") streamRunId = chunk.runId;
|
|
2863
|
+
if (chunk.type === "tool-call-approval" || chunk.type === "tool-call-suspended") suspended = true;
|
|
2864
|
+
else if (suspended && chunk.type === "tool-call" && typeof chunk.payload?.toolCallId === "string") {
|
|
2865
|
+
const toolName = chunk.payload.toolName;
|
|
2866
|
+
const held = streamRunId ? resumingClientToolNamesByRunKey.get(this.getSignalRuntimeRunKey(streamRunId)) : void 0;
|
|
2867
|
+
if (typeof toolName === "string" && held?.has(toolName)) resumedToolCallIds.add(chunk.payload.toolCallId);
|
|
2868
|
+
}
|
|
2224
2869
|
},
|
|
2225
2870
|
lastMessage: void 0
|
|
2226
2871
|
}).catch(async (error) => {
|
|
@@ -2231,6 +2876,7 @@ var Agent = class extends BaseResource {
|
|
|
2231
2876
|
safeClose();
|
|
2232
2877
|
}).finally(() => {
|
|
2233
2878
|
signal?.removeEventListener("abort", onAbort);
|
|
2879
|
+
releaseOpenStream();
|
|
2234
2880
|
});
|
|
2235
2881
|
} catch (error) {
|
|
2236
2882
|
if (!isAbortError(error)) console.error("Error processing stream response:", error);
|
|
@@ -2398,12 +3044,18 @@ var Agent = class extends BaseResource {
|
|
|
2398
3044
|
}
|
|
2399
3045
|
async approveToolCall(params) {
|
|
2400
3046
|
const { requestContext, ...rest } = params;
|
|
3047
|
+
const executableClientTools = params.clientToolsResolver?.() ?? params.clientTools;
|
|
3048
|
+
const releaseHold = this.holdResumingClientTools(rest.runId, executableClientTools);
|
|
2401
3049
|
const processedParams = {
|
|
2402
3050
|
...rest,
|
|
2403
|
-
requestContext: parseClientRequestContext(requestContext)
|
|
3051
|
+
requestContext: parseClientRequestContext(requestContext),
|
|
3052
|
+
clientTools: processClientTools(executableClientTools)
|
|
2404
3053
|
};
|
|
2405
3054
|
const { readable, controller: readableController, signal } = this.createCancellableStream(params.abortSignal);
|
|
2406
|
-
const response = await this.processStreamResponse(processedParams, readableController, "approve-tool-call", signal)
|
|
3055
|
+
const response = await this.processStreamResponse(processedParams, readableController, "approve-tool-call", signal).catch((error) => {
|
|
3056
|
+
releaseHold({ force: true });
|
|
3057
|
+
throw error;
|
|
3058
|
+
});
|
|
2407
3059
|
const streamResponse = new Response(readable, {
|
|
2408
3060
|
status: response.status,
|
|
2409
3061
|
statusText: response.statusText,
|
|
@@ -2429,12 +3081,18 @@ var Agent = class extends BaseResource {
|
|
|
2429
3081
|
}
|
|
2430
3082
|
async declineToolCall(params) {
|
|
2431
3083
|
const { requestContext, ...rest } = params;
|
|
3084
|
+
const executableClientTools = params.clientToolsResolver?.() ?? params.clientTools;
|
|
3085
|
+
const releaseHold = this.holdResumingClientTools(rest.runId, executableClientTools);
|
|
2432
3086
|
const processedParams = {
|
|
2433
3087
|
...rest,
|
|
2434
|
-
requestContext: parseClientRequestContext(requestContext)
|
|
3088
|
+
requestContext: parseClientRequestContext(requestContext),
|
|
3089
|
+
clientTools: processClientTools(executableClientTools)
|
|
2435
3090
|
};
|
|
2436
3091
|
const { readable, controller: readableController, signal } = this.createCancellableStream(params.abortSignal);
|
|
2437
|
-
const response = await this.processStreamResponse(processedParams, readableController, "decline-tool-call", signal)
|
|
3092
|
+
const response = await this.processStreamResponse(processedParams, readableController, "decline-tool-call", signal).catch((error) => {
|
|
3093
|
+
releaseHold({ force: true });
|
|
3094
|
+
throw error;
|
|
3095
|
+
});
|
|
2438
3096
|
const streamResponse = new Response(readable, {
|
|
2439
3097
|
status: response.status,
|
|
2440
3098
|
statusText: response.statusText,
|
|
@@ -2494,18 +3152,23 @@ var Agent = class extends BaseResource {
|
|
|
2494
3152
|
* Used to continue execution after a suspension point (e.g., workflow suspend within an agent).
|
|
2495
3153
|
*/
|
|
2496
3154
|
async resumeStream(resumeData, options) {
|
|
3155
|
+
const executableClientTools = options.clientToolsResolver?.() ?? options.clientTools;
|
|
3156
|
+
const releaseHold = this.holdResumingClientTools(options.runId, executableClientTools);
|
|
2497
3157
|
const processedParams = {
|
|
2498
3158
|
...options,
|
|
2499
3159
|
resumeData,
|
|
2500
3160
|
requestContext: parseClientRequestContext(options.requestContext),
|
|
2501
|
-
clientTools: processClientTools(
|
|
3161
|
+
clientTools: processClientTools(executableClientTools),
|
|
2502
3162
|
structuredOutput: options.structuredOutput ? {
|
|
2503
3163
|
...options.structuredOutput,
|
|
2504
3164
|
schema: standardSchemaToJSONSchema(toStandardSchema(options.structuredOutput.schema))
|
|
2505
3165
|
} : void 0
|
|
2506
3166
|
};
|
|
2507
3167
|
const { readable, controller: readableController, signal } = this.createCancellableStream(options.abortSignal);
|
|
2508
|
-
const response = await this.processStreamResponse(processedParams, readableController, "resume-stream", signal)
|
|
3168
|
+
const response = await this.processStreamResponse(processedParams, readableController, "resume-stream", signal).catch((error) => {
|
|
3169
|
+
releaseHold({ force: true });
|
|
3170
|
+
throw error;
|
|
3171
|
+
});
|
|
2509
3172
|
const streamResponse = new Response(readable, {
|
|
2510
3173
|
status: response.status,
|
|
2511
3174
|
statusText: response.statusText,
|
|
@@ -2558,18 +3221,23 @@ var Agent = class extends BaseResource {
|
|
|
2558
3221
|
* Used to continue execution after a suspension point (e.g., workflow suspend within an agent).
|
|
2559
3222
|
*/
|
|
2560
3223
|
async resumeStreamUntilIdle(resumeData, options) {
|
|
3224
|
+
const executableClientTools = options.clientToolsResolver?.() ?? options.clientTools;
|
|
3225
|
+
const releaseHold = this.holdResumingClientTools(options.runId, executableClientTools);
|
|
2561
3226
|
const processedParams = {
|
|
2562
3227
|
...options,
|
|
2563
3228
|
resumeData,
|
|
2564
3229
|
requestContext: parseClientRequestContext(options.requestContext),
|
|
2565
|
-
clientTools: processClientTools(
|
|
3230
|
+
clientTools: processClientTools(executableClientTools),
|
|
2566
3231
|
structuredOutput: options.structuredOutput ? {
|
|
2567
3232
|
...options.structuredOutput,
|
|
2568
3233
|
schema: standardSchemaToJSONSchema(toStandardSchema(options.structuredOutput.schema))
|
|
2569
3234
|
} : void 0
|
|
2570
3235
|
};
|
|
2571
3236
|
const { readable, controller: readableController, signal } = this.createCancellableStream(options.abortSignal);
|
|
2572
|
-
const response = await this.processStreamResponse(processedParams, readableController, "resume-stream-until-idle", signal)
|
|
3237
|
+
const response = await this.processStreamResponse(processedParams, readableController, "resume-stream-until-idle", signal).catch((error) => {
|
|
3238
|
+
releaseHold({ force: true });
|
|
3239
|
+
throw error;
|
|
3240
|
+
});
|
|
2573
3241
|
const streamResponse = new Response(readable, {
|
|
2574
3242
|
status: response.status,
|
|
2575
3243
|
statusText: response.statusText,
|
|
@@ -2588,27 +3256,93 @@ var Agent = class extends BaseResource {
|
|
|
2588
3256
|
* Used when `requireToolApproval` is enabled with generate() to allow the agent to proceed.
|
|
2589
3257
|
*/
|
|
2590
3258
|
async approveToolCallGenerate(params) {
|
|
2591
|
-
const { requestContext, ...rest } = params;
|
|
2592
|
-
|
|
2593
|
-
|
|
2594
|
-
|
|
2595
|
-
|
|
2596
|
-
|
|
2597
|
-
|
|
2598
|
-
|
|
3259
|
+
const { requestContext, clientTools, clientToolsResolver, memory, ...rest } = params;
|
|
3260
|
+
const executableClientTools = clientToolsResolver?.() ?? clientTools;
|
|
3261
|
+
const releaseHold = this.holdResumingClientTools(rest.runId, executableClientTools);
|
|
3262
|
+
let response;
|
|
3263
|
+
try {
|
|
3264
|
+
response = await this.request(`/agents/${this.agentId}/approve-tool-call-generate`, {
|
|
3265
|
+
method: "POST",
|
|
3266
|
+
body: {
|
|
3267
|
+
...rest,
|
|
3268
|
+
requestContext: parseClientRequestContext(requestContext),
|
|
3269
|
+
clientTools: processClientTools(executableClientTools)
|
|
3270
|
+
}
|
|
3271
|
+
});
|
|
3272
|
+
} catch (error) {
|
|
3273
|
+
releaseHold({ force: true });
|
|
3274
|
+
throw error;
|
|
3275
|
+
}
|
|
3276
|
+
try {
|
|
3277
|
+
return await this.continueResumedGenerate(response, {
|
|
3278
|
+
requestContext,
|
|
3279
|
+
clientTools: executableClientTools,
|
|
3280
|
+
clientToolsResolver,
|
|
3281
|
+
memory
|
|
3282
|
+
});
|
|
3283
|
+
} finally {
|
|
3284
|
+
releaseHold();
|
|
3285
|
+
}
|
|
2599
3286
|
}
|
|
2600
3287
|
/**
|
|
2601
3288
|
* Declines a pending tool call and returns the complete response (non-streaming).
|
|
2602
3289
|
* Used when `requireToolApproval` is enabled with generate() to prevent tool execution.
|
|
2603
3290
|
*/
|
|
2604
3291
|
async declineToolCallGenerate(params) {
|
|
2605
|
-
const { requestContext, ...rest } = params;
|
|
2606
|
-
|
|
2607
|
-
|
|
2608
|
-
|
|
2609
|
-
|
|
2610
|
-
|
|
2611
|
-
|
|
3292
|
+
const { requestContext, clientTools, clientToolsResolver, memory, ...rest } = params;
|
|
3293
|
+
const executableClientTools = clientToolsResolver?.() ?? clientTools;
|
|
3294
|
+
const releaseHold = this.holdResumingClientTools(rest.runId, executableClientTools);
|
|
3295
|
+
let response;
|
|
3296
|
+
try {
|
|
3297
|
+
response = await this.request(`/agents/${this.agentId}/decline-tool-call-generate`, {
|
|
3298
|
+
method: "POST",
|
|
3299
|
+
body: {
|
|
3300
|
+
...rest,
|
|
3301
|
+
requestContext: parseClientRequestContext(requestContext),
|
|
3302
|
+
clientTools: processClientTools(executableClientTools)
|
|
3303
|
+
}
|
|
3304
|
+
});
|
|
3305
|
+
} catch (error) {
|
|
3306
|
+
releaseHold({ force: true });
|
|
3307
|
+
throw error;
|
|
3308
|
+
}
|
|
3309
|
+
try {
|
|
3310
|
+
return await this.continueResumedGenerate(response, {
|
|
3311
|
+
requestContext,
|
|
3312
|
+
clientTools: executableClientTools,
|
|
3313
|
+
clientToolsResolver,
|
|
3314
|
+
memory
|
|
3315
|
+
});
|
|
3316
|
+
} finally {
|
|
3317
|
+
releaseHold();
|
|
3318
|
+
}
|
|
3319
|
+
}
|
|
3320
|
+
/**
|
|
3321
|
+
* Runs executable client tools the model called after an approval decision and continues on
|
|
3322
|
+
* /generate, like generate() does. With memory the continuation sends only the new messages to the
|
|
3323
|
+
* thread. Without memory it re-sends the conversation up to the last user turn, because the resume
|
|
3324
|
+
* routes keep the earlier history server-side and drop it once the run finishes.
|
|
3325
|
+
*/
|
|
3326
|
+
async continueResumedGenerate(response, { requestContext, clientTools, clientToolsResolver, memory }) {
|
|
3327
|
+
if (response.finishReason !== "tool-calls") return response;
|
|
3328
|
+
const context = requestContext === void 0 || requestContext instanceof RequestContext$1 ? requestContext : new RequestContext$1(Object.entries(requestContext));
|
|
3329
|
+
const threadId = typeof memory?.thread === "string" ? memory.thread : memory?.thread?.id;
|
|
3330
|
+
const history = response.messages ?? [];
|
|
3331
|
+
const priorTurns = history.slice(0, history.findLastIndex((message) => message.role === "user") + 1);
|
|
3332
|
+
return executeToolCallAndRespond({
|
|
3333
|
+
response,
|
|
3334
|
+
params: {
|
|
3335
|
+
messages: threadId ? [] : priorTurns,
|
|
3336
|
+
clientTools: clientToolsResolver?.() ?? clientTools,
|
|
3337
|
+
clientToolsResolver,
|
|
3338
|
+
requestContext: context,
|
|
3339
|
+
memory
|
|
3340
|
+
},
|
|
3341
|
+
agentId: this.agentId,
|
|
3342
|
+
resourceId: memory?.resource,
|
|
3343
|
+
threadId,
|
|
3344
|
+
requestContext: context,
|
|
3345
|
+
respondFn: (messages, options) => this.generate(messages, options)
|
|
2612
3346
|
});
|
|
2613
3347
|
}
|
|
2614
3348
|
/**
|
|
@@ -3806,7 +4540,8 @@ async function verifyAgentCardSignatureIfPresent(agentCard, options) {
|
|
|
3806
4540
|
index
|
|
3807
4541
|
});
|
|
3808
4542
|
if (!verificationKey) throw new Error("No verification key was provided for Agent Card signature verification");
|
|
3809
|
-
|
|
4543
|
+
const importedKey = await importVerificationKey(verificationKey, protectedHeader.alg);
|
|
4544
|
+
await compactVerify(compactJws, importedKey, { algorithms: allowedAlgorithms });
|
|
3810
4545
|
return agentCard;
|
|
3811
4546
|
} catch (error) {
|
|
3812
4547
|
verificationErrors.push(error instanceof Error ? error.message : "Unknown verification failure");
|
|
@@ -4550,10 +5285,10 @@ var Observability = class extends BaseResource {
|
|
|
4550
5285
|
});
|
|
4551
5286
|
}
|
|
4552
5287
|
/**
|
|
4553
|
-
* Queries thread
|
|
5288
|
+
* Queries full-history thread rows using a trace or thread activity window.
|
|
4554
5289
|
*
|
|
4555
|
-
* @param params - Thread query with its
|
|
4556
|
-
* @returns Matching thread
|
|
5290
|
+
* @param params - Thread query with its qualification window, filters and pagination
|
|
5291
|
+
* @returns Matching thread rows. Legacy requests retain their identity-only response.
|
|
4557
5292
|
*/
|
|
4558
5293
|
queryTraceThreads(params) {
|
|
4559
5294
|
return this.request("/observability/threads/query", {
|
|
@@ -6138,48 +6873,40 @@ function hydrateEventTimestamps(event) {
|
|
|
6138
6873
|
return isKnownParsedEvent(event) ? hydrateKnownEvent(event) : event;
|
|
6139
6874
|
}
|
|
6140
6875
|
/**
|
|
6141
|
-
* A session
|
|
6142
|
-
* get-or-create on the server, so re-creating the same
|
|
6143
|
-
*
|
|
6144
|
-
*
|
|
6145
|
-
*
|
|
6146
|
-
* two sessions with the same resourceId but different scopes have their own
|
|
6147
|
-
* run loop, thread binding, and mode/model/state (e.g. one session per git
|
|
6148
|
-
* worktree, with the worktree path as the scope). The scope travels on every
|
|
6149
|
-
* request as a `sessionScope` query param.
|
|
6876
|
+
* A session addressed by its `sessionId` within one agent controller. Sessions
|
|
6877
|
+
* are get-or-create on the server, so re-creating the same sessionId resumes
|
|
6878
|
+
* the existing conversation rather than forking it. Many sessions can work on
|
|
6879
|
+
* one `resourceId` (whose threads and memory they use); each has its own run
|
|
6880
|
+
* loop, thread binding, and mode/model/state.
|
|
6150
6881
|
*/
|
|
6151
6882
|
var AgentControllerSession = class extends BaseResource {
|
|
6152
6883
|
controllerId;
|
|
6153
|
-
|
|
6154
|
-
|
|
6155
|
-
constructor(options, controllerId, resourceId, scope) {
|
|
6884
|
+
sessionId;
|
|
6885
|
+
constructor(options, controllerId, sessionId) {
|
|
6156
6886
|
super(options);
|
|
6157
6887
|
this.controllerId = controllerId;
|
|
6158
|
-
this.
|
|
6159
|
-
this.scope = scope;
|
|
6888
|
+
this.sessionId = sessionId;
|
|
6160
6889
|
}
|
|
6161
6890
|
base() {
|
|
6162
|
-
return `/agent-controller/${encodeURIComponent(this.controllerId)}/sessions/${encodeURIComponent(this.
|
|
6163
|
-
}
|
|
6164
|
-
/** Append this session's scope (if any) as a `sessionScope` query param. */
|
|
6165
|
-
url(path) {
|
|
6166
|
-
if (this.scope === void 0) return path;
|
|
6167
|
-
return `${path}${path.includes("?") ? "&" : "?"}sessionScope=${encodeURIComponent(this.scope)}`;
|
|
6891
|
+
return `/agent-controller/${encodeURIComponent(this.controllerId)}/sessions/${encodeURIComponent(this.sessionId)}`;
|
|
6168
6892
|
}
|
|
6169
6893
|
/**
|
|
6170
|
-
* Create or resume this session.
|
|
6171
|
-
*
|
|
6172
|
-
*
|
|
6173
|
-
*
|
|
6894
|
+
* Create or resume this session. `resourceId` names whose threads and memory
|
|
6895
|
+
* the session works on. Without it the server resumes the session on the
|
|
6896
|
+
* resource it already has (the live session's, or the resource of the thread
|
|
6897
|
+
* with the session's id), falling back to the sessionId. Pass `tags` to scope
|
|
6898
|
+
* initial thread selection — a thread is a resume candidate only when its
|
|
6899
|
+
* metadata matches every tag. Pass `threadId` to bind the session to one
|
|
6900
|
+
* exact thread, creating it with that id when it does not exist.
|
|
6174
6901
|
*/
|
|
6175
6902
|
create(options) {
|
|
6176
6903
|
return this.request(`/agent-controller/${encodeURIComponent(this.controllerId)}/sessions`, {
|
|
6177
6904
|
method: "POST",
|
|
6178
6905
|
body: {
|
|
6179
|
-
resourceId:
|
|
6906
|
+
resourceId: options?.resourceId,
|
|
6907
|
+
sessionId: this.sessionId,
|
|
6180
6908
|
tags: options?.tags,
|
|
6181
|
-
threadId: options?.threadId
|
|
6182
|
-
sessionScope: this.scope
|
|
6909
|
+
threadId: options?.threadId
|
|
6183
6910
|
}
|
|
6184
6911
|
});
|
|
6185
6912
|
}
|
|
@@ -6205,10 +6932,12 @@ var AgentControllerSession = class extends BaseResource {
|
|
|
6205
6932
|
delayMs: finiteOr(options.reconnect.delayMs, 1e3),
|
|
6206
6933
|
maxDelayMs: finiteOr(options.reconnect.maxDelayMs, 3e4)
|
|
6207
6934
|
} : null;
|
|
6935
|
+
const idleTimeoutMs = finiteOr(options.idleTimeoutMs, 6e4);
|
|
6208
6936
|
/** Exponential backoff for the Nth (1-based) retry of an outage streak. */
|
|
6209
6937
|
const backoffDelay = (attempt) => reconnectOptions ? Math.min(reconnectOptions.delayMs * 2 ** (attempt - 1), reconnectOptions.maxDelayMs) : 0;
|
|
6210
6938
|
let cancelled = false;
|
|
6211
6939
|
let currentReader = null;
|
|
6940
|
+
let currentAbort = null;
|
|
6212
6941
|
let reconnectTimer;
|
|
6213
6942
|
let delayResolve;
|
|
6214
6943
|
const settleDelay = () => {
|
|
@@ -6224,8 +6953,39 @@ var AgentControllerSession = class extends BaseResource {
|
|
|
6224
6953
|
delayResolve = resolve;
|
|
6225
6954
|
reconnectTimer = setTimeout(settleDelay, ms);
|
|
6226
6955
|
});
|
|
6956
|
+
const idleTimeoutError = () => {
|
|
6957
|
+
const error = /* @__PURE__ */ new Error(`Agent controller session stream received no data for ${idleTimeoutMs}ms`);
|
|
6958
|
+
error.name = "AgentControllerStreamIdleError";
|
|
6959
|
+
return error;
|
|
6960
|
+
};
|
|
6227
6961
|
const requestStream = async () => {
|
|
6228
|
-
const
|
|
6962
|
+
const abort = new AbortController();
|
|
6963
|
+
currentAbort = abort;
|
|
6964
|
+
let openTimer;
|
|
6965
|
+
const request = this.request(`${this.base()}/stream`, {
|
|
6966
|
+
stream: true,
|
|
6967
|
+
signal: abort.signal
|
|
6968
|
+
});
|
|
6969
|
+
request.then((response) => {
|
|
6970
|
+
if (abort.signal.aborted) response.body?.cancel().catch(() => {});
|
|
6971
|
+
}).catch(() => {});
|
|
6972
|
+
let response;
|
|
6973
|
+
try {
|
|
6974
|
+
if (idleTimeoutMs > 0) response = await Promise.race([request, new Promise((_resolve, reject) => {
|
|
6975
|
+
openTimer = setTimeout(() => {
|
|
6976
|
+
const error = idleTimeoutError();
|
|
6977
|
+
abort.abort(error);
|
|
6978
|
+
reject(error);
|
|
6979
|
+
}, idleTimeoutMs);
|
|
6980
|
+
})]);
|
|
6981
|
+
else response = await request;
|
|
6982
|
+
} finally {
|
|
6983
|
+
clearTimeout(openTimer);
|
|
6984
|
+
}
|
|
6985
|
+
if (abort.signal.aborted) {
|
|
6986
|
+
response.body?.cancel().catch(() => {});
|
|
6987
|
+
throw abort.signal.reason;
|
|
6988
|
+
}
|
|
6229
6989
|
if (!response.body) throw new Error("No response body for agent controller session stream");
|
|
6230
6990
|
return response;
|
|
6231
6991
|
};
|
|
@@ -6251,12 +7011,40 @@ var AgentControllerSession = class extends BaseResource {
|
|
|
6251
7011
|
const pump = async (response) => {
|
|
6252
7012
|
const reader = response.body.getReader();
|
|
6253
7013
|
currentReader = reader;
|
|
7014
|
+
const abort = currentAbort;
|
|
6254
7015
|
const decoder = new TextDecoder();
|
|
6255
7016
|
let buffer = "";
|
|
7017
|
+
let idleTimer;
|
|
7018
|
+
let timedOut = false;
|
|
7019
|
+
const armIdleTimer = () => {
|
|
7020
|
+
if (idleTimeoutMs <= 0) return;
|
|
7021
|
+
clearTimeout(idleTimer);
|
|
7022
|
+
idleTimer = setTimeout(() => {
|
|
7023
|
+
timedOut = true;
|
|
7024
|
+
reader.cancel(idleTimeoutError()).catch(() => {});
|
|
7025
|
+
abort?.abort(idleTimeoutError());
|
|
7026
|
+
}, idleTimeoutMs);
|
|
7027
|
+
};
|
|
6256
7028
|
try {
|
|
7029
|
+
armIdleTimer();
|
|
6257
7030
|
while (!cancelled) {
|
|
6258
|
-
|
|
7031
|
+
let chunk;
|
|
7032
|
+
try {
|
|
7033
|
+
chunk = await reader.read();
|
|
7034
|
+
} catch (error) {
|
|
7035
|
+
if (timedOut && !cancelled) return {
|
|
7036
|
+
kind: "transport_error",
|
|
7037
|
+
error: idleTimeoutError()
|
|
7038
|
+
};
|
|
7039
|
+
throw error;
|
|
7040
|
+
}
|
|
7041
|
+
if (timedOut && !cancelled) return {
|
|
7042
|
+
kind: "transport_error",
|
|
7043
|
+
error: idleTimeoutError()
|
|
7044
|
+
};
|
|
7045
|
+
const { done, value } = chunk;
|
|
6259
7046
|
if (done) return cancelled ? { kind: "cancelled" } : { kind: "done" };
|
|
7047
|
+
armIdleTimer();
|
|
6260
7048
|
if (cancelled) return { kind: "cancelled" };
|
|
6261
7049
|
buffer += decoder.decode(value, { stream: true });
|
|
6262
7050
|
let separator;
|
|
@@ -6290,7 +7078,9 @@ var AgentControllerSession = class extends BaseResource {
|
|
|
6290
7078
|
error
|
|
6291
7079
|
};
|
|
6292
7080
|
} finally {
|
|
7081
|
+
clearTimeout(idleTimer);
|
|
6293
7082
|
if (currentReader === reader) currentReader = null;
|
|
7083
|
+
if (currentAbort === abort) currentAbort = null;
|
|
6294
7084
|
reader.cancel().catch(() => {});
|
|
6295
7085
|
}
|
|
6296
7086
|
};
|
|
@@ -6367,6 +7157,7 @@ var AgentControllerSession = class extends BaseResource {
|
|
|
6367
7157
|
cancelled = true;
|
|
6368
7158
|
settleDelay();
|
|
6369
7159
|
currentReader?.cancel().catch(() => {});
|
|
7160
|
+
currentAbort?.abort();
|
|
6370
7161
|
} };
|
|
6371
7162
|
}
|
|
6372
7163
|
/**
|
|
@@ -6381,7 +7172,7 @@ var AgentControllerSession = class extends BaseResource {
|
|
|
6381
7172
|
files: void 0
|
|
6382
7173
|
} : message;
|
|
6383
7174
|
const requestContext = parseClientRequestContext(options?.requestContext);
|
|
6384
|
-
await this.request(
|
|
7175
|
+
await this.request(`${this.base()}/messages`, {
|
|
6385
7176
|
method: "POST",
|
|
6386
7177
|
body: {
|
|
6387
7178
|
message: content,
|
|
@@ -6392,7 +7183,7 @@ var AgentControllerSession = class extends BaseResource {
|
|
|
6392
7183
|
}
|
|
6393
7184
|
/** Abort the in-flight run for this session. */
|
|
6394
7185
|
async abort() {
|
|
6395
|
-
await this.request(
|
|
7186
|
+
await this.request(`${this.base()}/abort`, { method: "POST" });
|
|
6396
7187
|
}
|
|
6397
7188
|
/**
|
|
6398
7189
|
* Approve or decline a pending tool call (`tool_approval_required`). Resolves
|
|
@@ -6400,12 +7191,13 @@ var AgentControllerSession = class extends BaseResource {
|
|
|
6400
7191
|
*/
|
|
6401
7192
|
async approveTool(toolCallId, approved, options) {
|
|
6402
7193
|
const requestContext = parseClientRequestContext(options?.requestContext);
|
|
6403
|
-
return this.request(
|
|
7194
|
+
return this.request(`${this.base()}/tool-approval`, {
|
|
6404
7195
|
method: "POST",
|
|
6405
7196
|
retries: 0,
|
|
6406
7197
|
body: {
|
|
6407
7198
|
toolCallId,
|
|
6408
7199
|
approved,
|
|
7200
|
+
...options?.alwaysAllowCategory ? { alwaysAllowCategory: true } : {},
|
|
6409
7201
|
...requestContext ? { requestContext } : {}
|
|
6410
7202
|
}
|
|
6411
7203
|
});
|
|
@@ -6417,7 +7209,7 @@ var AgentControllerSession = class extends BaseResource {
|
|
|
6417
7209
|
*/
|
|
6418
7210
|
async respondToToolSuspension(toolCallId, resumeData, options) {
|
|
6419
7211
|
const requestContext = parseClientRequestContext(options?.requestContext);
|
|
6420
|
-
return this.request(
|
|
7212
|
+
return this.request(`${this.base()}/tool-suspension`, {
|
|
6421
7213
|
method: "POST",
|
|
6422
7214
|
retries: 0,
|
|
6423
7215
|
body: {
|
|
@@ -6437,7 +7229,7 @@ var AgentControllerSession = class extends BaseResource {
|
|
|
6437
7229
|
files: void 0
|
|
6438
7230
|
} : message;
|
|
6439
7231
|
const requestContext = parseClientRequestContext(options?.requestContext);
|
|
6440
|
-
await this.request(
|
|
7232
|
+
await this.request(`${this.base()}/steer`, {
|
|
6441
7233
|
method: "POST",
|
|
6442
7234
|
body: {
|
|
6443
7235
|
message: content,
|
|
@@ -6449,18 +7241,18 @@ var AgentControllerSession = class extends BaseResource {
|
|
|
6449
7241
|
/** Get the current mode, model, and thread (for initial UI hydration). */
|
|
6450
7242
|
state(options) {
|
|
6451
7243
|
const path = options?.threadId ? `${this.base()}?threadId=${encodeURIComponent(options.threadId)}` : this.base();
|
|
6452
|
-
return this.request(
|
|
7244
|
+
return this.request(path);
|
|
6453
7245
|
}
|
|
6454
7246
|
/** Merge key-value pairs into the session state. Existing keys not in the payload are preserved. */
|
|
6455
7247
|
async setState(updates) {
|
|
6456
|
-
await this.request(
|
|
7248
|
+
await this.request(`${this.base()}/state`, {
|
|
6457
7249
|
method: "PUT",
|
|
6458
7250
|
body: { state: updates }
|
|
6459
7251
|
});
|
|
6460
7252
|
}
|
|
6461
7253
|
/** Switch the active mode (e.g. `build`, `plan`). */
|
|
6462
7254
|
async switchMode(modeId) {
|
|
6463
|
-
await this.request(
|
|
7255
|
+
await this.request(`${this.base()}/mode`, {
|
|
6464
7256
|
method: "POST",
|
|
6465
7257
|
body: { modeId }
|
|
6466
7258
|
});
|
|
@@ -6470,7 +7262,7 @@ var AgentControllerSession = class extends BaseResource {
|
|
|
6470
7262
|
* `thinkingLevel` is provided it is applied and persisted with the model.
|
|
6471
7263
|
*/
|
|
6472
7264
|
async switchModel(modelId, { thinkingLevel } = {}) {
|
|
6473
|
-
await this.request(
|
|
7265
|
+
await this.request(`${this.base()}/model`, {
|
|
6474
7266
|
method: "POST",
|
|
6475
7267
|
body: thinkingLevel !== void 0 ? {
|
|
6476
7268
|
modelId,
|
|
@@ -6491,36 +7283,36 @@ var AgentControllerSession = class extends BaseResource {
|
|
|
6491
7283
|
if (opts.limit != null) params.set("limit", String(opts.limit));
|
|
6492
7284
|
if (opts.tags && Object.keys(opts.tags).length > 0) params.set("tags", JSON.stringify(opts.tags));
|
|
6493
7285
|
const query = params.toString() ? `?${params.toString()}` : "";
|
|
6494
|
-
return (await this.request(
|
|
7286
|
+
return (await this.request(`${this.base()}/threads${query}`)).threads;
|
|
6495
7287
|
}
|
|
6496
7288
|
/** Switch the session to an existing thread (rebinds stream + state). */
|
|
6497
7289
|
async switchThread(threadId) {
|
|
6498
|
-
await this.request(
|
|
7290
|
+
await this.request(`${this.base()}/thread`, {
|
|
6499
7291
|
method: "POST",
|
|
6500
7292
|
body: { threadId }
|
|
6501
7293
|
});
|
|
6502
7294
|
}
|
|
6503
7295
|
/** Create a new thread (unbinds previous, binds the new one). */
|
|
6504
7296
|
async createThread(title) {
|
|
6505
|
-
return this.request(
|
|
7297
|
+
return this.request(`${this.base()}/threads`, {
|
|
6506
7298
|
method: "POST",
|
|
6507
7299
|
body: { title }
|
|
6508
7300
|
});
|
|
6509
7301
|
}
|
|
6510
7302
|
/** Delete a thread. If it's the active thread the session unbinds. */
|
|
6511
7303
|
async deleteThread(threadId) {
|
|
6512
|
-
await this.request(
|
|
7304
|
+
await this.request(`${this.base()}/threads/${encodeURIComponent(threadId)}`, { method: "DELETE" });
|
|
6513
7305
|
}
|
|
6514
7306
|
/** Rename a thread. */
|
|
6515
7307
|
async renameThread(threadId, title) {
|
|
6516
|
-
await this.request(
|
|
7308
|
+
await this.request(`${this.base()}/threads/${encodeURIComponent(threadId)}`, {
|
|
6517
7309
|
method: "PUT",
|
|
6518
7310
|
body: { title }
|
|
6519
7311
|
});
|
|
6520
7312
|
}
|
|
6521
7313
|
/** Clone a thread (and its messages). The session binds to the clone. */
|
|
6522
7314
|
async cloneThread(options) {
|
|
6523
|
-
return this.request(
|
|
7315
|
+
return this.request(`${this.base()}/threads/clone`, {
|
|
6524
7316
|
method: "POST",
|
|
6525
7317
|
body: options ?? {}
|
|
6526
7318
|
});
|
|
@@ -6541,7 +7333,7 @@ var AgentControllerSession = class extends BaseResource {
|
|
|
6541
7333
|
if (include) queryParams.set("include", JSON.stringify(include));
|
|
6542
7334
|
}
|
|
6543
7335
|
const query = queryParams.toString();
|
|
6544
|
-
const body = await this.request(
|
|
7336
|
+
const body = await this.request(`${this.base()}/threads/${encodeURIComponent(threadId)}/messages${query ? `?${query}` : ""}`);
|
|
6545
7337
|
const messages = body.messages.map(hydrateMessage);
|
|
6546
7338
|
if (legacy) return messages;
|
|
6547
7339
|
return {
|
|
@@ -6560,7 +7352,7 @@ var AgentControllerSession = class extends BaseResource {
|
|
|
6560
7352
|
files: void 0
|
|
6561
7353
|
} : message;
|
|
6562
7354
|
const requestContext = parseClientRequestContext(options?.requestContext);
|
|
6563
|
-
await this.request(
|
|
7355
|
+
await this.request(`${this.base()}/follow-up`, {
|
|
6564
7356
|
method: "POST",
|
|
6565
7357
|
body: {
|
|
6566
7358
|
message: content,
|
|
@@ -6571,26 +7363,26 @@ var AgentControllerSession = class extends BaseResource {
|
|
|
6571
7363
|
}
|
|
6572
7364
|
/** Get the observational memory record for this session's thread. */
|
|
6573
7365
|
async getOMRecord() {
|
|
6574
|
-
return (await this.request(
|
|
7366
|
+
return (await this.request(`${this.base()}/om`)).record;
|
|
6575
7367
|
}
|
|
6576
7368
|
/** Change the session's resource identity. */
|
|
6577
7369
|
async setResourceId(newResourceId) {
|
|
6578
|
-
await this.request(
|
|
7370
|
+
await this.request(`${this.base()}/resource`, {
|
|
6579
7371
|
method: "POST",
|
|
6580
7372
|
body: { newResourceId }
|
|
6581
7373
|
});
|
|
6582
7374
|
}
|
|
6583
7375
|
/** Get known resource IDs for this session. */
|
|
6584
7376
|
async getResourceIds() {
|
|
6585
|
-
return (await this.request(
|
|
7377
|
+
return (await this.request(`${this.base()}/resources`)).resourceIds;
|
|
6586
7378
|
}
|
|
6587
7379
|
/** Get the current goal for this session's thread. */
|
|
6588
7380
|
async getGoal() {
|
|
6589
|
-
return (await this.request(
|
|
7381
|
+
return (await this.request(`${this.base()}/goal`)).goal;
|
|
6590
7382
|
}
|
|
6591
7383
|
/** Set a new goal objective. The agent's in-loop judge evaluates progress after each turn. */
|
|
6592
7384
|
async setGoal(objective, options) {
|
|
6593
|
-
return (await this.request(
|
|
7385
|
+
return (await this.request(`${this.base()}/goal`, {
|
|
6594
7386
|
method: "POST",
|
|
6595
7387
|
body: {
|
|
6596
7388
|
objective,
|
|
@@ -6600,22 +7392,22 @@ var AgentControllerSession = class extends BaseResource {
|
|
|
6600
7392
|
}
|
|
6601
7393
|
/** Update goal options (judge model, max runs, status). */
|
|
6602
7394
|
async updateGoal(options) {
|
|
6603
|
-
return (await this.request(
|
|
7395
|
+
return (await this.request(`${this.base()}/goal`, {
|
|
6604
7396
|
method: "PUT",
|
|
6605
7397
|
body: options
|
|
6606
7398
|
})).goal;
|
|
6607
7399
|
}
|
|
6608
7400
|
/** Clear the current goal. */
|
|
6609
7401
|
async clearGoal() {
|
|
6610
|
-
await this.request(
|
|
7402
|
+
await this.request(`${this.base()}/goal`, { method: "DELETE" });
|
|
6611
7403
|
}
|
|
6612
7404
|
/** Get the current permission rules (per-category and per-tool policies). */
|
|
6613
7405
|
async getPermissions() {
|
|
6614
|
-
return this.request(
|
|
7406
|
+
return this.request(`${this.base()}/permissions`);
|
|
6615
7407
|
}
|
|
6616
7408
|
/** Set the approval policy for a tool category. */
|
|
6617
7409
|
async setPermissionForCategory(category, policy) {
|
|
6618
|
-
await this.request(
|
|
7410
|
+
await this.request(`${this.base()}/permissions/category`, {
|
|
6619
7411
|
method: "PUT",
|
|
6620
7412
|
body: {
|
|
6621
7413
|
category,
|
|
@@ -6625,7 +7417,7 @@ var AgentControllerSession = class extends BaseResource {
|
|
|
6625
7417
|
}
|
|
6626
7418
|
/** Set the approval policy for a specific tool. */
|
|
6627
7419
|
async setPermissionForTool(toolName, policy) {
|
|
6628
|
-
await this.request(
|
|
7420
|
+
await this.request(`${this.base()}/permissions/tool`, {
|
|
6629
7421
|
method: "PUT",
|
|
6630
7422
|
body: {
|
|
6631
7423
|
toolName,
|
|
@@ -6639,7 +7431,7 @@ var AgentControllerSession = class extends BaseResource {
|
|
|
6639
7431
|
* or is persisted for later.
|
|
6640
7432
|
*/
|
|
6641
7433
|
async sendNotification(input) {
|
|
6642
|
-
return this.request(
|
|
7434
|
+
return this.request(`${this.base()}/notifications`, {
|
|
6643
7435
|
method: "POST",
|
|
6644
7436
|
body: input
|
|
6645
7437
|
});
|
|
@@ -6672,12 +7464,11 @@ var AgentController = class extends BaseResource {
|
|
|
6672
7464
|
return this.request(`${this.basePath()}/workspace`);
|
|
6673
7465
|
}
|
|
6674
7466
|
/**
|
|
6675
|
-
*
|
|
6676
|
-
*
|
|
6677
|
-
* (e.g. one session per git worktree, with the worktree path as the scope).
|
|
7467
|
+
* Address the session with this `sessionId`. Sessions created without an
|
|
7468
|
+
* explicit id are addressed by their `resourceId`.
|
|
6678
7469
|
*/
|
|
6679
|
-
session(
|
|
6680
|
-
return new AgentControllerSession(this.options, this.controllerId,
|
|
7470
|
+
session(sessionId) {
|
|
7471
|
+
return new AgentControllerSession(this.options, this.controllerId, sessionId);
|
|
6681
7472
|
}
|
|
6682
7473
|
};
|
|
6683
7474
|
/** Pull the plain text out of an assistant message's nested content parts. */
|
|
@@ -6751,7 +7542,7 @@ var MastraClient = class extends BaseResource {
|
|
|
6751
7542
|
}
|
|
6752
7543
|
/**
|
|
6753
7544
|
* Scopes to an agent controller hosted on the connected Mastra instance. Use
|
|
6754
|
-
* `getAgentController(id).session(
|
|
7545
|
+
* `getAgentController(id).session(sessionId)` to create/resume a session,
|
|
6755
7546
|
* stream its events, and send messages.
|
|
6756
7547
|
* @param controllerId - The id the agent controller is registered under on Mastra
|
|
6757
7548
|
*/
|
|
@@ -7002,8 +7793,10 @@ var MastraClient = class extends BaseResource {
|
|
|
7002
7793
|
if (logLevel) searchParams.set("logLevel", logLevel);
|
|
7003
7794
|
if (page !== void 0) searchParams.set("page", String(page));
|
|
7004
7795
|
if (perPage !== void 0) searchParams.set("perPage", String(perPage));
|
|
7005
|
-
if (_filters)
|
|
7006
|
-
|
|
7796
|
+
if (_filters) {
|
|
7797
|
+
if (Array.isArray(_filters)) for (const filter of _filters) searchParams.append("filters", filter);
|
|
7798
|
+
else searchParams.set("filters", _filters);
|
|
7799
|
+
}
|
|
7007
7800
|
if (searchParams.size) return this.request(`/logs?${searchParams}`);
|
|
7008
7801
|
else return this.request(`/logs`);
|
|
7009
7802
|
}
|
|
@@ -7023,8 +7816,10 @@ var MastraClient = class extends BaseResource {
|
|
|
7023
7816
|
if (logLevel) searchParams.set("logLevel", logLevel);
|
|
7024
7817
|
if (page !== void 0) searchParams.set("page", String(page));
|
|
7025
7818
|
if (perPage !== void 0) searchParams.set("perPage", String(perPage));
|
|
7026
|
-
if (_filters)
|
|
7027
|
-
|
|
7819
|
+
if (_filters) {
|
|
7820
|
+
if (Array.isArray(_filters)) for (const filter of _filters) searchParams.append("filters", filter);
|
|
7821
|
+
else searchParams.set("filters", _filters);
|
|
7822
|
+
}
|
|
7028
7823
|
if (searchParams.size) return this.request(`/logs/${runId}?${searchParams}`);
|
|
7029
7824
|
else return this.request(`/logs/${runId}`);
|
|
7030
7825
|
}
|
|
@@ -7272,7 +8067,7 @@ var MastraClient = class extends BaseResource {
|
|
|
7272
8067
|
getTraceQueryValues(params, options) {
|
|
7273
8068
|
return this.observability.getTraceQueryValues(params, options);
|
|
7274
8069
|
}
|
|
7275
|
-
/** Queries thread
|
|
8070
|
+
/** Queries full-history thread rows using a trace or thread activity window. */
|
|
7276
8071
|
queryTraceThreads(params) {
|
|
7277
8072
|
return this.observability.queryTraceThreads(params);
|
|
7278
8073
|
}
|