llmz 0.9.0 → 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/DOCS.md +232 -1794
- package/ERRORS.md +101 -0
- package/README.md +96 -582
- package/dist/chat/chat.d.ts +63 -0
- package/dist/chat/component.d.ts +31 -0
- package/dist/chat/component.default.d.ts +58 -0
- package/dist/chat/response.d.ts +15 -0
- package/dist/compiler/compiler.d.ts +2 -7
- package/dist/compiler/plugins/dynamic-code.d.ts +7 -0
- package/dist/compiler/plugins/replace-comment.d.ts +2 -3
- package/dist/compiler/plugins/return-async.d.ts +5 -4
- package/dist/compiler/plugins/termination.d.ts +8 -0
- package/dist/compiler/plugins/tool-resolution.d.ts +4 -0
- package/dist/compiler/plugins/variable-extraction.d.ts +2 -8
- package/dist/component-CMFoCHyu.cjs +649 -0
- package/dist/component-DncqP4fB.js +614 -0
- package/dist/context.d.ts +71 -378
- package/dist/custom-client-C-WXvLD9.js +1655 -0
- package/dist/custom-client-Cgt9_0r1.cjs +1732 -0
- package/dist/custom-client.d.ts +12 -2
- package/dist/errors/catalog.d.ts +294 -0
- package/dist/errors/hooks.d.ts +2 -0
- package/dist/errors-C6ppQUZX.cjs +893 -0
- package/dist/errors-Crk5P8jo.js +636 -0
- package/dist/errors.d.ts +24 -36
- package/dist/execute-CiYvPs5Q.js +2061 -0
- package/dist/execute-DTTfacsi.cjs +2062 -0
- package/dist/{exit-DUM96DN1.cjs → exit-BOtKWPuT.cjs} +38 -28
- package/dist/{exit-CDdxDBRT.js → exit-DMPwCSba.js} +37 -27
- package/dist/exit.d.ts +19 -16
- package/dist/index.cjs +177 -1237
- package/dist/index.d.ts +25 -28
- package/dist/index.js +137 -1213
- package/dist/index.workerd.js +8974 -11145
- package/dist/inspect.d.ts +18 -4
- package/dist/inspection.d.ts +40 -0
- package/dist/native-0bq5ATZM.cjs +212 -0
- package/dist/native-n_718Z-T.js +177 -0
- package/dist/objects.d.ts +2 -57
- package/dist/prompts/native.d.ts +2 -0
- package/dist/prompts/prompt.d.ts +10 -101
- package/dist/quickjs-variant-21IO97PF.cjs +1080 -0
- package/dist/quickjs-variant-CtuGagsb.js +985 -0
- package/dist/result.d.ts +30 -861
- package/dist/runtime/execute.d.ts +3 -2
- package/dist/runtime/execution-activity.d.ts +11 -0
- package/dist/runtime/execution-diagnostics.d.ts +11 -0
- package/dist/runtime/execution-report.d.ts +51 -0
- package/dist/runtime/fixtures/chat.d.ts +8 -0
- package/dist/runtime/fixtures/long-search.d.ts +1 -1
- package/dist/runtime/fixtures/native-client.d.ts +33 -0
- package/dist/runtime/fixtures/protocol-languages.d.ts +1 -1
- package/dist/runtime/forced-inspection.d.ts +13 -0
- package/dist/runtime/forced-inspection.test.d.ts +1 -0
- package/dist/runtime/generate.d.ts +23 -20
- package/dist/runtime/generate.test.d.ts +1 -0
- package/dist/runtime/hook-provenance.test.d.ts +1 -0
- package/dist/runtime/inspection-hook.test.d.ts +1 -0
- package/dist/runtime/inspection-values.d.ts +14 -0
- package/dist/runtime/inspection-values.test.d.ts +1 -0
- package/dist/runtime/interruption-control-flow.test.d.ts +1 -0
- package/dist/runtime/interruption-settings.test.d.ts +1 -0
- package/dist/runtime/javascript-api.d.ts +62 -0
- package/dist/runtime/javascript-api.test.d.ts +1 -0
- package/dist/runtime/native-review.test.d.ts +1 -0
- package/dist/runtime/native-tools.d.ts +18 -0
- package/dist/runtime/native-tools.test.d.ts +1 -0
- package/dist/runtime/object-memory.test.d.ts +1 -0
- package/dist/runtime/single-tool.test.d.ts +1 -0
- package/dist/runtime/think-signal.test.d.ts +1 -0
- package/dist/runtime/token-budget.d.ts +22 -0
- package/dist/runtime/token-budget.test.d.ts +1 -0
- package/dist/runtime/tool-wrapper.d.ts +6 -5
- package/dist/runtime/traces.test.d.ts +1 -0
- package/dist/runtime/truncation.test.d.ts +1 -0
- package/dist/runtime/types.d.ts +47 -31
- package/dist/runtime/variable-recovery.test.d.ts +1 -0
- package/dist/runtime/vm-context.d.ts +6 -1
- package/dist/runtime/worker-completion.test.d.ts +1 -0
- package/dist/runtime-names.d.ts +4 -0
- package/dist/schema-CXlnbb3n.cjs +68 -0
- package/dist/schema-GE4ISPCR.js +45 -0
- package/dist/schema.d.ts +10 -0
- package/dist/schema.test.d.ts +1 -0
- package/dist/session/compactor.d.ts +51 -0
- package/dist/session/compactor.test.d.ts +1 -0
- package/dist/session/history.d.ts +36 -0
- package/dist/session/history.test.d.ts +1 -0
- package/dist/session/json.d.ts +3 -0
- package/dist/session/json.test.d.ts +1 -0
- package/dist/session/memory-codec.d.ts +9 -0
- package/dist/session/memory-codec.test.d.ts +1 -0
- package/dist/session/memory-render.d.ts +15 -0
- package/dist/session/memory-render.test.d.ts +1 -0
- package/dist/session/memory.d.ts +112 -0
- package/dist/session/memory.test.d.ts +1 -0
- package/dist/session/messages.d.ts +19 -0
- package/dist/session/messages.test.d.ts +1 -0
- package/dist/session/serialization.d.ts +36 -0
- package/dist/session/serialization.test.d.ts +1 -0
- package/dist/session/session-memory.test.d.ts +1 -0
- package/dist/session/session.d.ts +121 -0
- package/dist/session/session.test.d.ts +1 -0
- package/dist/session/speaker.test.d.ts +1 -0
- package/dist/{transcript.d.ts → session/transcript.d.ts} +4 -8
- package/dist/session/transcript.test.d.ts +1 -0
- package/dist/{tool-Bv8N4IPj.js → tool-DstssiAs.js} +144 -92
- package/dist/{tool-Dy6AJpJH.cjs → tool-_wK9hQOb.cjs} +146 -94
- package/dist/tool.d.ts +25 -17
- package/dist/truncate-BEKbdo3t.js +79 -0
- package/dist/truncate-uomAMGPs.cjs +102 -0
- package/dist/truncate.d.ts +24 -0
- package/dist/truncate.test.d.ts +1 -0
- package/dist/types.d.ts +33 -9
- package/dist/{typings-3lsqCbkn.cjs → typings-BA_XxAcY.cjs} +38 -193
- package/dist/{typings-CrBa7Tyy.js → typings-BEVDvtuk.js} +38 -175
- package/dist/typings-formatter.d.ts +1 -1
- package/dist/typings.d.ts +3 -0
- package/dist/{uniq-BYQ7GWwb.js → uniq-DfUeSNaX.js} +2 -2
- package/dist/{uniq-G872RWmE.cjs → uniq-DiXgysNV.cjs} +6 -18
- package/dist/{_baseIteratee-P_firB7b.js → utils-BOFzb8Ok.js} +1134 -16
- package/dist/{_baseIteratee-CF4qP2a8.cjs → utils-CTlsXvdj.cjs} +1281 -84
- package/dist/vm/drivers/node.d.ts +1 -1
- package/dist/vm/drivers/quickjs.d.ts +1 -1
- package/dist/vm/errors.d.ts +4 -4
- package/dist/vm/index.d.ts +3 -4
- package/dist/vm/instrument.d.ts +14 -6
- package/dist/vm/member-proxy.d.ts +4 -0
- package/dist/vm/member-proxy.test.d.ts +1 -0
- package/dist/vm/memory.test.d.ts +1 -0
- package/dist/vm/return-semantics.test.d.ts +1 -0
- package/dist/vm/types.d.ts +20 -3
- package/dist/{vm-BLsHw1da.js → vm-C7SfutHn.js} +1187 -180
- package/dist/{vm-D6s1zF6M.cjs → vm-gmekHc0i.cjs} +1221 -207
- package/package.json +13 -6
- package/dist/_baseForOwn-BfWDTL8L.cjs +0 -53
- package/dist/_baseForOwn-CFhWe_W6.js +0 -48
- package/dist/_getPrototype-CG7Dxrrz.js +0 -6
- package/dist/_getPrototype-DQDlNVVM.cjs +0 -10
- package/dist/_overArg-C5Hy7oCi.cjs +0 -196
- package/dist/_overArg-CRYbj1NH.js +0 -155
- package/dist/chat.d.ts +0 -401
- package/dist/common-BlRFtdf2.js +0 -807
- package/dist/common-BnvrDnIT.cjs +0 -860
- package/dist/compiler/plugins/track-tool-calls.d.ts +0 -33
- package/dist/compiler-C-OI9sim.cjs +0 -547
- package/dist/compiler-CW1VjQsn.js +0 -473
- package/dist/component-C6Agl2ns.cjs +0 -73
- package/dist/component-DGG7d_Mz.js +0 -44
- package/dist/component.d.ts +0 -88
- package/dist/component.default.d.ts +0 -278
- package/dist/custom-client-ChuZ63zp.js +0 -2658
- package/dist/custom-client-DAsGRnYc.cjs +0 -2729
- package/dist/dual-modes-DDkoCp3R.js +0 -3006
- package/dist/dual-modes-DPXiuvNe.cjs +0 -3090
- package/dist/errors-C962uJdS.cjs +0 -220
- package/dist/errors-Cg1G0Awu.js +0 -161
- package/dist/example-format.d.ts +0 -8
- package/dist/example.d.ts +0 -45
- package/dist/execute-BWcdv9so.js +0 -1059
- package/dist/execute-DM2-7y86.cjs +0 -1060
- package/dist/exit-parser.d.ts +0 -39
- package/dist/handlers.d.ts +0 -10
- package/dist/hoist.d.ts +0 -2
- package/dist/isEmpty-BhJRCqIF.js +0 -52
- package/dist/isEmpty-LY533Wmh.cjs +0 -57
- package/dist/isPlainObject-CSxXVKCk.cjs +0 -56
- package/dist/isPlainObject-D39AzPO2.js +0 -51
- package/dist/jsx-CIgdGGVs.js +0 -52
- package/dist/jsx-owqxrquU.cjs +0 -75
- package/dist/jsx.d.ts +0 -11
- package/dist/message-stream/index.d.ts +0 -9
- package/dist/message-stream/instructions.d.ts +0 -30
- package/dist/message-stream/normalizer.d.ts +0 -21
- package/dist/message-stream/parser.d.ts +0 -89
- package/dist/message-stream/registry.d.ts +0 -14
- package/dist/message-stream/replayable.d.ts +0 -27
- package/dist/message-stream/response-parser.d.ts +0 -24
- package/dist/message-stream/sanitize.d.ts +0 -10
- package/dist/message-stream/stream.d.ts +0 -54
- package/dist/message-stream/types.d.ts +0 -97
- package/dist/message-stream/validator.d.ts +0 -23
- package/dist/prompts/chat-mode/protocol.d.ts +0 -2
- package/dist/prompts/chat-mode/system.d.ts +0 -2
- package/dist/prompts/chat-mode/system.md.d.ts +0 -2
- package/dist/prompts/chat-mode/user.d.ts +0 -2
- package/dist/prompts/chat-mode/user.md.d.ts +0 -2
- package/dist/prompts/code-examples.d.ts +0 -2
- package/dist/prompts/common.d.ts +0 -7
- package/dist/prompts/dual-modes.d.ts +0 -2
- package/dist/prompts/execution-history.d.ts +0 -6
- package/dist/prompts/execution-state.d.ts +0 -3
- package/dist/prompts/protocol-basics.d.ts +0 -5
- package/dist/prompts/protocol.d.ts +0 -31
- package/dist/prompts/worker-mode/protocol.d.ts +0 -2
- package/dist/prompts/worker-mode/system.d.ts +0 -2
- package/dist/prompts/worker-mode/system.md.d.ts +0 -2
- package/dist/prompts/worker-mode/user.d.ts +0 -2
- package/dist/prompts/worker-mode/user.md.d.ts +0 -2
- package/dist/quickjs-variant-BYhMBpwU.js +0 -45
- package/dist/quickjs-variant-CsIwTVFC.cjs +0 -56
- package/dist/rolldown-runtime-EAsCxrDo.js +0 -14
- package/dist/runtime/fixtures/qwen-protocol-failures.d.ts +0 -29
- package/dist/runtime/interpret-result.d.ts +0 -22
- package/dist/snapshots.d.ts +0 -249
- package/dist/stack-traces-BIE_5Xwf.js +0 -21
- package/dist/stack-traces-ntw_qhoy.cjs +0 -26
- package/dist/truncator-CLkouTCO.cjs +0 -276
- package/dist/truncator-DZqEqnpD.js +0 -253
- package/dist/truncator.d.ts +0 -118
- package/dist/utils-3ESwP3yg.cjs +0 -1075
- package/dist/utils-UBeAFeEI.js +0 -950
- /package/dist/{citations.d.ts → chat/citations.d.ts} +0 -0
- /package/dist/{citations.test.d.ts → chat/citations.test.d.ts} +0 -0
- /package/dist/{component.default.test.d.ts → chat/component.default.test.d.ts} +0 -0
- /package/dist/{compiler/plugins/track-tool-calls.test.d.ts → chat/component.test.d.ts} +0 -0
- /package/dist/{example.test.d.ts → chat/response.test.d.ts} +0 -0
- /package/dist/{exit-parser.test.d.ts → compiler/plugins/dynamic-code.test.d.ts} +0 -0
- /package/dist/{handlers.test.d.ts → compiler/plugins/tool-resolution.test.d.ts} +0 -0
- /package/dist/{hoist.test.d.ts → errors/catalog.test.d.ts} +0 -0
- /package/dist/{message-stream/instructions.test.d.ts → exit.test.d.ts} +0 -0
- /package/dist/{message-stream/normalizer.test.d.ts → inspection.test.d.ts} +0 -0
- /package/dist/{message-stream/parser.test.d.ts → prompts/native.test.d.ts} +0 -0
- /package/dist/{message-stream/response-parser.test.d.ts → result.test.d.ts} +0 -0
- /package/dist/{message-stream/stream.test.d.ts → runtime/chat-completion.test.d.ts} +0 -0
- /package/dist/{message-stream/validator.test.d.ts → runtime/chat-delivery.test.d.ts} +0 -0
- /package/dist/{prompts/adherence.test.d.ts → runtime/chat-last-speaker.test.d.ts} +0 -0
- /package/dist/{prompts/catalogue-examples.test.d.ts → runtime/compatibility-regressions.test.d.ts} +0 -0
- /package/dist/{prompts/code-examples.test.d.ts → runtime/context-registration.test.d.ts} +0 -0
- /package/dist/{prompts/common.test.d.ts → runtime/empty-completion.test.d.ts} +0 -0
- /package/dist/{prompts/concrete-patterns.test.d.ts → runtime/error-recovery.test.d.ts} +0 -0
- /package/dist/{prompts/long-search.test.d.ts → runtime/errors.test.d.ts} +0 -0
- /package/dist/{prompts/protocol-simple.test.d.ts → runtime/execution-activity.test.d.ts} +0 -0
- /package/dist/{prompts/protocol.test.d.ts → runtime/execution-diagnostics.test.d.ts} +0 -0
- /package/dist/{prompts/sections.test.d.ts → runtime/execution-report.test.d.ts} +0 -0
- /package/dist/runtime/{interpret-result.test.d.ts → execution-safety.test.d.ts} +0 -0
- /package/dist/{transcript.test.d.ts → runtime/exit-control-flow.test.d.ts} +0 -0
- /package/dist/{truncator.test.d.ts → runtime/fixtures/long-search.test.d.ts} +0 -0
|
@@ -0,0 +1,1080 @@
|
|
|
1
|
+
const require_utils = require("./utils-CTlsXvdj.cjs");
|
|
2
|
+
const require_errors = require("./errors-C6ppQUZX.cjs");
|
|
3
|
+
const require_schema = require("./schema-CXlnbb3n.cjs");
|
|
4
|
+
const require_truncate = require("./truncate-uomAMGPs.cjs");
|
|
5
|
+
const require_typings = require("./typings-BA_XxAcY.cjs");
|
|
6
|
+
//#region src/inspect.ts
|
|
7
|
+
const SUBTITLE_LN = "--------------";
|
|
8
|
+
const TRUNCATION_MARKER = "[truncated]";
|
|
9
|
+
const LONG_TEXT_LENGTH = 4096;
|
|
10
|
+
const MAX_PREVIEW_CHARACTERS = 1e6;
|
|
11
|
+
const MAX_PREVIEW_NODES = 1e4;
|
|
12
|
+
const DEFAULT_OPTIONS = { tokens: 1e5 };
|
|
13
|
+
function getPreviewBudget() {
|
|
14
|
+
try {
|
|
15
|
+
const tokenizer = require_utils.getTokenizer();
|
|
16
|
+
return {
|
|
17
|
+
count: (value, options) => tokenizer.count(value, {
|
|
18
|
+
...options,
|
|
19
|
+
approximate: false
|
|
20
|
+
}),
|
|
21
|
+
truncate: (value, length, mode) => tokenizer.truncate(value, length, mode)
|
|
22
|
+
};
|
|
23
|
+
} catch {
|
|
24
|
+
const encoder = new TextEncoder();
|
|
25
|
+
return {
|
|
26
|
+
count: (value) => encoder.encode(value).length,
|
|
27
|
+
truncate: (value, length, mode = "head") => {
|
|
28
|
+
const take = (text, limit, fromEnd) => {
|
|
29
|
+
let output = "";
|
|
30
|
+
let bytes = 0;
|
|
31
|
+
const characters = Array.from(text);
|
|
32
|
+
if (fromEnd) characters.reverse();
|
|
33
|
+
for (const character of characters) {
|
|
34
|
+
bytes += encoder.encode(character).length;
|
|
35
|
+
if (bytes > limit) break;
|
|
36
|
+
output = fromEnd ? character + output : output + character;
|
|
37
|
+
}
|
|
38
|
+
return output;
|
|
39
|
+
};
|
|
40
|
+
if (mode === "middle") {
|
|
41
|
+
const head = Math.ceil(length / 2);
|
|
42
|
+
return take(value, head, false) + take(value, length - head, true);
|
|
43
|
+
}
|
|
44
|
+
return take(value, length, mode === "tail");
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
function takeCharacters(value, length, side) {
|
|
50
|
+
let output = side === "top" ? value.slice(0, length) : value.slice(Math.max(0, value.length - length));
|
|
51
|
+
if (output.length < value.length) {
|
|
52
|
+
if (side === "top" && /[\uD800-\uDBFF]$/.test(output)) output = output.slice(0, -1);
|
|
53
|
+
else if (side === "bottom" && /^[\uDC00-\uDFFF]/.test(output)) output = output.slice(1);
|
|
54
|
+
}
|
|
55
|
+
return output;
|
|
56
|
+
}
|
|
57
|
+
function takeTokens(value, tokens, side, budget) {
|
|
58
|
+
let output = budget.truncate(value, tokens, side === "top" ? "head" : "tail");
|
|
59
|
+
while (output && !(side === "top" ? value.startsWith(output) : value.endsWith(output))) output = side === "top" ? output.slice(0, -1) : output.slice(1);
|
|
60
|
+
return output;
|
|
61
|
+
}
|
|
62
|
+
function limitInspectionOutput(output, tokens, truncated, preserve = "top") {
|
|
63
|
+
if (tokens === 0) return "";
|
|
64
|
+
const budget = getPreviewBudget();
|
|
65
|
+
if (!truncated && budget.count(output) <= tokens) return output;
|
|
66
|
+
const markerTokens = budget.count(TRUNCATION_MARKER);
|
|
67
|
+
if (markerTokens > tokens) return budget.truncate(TRUNCATION_MARKER, tokens);
|
|
68
|
+
const marked = preserve === "bottom" ? `${TRUNCATION_MARKER} ${output}` : `${output} ${TRUNCATION_MARKER}`;
|
|
69
|
+
if (budget.count(marked) <= tokens) return marked;
|
|
70
|
+
let available = Math.max(0, tokens - markerTokens - 1);
|
|
71
|
+
while (available > 0) {
|
|
72
|
+
let candidate;
|
|
73
|
+
if (preserve === "bottom") {
|
|
74
|
+
const suffix = takeTokens(output, available, "bottom", budget).trimStart();
|
|
75
|
+
candidate = `${TRUNCATION_MARKER} ${suffix}`;
|
|
76
|
+
} else if (preserve === "both") {
|
|
77
|
+
const topTokens = Math.ceil(available / 2);
|
|
78
|
+
const prefix = takeTokens(output, topTokens, "top", budget).trimEnd();
|
|
79
|
+
const suffix = takeTokens(output, available - topTokens, "bottom", budget).trimStart();
|
|
80
|
+
candidate = `${prefix} ${TRUNCATION_MARKER} ${suffix}`;
|
|
81
|
+
} else candidate = `${takeTokens(output, available, "top", budget).trimEnd()} ${TRUNCATION_MARKER}`;
|
|
82
|
+
const count = budget.count(candidate);
|
|
83
|
+
if (count <= tokens) return candidate;
|
|
84
|
+
available -= Math.max(1, count - tokens);
|
|
85
|
+
}
|
|
86
|
+
return TRUNCATION_MARKER;
|
|
87
|
+
}
|
|
88
|
+
function previewText(value, state) {
|
|
89
|
+
const length = Math.max(0, Math.min(state.characters, state.maxStringLength));
|
|
90
|
+
if (value.length <= length) {
|
|
91
|
+
state.characters -= value.length;
|
|
92
|
+
return value;
|
|
93
|
+
}
|
|
94
|
+
state.truncated = true;
|
|
95
|
+
if (state.preserve === "both") {
|
|
96
|
+
const topLength = Math.ceil(length / 2);
|
|
97
|
+
const prefix = takeCharacters(value, topLength, "top");
|
|
98
|
+
const suffix = takeCharacters(value, length - topLength, "bottom");
|
|
99
|
+
state.characters -= prefix.length + suffix.length;
|
|
100
|
+
return `${prefix}...${suffix}`;
|
|
101
|
+
}
|
|
102
|
+
const output = takeCharacters(value, length, state.preserve);
|
|
103
|
+
state.characters -= output.length;
|
|
104
|
+
return state.preserve === "top" ? output + "..." : "..." + output;
|
|
105
|
+
}
|
|
106
|
+
function findNestedBudget(value, policies) {
|
|
107
|
+
const visited = /* @__PURE__ */ new WeakSet();
|
|
108
|
+
let remaining = MAX_PREVIEW_NODES;
|
|
109
|
+
let largest;
|
|
110
|
+
function visit(current, depth) {
|
|
111
|
+
if (remaining <= 0 || depth > 20) return;
|
|
112
|
+
const policy = policies === null || policies === void 0 ? void 0 : policies(current);
|
|
113
|
+
if (policy) largest = Math.max(largest ?? 0, policy.maxTokens);
|
|
114
|
+
if (!current || typeof current !== "object" || visited.has(current)) return;
|
|
115
|
+
visited.add(current);
|
|
116
|
+
remaining--;
|
|
117
|
+
if (require_truncate.isTruncated(current)) {
|
|
118
|
+
largest = Math.max(largest ?? 0, current.$$truncate.maxTokens);
|
|
119
|
+
visit(current.value, depth + 1);
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
for (const key in current) {
|
|
123
|
+
if (remaining <= 0) break;
|
|
124
|
+
if (Object.hasOwn(current, key)) {
|
|
125
|
+
remaining--;
|
|
126
|
+
visit(readProperty(current, key), depth + 1);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
visit(value, 0);
|
|
131
|
+
return largest;
|
|
132
|
+
}
|
|
133
|
+
function createState(tokens, options, explicitPolicy) {
|
|
134
|
+
const compact = options.compact ?? false;
|
|
135
|
+
const nodeLimit = explicitPolicy ? 1e5 : MAX_PREVIEW_NODES;
|
|
136
|
+
let maxEntries = compact ? 20 : 100;
|
|
137
|
+
if (explicitPolicy) maxEntries = Math.min(nodeLimit, Math.max(1, tokens * 2));
|
|
138
|
+
return {
|
|
139
|
+
characters: Math.min(MAX_PREVIEW_CHARACTERS, Math.max(256, tokens * 16)),
|
|
140
|
+
nodes: Math.min(nodeLimit, Math.max(20, tokens * 4)),
|
|
141
|
+
maxDepth: compact ? 4 : 10,
|
|
142
|
+
maxEntries,
|
|
143
|
+
maxStringLength: explicitPolicy ? Infinity : options.maxStringLength ?? LONG_TEXT_LENGTH,
|
|
144
|
+
compact,
|
|
145
|
+
tokens,
|
|
146
|
+
preserve: "top",
|
|
147
|
+
honorTruncation: options.honorTruncation ?? true,
|
|
148
|
+
truncated: false,
|
|
149
|
+
ancestors: /* @__PURE__ */ new WeakSet(),
|
|
150
|
+
policies: options.policies
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
function entryOrder(length, limit, preserve) {
|
|
154
|
+
const count = Math.min(length, limit);
|
|
155
|
+
const indices = [];
|
|
156
|
+
for (let index = 0; index < count; index++) if (preserve === "bottom") indices.push(length - index - 1);
|
|
157
|
+
else if (preserve === "both") {
|
|
158
|
+
const offset = Math.floor(index / 2);
|
|
159
|
+
indices.push(index % 2 === 0 ? offset : length - offset - 1);
|
|
160
|
+
} else indices.push(index);
|
|
161
|
+
return indices;
|
|
162
|
+
}
|
|
163
|
+
function readProperty(value, key) {
|
|
164
|
+
const descriptor = Object.getOwnPropertyDescriptor(value, key);
|
|
165
|
+
if (!descriptor) return;
|
|
166
|
+
return "value" in descriptor ? descriptor.value : "[Getter]";
|
|
167
|
+
}
|
|
168
|
+
function errorDetails(error) {
|
|
169
|
+
let prototype = error;
|
|
170
|
+
let name;
|
|
171
|
+
for (let depth = 0; prototype && depth < 10; depth++) {
|
|
172
|
+
name = readProperty(prototype, "name");
|
|
173
|
+
if (name !== void 0) break;
|
|
174
|
+
prototype = Object.getPrototypeOf(prototype);
|
|
175
|
+
}
|
|
176
|
+
return {
|
|
177
|
+
name: name ?? "Error",
|
|
178
|
+
message: readProperty(error, "message") ?? "",
|
|
179
|
+
stack: readProperty(error, "stack")
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
function renderValue(value, state, depth = 0, pretty = false, policyApplied = false) {
|
|
183
|
+
if (state.nodes <= 0 || state.characters <= 0 || depth > state.maxDepth) {
|
|
184
|
+
state.truncated = true;
|
|
185
|
+
return "...";
|
|
186
|
+
}
|
|
187
|
+
state.nodes--;
|
|
188
|
+
const wrapped = require_truncate.isTruncated(value);
|
|
189
|
+
let policy;
|
|
190
|
+
if (!policyApplied && state.honorTruncation) {
|
|
191
|
+
var _state$policies;
|
|
192
|
+
policy = wrapped ? value.$$truncate : (_state$policies = state.policies) === null || _state$policies === void 0 ? void 0 : _state$policies.call(state, value);
|
|
193
|
+
}
|
|
194
|
+
if (wrapped || policy) {
|
|
195
|
+
const displayed = wrapped ? value.value : value;
|
|
196
|
+
if (wrapped && state.ancestors.has(value)) return "[Circular]";
|
|
197
|
+
if (wrapped) state.ancestors.add(value);
|
|
198
|
+
try {
|
|
199
|
+
if (!policy) return renderValue(displayed, state, depth, pretty);
|
|
200
|
+
const tokens = Math.min(state.tokens, policy.maxTokens);
|
|
201
|
+
if (tokens === 0) return "";
|
|
202
|
+
const nested = createState(tokens, {
|
|
203
|
+
tokens,
|
|
204
|
+
compact: state.compact,
|
|
205
|
+
policies: state.policies
|
|
206
|
+
}, true);
|
|
207
|
+
nested.preserve = policy.preserve;
|
|
208
|
+
nested.ancestors = state.ancestors;
|
|
209
|
+
nested.characters = Math.min(nested.characters, state.characters);
|
|
210
|
+
nested.nodes = Math.min(nested.nodes, state.nodes);
|
|
211
|
+
const characters = nested.characters;
|
|
212
|
+
const nodes = nested.nodes;
|
|
213
|
+
const output = renderValue(displayed, nested, depth, pretty, true);
|
|
214
|
+
state.characters -= characters - nested.characters;
|
|
215
|
+
state.nodes -= nodes - nested.nodes;
|
|
216
|
+
return limitInspectionOutput(output, tokens, nested.truncated, nested.preserve);
|
|
217
|
+
} finally {
|
|
218
|
+
if (wrapped) state.ancestors.delete(value);
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
if (value === null) return "null";
|
|
222
|
+
if (value === void 0) return "undefined";
|
|
223
|
+
if (typeof value === "string") {
|
|
224
|
+
const text = previewText(value, state);
|
|
225
|
+
return JSON.stringify(text);
|
|
226
|
+
}
|
|
227
|
+
if (typeof value === "bigint") return previewText(`${value}n`, state);
|
|
228
|
+
if (typeof value === "function") return `[Function ${JSON.stringify(previewText(value.name || "anonymous", state))}]`;
|
|
229
|
+
if (typeof value === "symbol") return JSON.stringify(previewText(String(value), state));
|
|
230
|
+
if (typeof value !== "object") return previewText(String(value), state);
|
|
231
|
+
if (value instanceof Date) {
|
|
232
|
+
const timestamp = Date.prototype.getTime.call(value);
|
|
233
|
+
return Number.isNaN(timestamp) ? "Invalid Date" : Date.prototype.toISOString.call(value);
|
|
234
|
+
}
|
|
235
|
+
if (value instanceof RegExp) return previewText(String(value), state);
|
|
236
|
+
if (state.ancestors.has(value)) return "[Circular]";
|
|
237
|
+
state.ancestors.add(value);
|
|
238
|
+
try {
|
|
239
|
+
if (value instanceof Error) return renderValue(errorDetails(value), state, depth + 1, pretty);
|
|
240
|
+
const array = Array.isArray(value);
|
|
241
|
+
const entries = [];
|
|
242
|
+
const appendEntry = (index, item, label = "") => {
|
|
243
|
+
const preview = renderValue(item, state, depth + 1, pretty);
|
|
244
|
+
entries.push({
|
|
245
|
+
index,
|
|
246
|
+
preview: label + preview
|
|
247
|
+
});
|
|
248
|
+
};
|
|
249
|
+
if (array) {
|
|
250
|
+
for (const index of entryOrder(value.length, state.maxEntries, state.preserve)) {
|
|
251
|
+
if (state.nodes <= 0 || state.characters <= 0) break;
|
|
252
|
+
appendEntry(index, readProperty(value, String(index)));
|
|
253
|
+
}
|
|
254
|
+
if (entries.length < value.length) state.truncated = true;
|
|
255
|
+
} else {
|
|
256
|
+
const keys = Object.keys(value);
|
|
257
|
+
for (const index of entryOrder(keys.length, state.maxEntries, state.preserve)) {
|
|
258
|
+
if (state.nodes <= 0 || state.characters <= 0) break;
|
|
259
|
+
const key = keys[index];
|
|
260
|
+
const clippedKey = previewText(key, state);
|
|
261
|
+
const label = state.compact && /^[A-Za-z_$][\w$]*$/.test(clippedKey) ? clippedKey : JSON.stringify(clippedKey);
|
|
262
|
+
appendEntry(index, readProperty(value, key), `${label}: `);
|
|
263
|
+
}
|
|
264
|
+
if (entries.length < keys.length) state.truncated = true;
|
|
265
|
+
}
|
|
266
|
+
entries.sort((left, right) => left.index - right.index);
|
|
267
|
+
const open = array ? "[" : "{";
|
|
268
|
+
const close = array ? "]" : "}";
|
|
269
|
+
if (entries.length === 0) return open + close;
|
|
270
|
+
if (!pretty) return `${open} ${entries.map((entry) => entry.preview).join(", ")} ${close}`;
|
|
271
|
+
const indentation = " ".repeat(depth);
|
|
272
|
+
const itemIndentation = indentation + " ";
|
|
273
|
+
return `${open}\n${entries.map((entry, index) => {
|
|
274
|
+
const separator = index < entries.length - 1 ? "," : "";
|
|
275
|
+
return itemIndentation + entry.preview + separator;
|
|
276
|
+
}).join("\n")}\n${indentation}${close}`;
|
|
277
|
+
} finally {
|
|
278
|
+
state.ancestors.delete(value);
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
function previewPrimitive(value, state) {
|
|
282
|
+
if (value === null) return "<nil>";
|
|
283
|
+
if (value === void 0) return "<undefined>";
|
|
284
|
+
if (typeof value === "string") return previewText(value, state);
|
|
285
|
+
return `<${extractType(value, false).toLowerCase()}> ${renderValue(value, state, 0, !state.compact)}`;
|
|
286
|
+
}
|
|
287
|
+
function previewDetailed(value, state) {
|
|
288
|
+
if (Array.isArray(value)) {
|
|
289
|
+
if (value.length === 0) return "// Array Is Empty (0 element)";
|
|
290
|
+
const lines = ["// Array Preview", SUBTITLE_LN];
|
|
291
|
+
const entries = [];
|
|
292
|
+
for (const index of entryOrder(value.length, state.maxEntries, state.preserve)) {
|
|
293
|
+
var _state$policies2;
|
|
294
|
+
if (state.nodes <= 0 || state.characters <= 0) break;
|
|
295
|
+
const item = readProperty(value, String(index));
|
|
296
|
+
const preview = typeof item === "string" || require_truncate.isTruncated(item) || !!((_state$policies2 = state.policies) === null || _state$policies2 === void 0 ? void 0 : _state$policies2.call(state, item)) ? renderValue(item, state) : previewPrimitive(item, state);
|
|
297
|
+
entries.push({
|
|
298
|
+
index,
|
|
299
|
+
preview
|
|
300
|
+
});
|
|
301
|
+
}
|
|
302
|
+
if (entries.length < value.length) {
|
|
303
|
+
state.truncated = true;
|
|
304
|
+
lines[0] = `// Array Preview (${value.length} items, truncated)`;
|
|
305
|
+
}
|
|
306
|
+
entries.sort((left, right) => left.index - right.index);
|
|
307
|
+
for (const entry of entries) lines.push(`[${entry.index}]`.padEnd(15) + ` ${entry.preview}`);
|
|
308
|
+
return lines.join("\n");
|
|
309
|
+
}
|
|
310
|
+
if (value instanceof Error) {
|
|
311
|
+
const details = errorDetails(value);
|
|
312
|
+
return [
|
|
313
|
+
`Error: ${previewPrimitive(details.name, state)}`,
|
|
314
|
+
SUBTITLE_LN,
|
|
315
|
+
previewPrimitive(details.message, state),
|
|
316
|
+
"Stack Trace:",
|
|
317
|
+
SUBTITLE_LN,
|
|
318
|
+
previewPrimitive(details.stack ?? "<no stack trace>", state)
|
|
319
|
+
].join("\n");
|
|
320
|
+
}
|
|
321
|
+
if (extractType(value, false) === "object") {
|
|
322
|
+
const output = renderValue(value, state, 0, true);
|
|
323
|
+
if (output === "{}") return "// Empty Object {}";
|
|
324
|
+
return `${state.truncated ? "// Object Preview (truncated)" : "// Object Preview"}\n${SUBTITLE_LN}\n${output}`;
|
|
325
|
+
}
|
|
326
|
+
return previewPrimitive(value, state);
|
|
327
|
+
}
|
|
328
|
+
function extractType(value, generic = true) {
|
|
329
|
+
if (value === null) return "null";
|
|
330
|
+
if (Array.isArray(value)) {
|
|
331
|
+
if (!generic) return "Array";
|
|
332
|
+
if (value.length === 0) return "Array (empty)";
|
|
333
|
+
const types = /* @__PURE__ */ new Set();
|
|
334
|
+
for (let index = 0; index < Math.min(value.length, 100); index++) {
|
|
335
|
+
types.add(extractType(value[index], false));
|
|
336
|
+
if (types.size > 3) return "Array";
|
|
337
|
+
}
|
|
338
|
+
return `Array<${Array.from(types).join(" | ")}>`;
|
|
339
|
+
}
|
|
340
|
+
if (value instanceof Date) return "date";
|
|
341
|
+
if (value instanceof RegExp) return "regexp";
|
|
342
|
+
if (value instanceof Error) return "error";
|
|
343
|
+
if (typeof value === "string" && value.length === 0) return "<empty string>";
|
|
344
|
+
return typeof value;
|
|
345
|
+
}
|
|
346
|
+
function resolveInspectionBudget(value, options) {
|
|
347
|
+
var _options$policies;
|
|
348
|
+
const requested = options.tokens ?? DEFAULT_OPTIONS.tokens;
|
|
349
|
+
const tokens = Number.isFinite(requested) ? Math.max(0, Math.floor(requested)) : DEFAULT_OPTIONS.tokens;
|
|
350
|
+
if (options.honorTruncation === false) return {
|
|
351
|
+
tokens,
|
|
352
|
+
preserve: options.preserve ?? "top",
|
|
353
|
+
explicit: false
|
|
354
|
+
};
|
|
355
|
+
const wrapped = require_truncate.isTruncated(value);
|
|
356
|
+
const root = wrapped ? value.$$truncate : (_options$policies = options.policies) === null || _options$policies === void 0 ? void 0 : _options$policies.call(options, value);
|
|
357
|
+
const nested = findNestedBudget(wrapped ? value.value : value, options.policies);
|
|
358
|
+
return {
|
|
359
|
+
tokens: (root === null || root === void 0 ? void 0 : root.maxTokens) ?? Math.max(tokens, nested ?? 0),
|
|
360
|
+
preserve: (root === null || root === void 0 ? void 0 : root.preserve) ?? options.preserve ?? "top",
|
|
361
|
+
explicit: !!root || nested !== void 0
|
|
362
|
+
};
|
|
363
|
+
}
|
|
364
|
+
const inspect = (value, name, options = DEFAULT_OPTIONS) => {
|
|
365
|
+
const resolvedOptions = options ?? DEFAULT_OPTIONS;
|
|
366
|
+
let tokens = resolvedOptions.tokens ?? DEFAULT_OPTIONS.tokens;
|
|
367
|
+
let state = createState(tokens, resolvedOptions, false);
|
|
368
|
+
try {
|
|
369
|
+
const budget = resolveInspectionBudget(value, resolvedOptions);
|
|
370
|
+
tokens = budget.tokens;
|
|
371
|
+
if (tokens === 0) return "";
|
|
372
|
+
const displayed = require_truncate.isTruncated(value) ? value.value : value;
|
|
373
|
+
state = createState(tokens, resolvedOptions, budget.explicit);
|
|
374
|
+
state.preserve = budget.preserve;
|
|
375
|
+
let header = "";
|
|
376
|
+
if (name) {
|
|
377
|
+
const label = previewText(name, state);
|
|
378
|
+
header = state.compact ? `${JSON.stringify(label)}: ` : `// const ${label}: ${extractType(displayed, false)}\n`;
|
|
379
|
+
}
|
|
380
|
+
const output = state.compact ? renderValue(displayed, state) : previewDetailed(displayed, state);
|
|
381
|
+
return limitInspectionOutput(header + output, tokens, state.truncated, state.preserve);
|
|
382
|
+
} catch (error) {
|
|
383
|
+
const message = error instanceof Error ? readProperty(error, "message") : void 0;
|
|
384
|
+
const output = typeof message === "string" ? previewText(message, state) : "Unable to inspect value";
|
|
385
|
+
return limitInspectionOutput(`Error: ${JSON.stringify(output)}`, tokens, state.truncated, state.preserve);
|
|
386
|
+
}
|
|
387
|
+
};
|
|
388
|
+
//#endregion
|
|
389
|
+
//#region src/inspection.ts
|
|
390
|
+
/** The shared boundary for values displayed in prompts, reports, and memory inventories. */
|
|
391
|
+
function createInspector(onInspect) {
|
|
392
|
+
return (value, options) => {
|
|
393
|
+
const formatting = {
|
|
394
|
+
tokens: options.maxTokens,
|
|
395
|
+
preserve: options.preserve,
|
|
396
|
+
compact: options.compact ?? false,
|
|
397
|
+
honorTruncation: options.purpose === "result",
|
|
398
|
+
policies: options.policies,
|
|
399
|
+
maxStringLength: Infinity
|
|
400
|
+
};
|
|
401
|
+
if (onInspect) try {
|
|
402
|
+
const budget = resolveInspectionBudget(value, formatting);
|
|
403
|
+
const output = onInspect(Object.freeze({
|
|
404
|
+
value: snapshotInspectionValue(value),
|
|
405
|
+
purpose: options.purpose,
|
|
406
|
+
maxTokens: budget.tokens,
|
|
407
|
+
preserve: budget.preserve,
|
|
408
|
+
compact: formatting.compact,
|
|
409
|
+
identity: options.identity ? Object.freeze({ ...options.identity }) : void 0
|
|
410
|
+
}));
|
|
411
|
+
if (typeof output === "string") return limitInspectionOutput(output, budget.tokens, false, budget.preserve);
|
|
412
|
+
} catch {}
|
|
413
|
+
return inspect(value, void 0, formatting);
|
|
414
|
+
};
|
|
415
|
+
}
|
|
416
|
+
/** Isolate evidence from subsequent guest mutations without invoking getters. */
|
|
417
|
+
function snapshotInspectionValue(value, copies = /* @__PURE__ */ new WeakMap()) {
|
|
418
|
+
if (!value || typeof value !== "object") return typeof value === "function" ? "[Function]" : value;
|
|
419
|
+
if (copies.has(value)) return copies.get(value);
|
|
420
|
+
if (require_truncate.isTruncated(value)) {
|
|
421
|
+
copies.set(value, "[Circular]");
|
|
422
|
+
const copy = snapshotInspectionValue(value.value, copies);
|
|
423
|
+
copies.set(value, copy);
|
|
424
|
+
return copy;
|
|
425
|
+
}
|
|
426
|
+
if (value instanceof Date) return Object.freeze(new Date(Date.prototype.getTime.call(value)));
|
|
427
|
+
const copy = Array.isArray(value) ? new Array(value.length) : Object.create(null);
|
|
428
|
+
copies.set(value, copy);
|
|
429
|
+
for (const key of Reflect.ownKeys(value)) {
|
|
430
|
+
if (Array.isArray(value) && key === "length") continue;
|
|
431
|
+
const descriptor = Object.getOwnPropertyDescriptor(value, key);
|
|
432
|
+
if (descriptor) Object.defineProperty(copy, key, {
|
|
433
|
+
value: "value" in descriptor ? snapshotInspectionValue(descriptor.value, copies) : "[Getter]",
|
|
434
|
+
enumerable: descriptor.enumerable
|
|
435
|
+
});
|
|
436
|
+
}
|
|
437
|
+
return Object.freeze(copy);
|
|
438
|
+
}
|
|
439
|
+
//#endregion
|
|
440
|
+
//#region src/runtime-names.ts
|
|
441
|
+
/** Runtime bindings are never tool names or retained user variables. */
|
|
442
|
+
const RUNTIME_BINDING_NAMES = [
|
|
443
|
+
"$return",
|
|
444
|
+
"$iterations",
|
|
445
|
+
"exit",
|
|
446
|
+
"inspect",
|
|
447
|
+
"chat"
|
|
448
|
+
];
|
|
449
|
+
const TERMINATION_BINDING_NAMES = [
|
|
450
|
+
"__llmz_guard",
|
|
451
|
+
"__llmz_checkpoint",
|
|
452
|
+
"__llmz_missing_tool"
|
|
453
|
+
];
|
|
454
|
+
const RESERVED_RUNTIME_NAMES = /* @__PURE__ */ new Set([...RUNTIME_BINDING_NAMES, ...TERMINATION_BINDING_NAMES]);
|
|
455
|
+
//#endregion
|
|
456
|
+
//#region src/session/memory-codec.ts
|
|
457
|
+
function encodeMemoryValue(value, seen = /* @__PURE__ */ new Set()) {
|
|
458
|
+
if (value === void 0) return ["undefined"];
|
|
459
|
+
if (Object.is(value, -0)) return ["negative-zero"];
|
|
460
|
+
if (value === null || typeof value === "string" || typeof value === "boolean") return ["value", value];
|
|
461
|
+
if (typeof value === "number" && Number.isFinite(value)) return ["value", value];
|
|
462
|
+
if (typeof value !== "object") throw new require_errors.MemoryValueError(`Unsupported memory value: ${typeof value}`);
|
|
463
|
+
if (seen.has(value)) throw new require_errors.MemoryValueError("Cyclic values cannot be retained in memory");
|
|
464
|
+
if (!Array.isArray(value) && Object.getPrototypeOf(value) !== Object.prototype && Object.getPrototypeOf(value) !== null) throw new require_errors.MemoryValueError("Only plain objects and arrays can be retained in memory");
|
|
465
|
+
if (Object.getOwnPropertySymbols(value).length) throw new require_errors.MemoryValueError("Symbol properties cannot be retained in memory");
|
|
466
|
+
seen.add(value);
|
|
467
|
+
try {
|
|
468
|
+
if (Array.isArray(value)) {
|
|
469
|
+
if (Object.keys(value).length !== value.length) throw new require_errors.MemoryValueError("Sparse arrays and custom array properties are unsupported");
|
|
470
|
+
const items = [];
|
|
471
|
+
for (let index = 0; index < value.length; index++) {
|
|
472
|
+
const descriptor = Object.getOwnPropertyDescriptor(value, index);
|
|
473
|
+
if (!descriptor || descriptor.get || descriptor.set) throw new require_errors.MemoryValueError("Array accessor properties cannot be retained in memory");
|
|
474
|
+
items.push(encodeMemoryValue(descriptor.value, seen));
|
|
475
|
+
}
|
|
476
|
+
return ["array", items];
|
|
477
|
+
}
|
|
478
|
+
const entries = [];
|
|
479
|
+
for (const [key, descriptor] of Object.entries(Object.getOwnPropertyDescriptors(value))) {
|
|
480
|
+
if (descriptor.get || descriptor.set) throw new require_errors.MemoryValueError("Accessor properties cannot be retained in memory");
|
|
481
|
+
if (!descriptor.enumerable) throw new require_errors.MemoryValueError("Non-enumerable properties cannot be retained in memory");
|
|
482
|
+
entries.push([key, encodeMemoryValue(descriptor.value, seen)]);
|
|
483
|
+
}
|
|
484
|
+
return ["object", entries];
|
|
485
|
+
} finally {
|
|
486
|
+
seen.delete(value);
|
|
487
|
+
}
|
|
488
|
+
}
|
|
489
|
+
function decodeMemoryValue(value) {
|
|
490
|
+
if (!Array.isArray(value)) throw new require_errors.MemoryValueError("Invalid serialized memory value");
|
|
491
|
+
const tag = value[0];
|
|
492
|
+
if (value.length !== (tag === "negative-zero" || tag === "undefined" ? 1 : 2)) throw new require_errors.MemoryValueError("Invalid serialized memory tuple");
|
|
493
|
+
switch (tag) {
|
|
494
|
+
case "negative-zero": return -0;
|
|
495
|
+
case "undefined": return;
|
|
496
|
+
case "value": {
|
|
497
|
+
const primitive = value[1];
|
|
498
|
+
if (primitive === null || typeof primitive === "string" || typeof primitive === "boolean" || typeof primitive === "number" && Number.isFinite(primitive)) return primitive;
|
|
499
|
+
throw new require_errors.MemoryValueError("Invalid serialized primitive");
|
|
500
|
+
}
|
|
501
|
+
case "array":
|
|
502
|
+
if (!Array.isArray(value[1])) throw new require_errors.MemoryValueError("Invalid serialized array");
|
|
503
|
+
return Array.from(value[1], decodeMemoryValue);
|
|
504
|
+
case "object": {
|
|
505
|
+
if (!Array.isArray(value[1])) throw new require_errors.MemoryValueError("Invalid serialized object");
|
|
506
|
+
const keys = /* @__PURE__ */ new Set();
|
|
507
|
+
const entries = Array.from(value[1], (entry) => {
|
|
508
|
+
if (!Array.isArray(entry) || entry.length !== 2 || typeof entry[0] !== "string" || keys.has(entry[0])) throw new require_errors.MemoryValueError("Invalid or duplicate serialized object property");
|
|
509
|
+
keys.add(entry[0]);
|
|
510
|
+
return [entry[0], decodeMemoryValue(entry[1])];
|
|
511
|
+
});
|
|
512
|
+
return Object.fromEntries(entries);
|
|
513
|
+
}
|
|
514
|
+
default: throw new require_errors.MemoryValueError("Unknown serialized memory value");
|
|
515
|
+
}
|
|
516
|
+
}
|
|
517
|
+
const cloneMemoryValue = (value) => decodeMemoryValue(encodeMemoryValue(value));
|
|
518
|
+
function freezeMemoryValue(value) {
|
|
519
|
+
if (value && typeof value === "object" && !Object.isFrozen(value)) {
|
|
520
|
+
for (const child of Object.values(value)) freezeMemoryValue(child);
|
|
521
|
+
Object.freeze(value);
|
|
522
|
+
}
|
|
523
|
+
return value;
|
|
524
|
+
}
|
|
525
|
+
//#endregion
|
|
526
|
+
//#region src/session/memory-render.ts
|
|
527
|
+
function memoryValueType(value) {
|
|
528
|
+
if (value === null) return "null";
|
|
529
|
+
if (Array.isArray(value)) return "array";
|
|
530
|
+
return typeof value;
|
|
531
|
+
}
|
|
532
|
+
function previewMemoryValue(value) {
|
|
533
|
+
return createInspector()(value, {
|
|
534
|
+
purpose: "variable",
|
|
535
|
+
maxTokens: 60,
|
|
536
|
+
compact: true
|
|
537
|
+
});
|
|
538
|
+
}
|
|
539
|
+
/** Keep the full schema in state; show a bounded, readable description in the model inventory. */
|
|
540
|
+
function summarizeMemorySchema(schema, fallback, maxChars = 360) {
|
|
541
|
+
const shorten = (text, limit) => text.length <= limit ? text : `${text.slice(0, limit - 1)}…`;
|
|
542
|
+
const describe = (definition, depth) => {
|
|
543
|
+
if (definition === true) return "any";
|
|
544
|
+
if (definition === false) return "never";
|
|
545
|
+
const constraints = [];
|
|
546
|
+
for (const [key, label] of [
|
|
547
|
+
["minimum", "min"],
|
|
548
|
+
["maximum", "max"],
|
|
549
|
+
["exclusiveMinimum", "greater than"],
|
|
550
|
+
["exclusiveMaximum", "less than"],
|
|
551
|
+
["multipleOf", "multiple of"],
|
|
552
|
+
["minLength", "min length"],
|
|
553
|
+
["maxLength", "max length"],
|
|
554
|
+
["minItems", "min items"],
|
|
555
|
+
["maxItems", "max items"],
|
|
556
|
+
["minProperties", "min properties"],
|
|
557
|
+
["maxProperties", "max properties"]
|
|
558
|
+
]) if (typeof definition[key] === "number") constraints.push(`${label} ${definition[key]}`);
|
|
559
|
+
if (definition.format) constraints.push(definition.format);
|
|
560
|
+
if (definition.pattern && !definition.format) constraints.push(`pattern ${shorten(JSON.stringify(definition.pattern), 80)}`);
|
|
561
|
+
if (definition.uniqueItems) constraints.push("unique items");
|
|
562
|
+
let type = depth === 0 ? fallback : "unknown";
|
|
563
|
+
if (typeof definition.type === "string") type = definition.type;
|
|
564
|
+
else if (Array.isArray(definition.type)) type = definition.type.join(" | ");
|
|
565
|
+
if (definition.const !== void 0) type = JSON.stringify(definition.const);
|
|
566
|
+
else if (definition.enum) {
|
|
567
|
+
type = definition.enum.slice(0, 6).map((value) => shorten(JSON.stringify(value), 48)).join(" | ");
|
|
568
|
+
if (definition.enum.length > 6) type += ` | … (${definition.enum.length} allowed values)`;
|
|
569
|
+
} else if (depth < 3 && (definition.anyOf || definition.oneOf)) {
|
|
570
|
+
const variants = definition.anyOf ?? definition.oneOf ?? [];
|
|
571
|
+
type = variants.slice(0, 4).map((variant) => describe(variant, depth + 1)).join(" | ");
|
|
572
|
+
if (variants.length > 4) type += " | …";
|
|
573
|
+
} else if (depth < 3 && definition.allOf) {
|
|
574
|
+
type = definition.allOf.slice(0, 4).map((variant) => describe(variant, depth + 1)).join(" & ");
|
|
575
|
+
if (definition.allOf.length > 4) type += " & …";
|
|
576
|
+
} else if (depth < 3 && definition.properties) {
|
|
577
|
+
const properties = Object.entries(definition.properties);
|
|
578
|
+
const required = new Set(definition.required ?? []);
|
|
579
|
+
const fields = properties.slice(0, 5).map(([name, property]) => {
|
|
580
|
+
return `${name}${required.has(name) ? "" : "?"}: ${describe(property, depth + 1)}`;
|
|
581
|
+
});
|
|
582
|
+
if (properties.length > 5) fields.push(`… (${properties.length} fields)`);
|
|
583
|
+
type = `{ ${fields.join(", ")} }`;
|
|
584
|
+
if (definition.additionalProperties === false) constraints.push("no extra fields");
|
|
585
|
+
} else if (depth < 3 && definition.items !== void 0) {
|
|
586
|
+
if (Array.isArray(definition.items)) type = `[${definition.items.slice(0, 5).map((item) => describe(item, depth + 1)).join(", ")}]`;
|
|
587
|
+
else type = `Array<${describe(definition.items, depth + 1)}>`;
|
|
588
|
+
}
|
|
589
|
+
if (constraints.length) return `${type} [${constraints.join(", ")}]`;
|
|
590
|
+
return type;
|
|
591
|
+
};
|
|
592
|
+
return shorten(describe(schema, 0), maxChars);
|
|
593
|
+
}
|
|
594
|
+
function age(provenance, turn, now) {
|
|
595
|
+
if (provenance.timestamp === void 0 || provenance.turn === void 0) return "age unknown";
|
|
596
|
+
const seconds = Math.max(0, Math.floor((now - provenance.timestamp) / 1e3));
|
|
597
|
+
let amount = 0;
|
|
598
|
+
let unit = "";
|
|
599
|
+
if (seconds >= 86400) {
|
|
600
|
+
amount = Math.floor(seconds / 86400);
|
|
601
|
+
unit = "day";
|
|
602
|
+
} else if (seconds >= 3600) {
|
|
603
|
+
amount = Math.floor(seconds / 3600);
|
|
604
|
+
unit = "hour";
|
|
605
|
+
} else if (seconds >= 60) {
|
|
606
|
+
amount = Math.floor(seconds / 60);
|
|
607
|
+
unit = "minute";
|
|
608
|
+
}
|
|
609
|
+
const elapsed = amount === 0 ? "just now" : `${amount} ${unit}${amount === 1 ? "" : "s"} ago`;
|
|
610
|
+
const turns = Math.max(0, turn - provenance.turn);
|
|
611
|
+
return `${elapsed} (${turns === 0 ? "this turn" : `${turns} turn${turns === 1 ? "" : "s"} ago`})`;
|
|
612
|
+
}
|
|
613
|
+
function renderMemory(options) {
|
|
614
|
+
const bindings = options.bindings;
|
|
615
|
+
const properties = options.properties;
|
|
616
|
+
const history = options.iterations ?? [];
|
|
617
|
+
const inspector = options.inspector ?? createInspector();
|
|
618
|
+
const now = options.now ?? Date.now();
|
|
619
|
+
const maxChars = Math.max(100, options.maxChars ?? 6e3);
|
|
620
|
+
const lines = ["## Memory"];
|
|
621
|
+
if (!bindings.length && !properties.length && !history.some((entry) => entry.hasResult)) return `${lines[0]}\nNo stored variables or results yet.`;
|
|
622
|
+
lines.push("Available in JavaScript. Previews are abbreviated; historical results are read-only.");
|
|
623
|
+
let omitted = 0;
|
|
624
|
+
const append = (line) => {
|
|
625
|
+
if (lines.join("\n").length + line.length + 60 > maxChars) omitted++;
|
|
626
|
+
else lines.push(line);
|
|
627
|
+
};
|
|
628
|
+
if (bindings.length) {
|
|
629
|
+
lines.push("", "### Variables");
|
|
630
|
+
const ordered = [...bindings].sort((a, b) => ((b.updated ?? b.assigned).timestamp ?? 0) - ((a.updated ?? a.assigned).timestamp ?? 0) || a.name.localeCompare(b.name));
|
|
631
|
+
for (const binding of ordered) {
|
|
632
|
+
const { name } = binding;
|
|
633
|
+
append(`- \`${name}\`: ${inspector(binding.value, {
|
|
634
|
+
purpose: "variable",
|
|
635
|
+
maxTokens: 60,
|
|
636
|
+
compact: true,
|
|
637
|
+
identity: { variable: name }
|
|
638
|
+
})} — ${binding.updated ? "updated" : "set"} ${age(binding.updated ?? binding.assigned, options.turn, now)}.`);
|
|
639
|
+
}
|
|
640
|
+
}
|
|
641
|
+
if (properties.length) {
|
|
642
|
+
lines.push("", "### Object properties");
|
|
643
|
+
for (const property of properties) {
|
|
644
|
+
const description = property.description ? ` ${property.description.replace(/\s+/g, " ").slice(0, 120)}` : "";
|
|
645
|
+
const schemaSummary = property.schema === void 0 ? property.type : summarizeMemorySchema(property.schema, property.type);
|
|
646
|
+
append(`- \`${`${property.object}.${property.property}`}\`: ${inspector(property.value, {
|
|
647
|
+
purpose: "property",
|
|
648
|
+
maxTokens: 60,
|
|
649
|
+
compact: true,
|
|
650
|
+
identity: {
|
|
651
|
+
object: property.object,
|
|
652
|
+
property: property.property
|
|
653
|
+
}
|
|
654
|
+
})} (${schemaSummary}; ${property.writable ? "writable" : "read-only"}) — ${property.provenance.timestamp === void 0 ? "age unknown" : `updated ${age(property.provenance, options.turn, now)}`}.${description}`);
|
|
655
|
+
}
|
|
656
|
+
}
|
|
657
|
+
if (history.some((entry) => entry.hasResult)) {
|
|
658
|
+
lines.push("", "### Results");
|
|
659
|
+
for (const [index, entry] of history.entries()) {
|
|
660
|
+
if (!entry.hasResult) continue;
|
|
661
|
+
const path = `\`$iterations[${index}].result\``;
|
|
662
|
+
append(`- ${entry.id === options.latestResultId ? `\`$return\` = ${path}` : path} (${memoryValueType(entry.result)}) — returned ${age(entry, options.turn, now)}.`);
|
|
663
|
+
}
|
|
664
|
+
}
|
|
665
|
+
if (omitted) lines.push(`\n${omitted} additional memory entr${omitted === 1 ? "y" : "ies"} omitted from this overview; retained history has ${history.length} iterations.`);
|
|
666
|
+
const rendered = lines.join("\n");
|
|
667
|
+
return rendered.length <= maxChars ? rendered : `## Memory\n${bindings.length} variables and ${history.length} iterations available; overview omitted.`;
|
|
668
|
+
}
|
|
669
|
+
//#endregion
|
|
670
|
+
//#region src/session/memory.ts
|
|
671
|
+
const RESERVED = RESERVED_RUNTIME_NAMES;
|
|
672
|
+
const DEFAULT_MAX_BYTES = 16777216;
|
|
673
|
+
function propertyMemorySchema(type) {
|
|
674
|
+
return cloneMemoryValue(require_schema.toModelSchema(type));
|
|
675
|
+
}
|
|
676
|
+
var Memory = class Memory {
|
|
677
|
+
_bindings = /* @__PURE__ */ new Map();
|
|
678
|
+
_objectProperties = /* @__PURE__ */ new Map();
|
|
679
|
+
_activeObjects = /* @__PURE__ */ new Set();
|
|
680
|
+
_additionalBytes;
|
|
681
|
+
maxBytes;
|
|
682
|
+
constructor(options = {}) {
|
|
683
|
+
this.maxBytes = options.maxBytes ?? DEFAULT_MAX_BYTES;
|
|
684
|
+
this._additionalBytes = options.additionalBytes ?? (() => 0);
|
|
685
|
+
if (!Number.isFinite(this.maxBytes) || this.maxBytes < 1) throw new require_errors.InvalidConfigurationError("Memory maxBytes must be positive");
|
|
686
|
+
for (const [name, value] of Object.entries(options.variables ?? {})) {
|
|
687
|
+
this._assertName(name);
|
|
688
|
+
this._bindings.set(name, {
|
|
689
|
+
value: cloneMemoryValue(value),
|
|
690
|
+
created: {},
|
|
691
|
+
assigned: {}
|
|
692
|
+
});
|
|
693
|
+
}
|
|
694
|
+
this.assertCapacity();
|
|
695
|
+
}
|
|
696
|
+
_assertName(name) {
|
|
697
|
+
if (RESERVED.has(name)) throw new require_errors.ReservedIdentifierError(name, "variable", false, `${name} is reserved for runtime memory`);
|
|
698
|
+
if (!/^[A-Za-z_$][\w$]*$/.test(name) || name.startsWith("__")) throw new require_errors.InvalidConfigurationError(`Invalid memory variable: ${name}`);
|
|
699
|
+
}
|
|
700
|
+
/** Object values remain authoritative in the host; this inventory never injects mutable duplicates. */
|
|
701
|
+
async syncObjects(objects, observation = {}) {
|
|
702
|
+
const roots = /* @__PURE__ */ new Set();
|
|
703
|
+
const next = /* @__PURE__ */ new Map();
|
|
704
|
+
for (const object of objects) {
|
|
705
|
+
this._assertName(object.name);
|
|
706
|
+
if (roots.has(object.name)) throw new require_errors.InvalidConfigurationError(`Duplicate object namespace: ${object.name}`);
|
|
707
|
+
if (this._bindings.has(object.name)) throw new require_errors.InvalidConfigurationError(`Object namespace ${object.name} conflicts with a named memory variable`);
|
|
708
|
+
roots.add(object.name);
|
|
709
|
+
for (const property of object.properties ?? []) {
|
|
710
|
+
const path = `${object.name}.${property.name}`;
|
|
711
|
+
if (next.has(path)) throw new require_errors.InvalidConfigurationError(`Duplicate object property: ${path}`);
|
|
712
|
+
const hostValue = cloneMemoryValue(property.value);
|
|
713
|
+
const previous = this._objectProperties.get(path);
|
|
714
|
+
const previousHostValue = previous && Object.prototype.hasOwnProperty.call(previous, "hostValue") ? previous.hostValue : previous === null || previous === void 0 ? void 0 : previous.value;
|
|
715
|
+
const changed = previous && JSON.stringify(encodeMemoryValue(previousHostValue)) !== JSON.stringify(encodeMemoryValue(hostValue));
|
|
716
|
+
const value = previous && !changed ? previous.value : hostValue;
|
|
717
|
+
const type = property.type ? (await require_typings.getTypings(property.type, {})).trim().replace(/\s+/g, " ") : memoryValueType(value);
|
|
718
|
+
const schema = property.type ? propertyMemorySchema(property.type) : void 0;
|
|
719
|
+
const schemaDescription = schema && typeof schema === "object" ? schema.description : void 0;
|
|
720
|
+
next.set(path, {
|
|
721
|
+
object: object.name,
|
|
722
|
+
property: property.name,
|
|
723
|
+
hostValue,
|
|
724
|
+
value,
|
|
725
|
+
type,
|
|
726
|
+
schema,
|
|
727
|
+
writable: property.writable === true,
|
|
728
|
+
description: property.description ?? schemaDescription,
|
|
729
|
+
provenance: changed ? { ...observation } : { ...(previous === null || previous === void 0 ? void 0 : previous.provenance) ?? {} }
|
|
730
|
+
});
|
|
731
|
+
}
|
|
732
|
+
}
|
|
733
|
+
const previous = this._objectProperties;
|
|
734
|
+
this._objectProperties = next;
|
|
735
|
+
try {
|
|
736
|
+
this.assertCapacity();
|
|
737
|
+
} catch (error) {
|
|
738
|
+
this._objectProperties = previous;
|
|
739
|
+
throw error;
|
|
740
|
+
}
|
|
741
|
+
this._activeObjects = roots;
|
|
742
|
+
}
|
|
743
|
+
getObjectPropertyValue(object, property) {
|
|
744
|
+
const path = `${object}.${property}`;
|
|
745
|
+
const entry = this._objectProperties.get(path);
|
|
746
|
+
if (!entry || !this._activeObjects.has(object)) throw new require_errors.InvalidConfigurationError(`Unknown object property: ${path}`);
|
|
747
|
+
return cloneMemoryValue(entry.value);
|
|
748
|
+
}
|
|
749
|
+
/** Reject collisions before executing code, even if the conflicting declaration would run later. */
|
|
750
|
+
assertNamesAvailable(names) {
|
|
751
|
+
for (const name of names) {
|
|
752
|
+
this._assertName(name);
|
|
753
|
+
if (this._activeObjects.has(name)) throw new require_errors.AssignmentError(`Variable ${name} conflicts with an object namespace`);
|
|
754
|
+
}
|
|
755
|
+
}
|
|
756
|
+
recordObjectMutations(mutations, provenance) {
|
|
757
|
+
const changes = /* @__PURE__ */ new Map();
|
|
758
|
+
for (const mutation of mutations) {
|
|
759
|
+
const path = `${mutation.object}.${mutation.property}`;
|
|
760
|
+
const previous = this._objectProperties.get(path);
|
|
761
|
+
if (!previous || !this._activeObjects.has(mutation.object)) throw new require_errors.InvalidConfigurationError(`Unknown object property: ${path}`);
|
|
762
|
+
if (!previous.writable) throw new require_errors.InvalidConfigurationError(`Object property ${path} is read-only`);
|
|
763
|
+
const value = cloneMemoryValue(mutation.after);
|
|
764
|
+
this._objectProperties.set(path, {
|
|
765
|
+
...previous,
|
|
766
|
+
value,
|
|
767
|
+
provenance: { ...provenance }
|
|
768
|
+
});
|
|
769
|
+
try {
|
|
770
|
+
this.assertCapacity();
|
|
771
|
+
} catch (error) {
|
|
772
|
+
this._objectProperties.set(path, previous);
|
|
773
|
+
throw error;
|
|
774
|
+
}
|
|
775
|
+
changes.set(path, {
|
|
776
|
+
name: path,
|
|
777
|
+
type: previous.type,
|
|
778
|
+
preview: previewMemoryValue(value),
|
|
779
|
+
provenance: { ...provenance }
|
|
780
|
+
});
|
|
781
|
+
}
|
|
782
|
+
return [...changes.values()];
|
|
783
|
+
}
|
|
784
|
+
get variables() {
|
|
785
|
+
return Object.fromEntries([...this._bindings].map(([name, binding]) => [name, cloneMemoryValue(binding.value)]));
|
|
786
|
+
}
|
|
787
|
+
get bindings() {
|
|
788
|
+
return [...this._bindings].map(([name, binding]) => ({
|
|
789
|
+
name,
|
|
790
|
+
...binding,
|
|
791
|
+
value: cloneMemoryValue(binding.value),
|
|
792
|
+
created: { ...binding.created },
|
|
793
|
+
assigned: { ...binding.assigned },
|
|
794
|
+
updated: binding.updated ? { ...binding.updated } : void 0
|
|
795
|
+
}));
|
|
796
|
+
}
|
|
797
|
+
get objectProperties() {
|
|
798
|
+
return [...this._objectProperties.values()].filter((property) => this._activeObjects.has(property.object)).map((property) => cloneMemoryValue(property));
|
|
799
|
+
}
|
|
800
|
+
assign(variables, metadata) {
|
|
801
|
+
var _input$variableWrites, _input$variableWrites2;
|
|
802
|
+
const input = {
|
|
803
|
+
...metadata,
|
|
804
|
+
variables
|
|
805
|
+
};
|
|
806
|
+
const timestamp = input.timestamp ?? Date.now();
|
|
807
|
+
const provenance = {
|
|
808
|
+
timestamp,
|
|
809
|
+
turn: input.turn,
|
|
810
|
+
turnId: input.turnId,
|
|
811
|
+
id: input.id,
|
|
812
|
+
number: input.number
|
|
813
|
+
};
|
|
814
|
+
const report = {
|
|
815
|
+
created: [],
|
|
816
|
+
updated: [],
|
|
817
|
+
unavailable: [...input.captureErrors ?? []],
|
|
818
|
+
resultAvailable: false
|
|
819
|
+
};
|
|
820
|
+
const writes = new Map((_input$variableWrites = input.variableWrites) === null || _input$variableWrites === void 0 ? void 0 : _input$variableWrites.map((write) => [write.name, write]));
|
|
821
|
+
const assignments = new Map((_input$variableWrites2 = input.variableWrites) === null || _input$variableWrites2 === void 0 ? void 0 : _input$variableWrites2.filter((write) => write.kind !== "mutation").map((write) => [write.name, write]));
|
|
822
|
+
for (const { name } of input.captureErrors ?? []) this._bindings.delete(name);
|
|
823
|
+
for (const [name, raw] of Object.entries(input.variables ?? {})) {
|
|
824
|
+
var _input$captureErrors;
|
|
825
|
+
if (RESERVED.has(name) || name.startsWith("__") || ((_input$captureErrors = input.captureErrors) === null || _input$captureErrors === void 0 ? void 0 : _input$captureErrors.some((failure) => failure.name === name))) continue;
|
|
826
|
+
const previous = this._bindings.get(name);
|
|
827
|
+
try {
|
|
828
|
+
this._assertName(name);
|
|
829
|
+
this.assertNamesAvailable([name]);
|
|
830
|
+
const value = cloneMemoryValue(raw);
|
|
831
|
+
const write = writes.get(name);
|
|
832
|
+
if (!(!previous || JSON.stringify(encodeMemoryValue(previous.value)) !== JSON.stringify(encodeMemoryValue(value))) && !write) continue;
|
|
833
|
+
const assigned = {
|
|
834
|
+
...provenance,
|
|
835
|
+
timestamp: (write === null || write === void 0 ? void 0 : write.timestamp) ?? timestamp
|
|
836
|
+
};
|
|
837
|
+
const mutation = !!previous && (!write || write.kind === "mutation");
|
|
838
|
+
const assignment = assignments.get(name);
|
|
839
|
+
let assignmentProvenance = assigned;
|
|
840
|
+
if (assignment) assignmentProvenance = {
|
|
841
|
+
...provenance,
|
|
842
|
+
timestamp: assignment.timestamp
|
|
843
|
+
};
|
|
844
|
+
else if (mutation) assignmentProvenance = previous.assigned;
|
|
845
|
+
this._bindings.set(name, {
|
|
846
|
+
value,
|
|
847
|
+
created: (previous === null || previous === void 0 ? void 0 : previous.created) ?? assignmentProvenance,
|
|
848
|
+
assigned: assignmentProvenance,
|
|
849
|
+
updated: mutation ? assigned : void 0
|
|
850
|
+
});
|
|
851
|
+
try {
|
|
852
|
+
this.assertCapacity();
|
|
853
|
+
} catch (err) {
|
|
854
|
+
this._bindings.delete(name);
|
|
855
|
+
throw err;
|
|
856
|
+
}
|
|
857
|
+
(previous ? report.updated : report.created).push({
|
|
858
|
+
name,
|
|
859
|
+
type: memoryValueType(value),
|
|
860
|
+
preview: previewMemoryValue(value),
|
|
861
|
+
provenance: assigned
|
|
862
|
+
});
|
|
863
|
+
} catch (err) {
|
|
864
|
+
this._bindings.delete(name);
|
|
865
|
+
report.unavailable.push({
|
|
866
|
+
name,
|
|
867
|
+
reason: err instanceof Error ? err.message : String(err)
|
|
868
|
+
});
|
|
869
|
+
}
|
|
870
|
+
}
|
|
871
|
+
return report;
|
|
872
|
+
}
|
|
873
|
+
render(options) {
|
|
874
|
+
return renderMemory({
|
|
875
|
+
...options,
|
|
876
|
+
bindings: this.bindings,
|
|
877
|
+
properties: this.objectProperties
|
|
878
|
+
});
|
|
879
|
+
}
|
|
880
|
+
serialize() {
|
|
881
|
+
return {
|
|
882
|
+
version: 2,
|
|
883
|
+
maxBytes: this.maxBytes,
|
|
884
|
+
variables: [...this._bindings].map(([name, binding]) => ({
|
|
885
|
+
name,
|
|
886
|
+
...binding,
|
|
887
|
+
value: encodeMemoryValue(binding.value),
|
|
888
|
+
created: { ...binding.created },
|
|
889
|
+
assigned: { ...binding.assigned },
|
|
890
|
+
updated: binding.updated ? { ...binding.updated } : void 0
|
|
891
|
+
})),
|
|
892
|
+
objects: [...this._objectProperties.values()].map((property) => ({
|
|
893
|
+
...property,
|
|
894
|
+
value: encodeMemoryValue(property.value),
|
|
895
|
+
hostValue: encodeMemoryValue(property.hostValue),
|
|
896
|
+
schema: cloneMemoryValue(property.schema),
|
|
897
|
+
provenance: { ...property.provenance }
|
|
898
|
+
}))
|
|
899
|
+
};
|
|
900
|
+
}
|
|
901
|
+
toJSON() {
|
|
902
|
+
return this.serialize();
|
|
903
|
+
}
|
|
904
|
+
static fromJSON(state) {
|
|
905
|
+
return Memory.restore(state);
|
|
906
|
+
}
|
|
907
|
+
static restore(state, additionalBytes) {
|
|
908
|
+
if (state.version !== 2) throw new require_errors.InvalidConfigurationError("Unsupported memory version");
|
|
909
|
+
const memory = new Memory({
|
|
910
|
+
maxBytes: state.maxBytes,
|
|
911
|
+
additionalBytes
|
|
912
|
+
});
|
|
913
|
+
for (const binding of state.variables) {
|
|
914
|
+
memory._assertName(binding.name);
|
|
915
|
+
if (memory._bindings.has(binding.name)) throw new require_errors.InvalidConfigurationError("Duplicate persisted memory binding");
|
|
916
|
+
memory._bindings.set(binding.name, {
|
|
917
|
+
value: decodeMemoryValue(binding.value),
|
|
918
|
+
created: { ...binding.created },
|
|
919
|
+
assigned: { ...binding.assigned },
|
|
920
|
+
updated: binding.updated ? { ...binding.updated } : void 0
|
|
921
|
+
});
|
|
922
|
+
}
|
|
923
|
+
for (const property of state.objects ?? []) {
|
|
924
|
+
memory._assertName(property.object);
|
|
925
|
+
memory._objectProperties.set(`${property.object}.${property.property}`, {
|
|
926
|
+
...property,
|
|
927
|
+
value: decodeMemoryValue(property.value),
|
|
928
|
+
hostValue: property.hostValue ? decodeMemoryValue(property.hostValue) : decodeMemoryValue(property.value),
|
|
929
|
+
schema: cloneMemoryValue(property.schema),
|
|
930
|
+
provenance: { ...property.provenance }
|
|
931
|
+
});
|
|
932
|
+
}
|
|
933
|
+
memory.assertCapacity();
|
|
934
|
+
return memory;
|
|
935
|
+
}
|
|
936
|
+
assertCapacity(additionalBytes = 0) {
|
|
937
|
+
if (new TextEncoder().encode(JSON.stringify(this.serialize())).byteLength + this._additionalBytes() + additionalBytes > this.maxBytes) throw new require_errors.MemoryCapacityError(this.maxBytes);
|
|
938
|
+
}
|
|
939
|
+
};
|
|
940
|
+
//#endregion
|
|
941
|
+
//#region src/quickjs-variant.ts
|
|
942
|
+
/**
|
|
943
|
+
* QuickJS variant using the singlefile browser release.
|
|
944
|
+
* This variant has WASM inlined as base64 directly in the JavaScript file.
|
|
945
|
+
* No separate .wasm files, no path resolution issues, no import.meta.url problems.
|
|
946
|
+
* Works everywhere: Node.js, browsers, bundlers, AWS Lambda, etc.
|
|
947
|
+
*/
|
|
948
|
+
const getVariant = async () => {
|
|
949
|
+
return (await import("@jitl/quickjs-singlefile-browser-release-sync")).default;
|
|
950
|
+
};
|
|
951
|
+
let _activeVariant = {
|
|
952
|
+
type: "sync",
|
|
953
|
+
importFFI: async () => {
|
|
954
|
+
return (await getVariant()).importFFI();
|
|
955
|
+
},
|
|
956
|
+
importModuleLoader: async () => {
|
|
957
|
+
return (await getVariant()).importModuleLoader();
|
|
958
|
+
}
|
|
959
|
+
};
|
|
960
|
+
/**
|
|
961
|
+
* Overrides the QuickJS variant used by the sandbox.
|
|
962
|
+
*
|
|
963
|
+
* The default variant inlines the WASM as base64 and compiles it at runtime
|
|
964
|
+
* (`new WebAssembly.Module(bytes)`), which is disallowed on some platforms
|
|
965
|
+
* (e.g. Cloudflare Workers / workerd). On those platforms, inject a variant
|
|
966
|
+
* built from a statically imported precompiled `WebAssembly.Module` — e.g.
|
|
967
|
+
* quickjs-emscripten's documented Cloudflare recipe:
|
|
968
|
+
*
|
|
969
|
+
* ```ts
|
|
970
|
+
* import { newVariant } from 'quickjs-emscripten-core'
|
|
971
|
+
* import wasmfileVariant from '@jitl/quickjs-wasmfile-release-sync'
|
|
972
|
+
* import wasmModule from '@jitl/quickjs-wasmfile-release-sync/wasm'
|
|
973
|
+
*
|
|
974
|
+
* configureQuickJS(newVariant(wasmfileVariant, { wasmModule }))
|
|
975
|
+
* ```
|
|
976
|
+
*
|
|
977
|
+
* Call this before the first `execute()` (or `warmupVM()`); the WASM module is
|
|
978
|
+
* loaded once per variant and cached.
|
|
979
|
+
*/
|
|
980
|
+
const configureQuickJS = (variant) => {
|
|
981
|
+
_activeVariant = variant;
|
|
982
|
+
};
|
|
983
|
+
const getQuickJSVariant = () => _activeVariant;
|
|
984
|
+
//#endregion
|
|
985
|
+
Object.defineProperty(exports, "Memory", {
|
|
986
|
+
enumerable: true,
|
|
987
|
+
get: function() {
|
|
988
|
+
return Memory;
|
|
989
|
+
}
|
|
990
|
+
});
|
|
991
|
+
Object.defineProperty(exports, "RESERVED_RUNTIME_NAMES", {
|
|
992
|
+
enumerable: true,
|
|
993
|
+
get: function() {
|
|
994
|
+
return RESERVED_RUNTIME_NAMES;
|
|
995
|
+
}
|
|
996
|
+
});
|
|
997
|
+
Object.defineProperty(exports, "RUNTIME_BINDING_NAMES", {
|
|
998
|
+
enumerable: true,
|
|
999
|
+
get: function() {
|
|
1000
|
+
return RUNTIME_BINDING_NAMES;
|
|
1001
|
+
}
|
|
1002
|
+
});
|
|
1003
|
+
Object.defineProperty(exports, "TERMINATION_BINDING_NAMES", {
|
|
1004
|
+
enumerable: true,
|
|
1005
|
+
get: function() {
|
|
1006
|
+
return TERMINATION_BINDING_NAMES;
|
|
1007
|
+
}
|
|
1008
|
+
});
|
|
1009
|
+
Object.defineProperty(exports, "cloneMemoryValue", {
|
|
1010
|
+
enumerable: true,
|
|
1011
|
+
get: function() {
|
|
1012
|
+
return cloneMemoryValue;
|
|
1013
|
+
}
|
|
1014
|
+
});
|
|
1015
|
+
Object.defineProperty(exports, "configureQuickJS", {
|
|
1016
|
+
enumerable: true,
|
|
1017
|
+
get: function() {
|
|
1018
|
+
return configureQuickJS;
|
|
1019
|
+
}
|
|
1020
|
+
});
|
|
1021
|
+
Object.defineProperty(exports, "createInspector", {
|
|
1022
|
+
enumerable: true,
|
|
1023
|
+
get: function() {
|
|
1024
|
+
return createInspector;
|
|
1025
|
+
}
|
|
1026
|
+
});
|
|
1027
|
+
Object.defineProperty(exports, "decodeMemoryValue", {
|
|
1028
|
+
enumerable: true,
|
|
1029
|
+
get: function() {
|
|
1030
|
+
return decodeMemoryValue;
|
|
1031
|
+
}
|
|
1032
|
+
});
|
|
1033
|
+
Object.defineProperty(exports, "encodeMemoryValue", {
|
|
1034
|
+
enumerable: true,
|
|
1035
|
+
get: function() {
|
|
1036
|
+
return encodeMemoryValue;
|
|
1037
|
+
}
|
|
1038
|
+
});
|
|
1039
|
+
Object.defineProperty(exports, "freezeMemoryValue", {
|
|
1040
|
+
enumerable: true,
|
|
1041
|
+
get: function() {
|
|
1042
|
+
return freezeMemoryValue;
|
|
1043
|
+
}
|
|
1044
|
+
});
|
|
1045
|
+
Object.defineProperty(exports, "getQuickJSVariant", {
|
|
1046
|
+
enumerable: true,
|
|
1047
|
+
get: function() {
|
|
1048
|
+
return getQuickJSVariant;
|
|
1049
|
+
}
|
|
1050
|
+
});
|
|
1051
|
+
Object.defineProperty(exports, "inspect", {
|
|
1052
|
+
enumerable: true,
|
|
1053
|
+
get: function() {
|
|
1054
|
+
return inspect;
|
|
1055
|
+
}
|
|
1056
|
+
});
|
|
1057
|
+
Object.defineProperty(exports, "limitInspectionOutput", {
|
|
1058
|
+
enumerable: true,
|
|
1059
|
+
get: function() {
|
|
1060
|
+
return limitInspectionOutput;
|
|
1061
|
+
}
|
|
1062
|
+
});
|
|
1063
|
+
Object.defineProperty(exports, "renderMemory", {
|
|
1064
|
+
enumerable: true,
|
|
1065
|
+
get: function() {
|
|
1066
|
+
return renderMemory;
|
|
1067
|
+
}
|
|
1068
|
+
});
|
|
1069
|
+
Object.defineProperty(exports, "resolveInspectionBudget", {
|
|
1070
|
+
enumerable: true,
|
|
1071
|
+
get: function() {
|
|
1072
|
+
return resolveInspectionBudget;
|
|
1073
|
+
}
|
|
1074
|
+
});
|
|
1075
|
+
Object.defineProperty(exports, "snapshotInspectionValue", {
|
|
1076
|
+
enumerable: true,
|
|
1077
|
+
get: function() {
|
|
1078
|
+
return snapshotInspectionValue;
|
|
1079
|
+
}
|
|
1080
|
+
});
|