@agent-native/core 0.202.0 → 0.202.1-nightly-20261007011022

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 (75) hide show
  1. package/dist/agent/actions/list-model-providers.d.ts +2 -0
  2. package/dist/agent/actions/list-model-providers.js +32 -5
  3. package/dist/agent/actions/manage-provider-models.d.ts +1 -0
  4. package/dist/agent/engine/builder-engine.d.ts +1 -1
  5. package/dist/agent/engine/builtin.js +1 -1
  6. package/dist/agent/engine/index.d.ts +1 -1
  7. package/dist/agent/engine/index.js +1 -1
  8. package/dist/agent/engine/registry.d.ts +2 -0
  9. package/dist/agent/engine/registry.js +63 -47
  10. package/dist/agent/model-config.d.ts +6 -6
  11. package/dist/agent/model-config.js +7 -11
  12. package/dist/agent/model-version.d.ts +3 -0
  13. package/dist/agent/model-version.js +67 -0
  14. package/dist/agent/provider-model-selection.d.ts +6 -1
  15. package/dist/agent/provider-model-selection.js +131 -13
  16. package/dist/automation/index.d.ts +1 -1
  17. package/dist/cli/create.d.ts +2 -1
  18. package/dist/cli/create.js +17 -4
  19. package/dist/cli/template-sync.js +2 -1
  20. package/dist/cli/workspacify.d.ts +1 -0
  21. package/dist/cli/workspacify.js +4 -0
  22. package/dist/client/app-config.d.ts +1 -0
  23. package/dist/client/app-config.js +19 -0
  24. package/dist/client/chat/agentkit-protocol.js +122 -16
  25. package/dist/client/chat/runtime.js +943 -50
  26. package/dist/client/chat-model-groups.d.ts +1 -0
  27. package/dist/client/chat-model-groups.js +1 -0
  28. package/dist/client/use-chat-models.js +47 -6
  29. package/dist/deploy/build.js +23 -9
  30. package/dist/email-catalog/redact-body.js +1 -1
  31. package/dist/jobs/actions/manage-recurring-job.d.ts +1 -1
  32. package/dist/jobs/background-automation-runner.d.ts +3 -1
  33. package/dist/jobs/background-automation-runner.js +15 -8
  34. package/dist/jobs/scheduler.js +1 -1
  35. package/dist/mcp/build-server.d.ts +0 -1
  36. package/dist/mcp/build-server.js +10 -59
  37. package/dist/observability/routes.d.ts +6 -6
  38. package/dist/onboarding/app-profile-data.d.ts +10 -0
  39. package/dist/onboarding/app-profile-data.js +423 -0
  40. package/dist/onboarding/app-profile.d.ts +1 -7
  41. package/dist/onboarding/app-profile.js +5 -422
  42. package/dist/onboarding/index.d.ts +1 -0
  43. package/dist/onboarding/index.js +1 -0
  44. package/dist/org/handlers.d.ts +1 -1
  45. package/dist/org/index.d.ts +1 -1
  46. package/dist/progress/routes.d.ts +1 -1
  47. package/dist/provider-api/actions/custom-provider-registration.d.ts +2 -2
  48. package/dist/provider-api/actions/provider-api.d.ts +10 -10
  49. package/dist/provider-api/corpus-jobs.d.ts +2 -2
  50. package/dist/scripts/agent-engines/manage-agent-engine.js +1 -1
  51. package/dist/scripts/agent-engines/set-agent-engine.js +1 -1
  52. package/dist/secrets/routes.d.ts +11 -11
  53. package/dist/server/action-routes.js +1 -0
  54. package/dist/server/agent-engine-api-key-route.d.ts +1 -1
  55. package/dist/server/app-origin-config.d.ts +2 -0
  56. package/dist/server/app-origin-config.js +4 -0
  57. package/dist/server/auth.js +43 -1
  58. package/dist/server/better-auth-instance.js +7 -12
  59. package/dist/server/email-auth-links.d.ts +11 -0
  60. package/dist/server/email-auth-links.js +126 -0
  61. package/dist/server/fusion-app.js +11 -1
  62. package/dist/shared/agent-chat-context.d.ts +3 -3
  63. package/dist/shared/agent-chat-context.js +2 -2
  64. package/dist/shared/auth-copy.d.ts +3 -0
  65. package/dist/shared/auth-copy.js +33 -0
  66. package/dist/shared/design-system-agent-context.d.ts +5 -0
  67. package/dist/shared/design-system-agent-context.js +37 -8
  68. package/dist/shared/index.d.ts +1 -1
  69. package/dist/triggers/actions/manage-automation.d.ts +7 -7
  70. package/dist/triggers/condition-evaluator.d.ts +21 -5
  71. package/dist/triggers/condition-evaluator.js +113 -59
  72. package/dist/triggers/dispatcher.js +39 -21
  73. package/dist/vite/client.js +10 -0
  74. package/docs/content/durable-resume.mdx +9 -3
  75. package/package.json +5 -3
@@ -5,6 +5,7 @@ import { CHAT_REQUEST_TOO_LARGE_MESSAGE } from "../error-format.js";
5
5
  import { appendMissingFinalResponseWarning, } from "../sse-event-processor.js";
6
6
  import { runOutcomeForCode } from "./run-outcome.js";
7
7
  export const AGENT_NATIVE_RUN_RESUME_STATE_METADATA_KEY = "agentNativeRunResumeState";
8
+ const AGENTKIT_TOOL_HISTORY_OMISSION_MESSAGE_ID_PREFIX = "agentkit-tool-history-omission";
8
9
  const DEFAULT_RUNTIME_CAPABILITIES = {
9
10
  messages: {
10
11
  streaming: true,
@@ -613,58 +614,959 @@ function runtimeMessageText(message) {
613
614
  .filter(Boolean)
614
615
  .join("\n");
615
616
  }
617
+ function isSyntheticToolHistoryOmissionMessage(message) {
618
+ return (message.role === "assistant" &&
619
+ (message.id === AGENTKIT_TOOL_HISTORY_OMISSION_MESSAGE_ID_PREFIX ||
620
+ /^agentkit-tool-history-omission-\d+$/.test(message.id)));
621
+ }
622
+ function priorNativeHistoryMessages(messages, currentPrompt) {
623
+ const source = messages ?? [];
624
+ let currentPromptMessageIndex;
625
+ if (currentPrompt.trim()) {
626
+ for (let index = source.length - 1; index >= 0; index--) {
627
+ const message = source[index];
628
+ if (isSyntheticToolHistoryOmissionMessage(message))
629
+ continue;
630
+ if (message.role !== "user" && message.role !== "assistant")
631
+ continue;
632
+ if (message.role === "user") {
633
+ const match = runtimeMessageTextMatches(message, currentPrompt);
634
+ if (match.matches || !match.complete)
635
+ currentPromptMessageIndex = index;
636
+ }
637
+ break;
638
+ }
639
+ }
640
+ return source.filter((message, index) => index !== currentPromptMessageIndex &&
641
+ (message.role === "user" || message.role === "assistant"));
642
+ }
616
643
  function nativeHistoryFromMessages(messages, currentPrompt) {
617
- const history = (messages ?? [])
644
+ return priorNativeHistoryMessages(messages, currentPrompt)
618
645
  .filter((message) => message.role === "user" || message.role === "assistant")
619
646
  .map((message) => ({
620
647
  role: message.role,
621
648
  content: runtimeMessageText(message),
622
649
  }))
623
650
  .filter((message) => message.content.trim());
624
- if (!currentPrompt.trim())
625
- return history;
626
- const last = history[history.length - 1];
627
- return last?.role === "user" && last.content === currentPrompt
628
- ? history.slice(0, -1)
629
- : history;
630
651
  }
631
- function pendingApprovalStructuredHistory(state) {
632
- return state.message.content.flatMap((part) => {
633
- if (part.type === "text") {
634
- return [
635
- {
636
- role: "assistant",
637
- content: [{ type: "text", text: part.text }],
638
- },
639
- ];
652
+ const MAX_TOOL_HISTORY_VALUE_BYTES = 64 * 1024;
653
+ const MAX_TOOL_HISTORY_SERIALIZATION_STEPS = 64 * 1024;
654
+ const MAX_TOOL_HISTORY_SERIALIZATION_DEPTH = 512;
655
+ const MAX_TOOL_HISTORY_CALLS = 64;
656
+ const MAX_ADDED_TOOL_HISTORY_BYTES = 256 * 1024;
657
+ const MAX_TOOL_HISTORY_RESULT_SUMMARY_BYTES = 4 * 1024;
658
+ const MAX_STRUCTURED_HISTORY_TOOL_SOURCE_PARTS = MAX_TOOL_HISTORY_CALLS * 2;
659
+ const MAX_STRUCTURED_HISTORY_TEXT_SOURCE_PARTS = MAX_TOOL_HISTORY_CALLS * 2;
660
+ const MAX_STRUCTURED_HISTORY_SOURCE_PARTS = MAX_STRUCTURED_HISTORY_TOOL_SOURCE_PARTS +
661
+ MAX_STRUCTURED_HISTORY_TEXT_SOURCE_PARTS;
662
+ const MAX_STRUCTURED_HISTORY_SOURCE_MESSAGES = 1024;
663
+ const MAX_STRUCTURED_HISTORY_SOURCE_SCAN_STEPS = MAX_STRUCTURED_HISTORY_SOURCE_PARTS * 4;
664
+ const TOOL_INPUT_OMISSION_TEXT = "Tool input omitted from history because it could not be serialized.";
665
+ const TOOL_INPUT_SIZE_OMISSION_TEXT = "Tool input omitted from history because it exceeds 64 KiB.";
666
+ const TOOL_RESULT_OMISSION_TEXT = "Tool result omitted from history because it could not be serialized.";
667
+ const TOOL_RESULT_SIZE_OMISSION_TEXT = "Tool result omitted from history because it exceeds 64 KiB.";
668
+ const TOOL_INPUT_WORK_LIMIT_OMISSION_TEXT = "Tool input omitted from history because serialization exceeded its work limit.";
669
+ const TOOL_RESULT_WORK_LIMIT_OMISSION_TEXT = "Tool result omitted from history because serialization exceeded its work limit.";
670
+ const TOOL_CALL_METADATA_OMISSION_TEXT = "Tool call omitted from history because its ID or name exceeds 64 KiB.";
671
+ const TOOL_RESULT_METADATA_OMISSION_TEXT = "Tool result omitted from history because its ID or name exceeds 64 KiB.";
672
+ const TOOL_HISTORY_OMISSION_TEXT = "Some history was omitted to keep structured history within 256 KiB and 64 tool entries.";
673
+ function structuredHistoryProjection(history, optionalParts, retainedParts, sourceHistoryOmitted) {
674
+ const projection = [];
675
+ let omittedHistory = sourceHistoryOmitted;
676
+ for (const message of history) {
677
+ const content = [];
678
+ for (const part of message.content) {
679
+ if (!optionalParts.has(part) || retainedParts.has(part)) {
680
+ content.push(part);
681
+ }
682
+ else {
683
+ omittedHistory = true;
684
+ }
640
685
  }
641
- if (part.type !== "tool-call" || part.result === undefined)
642
- return [];
643
- return [
644
- {
645
- role: "assistant",
646
- content: [
647
- {
686
+ if (content.length)
687
+ projection.push({ role: message.role, content });
688
+ }
689
+ if (omittedHistory) {
690
+ projection.push({
691
+ role: "assistant",
692
+ content: [{ type: "text", text: TOOL_HISTORY_OMISSION_TEXT }],
693
+ });
694
+ }
695
+ return projection;
696
+ }
697
+ function structuredHistoryPartByteCost(role, part) {
698
+ // Treat each part as a standalone message so the sum bounds grouped output.
699
+ const serialization = boundedJsonStringify(part, MAX_ADDED_TOOL_HISTORY_BYTES);
700
+ if (serialization.status !== "serialized") {
701
+ return MAX_ADDED_TOOL_HISTORY_BYTES + 1;
702
+ }
703
+ const envelopeBytes = new TextEncoder().encode(JSON.stringify([{ role, content: [] }])).byteLength;
704
+ const partBytes = new TextEncoder().encode(serialization.serialized).byteLength;
705
+ return envelopeBytes + partBytes;
706
+ }
707
+ function structuredToolHistoryCandidateByteCost(candidate) {
708
+ return (candidate.assistantParts.reduce((bytes, part) => bytes + structuredHistoryPartByteCost("assistant", part), 0) +
709
+ candidate.resultParts.reduce((bytes, part) => bytes + structuredHistoryPartByteCost("user", part), 0));
710
+ }
711
+ function structuredTextHistoryCandidateByteCost(candidate) {
712
+ return candidate.parts.reduce((bytes, part) => bytes + structuredHistoryPartByteCost(candidate.role, part), 0);
713
+ }
714
+ const TOOL_HISTORY_VALUE_SIZE_LIMIT_EXCEEDED = Symbol("tool history value size limit exceeded");
715
+ const TOOL_HISTORY_SERIALIZATION_STEP_LIMIT_EXCEEDED = Symbol("tool history serialization step limit exceeded");
716
+ function jsonStringByteLengthWithinLimit(value, limit) {
717
+ let bytes = 2;
718
+ if (bytes > limit)
719
+ return undefined;
720
+ for (let index = 0; index < value.length; index++) {
721
+ const code = value.charCodeAt(index);
722
+ if (code === 0x22 || code === 0x5c) {
723
+ bytes += 2;
724
+ }
725
+ else if (code === 0x08 ||
726
+ code === 0x09 ||
727
+ code === 0x0a ||
728
+ code === 0x0c ||
729
+ code === 0x0d) {
730
+ bytes += 2;
731
+ }
732
+ else if (code < 0x20) {
733
+ bytes += 6;
734
+ }
735
+ else if (code >= 0xd800 && code <= 0xdbff) {
736
+ const next = value.charCodeAt(index + 1);
737
+ if (next >= 0xdc00 && next <= 0xdfff) {
738
+ bytes += 4;
739
+ index++;
740
+ }
741
+ else {
742
+ bytes += 6;
743
+ }
744
+ }
745
+ else if (code >= 0xdc00 && code <= 0xdfff) {
746
+ bytes += 6;
747
+ }
748
+ else if (code <= 0x7f) {
749
+ bytes++;
750
+ }
751
+ else if (code <= 0x7ff) {
752
+ bytes += 2;
753
+ }
754
+ else {
755
+ bytes += 3;
756
+ }
757
+ if (bytes > limit)
758
+ return undefined;
759
+ }
760
+ return bytes;
761
+ }
762
+ function exceedsToolHistoryValueLimit(value) {
763
+ return (jsonStringByteLengthWithinLimit(value, MAX_TOOL_HISTORY_VALUE_BYTES) ===
764
+ undefined);
765
+ }
766
+ function boxedJsonPrimitive(value) {
767
+ try {
768
+ return { boxed: true, value: String.prototype.valueOf.call(value) };
769
+ }
770
+ catch {
771
+ // coercion-ok: A brand mismatch is expected while probing boxed primitives.
772
+ // Try the other boxed primitive types.
773
+ }
774
+ try {
775
+ return { boxed: true, value: Number.prototype.valueOf.call(value) };
776
+ }
777
+ catch {
778
+ // coercion-ok: A brand mismatch is expected while probing boxed primitives.
779
+ // Try the other boxed primitive types.
780
+ }
781
+ try {
782
+ return { boxed: true, value: Boolean.prototype.valueOf.call(value) };
783
+ }
784
+ catch {
785
+ // coercion-ok: A brand mismatch is expected while probing boxed primitives.
786
+ // Try BigInt wrappers when available.
787
+ }
788
+ if (typeof BigInt !== "undefined") {
789
+ try {
790
+ return { boxed: true, value: BigInt.prototype.valueOf.call(value) };
791
+ }
792
+ catch {
793
+ // coercion-ok: A brand mismatch means this value is not a BigInt wrapper.
794
+ // This is an ordinary object or another wrapper type.
795
+ }
796
+ }
797
+ return { boxed: false };
798
+ }
799
+ function boundedJsonStringify(value, maxBytes) {
800
+ let bytes = 0;
801
+ let steps = 0;
802
+ const chunks = [];
803
+ const activeContainers = new Set();
804
+ const addRaw = (text, count = text.length) => {
805
+ bytes += count;
806
+ if (bytes > maxBytes)
807
+ throw TOOL_HISTORY_VALUE_SIZE_LIMIT_EXCEEDED;
808
+ chunks.push(text);
809
+ };
810
+ const addJsonString = (string) => {
811
+ const stringBytes = jsonStringByteLengthWithinLimit(string, maxBytes - bytes);
812
+ if (stringBytes === undefined) {
813
+ throw TOOL_HISTORY_VALUE_SIZE_LIMIT_EXCEEDED;
814
+ }
815
+ bytes += stringBytes;
816
+ chunks.push(JSON.stringify(string));
817
+ };
818
+ const isOmittedJsonValue = (current) => current === undefined ||
819
+ typeof current === "function" ||
820
+ typeof current === "symbol";
821
+ const countStep = () => {
822
+ steps++;
823
+ if (steps > MAX_TOOL_HISTORY_SERIALIZATION_STEPS) {
824
+ throw TOOL_HISTORY_SERIALIZATION_STEP_LIMIT_EXCEEDED;
825
+ }
826
+ };
827
+ // JSON hooks run synchronously; this budget can limit traversal, not hook work.
828
+ const prepareValue = (current, key) => {
829
+ if ((typeof current === "object" && current !== null) ||
830
+ typeof current === "function" ||
831
+ typeof current === "bigint") {
832
+ const toJSON = current.toJSON;
833
+ if (typeof toJSON === "function") {
834
+ current = Reflect.apply(toJSON, current, [key]);
835
+ }
836
+ }
837
+ if (typeof current !== "object" || current === null)
838
+ return current;
839
+ const boxed = boxedJsonPrimitive(current);
840
+ return boxed.boxed ? boxed.value : current;
841
+ };
842
+ const writeValue = (input, key, parent, readInput, depth = 0) => {
843
+ countStep();
844
+ if (depth > MAX_TOOL_HISTORY_SERIALIZATION_DEPTH) {
845
+ throw TOOL_HISTORY_SERIALIZATION_STEP_LIMIT_EXCEEDED;
846
+ }
847
+ const current = prepareValue(readInput ? readInput() : input, key);
848
+ if (isOmittedJsonValue(current)) {
849
+ if (parent?.kind === "array") {
850
+ parent.emit();
851
+ addRaw("null");
852
+ return true;
853
+ }
854
+ return false;
855
+ }
856
+ parent?.emit();
857
+ if (current === null) {
858
+ addRaw("null");
859
+ return true;
860
+ }
861
+ if (typeof current === "string") {
862
+ addJsonString(current);
863
+ return true;
864
+ }
865
+ if (typeof current === "number") {
866
+ addRaw(JSON.stringify(current));
867
+ return true;
868
+ }
869
+ if (typeof current === "boolean") {
870
+ addRaw(current ? "true" : "false");
871
+ return true;
872
+ }
873
+ if (typeof current === "bigint") {
874
+ throw new TypeError("BigInt is not JSON serializable");
875
+ }
876
+ if (typeof current !== "object")
877
+ return true;
878
+ if (activeContainers.has(current)) {
879
+ throw new TypeError("Converting circular structure to JSON");
880
+ }
881
+ activeContainers.add(current);
882
+ try {
883
+ if (Array.isArray(current)) {
884
+ addRaw("[");
885
+ let emitted = 0;
886
+ const array = current;
887
+ const length = array.length;
888
+ for (let index = 0; index < length; index++) {
889
+ writeValue(undefined, String(index), {
890
+ kind: "array",
891
+ emit: () => {
892
+ if (emitted > 0)
893
+ addRaw(",");
894
+ emitted++;
895
+ },
896
+ }, () => array[index], depth + 1);
897
+ }
898
+ addRaw("]");
899
+ return true;
900
+ }
901
+ addRaw("{");
902
+ let emitted = 0;
903
+ const prototype = Object.getPrototypeOf(current);
904
+ let inheritedEnumerableKeys = prototype !== null;
905
+ if (prototype === Object.prototype) {
906
+ inheritedEnumerableKeys = false;
907
+ for (const _propertyKey in Object.prototype) {
908
+ inheritedEnumerableKeys = true;
909
+ break;
910
+ }
911
+ }
912
+ // This avoids an Object.keys array, though engines may still enumerate internally and Proxy traps remain synchronous.
913
+ for (const propertyKey in current) {
914
+ countStep();
915
+ if (inheritedEnumerableKeys &&
916
+ !Object.prototype.hasOwnProperty.call(current, propertyKey)) {
917
+ continue;
918
+ }
919
+ writeValue(undefined, propertyKey, {
920
+ kind: "object",
921
+ emit: () => {
922
+ if (emitted > 0)
923
+ addRaw(",");
924
+ addJsonString(propertyKey);
925
+ addRaw(":");
926
+ emitted++;
927
+ },
928
+ }, () => current[propertyKey], depth + 1);
929
+ }
930
+ addRaw("}");
931
+ return true;
932
+ }
933
+ finally {
934
+ activeContainers.delete(current);
935
+ }
936
+ };
937
+ try {
938
+ return writeValue(value, "")
939
+ ? { status: "serialized", serialized: chunks.join("") }
940
+ : { status: "unserializable" };
941
+ }
942
+ catch (error) {
943
+ if (error === TOOL_HISTORY_VALUE_SIZE_LIMIT_EXCEEDED) {
944
+ return { status: "too-large" };
945
+ }
946
+ if (error === TOOL_HISTORY_SERIALIZATION_STEP_LIMIT_EXCEEDED) {
947
+ return { status: "too-complex" };
948
+ }
949
+ return { status: "unserializable" };
950
+ }
951
+ }
952
+ function toolInputForStructuredHistory(input) {
953
+ const serialization = boundedJsonStringify(input, MAX_TOOL_HISTORY_VALUE_BYTES);
954
+ if (serialization.status === "too-large") {
955
+ return { omissionText: TOOL_INPUT_SIZE_OMISSION_TEXT };
956
+ }
957
+ if (serialization.status === "too-complex") {
958
+ return { omissionText: TOOL_INPUT_WORK_LIMIT_OMISSION_TEXT };
959
+ }
960
+ if (serialization.status === "unserializable") {
961
+ return { omissionText: TOOL_INPUT_OMISSION_TEXT };
962
+ }
963
+ return { input: JSON.parse(serialization.serialized) };
964
+ }
965
+ function toolResultOmissionWithSummary(omissionText, resultText) {
966
+ if (!resultText ||
967
+ jsonStringByteLengthWithinLimit(resultText, MAX_TOOL_HISTORY_RESULT_SUMMARY_BYTES) === undefined ||
968
+ !resultText.trim()) {
969
+ return omissionText;
970
+ }
971
+ const content = `${omissionText}\n${resultText}`;
972
+ return exceedsToolHistoryValueLimit(content) ? omissionText : content;
973
+ }
974
+ function toolResultForStructuredHistory(result, resultText) {
975
+ let content;
976
+ if (result === undefined) {
977
+ content = resultText ?? "No tool result was recorded.";
978
+ }
979
+ else {
980
+ if (typeof result === "string") {
981
+ content = result;
982
+ }
983
+ else {
984
+ const serialization = boundedJsonStringify(result, MAX_TOOL_HISTORY_VALUE_BYTES);
985
+ if (serialization.status === "too-large") {
986
+ return toolResultOmissionWithSummary(TOOL_RESULT_SIZE_OMISSION_TEXT, resultText);
987
+ }
988
+ if (serialization.status === "too-complex") {
989
+ return toolResultOmissionWithSummary(TOOL_RESULT_WORK_LIMIT_OMISSION_TEXT, resultText);
990
+ }
991
+ if (serialization.status === "unserializable") {
992
+ return toolResultOmissionWithSummary(TOOL_RESULT_OMISSION_TEXT, resultText);
993
+ }
994
+ content = serialization.serialized;
995
+ }
996
+ if (result !== undefined && resultText) {
997
+ const contentBytes = jsonStringByteLengthWithinLimit(content, MAX_TOOL_HISTORY_VALUE_BYTES);
998
+ const resultTextBytes = jsonStringByteLengthWithinLimit(resultText, MAX_TOOL_HISTORY_VALUE_BYTES);
999
+ if (contentBytes === undefined ||
1000
+ resultTextBytes === undefined ||
1001
+ contentBytes + resultTextBytes > MAX_TOOL_HISTORY_VALUE_BYTES) {
1002
+ return toolResultOmissionWithSummary(TOOL_RESULT_SIZE_OMISSION_TEXT, resultText);
1003
+ }
1004
+ content = `${content}\n${resultText}`;
1005
+ }
1006
+ if (exceedsToolHistoryValueLimit(content)) {
1007
+ return toolResultOmissionWithSummary(TOOL_RESULT_SIZE_OMISSION_TEXT, resultText);
1008
+ }
1009
+ }
1010
+ return exceedsToolHistoryValueLimit(content)
1011
+ ? toolResultOmissionWithSummary(TOOL_RESULT_SIZE_OMISSION_TEXT, resultText)
1012
+ : content;
1013
+ }
1014
+ function boundStructuredToolHistory(structuredHistory, callCandidates, resultReferences, textCandidates, toolHistoryParts, textHistoryParts, sourceHistoryOmitted) {
1015
+ const candidatesByCallId = new Map();
1016
+ for (const candidate of callCandidates) {
1017
+ if (!candidate.isToolCall)
1018
+ continue;
1019
+ const candidates = candidatesByCallId.get(candidate.toolCallId) ?? [];
1020
+ candidates.push(candidate);
1021
+ candidatesByCallId.set(candidate.toolCallId, candidates);
1022
+ }
1023
+ const candidates = callCandidates.map((candidate) => ({
1024
+ kind: "tool",
1025
+ position: candidate.position,
1026
+ candidate,
1027
+ }));
1028
+ for (const result of resultReferences) {
1029
+ const matchingCalls = candidatesByCallId.get(result.toolCallId) ?? [];
1030
+ let matchingCall;
1031
+ for (let index = matchingCalls.length - 1; index >= 0; index--) {
1032
+ const candidate = matchingCalls[index];
1033
+ if (candidate.position < result.position) {
1034
+ matchingCall = candidate;
1035
+ break;
1036
+ }
1037
+ }
1038
+ if (matchingCall) {
1039
+ matchingCall.resultParts.push(result.part);
1040
+ matchingCall.priority ||= result.priority;
1041
+ continue;
1042
+ }
1043
+ candidates.push({
1044
+ kind: "tool",
1045
+ position: result.position,
1046
+ candidate: {
1047
+ position: result.position,
1048
+ toolCallId: result.toolCallId,
1049
+ assistantParts: [],
1050
+ resultParts: [result.part],
1051
+ isToolCall: false,
1052
+ priority: result.priority,
1053
+ },
1054
+ });
1055
+ }
1056
+ candidates.push(...textCandidates.map((candidate) => ({
1057
+ kind: "text",
1058
+ position: candidate.position,
1059
+ candidate,
1060
+ })));
1061
+ candidates.sort((left, right) => {
1062
+ const leftPriority = left.kind === "tool" && left.candidate.priority ? 1 : 0;
1063
+ const rightPriority = right.kind === "tool" && right.candidate.priority ? 1 : 0;
1064
+ return leftPriority - rightPriority || left.position - right.position;
1065
+ });
1066
+ const retainedParts = new Set();
1067
+ let selectedToolHistoryCount = 0;
1068
+ let selectedBytes = 0;
1069
+ const optionalParts = new Set([
1070
+ ...toolHistoryParts,
1071
+ ...textHistoryParts,
1072
+ ]);
1073
+ const omissionMarkerBytes = structuredHistoryPartByteCost("assistant", {
1074
+ type: "text",
1075
+ text: TOOL_HISTORY_OMISSION_TEXT,
1076
+ });
1077
+ for (let index = candidates.length - 1; index >= 0; index--) {
1078
+ const candidate = candidates[index];
1079
+ const toolCandidate = candidate.kind === "tool" ? candidate.candidate : undefined;
1080
+ if (toolCandidate && selectedToolHistoryCount >= MAX_TOOL_HISTORY_CALLS) {
1081
+ continue;
1082
+ }
1083
+ const candidateBytes = toolCandidate !== undefined
1084
+ ? structuredToolHistoryCandidateByteCost(toolCandidate)
1085
+ : candidate.kind === "text"
1086
+ ? structuredTextHistoryCandidateByteCost(candidate.candidate)
1087
+ : 0;
1088
+ if (selectedBytes + candidateBytes + omissionMarkerBytes >
1089
+ MAX_ADDED_TOOL_HISTORY_BYTES) {
1090
+ continue;
1091
+ }
1092
+ selectedBytes += candidateBytes;
1093
+ if (toolCandidate) {
1094
+ for (const part of toolCandidate.assistantParts)
1095
+ retainedParts.add(part);
1096
+ for (const part of toolCandidate.resultParts)
1097
+ retainedParts.add(part);
1098
+ selectedToolHistoryCount++;
1099
+ }
1100
+ else if (candidate.kind === "text") {
1101
+ for (const part of candidate.candidate.parts)
1102
+ retainedParts.add(part);
1103
+ }
1104
+ }
1105
+ return structuredHistoryProjection(structuredHistory, optionalParts, retainedParts, sourceHistoryOmitted);
1106
+ }
1107
+ function runtimeMessageTextMatches(message, expected) {
1108
+ let offset = 0;
1109
+ let hasText = false;
1110
+ let scannedParts = 0;
1111
+ for (const part of message.content) {
1112
+ if (scannedParts >= MAX_STRUCTURED_HISTORY_SOURCE_SCAN_STEPS) {
1113
+ return { matches: true, complete: false };
1114
+ }
1115
+ scannedParts++;
1116
+ if (part.type !== "text" && part.type !== "reasoning")
1117
+ continue;
1118
+ if (!part.text)
1119
+ continue;
1120
+ if (hasText) {
1121
+ if (expected[offset] !== "\n")
1122
+ return { matches: false, complete: true };
1123
+ offset++;
1124
+ }
1125
+ if (!expected.startsWith(part.text, offset)) {
1126
+ return { matches: false, complete: true };
1127
+ }
1128
+ offset += part.text.length;
1129
+ hasText = true;
1130
+ }
1131
+ return { matches: hasText && offset === expected.length, complete: true };
1132
+ }
1133
+ function boundedStructuredHistorySources(messages, currentPrompt, supplementalMessages) {
1134
+ const historyMessages = messages ?? [];
1135
+ let currentPromptMessageIndex;
1136
+ let currentPromptScanLimited = false;
1137
+ let omitted = false;
1138
+ let toolHistoryOmitted = false;
1139
+ if (currentPrompt.trim()) {
1140
+ let visitedMessages = 0;
1141
+ for (let index = historyMessages.length - 1; index >= 0; index--) {
1142
+ if (visitedMessages >= MAX_STRUCTURED_HISTORY_SOURCE_MESSAGES) {
1143
+ currentPromptScanLimited = true;
1144
+ omitted = true;
1145
+ toolHistoryOmitted = true;
1146
+ break;
1147
+ }
1148
+ visitedMessages++;
1149
+ const message = historyMessages[index];
1150
+ if (isSyntheticToolHistoryOmissionMessage(message))
1151
+ continue;
1152
+ if (message.role !== "user" && message.role !== "assistant")
1153
+ continue;
1154
+ if (message.role === "user") {
1155
+ const match = runtimeMessageTextMatches(message, currentPrompt);
1156
+ if (match.matches)
1157
+ currentPromptMessageIndex = index;
1158
+ if (!match.complete) {
1159
+ omitted = true;
1160
+ toolHistoryOmitted = true;
1161
+ currentPromptMessageIndex = index;
1162
+ }
1163
+ }
1164
+ break;
1165
+ }
1166
+ }
1167
+ const selectedReversed = [];
1168
+ let selectedToolPartCount = 0;
1169
+ let selectedTextPartCount = 0;
1170
+ let scannedPartCount = 0;
1171
+ let visitedMessageCount = 0;
1172
+ let toolBoundary;
1173
+ let stop = false;
1174
+ const visitMessage = (message, list, messageIndex) => {
1175
+ if (visitedMessageCount >= MAX_STRUCTURED_HISTORY_SOURCE_MESSAGES) {
1176
+ omitted = true;
1177
+ toolHistoryOmitted = true;
1178
+ toolBoundary ??= {
1179
+ list,
1180
+ messageIndex,
1181
+ partIndex: message.content.length - 1,
1182
+ };
1183
+ stop = true;
1184
+ return;
1185
+ }
1186
+ visitedMessageCount++;
1187
+ if (message.role !== "user" && message.role !== "assistant")
1188
+ return;
1189
+ const partsReversed = [];
1190
+ for (let partIndex = message.content.length - 1; partIndex >= 0; partIndex--) {
1191
+ if (scannedPartCount >= MAX_STRUCTURED_HISTORY_SOURCE_SCAN_STEPS) {
1192
+ omitted = true;
1193
+ toolHistoryOmitted = true;
1194
+ toolBoundary ??= { list, messageIndex, partIndex };
1195
+ stop = true;
1196
+ break;
1197
+ }
1198
+ scannedPartCount++;
1199
+ const part = message.content[partIndex];
1200
+ const isToolPart = (part.type === "tool-call" && message.role === "assistant") ||
1201
+ part.type === "tool-result";
1202
+ const isTextPart = part.type === "text" || part.type === "reasoning";
1203
+ if (!isToolPart && !isTextPart)
1204
+ continue;
1205
+ if (selectedToolPartCount >= MAX_STRUCTURED_HISTORY_TOOL_SOURCE_PARTS &&
1206
+ selectedTextPartCount >= MAX_STRUCTURED_HISTORY_TEXT_SOURCE_PARTS) {
1207
+ omitted = true;
1208
+ toolHistoryOmitted = true;
1209
+ toolBoundary ??= { list, messageIndex, partIndex };
1210
+ stop = true;
1211
+ break;
1212
+ }
1213
+ if (isToolPart) {
1214
+ if (selectedToolPartCount >= MAX_STRUCTURED_HISTORY_TOOL_SOURCE_PARTS) {
1215
+ omitted = true;
1216
+ toolHistoryOmitted = true;
1217
+ toolBoundary ??= { list, messageIndex, partIndex };
1218
+ continue;
1219
+ }
1220
+ selectedToolPartCount++;
1221
+ }
1222
+ else {
1223
+ if (selectedTextPartCount >= MAX_STRUCTURED_HISTORY_TEXT_SOURCE_PARTS) {
1224
+ omitted = true;
1225
+ continue;
1226
+ }
1227
+ selectedTextPartCount++;
1228
+ }
1229
+ partsReversed.push(part);
1230
+ }
1231
+ if (partsReversed.length) {
1232
+ selectedReversed.push({
1233
+ message,
1234
+ parts: partsReversed.reverse(),
1235
+ priority: list === "supplemental",
1236
+ });
1237
+ }
1238
+ };
1239
+ for (let index = supplementalMessages.length - 1; index >= 0 && !stop; index--) {
1240
+ visitMessage(supplementalMessages[index], "supplemental", index);
1241
+ }
1242
+ if (currentPromptScanLimited)
1243
+ stop = true;
1244
+ for (let index = historyMessages.length - 1; index >= 0 && !stop; index--) {
1245
+ if (index === currentPromptMessageIndex)
1246
+ continue;
1247
+ visitMessage(historyMessages[index], "messages", index);
1248
+ }
1249
+ return {
1250
+ messages: selectedReversed.reverse(),
1251
+ omitted,
1252
+ toolHistoryOmitted,
1253
+ ...(toolBoundary ? { toolBoundary } : {}),
1254
+ ...(currentPromptMessageIndex !== undefined
1255
+ ? { currentPromptMessageIndex }
1256
+ : {}),
1257
+ };
1258
+ }
1259
+ function precedingToolCallIds(messages, supplementalMessages, sources, wantedIds, supplementalToolHistoryOmitted) {
1260
+ const matchedIds = new Set();
1261
+ const remainingIds = new Set(wantedIds);
1262
+ const boundary = sources.toolBoundary;
1263
+ if (!sources.toolHistoryOmitted || !boundary || !remainingIds.size) {
1264
+ return { matchedIds, complete: !sources.toolHistoryOmitted };
1265
+ }
1266
+ let visitedMessages = 0;
1267
+ let scannedParts = 0;
1268
+ let complete = true;
1269
+ const scanMessage = (message, fromPartIndex) => {
1270
+ if (visitedMessages >= MAX_STRUCTURED_HISTORY_SOURCE_MESSAGES) {
1271
+ complete = false;
1272
+ return false;
1273
+ }
1274
+ visitedMessages++;
1275
+ for (let partIndex = Math.min(fromPartIndex, message.content.length - 1); partIndex >= 0 && remainingIds.size > 0; partIndex--) {
1276
+ if (scannedParts >= MAX_STRUCTURED_HISTORY_SOURCE_SCAN_STEPS) {
1277
+ complete = false;
1278
+ return false;
1279
+ }
1280
+ scannedParts++;
1281
+ if (message.role !== "assistant")
1282
+ continue;
1283
+ const part = message.content[partIndex];
1284
+ if (part.type === "tool-call" && remainingIds.delete(part.toolCallId)) {
1285
+ matchedIds.add(part.toolCallId);
1286
+ }
1287
+ }
1288
+ return true;
1289
+ };
1290
+ const scanList = (source, beforeIndex, currentPromptMessageIndex) => {
1291
+ for (let index = beforeIndex; index >= 0 && remainingIds.size > 0; index--) {
1292
+ if (index === currentPromptMessageIndex)
1293
+ continue;
1294
+ if (!scanMessage(source[index], source[index].content.length - 1)) {
1295
+ return false;
1296
+ }
1297
+ }
1298
+ return true;
1299
+ };
1300
+ if (boundary.list === "supplemental") {
1301
+ const boundedSupplemental = supplementalMessages[boundary.messageIndex];
1302
+ if (boundedSupplemental &&
1303
+ !scanMessage(boundedSupplemental, boundary.partIndex)) {
1304
+ return { matchedIds, complete: false };
1305
+ }
1306
+ if (!scanList(supplementalMessages, boundary.messageIndex - 1) ||
1307
+ !scanList(messages ?? [], (messages?.length ?? 0) - 1, sources.currentPromptMessageIndex)) {
1308
+ return { matchedIds, complete: false };
1309
+ }
1310
+ if (supplementalToolHistoryOmitted && remainingIds.size > 0) {
1311
+ complete = false;
1312
+ }
1313
+ }
1314
+ else {
1315
+ const historyMessages = messages ?? [];
1316
+ const boundedHistory = historyMessages[boundary.messageIndex];
1317
+ if (boundedHistory && !scanMessage(boundedHistory, boundary.partIndex)) {
1318
+ return { matchedIds, complete: false };
1319
+ }
1320
+ if (!scanList(historyMessages, boundary.messageIndex - 1, sources.currentPromptMessageIndex)) {
1321
+ return { matchedIds, complete: false };
1322
+ }
1323
+ }
1324
+ return { matchedIds, complete };
1325
+ }
1326
+ function boundaryToolResultPartsToOmit(messages, supplementalMessages, sources, supplementalToolHistoryOmitted) {
1327
+ const partsToOmit = new Set();
1328
+ const truncatedToolHistory = sources.toolHistoryOmitted ||
1329
+ (supplementalToolHistoryOmitted &&
1330
+ sources.toolBoundary?.list === "supplemental");
1331
+ if (!truncatedToolHistory)
1332
+ return partsToOmit;
1333
+ const priorCallIds = new Set();
1334
+ const unmatchedResults = [];
1335
+ for (const { message, parts } of sources.messages) {
1336
+ for (const part of parts) {
1337
+ if (part.type === "tool-call" && message.role === "assistant") {
1338
+ priorCallIds.add(part.toolCallId);
1339
+ }
1340
+ else if (part.type === "tool-result" &&
1341
+ !priorCallIds.has(part.toolCallId)) {
1342
+ unmatchedResults.push({ part, toolCallId: part.toolCallId });
1343
+ }
1344
+ }
1345
+ }
1346
+ if (!unmatchedResults.length)
1347
+ return partsToOmit;
1348
+ const boundaryScan = precedingToolCallIds(messages, supplementalMessages, sources, new Set(unmatchedResults.map((result) => result.toolCallId)), supplementalToolHistoryOmitted);
1349
+ for (const result of unmatchedResults) {
1350
+ if (boundaryScan.matchedIds.has(result.toolCallId) ||
1351
+ !boundaryScan.complete) {
1352
+ partsToOmit.add(result.part);
1353
+ }
1354
+ }
1355
+ return partsToOmit;
1356
+ }
1357
+ function nativeStructuredHistoryFromMessages(messages, currentPrompt, supplementalMessages = [], supplementalHistoryOmitted = false, supplementalToolHistoryOmitted = false) {
1358
+ const structuredHistory = [];
1359
+ const callCandidates = [];
1360
+ const resultReferences = [];
1361
+ const toolHistoryParts = new Set();
1362
+ const textHistoryParts = new Set();
1363
+ const textCandidates = [];
1364
+ let toolHistoryPosition = 0;
1365
+ let hasToolHistory = false;
1366
+ const sources = boundedStructuredHistorySources(messages, currentPrompt, supplementalMessages);
1367
+ const boundaryResultsToOmit = boundaryToolResultPartsToOmit(messages, supplementalMessages, sources, supplementalToolHistoryOmitted);
1368
+ for (const { message, parts, priority } of sources.messages) {
1369
+ if (message.role !== "user" && message.role !== "assistant")
1370
+ continue;
1371
+ const role = message.role;
1372
+ let content = [];
1373
+ let results = [];
1374
+ let pendingTextParts = [];
1375
+ const flushTextCandidate = () => {
1376
+ if (!pendingTextParts.length)
1377
+ return;
1378
+ textCandidates.push({
1379
+ position: toolHistoryPosition++,
1380
+ role,
1381
+ parts: pendingTextParts,
1382
+ });
1383
+ pendingTextParts = [];
1384
+ };
1385
+ const flushContent = () => {
1386
+ if (!content.length)
1387
+ return;
1388
+ structuredHistory.push({ role, content });
1389
+ content = [];
1390
+ };
1391
+ const flushResults = () => {
1392
+ if (!results.length)
1393
+ return;
1394
+ structuredHistory.push({ role: "user", content: results });
1395
+ results = [];
1396
+ };
1397
+ for (const part of parts) {
1398
+ if (part.type === "text" || part.type === "reasoning") {
1399
+ if (jsonStringByteLengthWithinLimit(part.text, MAX_ADDED_TOOL_HISTORY_BYTES) === undefined ||
1400
+ part.text.trim()) {
1401
+ flushResults();
1402
+ const textPart = {
1403
+ type: "text",
1404
+ text: part.text,
1405
+ };
1406
+ content.push(textPart);
1407
+ textHistoryParts.add(textPart);
1408
+ pendingTextParts.push(textPart);
1409
+ }
1410
+ }
1411
+ else if (part.type === "tool-call" && message.role === "assistant") {
1412
+ hasToolHistory = true;
1413
+ flushTextCandidate();
1414
+ flushResults();
1415
+ const candidateAssistantParts = [];
1416
+ const addToolInputText = (text) => {
1417
+ const inputTextPart = { type: "text", text };
1418
+ content.push(inputTextPart);
1419
+ candidateAssistantParts.push(inputTextPart);
1420
+ toolHistoryParts.add(inputTextPart);
1421
+ };
1422
+ const metadataTooLarge = exceedsToolHistoryValueLimit(part.toolCallId) ||
1423
+ exceedsToolHistoryValueLimit(part.toolName);
1424
+ if (metadataTooLarge) {
1425
+ addToolInputText(TOOL_CALL_METADATA_OMISSION_TEXT);
1426
+ }
1427
+ else {
1428
+ if (part.inputText) {
1429
+ if (exceedsToolHistoryValueLimit(part.inputText)) {
1430
+ addToolInputText(TOOL_INPUT_SIZE_OMISSION_TEXT);
1431
+ }
1432
+ else if (part.inputText.trim()) {
1433
+ addToolInputText(part.inputText);
1434
+ }
1435
+ }
1436
+ const input = part.input === undefined
1437
+ ? undefined
1438
+ : toolInputForStructuredHistory(part.input);
1439
+ if (input && "omissionText" in input) {
1440
+ addToolInputText(input.omissionText);
1441
+ }
1442
+ const callPart = {
648
1443
  type: "tool-call",
649
1444
  id: part.toolCallId,
650
1445
  name: part.toolName,
651
- input: part.args,
652
- },
653
- ],
654
- },
655
- {
656
- role: "user",
657
- content: [
658
- {
1446
+ ...(input && "input" in input ? { input: input.input } : {}),
1447
+ };
1448
+ content.push(callPart);
1449
+ candidateAssistantParts.push(callPart);
1450
+ toolHistoryParts.add(callPart);
1451
+ }
1452
+ callCandidates.push({
1453
+ position: toolHistoryPosition++,
1454
+ toolCallId: part.toolCallId,
1455
+ assistantParts: candidateAssistantParts,
1456
+ resultParts: [],
1457
+ isToolCall: true,
1458
+ priority,
1459
+ });
1460
+ }
1461
+ else if (part.type === "tool-result") {
1462
+ hasToolHistory = true;
1463
+ flushTextCandidate();
1464
+ flushContent();
1465
+ if (boundaryResultsToOmit.has(part)) {
1466
+ flushResults();
1467
+ toolHistoryPosition++;
1468
+ continue;
1469
+ }
1470
+ const metadataTooLarge = exceedsToolHistoryValueLimit(part.toolCallId) ||
1471
+ (part.toolName !== undefined &&
1472
+ exceedsToolHistoryValueLimit(part.toolName));
1473
+ const resultPart = metadataTooLarge
1474
+ ? { type: "text", text: TOOL_RESULT_METADATA_OMISSION_TEXT }
1475
+ : {
659
1476
  type: "tool-result",
660
1477
  toolCallId: part.toolCallId,
661
- content: part.result,
1478
+ ...(part.toolName ? { toolName: part.toolName } : {}),
1479
+ content: toolResultForStructuredHistory(part.result, part.resultText),
662
1480
  ...(part.isError ? { isError: true } : {}),
663
- },
664
- ],
665
- },
666
- ];
667
- });
1481
+ };
1482
+ results.push(resultPart);
1483
+ toolHistoryParts.add(resultPart);
1484
+ resultReferences.push({
1485
+ position: toolHistoryPosition++,
1486
+ toolCallId: part.toolCallId,
1487
+ part: resultPart,
1488
+ priority,
1489
+ });
1490
+ }
1491
+ }
1492
+ flushTextCandidate();
1493
+ flushContent();
1494
+ flushResults();
1495
+ }
1496
+ if (!hasToolHistory &&
1497
+ supplementalMessages.length === 0 &&
1498
+ !sources.omitted &&
1499
+ !supplementalHistoryOmitted &&
1500
+ !supplementalToolHistoryOmitted) {
1501
+ return undefined;
1502
+ }
1503
+ return boundStructuredToolHistory(structuredHistory, callCandidates, resultReferences, textCandidates, toolHistoryParts, textHistoryParts, sources.omitted ||
1504
+ supplementalHistoryOmitted ||
1505
+ supplementalToolHistoryOmitted);
1506
+ }
1507
+ function pendingApprovalRuntimeMessages(state) {
1508
+ const messagesReversed = [];
1509
+ let selectedToolPartCount = 0;
1510
+ let selectedTextPartCount = 0;
1511
+ let scannedPartCount = 0;
1512
+ let omitted = false;
1513
+ let toolHistoryOmitted = false;
1514
+ for (let index = state.message.content.length - 1; index >= 0; index--) {
1515
+ if (scannedPartCount >= MAX_STRUCTURED_HISTORY_SOURCE_SCAN_STEPS) {
1516
+ omitted = true;
1517
+ toolHistoryOmitted = true;
1518
+ break;
1519
+ }
1520
+ scannedPartCount++;
1521
+ const part = state.message.content[index];
1522
+ if (part.type === "text") {
1523
+ if (selectedTextPartCount >= MAX_STRUCTURED_HISTORY_TEXT_SOURCE_PARTS) {
1524
+ omitted = true;
1525
+ continue;
1526
+ }
1527
+ selectedTextPartCount++;
1528
+ messagesReversed.push({
1529
+ role: "assistant",
1530
+ content: [{ type: "text", text: part.text }],
1531
+ });
1532
+ continue;
1533
+ }
1534
+ if (part.type !== "tool-call" || part.result === undefined)
1535
+ continue;
1536
+ if (selectedToolPartCount + 2 > MAX_STRUCTURED_HISTORY_TOOL_SOURCE_PARTS) {
1537
+ omitted = true;
1538
+ toolHistoryOmitted = true;
1539
+ continue;
1540
+ }
1541
+ selectedToolPartCount += 2;
1542
+ messagesReversed.push({
1543
+ role: "user",
1544
+ content: [
1545
+ {
1546
+ type: "tool-result",
1547
+ toolCallId: part.toolCallId,
1548
+ result: part.result,
1549
+ ...(part.isError ? { isError: true } : {}),
1550
+ },
1551
+ ],
1552
+ });
1553
+ messagesReversed.push({
1554
+ role: "assistant",
1555
+ content: [
1556
+ {
1557
+ type: "tool-call",
1558
+ toolCallId: part.toolCallId,
1559
+ toolName: part.toolName,
1560
+ input: part.args,
1561
+ },
1562
+ ],
1563
+ });
1564
+ }
1565
+ const messages = messagesReversed.reverse().map((message, index) => ({
1566
+ id: `${state.messageId}-pending-${index}`,
1567
+ ...message,
1568
+ }));
1569
+ return { messages, omitted, toolHistoryOmitted };
668
1570
  }
669
1571
  function definedMetadata(values) {
670
1572
  const entries = Object.entries(values).filter(([, value]) => value !== undefined);
@@ -1555,8 +2457,9 @@ export function createAgentNativeChatRuntime(options = {}) {
1555
2457
  }
1556
2458
  const history = nativeHistoryFromMessages(turn.messages, prompt);
1557
2459
  const pendingApprovalHistory = approvedToolCalls && continuationMessageState
1558
- ? pendingApprovalStructuredHistory(continuationMessageState)
1559
- : [];
2460
+ ? pendingApprovalRuntimeMessages(continuationMessageState)
2461
+ : { messages: [], omitted: false, toolHistoryOmitted: false };
2462
+ const structuredHistory = nativeStructuredHistoryFromMessages(turn.messages, prompt, pendingApprovalHistory.messages, pendingApprovalHistory.omitted, pendingApprovalHistory.toolHistoryOmitted);
1560
2463
  return {
1561
2464
  message: prompt,
1562
2465
  ...(latestUserMessage?.id
@@ -1564,17 +2467,7 @@ export function createAgentNativeChatRuntime(options = {}) {
1564
2467
  : {}),
1565
2468
  displayMessage: prompt,
1566
2469
  history,
1567
- ...(pendingApprovalHistory.length
1568
- ? {
1569
- structuredHistory: [
1570
- ...history.map(({ role, content }) => ({
1571
- role,
1572
- content: [{ type: "text", text: content }],
1573
- })),
1574
- ...pendingApprovalHistory,
1575
- ],
1576
- }
1577
- : {}),
2470
+ ...(structuredHistory?.length ? { structuredHistory } : {}),
1578
2471
  turnId: continuationTurnId ?? turn.queuePromotion?.turnId ?? turnId,
1579
2472
  threadId: session.threadId ?? options.threadId,
1580
2473
  ...(turn.queuePromotion