@mastra/client-js 1.56.0-alpha.1 → 1.56.0-alpha.10

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.
Files changed (48) hide show
  1. package/dist/client.d.ts +3 -3
  2. package/dist/client.d.ts.map +1 -1
  3. package/dist/docs/SKILL.md +2 -2
  4. package/dist/docs/assets/SOURCE_MAP.json +1 -1
  5. package/dist/docs/references/docs-harness-agent-controller.md +11 -14
  6. package/dist/docs/references/docs-harness-schedules.md +8 -6
  7. package/dist/docs/references/docs-harness-signals.md +3 -1
  8. package/dist/docs/references/reference-client-js-agent-controller.md +15 -3
  9. package/dist/docs/references/reference-client-js-agents.md +20 -0
  10. package/dist/docs/references/reference-client-js-mastra-client.md +1 -1
  11. package/dist/docs/references/reference-client-js-observability.md +124 -9
  12. package/dist/docs/references/{reference-observability-tracing-trace-query.md → reference-observability-tracing-advanced-queries.md} +486 -158
  13. package/dist/index.cjs +780 -86
  14. package/dist/index.cjs.map +1 -1
  15. package/dist/index.js +774 -80
  16. package/dist/index.js.map +1 -1
  17. package/dist/resources/agent-controller.d.ts +36 -26
  18. package/dist/resources/agent-controller.d.ts.map +1 -1
  19. package/dist/resources/agent.d.ts +46 -6
  20. package/dist/resources/agent.d.ts.map +1 -1
  21. package/dist/resources/base.d.ts.map +1 -1
  22. package/dist/resources/observability.d.ts +9 -7
  23. package/dist/resources/observability.d.ts.map +1 -1
  24. package/dist/route-types.generated.d.ts +711 -596
  25. package/dist/route-types.generated.d.ts.map +1 -1
  26. package/dist/types.d.ts +9 -9
  27. package/dist/types.d.ts.map +1 -1
  28. package/dist/utils/ai-sdk-v4/data-stream-parts.d.ts +89 -0
  29. package/dist/utils/ai-sdk-v4/data-stream-parts.d.ts.map +1 -0
  30. package/dist/utils/ai-sdk-v4/fix-json.d.ts +2 -0
  31. package/dist/utils/ai-sdk-v4/fix-json.d.ts.map +1 -0
  32. package/dist/utils/ai-sdk-v4/index.d.ts +5 -0
  33. package/dist/utils/ai-sdk-v4/index.d.ts.map +1 -0
  34. package/dist/utils/ai-sdk-v4/parse-partial-json.d.ts +6 -0
  35. package/dist/utils/ai-sdk-v4/parse-partial-json.d.ts.map +1 -0
  36. package/dist/utils/ai-sdk-v4/process-data-stream.d.ts +53 -0
  37. package/dist/utils/ai-sdk-v4/process-data-stream.d.ts.map +1 -0
  38. package/dist/utils/ai-sdk-v4/types.d.ts +93 -0
  39. package/dist/utils/ai-sdk-v4/types.d.ts.map +1 -0
  40. package/dist/utils/index.d.ts +7 -0
  41. package/dist/utils/index.d.ts.map +1 -1
  42. package/package.json +8 -10
  43. package/dist/_types/@ai-sdk_provider/dist/index.d.ts +0 -1587
  44. package/dist/_types/@ai-sdk_provider/package.json +0 -1
  45. package/dist/_types/@ai-sdk_provider-utils/dist/index.d.ts +0 -379
  46. package/dist/_types/@ai-sdk_provider-utils/package.json +0 -1
  47. package/dist/_types/@ai-sdk_ui-utils/dist/index.d.ts +0 -820
  48. 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";
@@ -377,6 +376,16 @@ function isTerminalHttpError(error) {
377
376
  return typeof status === "number" && (status >= 400 && status < 500 || status === 501);
378
377
  }
379
378
  /**
379
+ * Whether an error is the server's trace query execution timeout (504 with code
380
+ * `TRACE_QUERY_EXECUTION_TIMEOUT`). Re-sending the same query hits the same
381
+ * timeout budget, so retrying only repeats an expensive database query.
382
+ * Plain 504s from proxies or gateways do not carry this code and stay retryable.
383
+ */
384
+ function isTraceQueryTimeoutError(error) {
385
+ const { status, body } = error ?? {};
386
+ return status === 504 && body?.code === "TRACE_QUERY_EXECUTION_TIMEOUT";
387
+ }
388
+ /**
380
389
  * Whether a failed resubscribe should end a long-lived subscription instead of
381
390
  * retrying. Like {@link isTerminalHttpError}, but 408 Request Timeout and
382
391
  * 429 Too Many Requests stay retryable because they mean "try again later".
@@ -386,6 +395,583 @@ function isTerminalReconnectError(error) {
386
395
  return isTerminalHttpError(error) && status !== 408 && status !== 429;
387
396
  }
388
397
  //#endregion
398
+ //#region src/utils/ai-sdk-v4/data-stream-parts.ts
399
+ const dataStreamParts = [
400
+ {
401
+ code: "0",
402
+ name: "text",
403
+ parse: (value) => {
404
+ if (typeof value !== "string") throw new Error("\"text\" parts expect a string value.");
405
+ return {
406
+ type: "text",
407
+ value
408
+ };
409
+ }
410
+ },
411
+ {
412
+ code: "2",
413
+ name: "data",
414
+ parse: (value) => {
415
+ if (!Array.isArray(value)) throw new Error("\"data\" parts expect an array value.");
416
+ return {
417
+ type: "data",
418
+ value
419
+ };
420
+ }
421
+ },
422
+ {
423
+ code: "3",
424
+ name: "error",
425
+ parse: (value) => {
426
+ if (typeof value !== "string") throw new Error("\"error\" parts expect a string value.");
427
+ return {
428
+ type: "error",
429
+ value
430
+ };
431
+ }
432
+ },
433
+ {
434
+ code: "8",
435
+ name: "message_annotations",
436
+ parse: (value) => {
437
+ if (!Array.isArray(value)) throw new Error("\"message_annotations\" parts expect an array value.");
438
+ return {
439
+ type: "message_annotations",
440
+ value
441
+ };
442
+ }
443
+ },
444
+ {
445
+ code: "9",
446
+ name: "tool_call",
447
+ parse: (value) => {
448
+ 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.");
449
+ return {
450
+ type: "tool_call",
451
+ value
452
+ };
453
+ }
454
+ },
455
+ {
456
+ code: "a",
457
+ name: "tool_result",
458
+ parse: (value) => {
459
+ 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.");
460
+ return {
461
+ type: "tool_result",
462
+ value
463
+ };
464
+ }
465
+ },
466
+ {
467
+ code: "b",
468
+ name: "tool_call_streaming_start",
469
+ parse: (value) => {
470
+ 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.");
471
+ return {
472
+ type: "tool_call_streaming_start",
473
+ value
474
+ };
475
+ }
476
+ },
477
+ {
478
+ code: "c",
479
+ name: "tool_call_delta",
480
+ parse: (value) => {
481
+ 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.");
482
+ return {
483
+ type: "tool_call_delta",
484
+ value
485
+ };
486
+ }
487
+ },
488
+ {
489
+ code: "d",
490
+ name: "finish_message",
491
+ parse: (value) => {
492
+ 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.");
493
+ const result = { finishReason: value.finishReason };
494
+ if ("usage" in value && value.usage != null && typeof value.usage === "object" && "promptTokens" in value.usage && "completionTokens" in value.usage) result.usage = {
495
+ promptTokens: typeof value.usage.promptTokens === "number" ? value.usage.promptTokens : NaN,
496
+ completionTokens: typeof value.usage.completionTokens === "number" ? value.usage.completionTokens : NaN
497
+ };
498
+ return {
499
+ type: "finish_message",
500
+ value: result
501
+ };
502
+ }
503
+ },
504
+ {
505
+ code: "e",
506
+ name: "finish_step",
507
+ parse: (value) => {
508
+ 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.");
509
+ const result = {
510
+ finishReason: value.finishReason,
511
+ isContinued: false
512
+ };
513
+ if ("usage" in value && value.usage != null && typeof value.usage === "object" && "promptTokens" in value.usage && "completionTokens" in value.usage) result.usage = {
514
+ promptTokens: typeof value.usage.promptTokens === "number" ? value.usage.promptTokens : NaN,
515
+ completionTokens: typeof value.usage.completionTokens === "number" ? value.usage.completionTokens : NaN
516
+ };
517
+ if ("isContinued" in value && typeof value.isContinued === "boolean") result.isContinued = value.isContinued;
518
+ return {
519
+ type: "finish_step",
520
+ value: result
521
+ };
522
+ }
523
+ },
524
+ {
525
+ code: "f",
526
+ name: "start_step",
527
+ parse: (value) => {
528
+ 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.");
529
+ return {
530
+ type: "start_step",
531
+ value: { messageId: value.messageId }
532
+ };
533
+ }
534
+ },
535
+ {
536
+ code: "g",
537
+ name: "reasoning",
538
+ parse: (value) => {
539
+ if (typeof value !== "string") throw new Error("\"reasoning\" parts expect a string value.");
540
+ return {
541
+ type: "reasoning",
542
+ value
543
+ };
544
+ }
545
+ },
546
+ {
547
+ code: "h",
548
+ name: "source",
549
+ parse: (value) => {
550
+ if (value == null || typeof value !== "object") throw new Error("\"source\" parts expect a Source object.");
551
+ return {
552
+ type: "source",
553
+ value
554
+ };
555
+ }
556
+ },
557
+ {
558
+ code: "i",
559
+ name: "redacted_reasoning",
560
+ parse: (value) => {
561
+ 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.");
562
+ return {
563
+ type: "redacted_reasoning",
564
+ value: { data: value.data }
565
+ };
566
+ }
567
+ },
568
+ {
569
+ code: "j",
570
+ name: "reasoning_signature",
571
+ parse: (value) => {
572
+ 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.");
573
+ return {
574
+ type: "reasoning_signature",
575
+ value: { signature: value.signature }
576
+ };
577
+ }
578
+ },
579
+ {
580
+ code: "k",
581
+ name: "file",
582
+ parse: (value) => {
583
+ 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.");
584
+ return {
585
+ type: "file",
586
+ value
587
+ };
588
+ }
589
+ }
590
+ ];
591
+ const dataStreamPartsByCode = Object.fromEntries(dataStreamParts.map((part) => [part.code, part]));
592
+ Object.fromEntries(dataStreamParts.map((part) => [part.name, part.code]));
593
+ const validCodes = dataStreamParts.map((part) => part.code);
594
+ /**
595
+ Parses a stream part from a string.
596
+
597
+ @param line The string to parse.
598
+ @returns The parsed stream part.
599
+ @throws An error if the string cannot be parsed.
600
+ */
601
+ const parseDataStreamPart = (line) => {
602
+ const firstSeparatorIndex = line.indexOf(":");
603
+ if (firstSeparatorIndex === -1) throw new Error("Failed to parse stream string. No separator found.");
604
+ const prefix = line.slice(0, firstSeparatorIndex);
605
+ if (!validCodes.includes(prefix)) throw new Error(`Failed to parse stream string. Invalid code ${prefix}.`);
606
+ const code = prefix;
607
+ const textValue = line.slice(firstSeparatorIndex + 1);
608
+ const jsonValue = JSON.parse(textValue);
609
+ return dataStreamPartsByCode[code].parse(jsonValue);
610
+ };
611
+ //#endregion
612
+ //#region src/utils/ai-sdk-v4/fix-json.ts
613
+ function fixJson(input) {
614
+ const stack = ["ROOT"];
615
+ let lastValidIndex = -1;
616
+ let literalStart = null;
617
+ function processValueStart(char, i, swapState) {
618
+ switch (char) {
619
+ case "\"":
620
+ lastValidIndex = i;
621
+ stack.pop();
622
+ stack.push(swapState);
623
+ stack.push("INSIDE_STRING");
624
+ break;
625
+ case "f":
626
+ case "t":
627
+ case "n":
628
+ lastValidIndex = i;
629
+ literalStart = i;
630
+ stack.pop();
631
+ stack.push(swapState);
632
+ stack.push("INSIDE_LITERAL");
633
+ break;
634
+ case "-":
635
+ stack.pop();
636
+ stack.push(swapState);
637
+ stack.push("INSIDE_NUMBER");
638
+ break;
639
+ case "0":
640
+ case "1":
641
+ case "2":
642
+ case "3":
643
+ case "4":
644
+ case "5":
645
+ case "6":
646
+ case "7":
647
+ case "8":
648
+ case "9":
649
+ lastValidIndex = i;
650
+ stack.pop();
651
+ stack.push(swapState);
652
+ stack.push("INSIDE_NUMBER");
653
+ break;
654
+ case "{":
655
+ lastValidIndex = i;
656
+ stack.pop();
657
+ stack.push(swapState);
658
+ stack.push("INSIDE_OBJECT_START");
659
+ break;
660
+ case "[":
661
+ lastValidIndex = i;
662
+ stack.pop();
663
+ stack.push(swapState);
664
+ stack.push("INSIDE_ARRAY_START");
665
+ break;
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
+ break;
678
+ }
679
+ }
680
+ function processAfterArrayValue(char, i) {
681
+ switch (char) {
682
+ case ",":
683
+ stack.pop();
684
+ stack.push("INSIDE_ARRAY_AFTER_COMMA");
685
+ break;
686
+ case "]":
687
+ lastValidIndex = i;
688
+ stack.pop();
689
+ break;
690
+ }
691
+ }
692
+ for (let i = 0; i < input.length; i++) {
693
+ const char = input[i];
694
+ switch (stack[stack.length - 1]) {
695
+ case "ROOT":
696
+ processValueStart(char, i, "FINISH");
697
+ break;
698
+ case "INSIDE_OBJECT_START":
699
+ switch (char) {
700
+ case "\"":
701
+ stack.pop();
702
+ stack.push("INSIDE_OBJECT_KEY");
703
+ break;
704
+ case "}":
705
+ lastValidIndex = i;
706
+ stack.pop();
707
+ break;
708
+ }
709
+ break;
710
+ case "INSIDE_OBJECT_AFTER_COMMA":
711
+ switch (char) {
712
+ case "\"":
713
+ stack.pop();
714
+ stack.push("INSIDE_OBJECT_KEY");
715
+ break;
716
+ }
717
+ break;
718
+ case "INSIDE_OBJECT_KEY":
719
+ switch (char) {
720
+ case "\"":
721
+ stack.pop();
722
+ stack.push("INSIDE_OBJECT_AFTER_KEY");
723
+ break;
724
+ }
725
+ break;
726
+ case "INSIDE_OBJECT_AFTER_KEY":
727
+ switch (char) {
728
+ case ":":
729
+ stack.pop();
730
+ stack.push("INSIDE_OBJECT_BEFORE_VALUE");
731
+ break;
732
+ }
733
+ break;
734
+ case "INSIDE_OBJECT_BEFORE_VALUE":
735
+ processValueStart(char, i, "INSIDE_OBJECT_AFTER_VALUE");
736
+ break;
737
+ case "INSIDE_OBJECT_AFTER_VALUE":
738
+ processAfterObjectValue(char, i);
739
+ break;
740
+ case "INSIDE_STRING":
741
+ switch (char) {
742
+ case "\"":
743
+ stack.pop();
744
+ lastValidIndex = i;
745
+ break;
746
+ case "\\":
747
+ stack.push("INSIDE_STRING_ESCAPE");
748
+ break;
749
+ default: lastValidIndex = i;
750
+ }
751
+ break;
752
+ case "INSIDE_ARRAY_START":
753
+ switch (char) {
754
+ case "]":
755
+ lastValidIndex = i;
756
+ stack.pop();
757
+ break;
758
+ default:
759
+ lastValidIndex = i;
760
+ processValueStart(char, i, "INSIDE_ARRAY_AFTER_VALUE");
761
+ break;
762
+ }
763
+ break;
764
+ case "INSIDE_ARRAY_AFTER_VALUE":
765
+ switch (char) {
766
+ case ",":
767
+ stack.pop();
768
+ stack.push("INSIDE_ARRAY_AFTER_COMMA");
769
+ break;
770
+ case "]":
771
+ lastValidIndex = i;
772
+ stack.pop();
773
+ break;
774
+ default:
775
+ lastValidIndex = i;
776
+ break;
777
+ }
778
+ break;
779
+ case "INSIDE_ARRAY_AFTER_COMMA":
780
+ processValueStart(char, i, "INSIDE_ARRAY_AFTER_VALUE");
781
+ break;
782
+ case "INSIDE_STRING_ESCAPE":
783
+ stack.pop();
784
+ lastValidIndex = i;
785
+ break;
786
+ case "INSIDE_NUMBER":
787
+ switch (char) {
788
+ case "0":
789
+ case "1":
790
+ case "2":
791
+ case "3":
792
+ case "4":
793
+ case "5":
794
+ case "6":
795
+ case "7":
796
+ case "8":
797
+ case "9":
798
+ lastValidIndex = i;
799
+ break;
800
+ case "e":
801
+ case "E":
802
+ case "-":
803
+ case ".": break;
804
+ case ",":
805
+ stack.pop();
806
+ if (stack[stack.length - 1] === "INSIDE_ARRAY_AFTER_VALUE") processAfterArrayValue(char, i);
807
+ if (stack[stack.length - 1] === "INSIDE_OBJECT_AFTER_VALUE") processAfterObjectValue(char, i);
808
+ break;
809
+ case "}":
810
+ stack.pop();
811
+ if (stack[stack.length - 1] === "INSIDE_OBJECT_AFTER_VALUE") processAfterObjectValue(char, i);
812
+ break;
813
+ case "]":
814
+ stack.pop();
815
+ if (stack[stack.length - 1] === "INSIDE_ARRAY_AFTER_VALUE") processAfterArrayValue(char, i);
816
+ break;
817
+ default:
818
+ stack.pop();
819
+ break;
820
+ }
821
+ break;
822
+ case "INSIDE_LITERAL": {
823
+ const partialLiteral = input.substring(literalStart, i + 1);
824
+ if (!"false".startsWith(partialLiteral) && !"true".startsWith(partialLiteral) && !"null".startsWith(partialLiteral)) {
825
+ stack.pop();
826
+ if (stack[stack.length - 1] === "INSIDE_OBJECT_AFTER_VALUE") processAfterObjectValue(char, i);
827
+ else if (stack[stack.length - 1] === "INSIDE_ARRAY_AFTER_VALUE") processAfterArrayValue(char, i);
828
+ } else lastValidIndex = i;
829
+ break;
830
+ }
831
+ }
832
+ }
833
+ let result = input.slice(0, lastValidIndex + 1);
834
+ for (let i = stack.length - 1; i >= 0; i--) switch (stack[i]) {
835
+ case "INSIDE_STRING":
836
+ result += "\"";
837
+ break;
838
+ case "INSIDE_OBJECT_KEY":
839
+ case "INSIDE_OBJECT_AFTER_KEY":
840
+ case "INSIDE_OBJECT_AFTER_COMMA":
841
+ case "INSIDE_OBJECT_START":
842
+ case "INSIDE_OBJECT_BEFORE_VALUE":
843
+ case "INSIDE_OBJECT_AFTER_VALUE":
844
+ result += "}";
845
+ break;
846
+ case "INSIDE_ARRAY_START":
847
+ case "INSIDE_ARRAY_AFTER_COMMA":
848
+ case "INSIDE_ARRAY_AFTER_VALUE":
849
+ result += "]";
850
+ break;
851
+ case "INSIDE_LITERAL": {
852
+ const partialLiteral = input.substring(literalStart, input.length);
853
+ if ("true".startsWith(partialLiteral)) result += "true".slice(partialLiteral.length);
854
+ else if ("false".startsWith(partialLiteral)) result += "false".slice(partialLiteral.length);
855
+ else if ("null".startsWith(partialLiteral)) result += "null".slice(partialLiteral.length);
856
+ }
857
+ }
858
+ return result;
859
+ }
860
+ //#endregion
861
+ //#region src/utils/ai-sdk-v4/parse-partial-json.ts
862
+ function tryParse(text) {
863
+ try {
864
+ return {
865
+ success: true,
866
+ value: JSON.parse(text)
867
+ };
868
+ } catch {
869
+ return { success: false };
870
+ }
871
+ }
872
+ function parsePartialJson(jsonText) {
873
+ if (jsonText === void 0) return {
874
+ value: void 0,
875
+ state: "undefined-input"
876
+ };
877
+ let result = tryParse(jsonText);
878
+ if (result.success) return {
879
+ value: result.value,
880
+ state: "successful-parse"
881
+ };
882
+ result = tryParse(fixJson(jsonText));
883
+ if (result.success) return {
884
+ value: result.value,
885
+ state: "repaired-parse"
886
+ };
887
+ return {
888
+ value: void 0,
889
+ state: "failed-parse"
890
+ };
891
+ }
892
+ //#endregion
893
+ //#region src/utils/ai-sdk-v4/process-data-stream.ts
894
+ const NEWLINE = "\n".charCodeAt(0);
895
+ function concatChunks(chunks, totalLength) {
896
+ const concatenatedChunks = new Uint8Array(totalLength);
897
+ let offset = 0;
898
+ for (const chunk of chunks) {
899
+ concatenatedChunks.set(chunk, offset);
900
+ offset += chunk.length;
901
+ }
902
+ chunks.length = 0;
903
+ return concatenatedChunks;
904
+ }
905
+ async function processDataStream({ stream, onTextPart, onReasoningPart, onReasoningSignaturePart, onRedactedReasoningPart, onSourcePart, onFilePart, onDataPart, onErrorPart, onToolCallStreamingStartPart, onToolCallDeltaPart, onToolCallPart, onToolResultPart, onMessageAnnotationsPart, onFinishMessagePart, onFinishStepPart, onStartStepPart }) {
906
+ const reader = stream.getReader();
907
+ const decoder = new TextDecoder();
908
+ const chunks = [];
909
+ let totalLength = 0;
910
+ while (true) {
911
+ const { value } = await reader.read();
912
+ if (value) {
913
+ chunks.push(value);
914
+ totalLength += value.length;
915
+ if (value[value.length - 1] !== NEWLINE) continue;
916
+ }
917
+ if (chunks.length === 0) break;
918
+ const concatenatedChunks = concatChunks(chunks, totalLength);
919
+ totalLength = 0;
920
+ const streamParts = decoder.decode(concatenatedChunks, { stream: true }).split("\n").filter((line) => line !== "").map(parseDataStreamPart);
921
+ for (const { type, value } of streamParts) switch (type) {
922
+ case "text":
923
+ await onTextPart?.(value);
924
+ break;
925
+ case "reasoning":
926
+ await onReasoningPart?.(value);
927
+ break;
928
+ case "reasoning_signature":
929
+ await onReasoningSignaturePart?.(value);
930
+ break;
931
+ case "redacted_reasoning":
932
+ await onRedactedReasoningPart?.(value);
933
+ break;
934
+ case "file":
935
+ await onFilePart?.(value);
936
+ break;
937
+ case "source":
938
+ await onSourcePart?.(value);
939
+ break;
940
+ case "data":
941
+ await onDataPart?.(value);
942
+ break;
943
+ case "error":
944
+ await onErrorPart?.(value);
945
+ break;
946
+ case "message_annotations":
947
+ await onMessageAnnotationsPart?.(value);
948
+ break;
949
+ case "tool_call_streaming_start":
950
+ await onToolCallStreamingStartPart?.(value);
951
+ break;
952
+ case "tool_call_delta":
953
+ await onToolCallDeltaPart?.(value);
954
+ break;
955
+ case "tool_call":
956
+ await onToolCallPart?.(value);
957
+ break;
958
+ case "tool_result":
959
+ await onToolResultPart?.(value);
960
+ break;
961
+ case "finish_message":
962
+ await onFinishMessagePart?.(value);
963
+ break;
964
+ case "finish_step":
965
+ await onFinishStepPart?.(value);
966
+ break;
967
+ case "start_step":
968
+ await onStartStepPart?.(value);
969
+ break;
970
+ default: throw new Error(`Unknown stream part type: ${type}`);
971
+ }
972
+ }
973
+ }
974
+ //#endregion
389
975
  //#region src/utils/client-tool-model-output.ts
390
976
  /**
391
977
  * Normalize modelOutput from toModelOutput() to the AI SDK V2 tool result
@@ -618,7 +1204,7 @@ var BaseResource = class {
618
1204
  } catch (error) {
619
1205
  lastError = error;
620
1206
  if (signal?.aborted || error?.name === "AbortError") throw error;
621
- if (isTerminalHttpError(error)) throw error;
1207
+ if (isTerminalHttpError(error) || isTraceQueryTimeoutError(error)) throw error;
622
1208
  if (attempt === retries) break;
623
1209
  await new Promise((resolve, reject) => {
624
1210
  const timer = setTimeout(() => {
@@ -2034,6 +2620,7 @@ var Agent = class extends BaseResource {
2034
2620
  try {
2035
2621
  let messages = [];
2036
2622
  let streamRunId = processedParams.runId;
2623
+ let finishedHistory;
2037
2624
  const [streamForController, streamForProcessing] = response.body.tee();
2038
2625
  const decoder = new TextDecoder();
2039
2626
  let pendingText = "";
@@ -2041,6 +2628,13 @@ var Agent = class extends BaseResource {
2041
2628
  pendingText += text;
2042
2629
  const lines = pendingText.split("\n\n");
2043
2630
  pendingText = isFinal ? "" : lines.pop() ?? "";
2631
+ for (const line of lines) {
2632
+ if (!line.startsWith("data: ") || !line.includes("\"type\":\"finish\"")) continue;
2633
+ try {
2634
+ const all = JSON.parse(line.slice(6))?.payload?.messages?.all;
2635
+ if (Array.isArray(all)) finishedHistory = all;
2636
+ } catch {}
2637
+ }
2044
2638
  const readableLines = lines.filter((line) => line.trim() !== "[DONE]" && line.trim() !== "data: [DONE]").join("\n\n");
2045
2639
  if (readableLines) safeEnqueue(new TextEncoder().encode(`${readableLines}\n\n`));
2046
2640
  };
@@ -2194,12 +2788,12 @@ var Agent = class extends BaseResource {
2194
2788
  role: "tool",
2195
2789
  content: toolResultContents
2196
2790
  };
2197
- const updatedMessages = threadId ? [toolResultMessage] : [
2791
+ const updatedMessages = threadId ? [toolResultMessage] : (route === "resume-stream" || route === "approve-tool-call" || route === "decline-tool-call") && finishedHistory ? [...finishedHistory, toolResultMessage] : [
2198
2792
  ...Array.isArray(processedParams.messages) ? processedParams.messages : [],
2199
2793
  ...messages,
2200
2794
  toolResultMessage
2201
2795
  ];
2202
- const recursionRoute = route === "resume-stream" ? "stream" : route === "resume-stream-until-idle" ? "stream-until-idle" : route;
2796
+ const recursionRoute = route === "resume-stream" || route === "approve-tool-call" || route === "decline-tool-call" ? "stream" : route === "resume-stream-until-idle" ? "stream-until-idle" : route;
2203
2797
  if (isAborted()) return;
2204
2798
  try {
2205
2799
  await this.processStreamResponse({
@@ -2400,7 +2994,8 @@ var Agent = class extends BaseResource {
2400
2994
  const { requestContext, ...rest } = params;
2401
2995
  const processedParams = {
2402
2996
  ...rest,
2403
- requestContext: parseClientRequestContext(requestContext)
2997
+ requestContext: parseClientRequestContext(requestContext),
2998
+ clientTools: processClientTools(params.clientToolsResolver?.() ?? params.clientTools)
2404
2999
  };
2405
3000
  const { readable, controller: readableController, signal } = this.createCancellableStream(params.abortSignal);
2406
3001
  const response = await this.processStreamResponse(processedParams, readableController, "approve-tool-call", signal);
@@ -2431,7 +3026,8 @@ var Agent = class extends BaseResource {
2431
3026
  const { requestContext, ...rest } = params;
2432
3027
  const processedParams = {
2433
3028
  ...rest,
2434
- requestContext: parseClientRequestContext(requestContext)
3029
+ requestContext: parseClientRequestContext(requestContext),
3030
+ clientTools: processClientTools(params.clientToolsResolver?.() ?? params.clientTools)
2435
3031
  };
2436
3032
  const { readable, controller: readableController, signal } = this.createCancellableStream(params.abortSignal);
2437
3033
  const response = await this.processStreamResponse(processedParams, readableController, "decline-tool-call", signal);
@@ -2588,28 +3184,70 @@ var Agent = class extends BaseResource {
2588
3184
  * Used when `requireToolApproval` is enabled with generate() to allow the agent to proceed.
2589
3185
  */
2590
3186
  async approveToolCallGenerate(params) {
2591
- const { requestContext, ...rest } = params;
2592
- return this.request(`/agents/${this.agentId}/approve-tool-call-generate`, {
3187
+ const { requestContext, clientTools, clientToolsResolver, memory, ...rest } = params;
3188
+ const response = await this.request(`/agents/${this.agentId}/approve-tool-call-generate`, {
2593
3189
  method: "POST",
2594
3190
  body: {
2595
3191
  ...rest,
2596
- requestContext: parseClientRequestContext(requestContext)
3192
+ requestContext: parseClientRequestContext(requestContext),
3193
+ clientTools: processClientTools(clientToolsResolver?.() ?? clientTools)
2597
3194
  }
2598
3195
  });
3196
+ return this.continueResumedGenerate(response, {
3197
+ requestContext,
3198
+ clientTools,
3199
+ clientToolsResolver,
3200
+ memory
3201
+ });
2599
3202
  }
2600
3203
  /**
2601
3204
  * Declines a pending tool call and returns the complete response (non-streaming).
2602
3205
  * Used when `requireToolApproval` is enabled with generate() to prevent tool execution.
2603
3206
  */
2604
3207
  async declineToolCallGenerate(params) {
2605
- const { requestContext, ...rest } = params;
2606
- return this.request(`/agents/${this.agentId}/decline-tool-call-generate`, {
3208
+ const { requestContext, clientTools, clientToolsResolver, memory, ...rest } = params;
3209
+ const response = await this.request(`/agents/${this.agentId}/decline-tool-call-generate`, {
2607
3210
  method: "POST",
2608
3211
  body: {
2609
3212
  ...rest,
2610
- requestContext: parseClientRequestContext(requestContext)
3213
+ requestContext: parseClientRequestContext(requestContext),
3214
+ clientTools: processClientTools(clientToolsResolver?.() ?? clientTools)
2611
3215
  }
2612
3216
  });
3217
+ return this.continueResumedGenerate(response, {
3218
+ requestContext,
3219
+ clientTools,
3220
+ clientToolsResolver,
3221
+ memory
3222
+ });
3223
+ }
3224
+ /**
3225
+ * Runs executable client tools the model called after an approval decision and continues on
3226
+ * /generate, like generate() does. With memory the continuation sends only the new messages to the
3227
+ * thread. Without memory it re-sends the conversation up to the last user turn, because the resume
3228
+ * routes keep the earlier history server-side and drop it once the run finishes.
3229
+ */
3230
+ async continueResumedGenerate(response, { requestContext, clientTools, clientToolsResolver, memory }) {
3231
+ if (response.finishReason !== "tool-calls") return response;
3232
+ const context = requestContext === void 0 || requestContext instanceof RequestContext$1 ? requestContext : new RequestContext$1(Object.entries(requestContext));
3233
+ const threadId = typeof memory?.thread === "string" ? memory.thread : memory?.thread?.id;
3234
+ const history = response.messages ?? [];
3235
+ const priorTurns = history.slice(0, history.findLastIndex((message) => message.role === "user") + 1);
3236
+ return executeToolCallAndRespond({
3237
+ response,
3238
+ params: {
3239
+ messages: threadId ? [] : priorTurns,
3240
+ clientTools: clientToolsResolver?.() ?? clientTools,
3241
+ clientToolsResolver,
3242
+ requestContext: context,
3243
+ memory
3244
+ },
3245
+ agentId: this.agentId,
3246
+ resourceId: memory?.resource,
3247
+ threadId,
3248
+ requestContext: context,
3249
+ respondFn: (messages, options) => this.generate(messages, options)
3250
+ });
2613
3251
  }
2614
3252
  /**
2615
3253
  * Processes the stream response and handles tool calls
@@ -4550,10 +5188,10 @@ var Observability = class extends BaseResource {
4550
5188
  });
4551
5189
  }
4552
5190
  /**
4553
- * Queries thread identities using eligible-trace and cross-trace predicates.
5191
+ * Queries full-history thread rows using a trace or thread activity window.
4554
5192
  *
4555
- * @param params - Thread query with its eligible trace selection
4556
- * @returns Matching thread identities
5193
+ * @param params - Thread query with its qualification window, filters and pagination
5194
+ * @returns Matching thread rows. Legacy requests retain their identity-only response.
4557
5195
  */
4558
5196
  queryTraceThreads(params) {
4559
5197
  return this.request("/observability/threads/query", {
@@ -6138,48 +6776,40 @@ function hydrateEventTimestamps(event) {
6138
6776
  return isKnownParsedEvent(event) ? hydrateKnownEvent(event) : event;
6139
6777
  }
6140
6778
  /**
6141
- * A session bound to a `resourceId` within one agent controller. Sessions are
6142
- * get-or-create on the server, so re-creating the same resourceId (and scope)
6143
- * resumes the existing conversation rather than forking it.
6144
- *
6145
- * Pass a `scope` to address an independent session over the same resourceId:
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.
6779
+ * A session addressed by its `sessionId` within one agent controller. Sessions
6780
+ * are get-or-create on the server, so re-creating the same sessionId resumes
6781
+ * the existing conversation rather than forking it. Many sessions can work on
6782
+ * one `resourceId` (whose threads and memory they use); each has its own run
6783
+ * loop, thread binding, and mode/model/state.
6150
6784
  */
6151
6785
  var AgentControllerSession = class extends BaseResource {
6152
6786
  controllerId;
6153
- resourceId;
6154
- scope;
6155
- constructor(options, controllerId, resourceId, scope) {
6787
+ sessionId;
6788
+ constructor(options, controllerId, sessionId) {
6156
6789
  super(options);
6157
6790
  this.controllerId = controllerId;
6158
- this.resourceId = resourceId;
6159
- this.scope = scope;
6791
+ this.sessionId = sessionId;
6160
6792
  }
6161
6793
  base() {
6162
- return `/agent-controller/${encodeURIComponent(this.controllerId)}/sessions/${encodeURIComponent(this.resourceId)}`;
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)}`;
6794
+ return `/agent-controller/${encodeURIComponent(this.controllerId)}/sessions/${encodeURIComponent(this.sessionId)}`;
6168
6795
  }
6169
6796
  /**
6170
- * Create or resume this session. Pass `tags` to scope initial thread
6171
- * selection — a thread is a resume candidate only when its metadata matches
6172
- * every tag. Pass `threadId` to bind the session to one exact thread,
6173
- * creating it with that id when it does not exist.
6797
+ * Create or resume this session. `resourceId` names whose threads and memory
6798
+ * the session works on. Without it the server resumes the session on the
6799
+ * resource it already has (the live session's, or the resource of the thread
6800
+ * with the session's id), falling back to the sessionId. Pass `tags` to scope
6801
+ * initial thread selection — a thread is a resume candidate only when its
6802
+ * metadata matches every tag. Pass `threadId` to bind the session to one
6803
+ * exact thread, creating it with that id when it does not exist.
6174
6804
  */
6175
6805
  create(options) {
6176
6806
  return this.request(`/agent-controller/${encodeURIComponent(this.controllerId)}/sessions`, {
6177
6807
  method: "POST",
6178
6808
  body: {
6179
- resourceId: this.resourceId,
6809
+ resourceId: options?.resourceId,
6810
+ sessionId: this.sessionId,
6180
6811
  tags: options?.tags,
6181
- threadId: options?.threadId,
6182
- sessionScope: this.scope
6812
+ threadId: options?.threadId
6183
6813
  }
6184
6814
  });
6185
6815
  }
@@ -6205,10 +6835,12 @@ var AgentControllerSession = class extends BaseResource {
6205
6835
  delayMs: finiteOr(options.reconnect.delayMs, 1e3),
6206
6836
  maxDelayMs: finiteOr(options.reconnect.maxDelayMs, 3e4)
6207
6837
  } : null;
6838
+ const idleTimeoutMs = finiteOr(options.idleTimeoutMs, 6e4);
6208
6839
  /** Exponential backoff for the Nth (1-based) retry of an outage streak. */
6209
6840
  const backoffDelay = (attempt) => reconnectOptions ? Math.min(reconnectOptions.delayMs * 2 ** (attempt - 1), reconnectOptions.maxDelayMs) : 0;
6210
6841
  let cancelled = false;
6211
6842
  let currentReader = null;
6843
+ let currentAbort = null;
6212
6844
  let reconnectTimer;
6213
6845
  let delayResolve;
6214
6846
  const settleDelay = () => {
@@ -6224,8 +6856,39 @@ var AgentControllerSession = class extends BaseResource {
6224
6856
  delayResolve = resolve;
6225
6857
  reconnectTimer = setTimeout(settleDelay, ms);
6226
6858
  });
6859
+ const idleTimeoutError = () => {
6860
+ const error = /* @__PURE__ */ new Error(`Agent controller session stream received no data for ${idleTimeoutMs}ms`);
6861
+ error.name = "AgentControllerStreamIdleError";
6862
+ return error;
6863
+ };
6227
6864
  const requestStream = async () => {
6228
- const response = await this.request(this.url(`${this.base()}/stream`), { stream: true });
6865
+ const abort = new AbortController();
6866
+ currentAbort = abort;
6867
+ let openTimer;
6868
+ const request = this.request(`${this.base()}/stream`, {
6869
+ stream: true,
6870
+ signal: abort.signal
6871
+ });
6872
+ request.then((response) => {
6873
+ if (abort.signal.aborted) response.body?.cancel().catch(() => {});
6874
+ }).catch(() => {});
6875
+ let response;
6876
+ try {
6877
+ if (idleTimeoutMs > 0) response = await Promise.race([request, new Promise((_resolve, reject) => {
6878
+ openTimer = setTimeout(() => {
6879
+ const error = idleTimeoutError();
6880
+ abort.abort(error);
6881
+ reject(error);
6882
+ }, idleTimeoutMs);
6883
+ })]);
6884
+ else response = await request;
6885
+ } finally {
6886
+ clearTimeout(openTimer);
6887
+ }
6888
+ if (abort.signal.aborted) {
6889
+ response.body?.cancel().catch(() => {});
6890
+ throw abort.signal.reason;
6891
+ }
6229
6892
  if (!response.body) throw new Error("No response body for agent controller session stream");
6230
6893
  return response;
6231
6894
  };
@@ -6251,12 +6914,40 @@ var AgentControllerSession = class extends BaseResource {
6251
6914
  const pump = async (response) => {
6252
6915
  const reader = response.body.getReader();
6253
6916
  currentReader = reader;
6917
+ const abort = currentAbort;
6254
6918
  const decoder = new TextDecoder();
6255
6919
  let buffer = "";
6920
+ let idleTimer;
6921
+ let timedOut = false;
6922
+ const armIdleTimer = () => {
6923
+ if (idleTimeoutMs <= 0) return;
6924
+ clearTimeout(idleTimer);
6925
+ idleTimer = setTimeout(() => {
6926
+ timedOut = true;
6927
+ reader.cancel(idleTimeoutError()).catch(() => {});
6928
+ abort?.abort(idleTimeoutError());
6929
+ }, idleTimeoutMs);
6930
+ };
6256
6931
  try {
6932
+ armIdleTimer();
6257
6933
  while (!cancelled) {
6258
- const { done, value } = await reader.read();
6934
+ let chunk;
6935
+ try {
6936
+ chunk = await reader.read();
6937
+ } catch (error) {
6938
+ if (timedOut && !cancelled) return {
6939
+ kind: "transport_error",
6940
+ error: idleTimeoutError()
6941
+ };
6942
+ throw error;
6943
+ }
6944
+ if (timedOut && !cancelled) return {
6945
+ kind: "transport_error",
6946
+ error: idleTimeoutError()
6947
+ };
6948
+ const { done, value } = chunk;
6259
6949
  if (done) return cancelled ? { kind: "cancelled" } : { kind: "done" };
6950
+ armIdleTimer();
6260
6951
  if (cancelled) return { kind: "cancelled" };
6261
6952
  buffer += decoder.decode(value, { stream: true });
6262
6953
  let separator;
@@ -6290,7 +6981,9 @@ var AgentControllerSession = class extends BaseResource {
6290
6981
  error
6291
6982
  };
6292
6983
  } finally {
6984
+ clearTimeout(idleTimer);
6293
6985
  if (currentReader === reader) currentReader = null;
6986
+ if (currentAbort === abort) currentAbort = null;
6294
6987
  reader.cancel().catch(() => {});
6295
6988
  }
6296
6989
  };
@@ -6367,6 +7060,7 @@ var AgentControllerSession = class extends BaseResource {
6367
7060
  cancelled = true;
6368
7061
  settleDelay();
6369
7062
  currentReader?.cancel().catch(() => {});
7063
+ currentAbort?.abort();
6370
7064
  } };
6371
7065
  }
6372
7066
  /**
@@ -6381,7 +7075,7 @@ var AgentControllerSession = class extends BaseResource {
6381
7075
  files: void 0
6382
7076
  } : message;
6383
7077
  const requestContext = parseClientRequestContext(options?.requestContext);
6384
- await this.request(this.url(`${this.base()}/messages`), {
7078
+ await this.request(`${this.base()}/messages`, {
6385
7079
  method: "POST",
6386
7080
  body: {
6387
7081
  message: content,
@@ -6392,7 +7086,7 @@ var AgentControllerSession = class extends BaseResource {
6392
7086
  }
6393
7087
  /** Abort the in-flight run for this session. */
6394
7088
  async abort() {
6395
- await this.request(this.url(`${this.base()}/abort`), { method: "POST" });
7089
+ await this.request(`${this.base()}/abort`, { method: "POST" });
6396
7090
  }
6397
7091
  /**
6398
7092
  * Approve or decline a pending tool call (`tool_approval_required`). Resolves
@@ -6400,12 +7094,13 @@ var AgentControllerSession = class extends BaseResource {
6400
7094
  */
6401
7095
  async approveTool(toolCallId, approved, options) {
6402
7096
  const requestContext = parseClientRequestContext(options?.requestContext);
6403
- return this.request(this.url(`${this.base()}/tool-approval`), {
7097
+ return this.request(`${this.base()}/tool-approval`, {
6404
7098
  method: "POST",
6405
7099
  retries: 0,
6406
7100
  body: {
6407
7101
  toolCallId,
6408
7102
  approved,
7103
+ ...options?.alwaysAllowCategory ? { alwaysAllowCategory: true } : {},
6409
7104
  ...requestContext ? { requestContext } : {}
6410
7105
  }
6411
7106
  });
@@ -6417,7 +7112,7 @@ var AgentControllerSession = class extends BaseResource {
6417
7112
  */
6418
7113
  async respondToToolSuspension(toolCallId, resumeData, options) {
6419
7114
  const requestContext = parseClientRequestContext(options?.requestContext);
6420
- return this.request(this.url(`${this.base()}/tool-suspension`), {
7115
+ return this.request(`${this.base()}/tool-suspension`, {
6421
7116
  method: "POST",
6422
7117
  retries: 0,
6423
7118
  body: {
@@ -6437,7 +7132,7 @@ var AgentControllerSession = class extends BaseResource {
6437
7132
  files: void 0
6438
7133
  } : message;
6439
7134
  const requestContext = parseClientRequestContext(options?.requestContext);
6440
- await this.request(this.url(`${this.base()}/steer`), {
7135
+ await this.request(`${this.base()}/steer`, {
6441
7136
  method: "POST",
6442
7137
  body: {
6443
7138
  message: content,
@@ -6449,18 +7144,18 @@ var AgentControllerSession = class extends BaseResource {
6449
7144
  /** Get the current mode, model, and thread (for initial UI hydration). */
6450
7145
  state(options) {
6451
7146
  const path = options?.threadId ? `${this.base()}?threadId=${encodeURIComponent(options.threadId)}` : this.base();
6452
- return this.request(this.url(path));
7147
+ return this.request(path);
6453
7148
  }
6454
7149
  /** Merge key-value pairs into the session state. Existing keys not in the payload are preserved. */
6455
7150
  async setState(updates) {
6456
- await this.request(this.url(`${this.base()}/state`), {
7151
+ await this.request(`${this.base()}/state`, {
6457
7152
  method: "PUT",
6458
7153
  body: { state: updates }
6459
7154
  });
6460
7155
  }
6461
7156
  /** Switch the active mode (e.g. `build`, `plan`). */
6462
7157
  async switchMode(modeId) {
6463
- await this.request(this.url(`${this.base()}/mode`), {
7158
+ await this.request(`${this.base()}/mode`, {
6464
7159
  method: "POST",
6465
7160
  body: { modeId }
6466
7161
  });
@@ -6470,7 +7165,7 @@ var AgentControllerSession = class extends BaseResource {
6470
7165
  * `thinkingLevel` is provided it is applied and persisted with the model.
6471
7166
  */
6472
7167
  async switchModel(modelId, { thinkingLevel } = {}) {
6473
- await this.request(this.url(`${this.base()}/model`), {
7168
+ await this.request(`${this.base()}/model`, {
6474
7169
  method: "POST",
6475
7170
  body: thinkingLevel !== void 0 ? {
6476
7171
  modelId,
@@ -6491,36 +7186,36 @@ var AgentControllerSession = class extends BaseResource {
6491
7186
  if (opts.limit != null) params.set("limit", String(opts.limit));
6492
7187
  if (opts.tags && Object.keys(opts.tags).length > 0) params.set("tags", JSON.stringify(opts.tags));
6493
7188
  const query = params.toString() ? `?${params.toString()}` : "";
6494
- return (await this.request(this.url(`${this.base()}/threads${query}`))).threads;
7189
+ return (await this.request(`${this.base()}/threads${query}`)).threads;
6495
7190
  }
6496
7191
  /** Switch the session to an existing thread (rebinds stream + state). */
6497
7192
  async switchThread(threadId) {
6498
- await this.request(this.url(`${this.base()}/thread`), {
7193
+ await this.request(`${this.base()}/thread`, {
6499
7194
  method: "POST",
6500
7195
  body: { threadId }
6501
7196
  });
6502
7197
  }
6503
7198
  /** Create a new thread (unbinds previous, binds the new one). */
6504
7199
  async createThread(title) {
6505
- return this.request(this.url(`${this.base()}/threads`), {
7200
+ return this.request(`${this.base()}/threads`, {
6506
7201
  method: "POST",
6507
7202
  body: { title }
6508
7203
  });
6509
7204
  }
6510
7205
  /** Delete a thread. If it's the active thread the session unbinds. */
6511
7206
  async deleteThread(threadId) {
6512
- await this.request(this.url(`${this.base()}/threads/${encodeURIComponent(threadId)}`), { method: "DELETE" });
7207
+ await this.request(`${this.base()}/threads/${encodeURIComponent(threadId)}`, { method: "DELETE" });
6513
7208
  }
6514
7209
  /** Rename a thread. */
6515
7210
  async renameThread(threadId, title) {
6516
- await this.request(this.url(`${this.base()}/threads/${encodeURIComponent(threadId)}`), {
7211
+ await this.request(`${this.base()}/threads/${encodeURIComponent(threadId)}`, {
6517
7212
  method: "PUT",
6518
7213
  body: { title }
6519
7214
  });
6520
7215
  }
6521
7216
  /** Clone a thread (and its messages). The session binds to the clone. */
6522
7217
  async cloneThread(options) {
6523
- return this.request(this.url(`${this.base()}/threads/clone`), {
7218
+ return this.request(`${this.base()}/threads/clone`, {
6524
7219
  method: "POST",
6525
7220
  body: options ?? {}
6526
7221
  });
@@ -6541,7 +7236,7 @@ var AgentControllerSession = class extends BaseResource {
6541
7236
  if (include) queryParams.set("include", JSON.stringify(include));
6542
7237
  }
6543
7238
  const query = queryParams.toString();
6544
- const body = await this.request(this.url(`${this.base()}/threads/${encodeURIComponent(threadId)}/messages${query ? `?${query}` : ""}`));
7239
+ const body = await this.request(`${this.base()}/threads/${encodeURIComponent(threadId)}/messages${query ? `?${query}` : ""}`);
6545
7240
  const messages = body.messages.map(hydrateMessage);
6546
7241
  if (legacy) return messages;
6547
7242
  return {
@@ -6560,7 +7255,7 @@ var AgentControllerSession = class extends BaseResource {
6560
7255
  files: void 0
6561
7256
  } : message;
6562
7257
  const requestContext = parseClientRequestContext(options?.requestContext);
6563
- await this.request(this.url(`${this.base()}/follow-up`), {
7258
+ await this.request(`${this.base()}/follow-up`, {
6564
7259
  method: "POST",
6565
7260
  body: {
6566
7261
  message: content,
@@ -6571,26 +7266,26 @@ var AgentControllerSession = class extends BaseResource {
6571
7266
  }
6572
7267
  /** Get the observational memory record for this session's thread. */
6573
7268
  async getOMRecord() {
6574
- return (await this.request(this.url(`${this.base()}/om`))).record;
7269
+ return (await this.request(`${this.base()}/om`)).record;
6575
7270
  }
6576
7271
  /** Change the session's resource identity. */
6577
7272
  async setResourceId(newResourceId) {
6578
- await this.request(this.url(`${this.base()}/resource`), {
7273
+ await this.request(`${this.base()}/resource`, {
6579
7274
  method: "POST",
6580
7275
  body: { newResourceId }
6581
7276
  });
6582
7277
  }
6583
7278
  /** Get known resource IDs for this session. */
6584
7279
  async getResourceIds() {
6585
- return (await this.request(this.url(`${this.base()}/resources`))).resourceIds;
7280
+ return (await this.request(`${this.base()}/resources`)).resourceIds;
6586
7281
  }
6587
7282
  /** Get the current goal for this session's thread. */
6588
7283
  async getGoal() {
6589
- return (await this.request(this.url(`${this.base()}/goal`))).goal;
7284
+ return (await this.request(`${this.base()}/goal`)).goal;
6590
7285
  }
6591
7286
  /** Set a new goal objective. The agent's in-loop judge evaluates progress after each turn. */
6592
7287
  async setGoal(objective, options) {
6593
- return (await this.request(this.url(`${this.base()}/goal`), {
7288
+ return (await this.request(`${this.base()}/goal`, {
6594
7289
  method: "POST",
6595
7290
  body: {
6596
7291
  objective,
@@ -6600,22 +7295,22 @@ var AgentControllerSession = class extends BaseResource {
6600
7295
  }
6601
7296
  /** Update goal options (judge model, max runs, status). */
6602
7297
  async updateGoal(options) {
6603
- return (await this.request(this.url(`${this.base()}/goal`), {
7298
+ return (await this.request(`${this.base()}/goal`, {
6604
7299
  method: "PUT",
6605
7300
  body: options
6606
7301
  })).goal;
6607
7302
  }
6608
7303
  /** Clear the current goal. */
6609
7304
  async clearGoal() {
6610
- await this.request(this.url(`${this.base()}/goal`), { method: "DELETE" });
7305
+ await this.request(`${this.base()}/goal`, { method: "DELETE" });
6611
7306
  }
6612
7307
  /** Get the current permission rules (per-category and per-tool policies). */
6613
7308
  async getPermissions() {
6614
- return this.request(this.url(`${this.base()}/permissions`));
7309
+ return this.request(`${this.base()}/permissions`);
6615
7310
  }
6616
7311
  /** Set the approval policy for a tool category. */
6617
7312
  async setPermissionForCategory(category, policy) {
6618
- await this.request(this.url(`${this.base()}/permissions/category`), {
7313
+ await this.request(`${this.base()}/permissions/category`, {
6619
7314
  method: "PUT",
6620
7315
  body: {
6621
7316
  category,
@@ -6625,7 +7320,7 @@ var AgentControllerSession = class extends BaseResource {
6625
7320
  }
6626
7321
  /** Set the approval policy for a specific tool. */
6627
7322
  async setPermissionForTool(toolName, policy) {
6628
- await this.request(this.url(`${this.base()}/permissions/tool`), {
7323
+ await this.request(`${this.base()}/permissions/tool`, {
6629
7324
  method: "PUT",
6630
7325
  body: {
6631
7326
  toolName,
@@ -6639,7 +7334,7 @@ var AgentControllerSession = class extends BaseResource {
6639
7334
  * or is persisted for later.
6640
7335
  */
6641
7336
  async sendNotification(input) {
6642
- return this.request(this.url(`${this.base()}/notifications`), {
7337
+ return this.request(`${this.base()}/notifications`, {
6643
7338
  method: "POST",
6644
7339
  body: input
6645
7340
  });
@@ -6672,12 +7367,11 @@ var AgentController = class extends BaseResource {
6672
7367
  return this.request(`${this.basePath()}/workspace`);
6673
7368
  }
6674
7369
  /**
6675
- * Scope to a session bound to `resourceId` (e.g. a user or conversation id).
6676
- * Pass `scope` to address an independent session over the same resourceId
6677
- * (e.g. one session per git worktree, with the worktree path as the scope).
7370
+ * Address the session with this `sessionId`. Sessions created without an
7371
+ * explicit id are addressed by their `resourceId`.
6678
7372
  */
6679
- session(resourceId, scope) {
6680
- return new AgentControllerSession(this.options, this.controllerId, resourceId, scope);
7373
+ session(sessionId) {
7374
+ return new AgentControllerSession(this.options, this.controllerId, sessionId);
6681
7375
  }
6682
7376
  };
6683
7377
  /** Pull the plain text out of an assistant message's nested content parts. */
@@ -6751,7 +7445,7 @@ var MastraClient = class extends BaseResource {
6751
7445
  }
6752
7446
  /**
6753
7447
  * Scopes to an agent controller hosted on the connected Mastra instance. Use
6754
- * `getAgentController(id).session(resourceId)` to create/resume a session,
7448
+ * `getAgentController(id).session(sessionId)` to create/resume a session,
6755
7449
  * stream its events, and send messages.
6756
7450
  * @param controllerId - The id the agent controller is registered under on Mastra
6757
7451
  */
@@ -7272,7 +7966,7 @@ var MastraClient = class extends BaseResource {
7272
7966
  getTraceQueryValues(params, options) {
7273
7967
  return this.observability.getTraceQueryValues(params, options);
7274
7968
  }
7275
- /** Queries thread identities using eligible-trace and cross-trace predicates. */
7969
+ /** Queries full-history thread rows using a trace or thread activity window. */
7276
7970
  queryTraceThreads(params) {
7277
7971
  return this.observability.queryTraceThreads(params);
7278
7972
  }