@ai-sdk/code-mode 1.0.6 → 1.0.8

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 (40) hide show
  1. package/README.md +8 -5
  2. package/dist/approval-continuation.js +84 -0
  3. package/dist/approval-continuation.js.map +1 -0
  4. package/dist/approval.js +32 -0
  5. package/dist/approval.js.map +1 -0
  6. package/dist/continuation-capability.js +125 -0
  7. package/dist/continuation-capability.js.map +1 -0
  8. package/dist/direct-tool-call.js +5 -0
  9. package/dist/direct-tool-call.js.map +1 -0
  10. package/dist/errors.js +49 -0
  11. package/dist/errors.js.map +1 -1
  12. package/dist/host-interrupt.js +28 -0
  13. package/dist/host-interrupt.js.map +1 -0
  14. package/dist/index.d.ts +152 -1
  15. package/dist/index.js +31 -1
  16. package/dist/index.js.map +1 -1
  17. package/dist/interrupt-continuation.js +115 -0
  18. package/dist/interrupt-continuation.js.map +1 -0
  19. package/dist/runtime/guest-sources.js +91 -1
  20. package/dist/runtime/guest-sources.js.map +1 -1
  21. package/dist/runtime/manager.js +388 -8
  22. package/dist/runtime/manager.js.map +1 -1
  23. package/dist/runtime/worker-source.js +1 -1
  24. package/dist/tool-invocation.js +93 -16
  25. package/dist/tool-invocation.js.map +1 -1
  26. package/package.json +3 -3
  27. package/src/approval-continuation.ts +115 -0
  28. package/src/approval.ts +60 -0
  29. package/src/continuation-capability.ts +201 -0
  30. package/src/direct-tool-call.ts +6 -0
  31. package/src/errors.ts +65 -0
  32. package/src/host-interrupt.ts +49 -0
  33. package/src/index.ts +28 -0
  34. package/src/interrupt-continuation.ts +173 -0
  35. package/src/runtime/guest-sources.ts +92 -1
  36. package/src/runtime/manager.ts +473 -8
  37. package/src/runtime/protocol.ts +24 -2
  38. package/src/runtime/worker.ts +116 -6
  39. package/src/tool-invocation.ts +119 -18
  40. package/src/types.ts +139 -0
package/dist/index.d.ts CHANGED
@@ -1,5 +1,12 @@
1
1
  import { Tool, ModelMessage, Experimental_ToolCallerTool } from 'ai';
2
2
 
3
+ /**
4
+ * Allows the model to call a tool directly.
5
+ *
6
+ * Use a string instead of a Symbol to allow for serializability.
7
+ */
8
+ declare const DIRECT_TOOL_CALL = "AI_SDK_DIRECT_TOOL_CALL";
9
+
3
10
  /**
4
11
  * Host tools made available to sandboxed code through the global `tools` object.
5
12
  */
@@ -13,6 +20,7 @@ interface CodeModeToolExecutionOptions {
13
20
  abortSignal?: AbortSignal;
14
21
  experimental_context?: unknown;
15
22
  context?: unknown;
23
+ codeModeInterrupt?: CodeModeInterruptExecutionContext;
16
24
  }
17
25
  /**
18
26
  * AI SDK tool returned by `createCodeModeTool`.
@@ -32,6 +40,98 @@ interface CodeModeToolInput {
32
40
  */
33
41
  js: string;
34
42
  }
43
+ type ApprovalDecision = 'approved' | 'denied' | {
44
+ approved: boolean;
45
+ reason?: string;
46
+ };
47
+ interface CodeModeApprovalRequest {
48
+ toolName: string;
49
+ input: unknown;
50
+ toolCallId: string;
51
+ }
52
+ interface CodeModeApprovalResponse {
53
+ approvalId: string;
54
+ approved: boolean;
55
+ reason?: string;
56
+ }
57
+ interface CodeModeInterruptPayload {
58
+ kind: string;
59
+ [key: string]: unknown;
60
+ }
61
+ interface CodeModeInterruptResolution<TResolution = unknown> {
62
+ interruptId: string;
63
+ resolution: TResolution;
64
+ }
65
+ interface CodeModeInterruptExecutionContext<TPayload extends CodeModeInterruptPayload = CodeModeInterruptPayload, TResolution = unknown> {
66
+ interruptId: string;
67
+ payload: TPayload;
68
+ resolution: TResolution;
69
+ }
70
+ type CodeModeContinuationLedgerEntry = {
71
+ kind: 'tool';
72
+ name: string;
73
+ inputJson: string;
74
+ toolCallId: string;
75
+ status: 'fulfilled';
76
+ dateNowMs: number;
77
+ valueJson: string;
78
+ } | {
79
+ kind: 'tool';
80
+ name: string;
81
+ inputJson: string;
82
+ toolCallId: string;
83
+ status: 'rejected';
84
+ dateNowMs: number;
85
+ error: SerializableError;
86
+ } | {
87
+ kind: 'tool';
88
+ name: string;
89
+ inputJson: string;
90
+ toolCallId: string;
91
+ interruptId: string;
92
+ interruptPayload: CodeModeInterruptPayload;
93
+ status: 'interrupted';
94
+ };
95
+ interface CodeModeDeterminismState {
96
+ dateNowMs: number;
97
+ randomSeed: string;
98
+ }
99
+ interface CodeModeContinuationAuth {
100
+ alg: 'HMAC-SHA256';
101
+ nonce: string;
102
+ issuedAtMs: number;
103
+ expiresAtMs: number;
104
+ signature: string;
105
+ }
106
+ interface CodeModeContinuation {
107
+ version: 1;
108
+ js: string;
109
+ outerToolCallId: string;
110
+ determinism: CodeModeDeterminismState;
111
+ ledger: CodeModeContinuationLedgerEntry[];
112
+ auth: CodeModeContinuationAuth;
113
+ }
114
+ interface CodeModeInterrupt<TPayload extends CodeModeInterruptPayload = CodeModeInterruptPayload> {
115
+ type: 'code-mode-interrupt';
116
+ interruptId: string;
117
+ toolName: string;
118
+ toolCallId: string;
119
+ outerToolCallId: string;
120
+ input: unknown;
121
+ payload: TPayload;
122
+ continuation: CodeModeContinuation;
123
+ }
124
+ type CodeModeUnwrappedResult = {
125
+ status: 'completed';
126
+ output: unknown;
127
+ } | {
128
+ status: 'interrupted';
129
+ interrupt: CodeModeInterrupt;
130
+ };
131
+ interface CodeModeApprovalInterruptPayload extends CodeModeInterruptPayload {
132
+ kind: 'ai-sdk-code-mode/tool-approval';
133
+ }
134
+ type CodeModeApprovalInterrupt = CodeModeInterrupt<CodeModeApprovalInterruptPayload>;
35
135
  /**
36
136
  * Execution limits applied to each sandbox invocation.
37
137
  */
@@ -62,6 +162,21 @@ interface CodeModeExecutionPolicy {
62
162
  */
63
163
  interface CodeModeOptions {
64
164
  executionPolicy?: CodeModeExecutionPolicy;
165
+ continuationSecurity?: CodeModeContinuationSecurityOptions;
166
+ approval?: {
167
+ /**
168
+ * @defaultValue `'callback'`
169
+ */
170
+ mode?: 'callback' | 'interrupt';
171
+ onApprovalRequired?: (request: CodeModeApprovalRequest) => Promise<ApprovalDecision> | ApprovalDecision;
172
+ };
173
+ }
174
+ interface CodeModeContinuationSecurityOptions {
175
+ signingKey?: string | Uint8Array;
176
+ /**
177
+ * @defaultValue `60 * 60 * 1000`
178
+ */
179
+ maxAgeMs?: number;
65
180
  }
66
181
  /**
67
182
  * Input for `runCodeMode`.
@@ -71,6 +186,8 @@ interface RunCodeModeInput {
71
186
  tools: CodeModeToolSet;
72
187
  toolExecutionOptions?: Partial<CodeModeToolExecutionOptions>;
73
188
  options?: CodeModeOptions;
189
+ continuation?: CodeModeContinuation;
190
+ interruptResolution?: CodeModeInterruptResolution;
74
191
  }
75
192
 
76
193
  /**
@@ -84,6 +201,17 @@ declare function createCodeModeTool(tools: CodeModeToolSet, options?: CodeModeOp
84
201
  */
85
202
  declare function codeModeTool(options?: CodeModeOptions): Experimental_ToolCallerTool<CodeModeTool>;
86
203
 
204
+ declare function isCodeModeApprovalInterrupt(value: unknown, continuationSecurity?: CodeModeContinuationSecurityOptions): value is CodeModeApprovalInterrupt;
205
+ declare function continueCodeModeApproval({ interrupt, approvalResponse, tools, options, toolExecutionOptions, }: {
206
+ interrupt: CodeModeApprovalInterrupt;
207
+ approvalResponse: CodeModeApprovalResponse;
208
+ tools: CodeModeToolSet;
209
+ options?: CodeModeOptions;
210
+ toolExecutionOptions?: Partial<CodeModeToolExecutionOptions>;
211
+ }): Promise<unknown>;
212
+ declare function toCodeModeApprovalMessages(interrupt: CodeModeApprovalInterrupt): ModelMessage[];
213
+ declare function getCodeModeApprovalResponse(messages: ModelMessage[], interrupt: CodeModeApprovalInterrupt): CodeModeApprovalResponse | undefined;
214
+
87
215
  /**
88
216
  * Base class for errors raised by code mode.
89
217
  *
@@ -153,6 +281,25 @@ declare class CodeModeProtocolError extends CodeModeError {
153
281
  declare class CodeModeToolError extends CodeModeError {
154
282
  constructor(message: string, details?: unknown);
155
283
  }
284
+ declare class CodeModeToolApprovalRequiredError extends CodeModeToolError {
285
+ constructor(toolName: string, input: unknown, toolCallId: string);
286
+ }
287
+ declare class CodeModeToolApprovalDeniedError extends CodeModeToolError {
288
+ constructor(toolName: string, input: unknown, toolCallId: string, reason?: string);
289
+ }
290
+
291
+ declare function requestCodeModeInterrupt<TPayload extends CodeModeInterruptPayload>(payload: TPayload): never;
292
+
293
+ declare function isCodeModeInterrupt(value: unknown, continuationSecurity?: CodeModeContinuationSecurityOptions): value is CodeModeInterrupt;
294
+ declare function continueCodeModeInterrupt<TPayload extends CodeModeInterruptPayload = CodeModeInterruptPayload, TResolution = unknown>({ interrupt, resolution, tools, options, toolExecutionOptions, }: {
295
+ interrupt: CodeModeInterrupt<TPayload>;
296
+ resolution: TResolution;
297
+ tools: CodeModeToolSet;
298
+ options?: CodeModeOptions;
299
+ toolExecutionOptions?: Partial<CodeModeToolExecutionOptions>;
300
+ }): Promise<unknown>;
301
+ declare function getCodeModeInterrupt(result: unknown, continuationSecurity?: CodeModeContinuationSecurityOptions): CodeModeInterrupt | undefined;
302
+ declare function unwrapCodeModeResult(result: unknown, continuationSecurity?: CodeModeContinuationSecurityOptions): CodeModeUnwrappedResult;
156
303
 
157
304
  /**
158
305
  * Runs one code-mode invocation directly without wrapping it as an AI SDK tool.
@@ -165,6 +312,10 @@ declare class CodeModeToolError extends CodeModeError {
165
312
  */
166
313
  declare function runCodeMode(input: RunCodeModeInput): Promise<unknown>;
167
314
 
315
+ declare function setCodeModeContinuationSigningKey(key?: string | Uint8Array, options?: {
316
+ maxAgeMs?: number;
317
+ }): void;
318
+
168
319
  /**
169
320
  * Sets the process-global maximum number of active code-mode workers.
170
321
  *
@@ -176,4 +327,4 @@ declare function runCodeMode(input: RunCodeModeInput): Promise<unknown>;
176
327
  */
177
328
  declare function setMaxWorkers(maxWorkers?: number): void;
178
329
 
179
- export { CodeModeAbortedError, CodeModeBridgeLimitError, CodeModeConcurrencyError, CodeModeDetachedBridgeRequestError, CodeModeError, type CodeModeExecutionPolicy, type CodeModeOptions, CodeModeProtocolError, CodeModeSourceTooLargeError, CodeModeTimeoutError, type CodeModeTool, CodeModeToolError, type CodeModeToolExecutionOptions, type CodeModeToolInput, type CodeModeToolSet, type RunCodeModeInput, codeModeTool as experimental_codeModeTool, createCodeModeTool as experimental_createCodeModeTool, runCodeMode as experimental_runCodeMode, setMaxWorkers as experimental_setMaxWorkers };
330
+ export { type ApprovalDecision, CodeModeAbortedError, type CodeModeApprovalInterrupt, type CodeModeApprovalRequest, type CodeModeApprovalResponse, CodeModeBridgeLimitError, CodeModeConcurrencyError, type CodeModeContinuation, type CodeModeContinuationSecurityOptions, CodeModeDetachedBridgeRequestError, CodeModeError, type CodeModeExecutionPolicy, type CodeModeInterrupt, type CodeModeInterruptExecutionContext, type CodeModeInterruptPayload, type CodeModeInterruptResolution, type CodeModeOptions, CodeModeProtocolError, CodeModeSourceTooLargeError, CodeModeTimeoutError, type CodeModeTool, CodeModeToolApprovalDeniedError, CodeModeToolApprovalRequiredError, CodeModeToolError, type CodeModeToolExecutionOptions, type CodeModeToolInput, type CodeModeToolSet, type CodeModeUnwrappedResult, DIRECT_TOOL_CALL, type RunCodeModeInput, codeModeTool as experimental_codeModeTool, continueCodeModeApproval as experimental_continueCodeModeApproval, continueCodeModeInterrupt as experimental_continueCodeModeInterrupt, createCodeModeTool as experimental_createCodeModeTool, getCodeModeApprovalResponse as experimental_getCodeModeApprovalResponse, getCodeModeInterrupt as experimental_getCodeModeInterrupt, isCodeModeApprovalInterrupt as experimental_isCodeModeApprovalInterrupt, isCodeModeInterrupt as experimental_isCodeModeInterrupt, requestCodeModeInterrupt as experimental_requestCodeModeInterrupt, runCodeMode as experimental_runCodeMode, setCodeModeContinuationSigningKey as experimental_setCodeModeContinuationSigningKey, setMaxWorkers as experimental_setMaxWorkers, toCodeModeApprovalMessages as experimental_toCodeModeApprovalMessages, unwrapCodeModeResult as experimental_unwrapCodeModeResult };
package/dist/index.js CHANGED
@@ -1,7 +1,14 @@
1
+ import { DIRECT_TOOL_CALL } from "./direct-tool-call.js";
1
2
  import {
2
3
  codeModeTool,
3
4
  createCodeModeTool
4
5
  } from "./code-mode-tool.js";
6
+ import {
7
+ continueCodeModeApproval,
8
+ getCodeModeApprovalResponse,
9
+ isCodeModeApprovalInterrupt,
10
+ toCodeModeApprovalMessages
11
+ } from "./approval-continuation.js";
5
12
  import {
6
13
  CodeModeAbortedError,
7
14
  CodeModeBridgeLimitError,
@@ -11,9 +18,19 @@ import {
11
18
  CodeModeProtocolError,
12
19
  CodeModeSourceTooLargeError,
13
20
  CodeModeTimeoutError,
21
+ CodeModeToolApprovalDeniedError,
22
+ CodeModeToolApprovalRequiredError,
14
23
  CodeModeToolError
15
24
  } from "./errors.js";
25
+ import { requestCodeModeInterrupt } from "./host-interrupt.js";
26
+ import {
27
+ continueCodeModeInterrupt,
28
+ getCodeModeInterrupt,
29
+ isCodeModeInterrupt,
30
+ unwrapCodeModeResult
31
+ } from "./interrupt-continuation.js";
16
32
  import { runCodeMode } from "./run-code-mode.js";
33
+ import { setCodeModeContinuationSigningKey } from "./continuation-capability.js";
17
34
  import { setMaxWorkers } from "./runtime/max-workers.js";
18
35
  export {
19
36
  CodeModeAbortedError,
@@ -24,10 +41,23 @@ export {
24
41
  CodeModeProtocolError,
25
42
  CodeModeSourceTooLargeError,
26
43
  CodeModeTimeoutError,
44
+ CodeModeToolApprovalDeniedError,
45
+ CodeModeToolApprovalRequiredError,
27
46
  CodeModeToolError,
47
+ DIRECT_TOOL_CALL,
28
48
  codeModeTool as experimental_codeModeTool,
49
+ continueCodeModeApproval as experimental_continueCodeModeApproval,
50
+ continueCodeModeInterrupt as experimental_continueCodeModeInterrupt,
29
51
  createCodeModeTool as experimental_createCodeModeTool,
52
+ getCodeModeApprovalResponse as experimental_getCodeModeApprovalResponse,
53
+ getCodeModeInterrupt as experimental_getCodeModeInterrupt,
54
+ isCodeModeApprovalInterrupt as experimental_isCodeModeApprovalInterrupt,
55
+ isCodeModeInterrupt as experimental_isCodeModeInterrupt,
56
+ requestCodeModeInterrupt as experimental_requestCodeModeInterrupt,
30
57
  runCodeMode as experimental_runCodeMode,
31
- setMaxWorkers as experimental_setMaxWorkers
58
+ setCodeModeContinuationSigningKey as experimental_setCodeModeContinuationSigningKey,
59
+ setMaxWorkers as experimental_setMaxWorkers,
60
+ toCodeModeApprovalMessages as experimental_toCodeModeApprovalMessages,
61
+ unwrapCodeModeResult as experimental_unwrapCodeModeResult
32
62
  };
33
63
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"sourcesContent":["export {\n codeModeTool as experimental_codeModeTool,\n createCodeModeTool as experimental_createCodeModeTool,\n} from './code-mode-tool.js';\nexport {\n CodeModeAbortedError,\n CodeModeBridgeLimitError,\n CodeModeConcurrencyError,\n CodeModeDetachedBridgeRequestError,\n CodeModeError,\n CodeModeProtocolError,\n CodeModeSourceTooLargeError,\n CodeModeTimeoutError,\n CodeModeToolError,\n} from './errors.js';\nexport { runCodeMode as experimental_runCodeMode } from './run-code-mode.js';\nexport { setMaxWorkers as experimental_setMaxWorkers } from './runtime/max-workers.js';\nexport type {\n CodeModeExecutionPolicy,\n CodeModeOptions,\n CodeModeTool,\n CodeModeToolExecutionOptions,\n CodeModeToolInput,\n CodeModeToolSet,\n RunCodeModeInput,\n} from './types.js';\n"],"mappings":"AAAA;AAAA,EACkB;AAAA,EACM;AAAA,OACjB;AACP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAwB,mBAAgC;AACxD,SAA0B,qBAAkC;","names":[]}
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["export { DIRECT_TOOL_CALL } from './direct-tool-call.js';\nexport {\n codeModeTool as experimental_codeModeTool,\n createCodeModeTool as experimental_createCodeModeTool,\n} from './code-mode-tool.js';\nexport {\n continueCodeModeApproval as experimental_continueCodeModeApproval,\n getCodeModeApprovalResponse as experimental_getCodeModeApprovalResponse,\n isCodeModeApprovalInterrupt as experimental_isCodeModeApprovalInterrupt,\n toCodeModeApprovalMessages as experimental_toCodeModeApprovalMessages,\n} from './approval-continuation.js';\nexport {\n CodeModeAbortedError,\n CodeModeBridgeLimitError,\n CodeModeConcurrencyError,\n CodeModeDetachedBridgeRequestError,\n CodeModeError,\n CodeModeProtocolError,\n CodeModeSourceTooLargeError,\n CodeModeTimeoutError,\n CodeModeToolApprovalDeniedError,\n CodeModeToolApprovalRequiredError,\n CodeModeToolError,\n} from './errors.js';\nexport { requestCodeModeInterrupt as experimental_requestCodeModeInterrupt } from './host-interrupt.js';\nexport {\n continueCodeModeInterrupt as experimental_continueCodeModeInterrupt,\n getCodeModeInterrupt as experimental_getCodeModeInterrupt,\n isCodeModeInterrupt as experimental_isCodeModeInterrupt,\n unwrapCodeModeResult as experimental_unwrapCodeModeResult,\n} from './interrupt-continuation.js';\nexport { runCodeMode as experimental_runCodeMode } from './run-code-mode.js';\nexport { setCodeModeContinuationSigningKey as experimental_setCodeModeContinuationSigningKey } from './continuation-capability.js';\nexport { setMaxWorkers as experimental_setMaxWorkers } from './runtime/max-workers.js';\nexport type {\n ApprovalDecision,\n CodeModeApprovalInterrupt,\n CodeModeApprovalRequest,\n CodeModeApprovalResponse,\n CodeModeContinuation,\n CodeModeContinuationSecurityOptions,\n CodeModeExecutionPolicy,\n CodeModeInterrupt,\n CodeModeInterruptExecutionContext,\n CodeModeInterruptPayload,\n CodeModeInterruptResolution,\n CodeModeOptions,\n CodeModeTool,\n CodeModeToolExecutionOptions,\n CodeModeToolInput,\n CodeModeToolSet,\n CodeModeUnwrappedResult,\n RunCodeModeInput,\n} from './types.js';\n"],"mappings":"AAAA,SAAS,wBAAwB;AACjC;AAAA,EACkB;AAAA,EACM;AAAA,OACjB;AACP;AAAA,EAC8B;AAAA,EACG;AAAA,EACA;AAAA,EACD;AAAA,OACzB;AACP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAqC,gCAA6C;AAClF;AAAA,EAC+B;AAAA,EACL;AAAA,EACD;AAAA,EACC;AAAA,OACnB;AACP,SAAwB,mBAAgC;AACxD,SAA8C,yCAAsD;AACpG,SAA0B,qBAAkC;","names":[]}
@@ -0,0 +1,115 @@
1
+ import {
2
+ hasValidCodeModeContinuationCapability,
3
+ verifyCodeModeContinuation
4
+ } from "./continuation-capability.js";
5
+ import { CodeModeProtocolError } from "./errors.js";
6
+ import { runCodeMode } from "./run-code-mode.js";
7
+ function isCodeModeInterrupt(value, continuationSecurity = {}) {
8
+ if (isRecord(value) && value.type === "code-mode-interrupt" && typeof value.interruptId === "string" && typeof value.toolCallId === "string" && typeof value.toolName === "string" && typeof value.outerToolCallId === "string" && isRecord(value.payload) && typeof value.payload.kind === "string" && isRecord(value.continuation) && hasValidCodeModeContinuationCapability(
9
+ value.continuation,
10
+ continuationSecurity
11
+ )) {
12
+ try {
13
+ assertInterruptMatchesLedger(value);
14
+ return true;
15
+ } catch {
16
+ return false;
17
+ }
18
+ }
19
+ return false;
20
+ }
21
+ async function continueCodeModeInterrupt({
22
+ interrupt,
23
+ resolution,
24
+ tools,
25
+ options = {},
26
+ toolExecutionOptions
27
+ }) {
28
+ verifyCodeModeContinuation(
29
+ interrupt.continuation,
30
+ options.continuationSecurity
31
+ );
32
+ assertInterruptMatchesLedger(interrupt);
33
+ const interruptResolution = {
34
+ interruptId: interrupt.interruptId,
35
+ resolution
36
+ };
37
+ return await runCodeMode({
38
+ js: interrupt.continuation.js,
39
+ tools,
40
+ options,
41
+ continuation: interrupt.continuation,
42
+ interruptResolution,
43
+ ...toolExecutionOptions !== void 0 ? { toolExecutionOptions } : {}
44
+ });
45
+ }
46
+ function getCodeModeInterrupt(result, continuationSecurity = {}) {
47
+ const direct = readInterruptValue(result, continuationSecurity);
48
+ if (direct !== void 0) {
49
+ return direct;
50
+ }
51
+ if (!isRecord(result)) {
52
+ return void 0;
53
+ }
54
+ for (const key of ["toolResults", "content"]) {
55
+ const parts = result[key];
56
+ if (!Array.isArray(parts)) {
57
+ continue;
58
+ }
59
+ for (const part of parts) {
60
+ if (!isRecord(part)) {
61
+ continue;
62
+ }
63
+ const interrupt = readInterruptValue(part.output, continuationSecurity);
64
+ if (interrupt !== void 0) {
65
+ return interrupt;
66
+ }
67
+ }
68
+ }
69
+ return void 0;
70
+ }
71
+ function unwrapCodeModeResult(result, continuationSecurity = {}) {
72
+ const interrupt = getCodeModeInterrupt(result, continuationSecurity);
73
+ return interrupt === void 0 ? { status: "completed", output: result } : { status: "interrupted", interrupt };
74
+ }
75
+ function readInterruptValue(value, continuationSecurity) {
76
+ if (isCodeModeInterrupt(value, continuationSecurity)) {
77
+ return value;
78
+ }
79
+ if (isRecord(value) && (value.type === "json" || value.type === "text") && "value" in value) {
80
+ return readInterruptValue(value.value, continuationSecurity);
81
+ }
82
+ return void 0;
83
+ }
84
+ function assertInterruptMatchesLedger(interrupt) {
85
+ if (interrupt.continuation.outerToolCallId !== interrupt.outerToolCallId) {
86
+ throw new CodeModeProtocolError(
87
+ "Code-mode interrupt outer tool call id does not match its continuation."
88
+ );
89
+ }
90
+ const matches = interrupt.continuation.ledger.filter(
91
+ (entry) => entry.status === "interrupted" && entry.interruptId === interrupt.interruptId && entry.toolCallId === interrupt.toolCallId && entry.name === interrupt.toolName && jsonEqual(fromJsonPayload(entry.inputJson), interrupt.input) && jsonEqual(entry.interruptPayload, interrupt.payload)
92
+ );
93
+ if (matches.length !== 1) {
94
+ throw new CodeModeProtocolError(
95
+ "Code-mode interrupt metadata does not match the signed continuation ledger.",
96
+ { interruptId: interrupt.interruptId, matches: matches.length }
97
+ );
98
+ }
99
+ }
100
+ function jsonEqual(left, right) {
101
+ return JSON.stringify(left) === JSON.stringify(right);
102
+ }
103
+ function fromJsonPayload(valueJson) {
104
+ return valueJson === "" ? void 0 : JSON.parse(valueJson);
105
+ }
106
+ function isRecord(value) {
107
+ return typeof value === "object" && value !== null && !Array.isArray(value);
108
+ }
109
+ export {
110
+ continueCodeModeInterrupt,
111
+ getCodeModeInterrupt,
112
+ isCodeModeInterrupt,
113
+ unwrapCodeModeResult
114
+ };
115
+ //# sourceMappingURL=interrupt-continuation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/interrupt-continuation.ts"],"sourcesContent":["import {\n hasValidCodeModeContinuationCapability,\n verifyCodeModeContinuation,\n} from './continuation-capability.js';\nimport { CodeModeProtocolError } from './errors.js';\nimport { runCodeMode } from './run-code-mode.js';\nimport type {\n CodeModeContinuationSecurityOptions,\n CodeModeInterrupt,\n CodeModeInterruptPayload,\n CodeModeInterruptResolution,\n CodeModeOptions,\n CodeModeToolExecutionOptions,\n CodeModeToolSet,\n CodeModeUnwrappedResult,\n} from './types.js';\n\nexport function isCodeModeInterrupt(\n value: unknown,\n continuationSecurity: CodeModeContinuationSecurityOptions = {},\n): value is CodeModeInterrupt {\n if (\n isRecord(value) &&\n value.type === 'code-mode-interrupt' &&\n typeof value.interruptId === 'string' &&\n typeof value.toolCallId === 'string' &&\n typeof value.toolName === 'string' &&\n typeof value.outerToolCallId === 'string' &&\n isRecord(value.payload) &&\n typeof value.payload.kind === 'string' &&\n isRecord(value.continuation) &&\n hasValidCodeModeContinuationCapability(\n value.continuation,\n continuationSecurity,\n )\n ) {\n try {\n assertInterruptMatchesLedger(value as unknown as CodeModeInterrupt);\n return true;\n } catch {\n return false;\n }\n }\n return false;\n}\n\nexport async function continueCodeModeInterrupt<\n TPayload extends CodeModeInterruptPayload = CodeModeInterruptPayload,\n TResolution = unknown,\n>({\n interrupt,\n resolution,\n tools,\n options = {},\n toolExecutionOptions,\n}: {\n interrupt: CodeModeInterrupt<TPayload>;\n resolution: TResolution;\n tools: CodeModeToolSet;\n options?: CodeModeOptions;\n toolExecutionOptions?: Partial<CodeModeToolExecutionOptions>;\n}): Promise<unknown> {\n verifyCodeModeContinuation(\n interrupt.continuation,\n options.continuationSecurity,\n );\n assertInterruptMatchesLedger(interrupt);\n\n const interruptResolution: CodeModeInterruptResolution<TResolution> = {\n interruptId: interrupt.interruptId,\n resolution,\n };\n return await runCodeMode({\n js: interrupt.continuation.js,\n tools,\n options,\n continuation: interrupt.continuation,\n interruptResolution,\n ...(toolExecutionOptions !== undefined ? { toolExecutionOptions } : {}),\n });\n}\n\nexport function getCodeModeInterrupt(\n result: unknown,\n continuationSecurity: CodeModeContinuationSecurityOptions = {},\n): CodeModeInterrupt | undefined {\n const direct = readInterruptValue(result, continuationSecurity);\n if (direct !== undefined) {\n return direct;\n }\n if (!isRecord(result)) {\n return undefined;\n }\n\n for (const key of ['toolResults', 'content'] as const) {\n const parts = result[key];\n if (!Array.isArray(parts)) {\n continue;\n }\n for (const part of parts) {\n if (!isRecord(part)) {\n continue;\n }\n const interrupt = readInterruptValue(part.output, continuationSecurity);\n if (interrupt !== undefined) {\n return interrupt;\n }\n }\n }\n return undefined;\n}\n\nexport function unwrapCodeModeResult(\n result: unknown,\n continuationSecurity: CodeModeContinuationSecurityOptions = {},\n): CodeModeUnwrappedResult {\n const interrupt = getCodeModeInterrupt(result, continuationSecurity);\n return interrupt === undefined\n ? { status: 'completed', output: result }\n : { status: 'interrupted', interrupt };\n}\n\nfunction readInterruptValue(\n value: unknown,\n continuationSecurity: CodeModeContinuationSecurityOptions,\n): CodeModeInterrupt | undefined {\n if (isCodeModeInterrupt(value, continuationSecurity)) {\n return value;\n }\n if (\n isRecord(value) &&\n (value.type === 'json' || value.type === 'text') &&\n 'value' in value\n ) {\n return readInterruptValue(value.value, continuationSecurity);\n }\n return undefined;\n}\n\nfunction assertInterruptMatchesLedger(interrupt: CodeModeInterrupt): void {\n if (interrupt.continuation.outerToolCallId !== interrupt.outerToolCallId) {\n throw new CodeModeProtocolError(\n 'Code-mode interrupt outer tool call id does not match its continuation.',\n );\n }\n const matches = interrupt.continuation.ledger.filter(\n entry =>\n entry.status === 'interrupted' &&\n entry.interruptId === interrupt.interruptId &&\n entry.toolCallId === interrupt.toolCallId &&\n entry.name === interrupt.toolName &&\n jsonEqual(fromJsonPayload(entry.inputJson), interrupt.input) &&\n jsonEqual(entry.interruptPayload, interrupt.payload),\n );\n if (matches.length !== 1) {\n throw new CodeModeProtocolError(\n 'Code-mode interrupt metadata does not match the signed continuation ledger.',\n { interruptId: interrupt.interruptId, matches: matches.length },\n );\n }\n}\n\nfunction jsonEqual(left: unknown, right: unknown): boolean {\n return JSON.stringify(left) === JSON.stringify(right);\n}\n\nfunction fromJsonPayload(valueJson: string): unknown {\n return valueJson === '' ? undefined : JSON.parse(valueJson);\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n"],"mappings":"AAAA;AAAA,EACE;AAAA,EACA;AAAA,OACK;AACP,SAAS,6BAA6B;AACtC,SAAS,mBAAmB;AAYrB,SAAS,oBACd,OACA,uBAA4D,CAAC,GACjC;AAC5B,MACE,SAAS,KAAK,KACd,MAAM,SAAS,yBACf,OAAO,MAAM,gBAAgB,YAC7B,OAAO,MAAM,eAAe,YAC5B,OAAO,MAAM,aAAa,YAC1B,OAAO,MAAM,oBAAoB,YACjC,SAAS,MAAM,OAAO,KACtB,OAAO,MAAM,QAAQ,SAAS,YAC9B,SAAS,MAAM,YAAY,KAC3B;AAAA,IACE,MAAM;AAAA,IACN;AAAA,EACF,GACA;AACA,QAAI;AACF,mCAA6B,KAAqC;AAClE,aAAO;AAAA,IACT,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AACA,SAAO;AACT;AAEA,eAAsB,0BAGpB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,UAAU,CAAC;AAAA,EACX;AACF,GAMqB;AACnB;AAAA,IACE,UAAU;AAAA,IACV,QAAQ;AAAA,EACV;AACA,+BAA6B,SAAS;AAEtC,QAAM,sBAAgE;AAAA,IACpE,aAAa,UAAU;AAAA,IACvB;AAAA,EACF;AACA,SAAO,MAAM,YAAY;AAAA,IACvB,IAAI,UAAU,aAAa;AAAA,IAC3B;AAAA,IACA;AAAA,IACA,cAAc,UAAU;AAAA,IACxB;AAAA,IACA,GAAI,yBAAyB,SAAY,EAAE,qBAAqB,IAAI,CAAC;AAAA,EACvE,CAAC;AACH;AAEO,SAAS,qBACd,QACA,uBAA4D,CAAC,GAC9B;AAC/B,QAAM,SAAS,mBAAmB,QAAQ,oBAAoB;AAC9D,MAAI,WAAW,QAAW;AACxB,WAAO;AAAA,EACT;AACA,MAAI,CAAC,SAAS,MAAM,GAAG;AACrB,WAAO;AAAA,EACT;AAEA,aAAW,OAAO,CAAC,eAAe,SAAS,GAAY;AACrD,UAAM,QAAQ,OAAO,GAAG;AACxB,QAAI,CAAC,MAAM,QAAQ,KAAK,GAAG;AACzB;AAAA,IACF;AACA,eAAW,QAAQ,OAAO;AACxB,UAAI,CAAC,SAAS,IAAI,GAAG;AACnB;AAAA,MACF;AACA,YAAM,YAAY,mBAAmB,KAAK,QAAQ,oBAAoB;AACtE,UAAI,cAAc,QAAW;AAC3B,eAAO;AAAA,MACT;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;AAEO,SAAS,qBACd,QACA,uBAA4D,CAAC,GACpC;AACzB,QAAM,YAAY,qBAAqB,QAAQ,oBAAoB;AACnE,SAAO,cAAc,SACjB,EAAE,QAAQ,aAAa,QAAQ,OAAO,IACtC,EAAE,QAAQ,eAAe,UAAU;AACzC;AAEA,SAAS,mBACP,OACA,sBAC+B;AAC/B,MAAI,oBAAoB,OAAO,oBAAoB,GAAG;AACpD,WAAO;AAAA,EACT;AACA,MACE,SAAS,KAAK,MACb,MAAM,SAAS,UAAU,MAAM,SAAS,WACzC,WAAW,OACX;AACA,WAAO,mBAAmB,MAAM,OAAO,oBAAoB;AAAA,EAC7D;AACA,SAAO;AACT;AAEA,SAAS,6BAA6B,WAAoC;AACxE,MAAI,UAAU,aAAa,oBAAoB,UAAU,iBAAiB;AACxE,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AACA,QAAM,UAAU,UAAU,aAAa,OAAO;AAAA,IAC5C,WACE,MAAM,WAAW,iBACjB,MAAM,gBAAgB,UAAU,eAChC,MAAM,eAAe,UAAU,cAC/B,MAAM,SAAS,UAAU,YACzB,UAAU,gBAAgB,MAAM,SAAS,GAAG,UAAU,KAAK,KAC3D,UAAU,MAAM,kBAAkB,UAAU,OAAO;AAAA,EACvD;AACA,MAAI,QAAQ,WAAW,GAAG;AACxB,UAAM,IAAI;AAAA,MACR;AAAA,MACA,EAAE,aAAa,UAAU,aAAa,SAAS,QAAQ,OAAO;AAAA,IAChE;AAAA,EACF;AACF;AAEA,SAAS,UAAU,MAAe,OAAyB;AACzD,SAAO,KAAK,UAAU,IAAI,MAAM,KAAK,UAAU,KAAK;AACtD;AAEA,SAAS,gBAAgB,WAA4B;AACnD,SAAO,cAAc,KAAK,SAAY,KAAK,MAAM,SAAS;AAC5D;AAEA,SAAS,SAAS,OAAkD;AAClE,SAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,KAAK;AAC5E;","names":[]}
@@ -89,6 +89,92 @@ const HARDENING_SOURCE = `
89
89
  }
90
90
  })();
91
91
  `;
92
+ const DETERMINISTIC_APIS_SOURCE = `
93
+ var __codeModeResetDateNow = (function(config) {
94
+ var OriginalDate = Date;
95
+ var dateNowMs = Number(config && config.dateNowMs);
96
+ if (!Number.isFinite(dateNowMs)) dateNowMs = 0;
97
+
98
+ function resetDateNow(value) {
99
+ var next = Number(value);
100
+ if (Number.isFinite(next)) dateNowMs = Math.trunc(next);
101
+ }
102
+
103
+ function nextDateMs() {
104
+ var value = dateNowMs;
105
+ dateNowMs += 1;
106
+ return value;
107
+ }
108
+
109
+ function CodeModeDate() {
110
+ if (new.target) {
111
+ if (arguments.length === 0) return new OriginalDate(nextDateMs());
112
+ return Reflect.construct(OriginalDate, arguments, new.target);
113
+ }
114
+ return new OriginalDate(nextDateMs()).toString();
115
+ }
116
+
117
+ Object.defineProperty(CodeModeDate, 'prototype', {
118
+ value: OriginalDate.prototype,
119
+ writable: false,
120
+ configurable: false,
121
+ });
122
+ Object.defineProperty(OriginalDate.prototype, 'constructor', {
123
+ value: CodeModeDate,
124
+ writable: false,
125
+ configurable: false,
126
+ });
127
+ Object.defineProperty(CodeModeDate, 'now', {
128
+ value: nextDateMs,
129
+ writable: false,
130
+ configurable: false,
131
+ });
132
+ Object.defineProperty(CodeModeDate, 'parse', {
133
+ value: OriginalDate.parse,
134
+ writable: false,
135
+ configurable: false,
136
+ });
137
+ Object.defineProperty(CodeModeDate, 'UTC', {
138
+ value: OriginalDate.UTC,
139
+ writable: false,
140
+ configurable: false,
141
+ });
142
+ Object.defineProperty(globalThis, 'Date', {
143
+ value: CodeModeDate,
144
+ writable: false,
145
+ configurable: false,
146
+ });
147
+
148
+ var randomSeed = String(config && config.randomSeed || '');
149
+ var mask64 = (1n << 64n) - 1n;
150
+ function readSeedPart(offset, fallback) {
151
+ var part = randomSeed.slice(offset, offset + 16);
152
+ return /^[0-9a-fA-F]{16}$/.test(part) ? BigInt('0x' + part) : fallback;
153
+ }
154
+ var randomState0 = readSeedPart(0, 0x243f6a8885a308d3n);
155
+ var randomState1 = readSeedPart(16, 0x13198a2e03707344n);
156
+ if ((randomState0 | randomState1) === 0n) {
157
+ randomState1 = 0x9e3779b97f4a7c15n;
158
+ }
159
+ function nextRandom64() {
160
+ var s1 = randomState0;
161
+ var s0 = randomState1;
162
+ randomState0 = s0;
163
+ s1 = (s1 ^ ((s1 << 23n) & mask64)) & mask64;
164
+ randomState1 = (s1 ^ s0 ^ (s1 >> 17n) ^ (s0 >> 26n)) & mask64;
165
+ return (randomState1 + s0) & mask64;
166
+ }
167
+ Object.defineProperty(Math, 'random', {
168
+ value: function() {
169
+ return Number(nextRandom64() >> 11n) / 9007199254740992;
170
+ },
171
+ writable: false,
172
+ configurable: false,
173
+ });
174
+
175
+ return resetDateNow;
176
+ })(__codeModeDeterminism);
177
+ `;
92
178
  const BRIDGE_TRACKING_SOURCE = `
93
179
  (function() {
94
180
  var nextRecordId = 0;
@@ -238,11 +324,15 @@ const SERIALIZATION_GUARD_SOURCE = `
238
324
  `;
239
325
  function buildGuestRuntimeSetupSource() {
240
326
  return `
241
- (function(__codeModeInvokeTool) {
327
+ (function(__codeModeInvokeTool, __codeModeDeterminism) {
328
+ ${DETERMINISTIC_APIS_SOURCE}
242
329
  ${HARDENING_SOURCE}
243
330
  ${BRIDGE_TRACKING_SOURCE}
244
331
  ${TOOLS_PROXY_SOURCE}
245
332
  ${SERIALIZATION_GUARD_SOURCE}
333
+ return Object.freeze({
334
+ resetDateNow: __codeModeResetDateNow,
335
+ });
246
336
  })
247
337
  `;
248
338
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/runtime/guest-sources.ts"],"sourcesContent":["const HARDENING_SOURCE = `\n(function() {\n try { delete globalThis.crypto; } catch {}\n if ('crypto' in globalThis) {\n Object.defineProperty(globalThis, 'crypto', {\n value: undefined,\n writable: false,\n configurable: false,\n });\n }\n try { delete globalThis.performance; } catch {}\n if ('performance' in globalThis) {\n Object.defineProperty(globalThis, 'performance', {\n value: undefined,\n writable: false,\n configurable: false,\n });\n }\n\n Object.defineProperty(globalThis, 'eval', {\n value: undefined,\n writable: false,\n configurable: false,\n });\n\n const OriginalFunction = Function;\n const BlockedFunction = function() {\n throw new TypeError('Function constructor is not allowed');\n };\n BlockedFunction.prototype = OriginalFunction.prototype;\n\n const AsyncFunction = (async function(){}).constructor;\n const GeneratorFunction = (function*(){}).constructor;\n const AsyncGeneratorFunction = (async function*(){}).constructor;\n for (const proto of [\n OriginalFunction.prototype,\n AsyncFunction.prototype,\n GeneratorFunction.prototype,\n AsyncGeneratorFunction.prototype,\n ]) {\n Object.defineProperty(proto, 'constructor', {\n value: BlockedFunction,\n writable: false,\n configurable: false,\n });\n }\n Object.defineProperty(globalThis, 'Function', {\n value: BlockedFunction,\n writable: false,\n configurable: false,\n });\n\n const g = globalThis;\n const toFreeze = [\n Object, Object.prototype,\n OriginalFunction, OriginalFunction.prototype,\n AsyncFunction, AsyncFunction.prototype,\n GeneratorFunction, GeneratorFunction.prototype,\n AsyncGeneratorFunction, AsyncGeneratorFunction.prototype,\n Array, Array.prototype,\n String, String.prototype,\n Number, Number.prototype,\n g.BigInt, g.BigInt && g.BigInt.prototype,\n Boolean, Boolean.prototype,\n g.Symbol, g.Symbol && g.Symbol.prototype,\n RegExp, RegExp.prototype,\n Date, Date.prototype,\n Map, Map.prototype,\n Set, Set.prototype,\n WeakMap, WeakMap.prototype,\n WeakSet, WeakSet.prototype,\n Promise, Promise.prototype,\n ArrayBuffer, ArrayBuffer.prototype,\n g.DataView, g.DataView && g.DataView.prototype,\n JSON, Math, g.Reflect, g.Proxy,\n ];\n for (const name of [\n 'Int8Array','Uint8Array','Uint8ClampedArray',\n 'Int16Array','Uint16Array','Int32Array','Uint32Array',\n 'Float32Array','Float64Array',\n 'BigInt64Array','BigUint64Array',\n ]) {\n if (g[name]) toFreeze.push(g[name], g[name].prototype);\n }\n for (const obj of toFreeze) {\n if (obj != null) {\n try { Object.freeze(obj); } catch {}\n }\n }\n})();\n`;\n\nconst BRIDGE_TRACKING_SOURCE = `\n(function() {\n var nextRecordId = 0;\n var records = [];\n\n function detachedError(message, record) {\n var error = new Error(message);\n error.name = 'CodeModeDetachedBridgeRequestError';\n error.code = 'CODE_MODE_DETACHED_BRIDGE_REQUEST';\n error.details = {\n id: record.id,\n kind: record.kind,\n name: record.name,\n status: record.status\n };\n return error;\n }\n\n Object.defineProperty(globalThis, '__codeModeCreateBridgePromise', {\n value: function(kind, name, start) {\n var record = {\n id: ++nextRecordId,\n kind: String(kind),\n name: String(name || ''),\n observed: false,\n status: 'idle'\n };\n var promise;\n records.push(record);\n\n function getPromise() {\n record.observed = true;\n if (!promise) {\n record.status = 'pending';\n promise = Promise.resolve().then(start).then(\n function(value) {\n record.status = 'fulfilled';\n return value;\n },\n function(error) {\n record.status = 'rejected';\n throw error;\n }\n );\n }\n return promise;\n }\n\n return Object.freeze({\n then: function(onFulfilled, onRejected) {\n return getPromise().then(onFulfilled, onRejected);\n },\n catch: function(onRejected) {\n return getPromise().catch(onRejected);\n },\n finally: function(onFinally) {\n return getPromise().finally(onFinally);\n },\n get [Symbol.toStringTag]() {\n return 'Promise';\n }\n });\n },\n writable: false,\n configurable: false\n });\n\n Object.defineProperty(globalThis, '__codeModeAssertNoDetachedBridgeCalls', {\n value: function() {\n for (var i = 0; i < records.length; i++) {\n var record = records[i];\n if (!record.observed) {\n throw detachedError(\n 'Code mode created an unawaited ' + record.kind + ' bridge request: ' + record.name + '.',\n record\n );\n }\n if (record.status === 'pending') {\n throw detachedError(\n 'Code mode returned while a ' + record.kind + ' bridge request was still pending: ' + record.name + '.',\n record\n );\n }\n }\n },\n writable: false,\n configurable: false\n });\n})();\n`;\n\nconst TOOLS_PROXY_SOURCE = `\n(function(invokeTool) {\n globalThis.tools = (function makeProxy(path) {\n return new Proxy(function(){}, {\n get: function(_target, prop) {\n if (prop === 'then' || typeof prop === 'symbol') return undefined;\n return makeProxy(path.concat([String(prop)]));\n },\n apply: function(_target, _thisArg, args) {\n var toolPath = path.join('.');\n if (!toolPath) throw new Error('Tool path missing in invocation');\n var inputJson = args.length > 0 ? JSON.stringify(args[0]) : '';\n if (inputJson === undefined) {\n throw new Error('Tool input must be JSON-serializable');\n }\n return globalThis.__codeModeCreateBridgePromise('tool', toolPath, async function() {\n var resultJson = await invokeTool(toolPath, inputJson);\n return resultJson === '' ? undefined : JSON.parse(resultJson);\n });\n }\n });\n })([]);\n})(__codeModeInvokeTool);\n`;\n\nconst SERIALIZATION_GUARD_SOURCE = `\n(function() {\n function serializeJsonPayload(value) {\n if (typeof globalThis.__codeModeAssertNoDetachedBridgeCalls === 'function') {\n globalThis.__codeModeAssertNoDetachedBridgeCalls();\n }\n\n if (value === undefined) {\n return '';\n }\n\n var encoded;\n try {\n encoded = JSON.stringify(value);\n } catch (error) {\n var message = error && error.message ? String(error.message) : String(error);\n throw new TypeError('Code mode result is not JSON-serializable: ' + message);\n }\n\n if (encoded === undefined) {\n throw new TypeError('Code mode result is not JSON-serializable.');\n }\n\n return encoded;\n }\n\n Object.defineProperty(globalThis, '__codeModeSerializeJsonPayload', {\n value: serializeJsonPayload,\n writable: false,\n configurable: false,\n });\n})();\n`;\n\nexport function buildGuestRuntimeSetupSource(): string {\n return `\n(function(__codeModeInvokeTool) {\n${HARDENING_SOURCE}\n${BRIDGE_TRACKING_SOURCE}\n${TOOLS_PROXY_SOURCE}\n${SERIALIZATION_GUARD_SOURCE}\n})\n`;\n}\n\nexport function wrapUserCode(js: string): string {\n return `\nglobalThis.__codeModeResult = (async () => {\n${js}\n})();\n`;\n}\n"],"mappings":"AAAA,MAAM,mBAAmB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA4FzB,MAAM,yBAAyB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA2F/B,MAAM,qBAAqB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAyB3B,MAAM,6BAA6B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAkC5B,SAAS,+BAAuC;AACrD,SAAO;AAAA;AAAA,EAEP,gBAAgB;AAAA,EAChB,sBAAsB;AAAA,EACtB,kBAAkB;AAAA,EAClB,0BAA0B;AAAA;AAAA;AAG5B;AAEO,SAAS,aAAa,IAAoB;AAC/C,SAAO;AAAA;AAAA,EAEP,EAAE;AAAA;AAAA;AAGJ;","names":[]}
1
+ {"version":3,"sources":["../../src/runtime/guest-sources.ts"],"sourcesContent":["const HARDENING_SOURCE = `\n(function() {\n try { delete globalThis.crypto; } catch {}\n if ('crypto' in globalThis) {\n Object.defineProperty(globalThis, 'crypto', {\n value: undefined,\n writable: false,\n configurable: false,\n });\n }\n try { delete globalThis.performance; } catch {}\n if ('performance' in globalThis) {\n Object.defineProperty(globalThis, 'performance', {\n value: undefined,\n writable: false,\n configurable: false,\n });\n }\n\n Object.defineProperty(globalThis, 'eval', {\n value: undefined,\n writable: false,\n configurable: false,\n });\n\n const OriginalFunction = Function;\n const BlockedFunction = function() {\n throw new TypeError('Function constructor is not allowed');\n };\n BlockedFunction.prototype = OriginalFunction.prototype;\n\n const AsyncFunction = (async function(){}).constructor;\n const GeneratorFunction = (function*(){}).constructor;\n const AsyncGeneratorFunction = (async function*(){}).constructor;\n for (const proto of [\n OriginalFunction.prototype,\n AsyncFunction.prototype,\n GeneratorFunction.prototype,\n AsyncGeneratorFunction.prototype,\n ]) {\n Object.defineProperty(proto, 'constructor', {\n value: BlockedFunction,\n writable: false,\n configurable: false,\n });\n }\n Object.defineProperty(globalThis, 'Function', {\n value: BlockedFunction,\n writable: false,\n configurable: false,\n });\n\n const g = globalThis;\n const toFreeze = [\n Object, Object.prototype,\n OriginalFunction, OriginalFunction.prototype,\n AsyncFunction, AsyncFunction.prototype,\n GeneratorFunction, GeneratorFunction.prototype,\n AsyncGeneratorFunction, AsyncGeneratorFunction.prototype,\n Array, Array.prototype,\n String, String.prototype,\n Number, Number.prototype,\n g.BigInt, g.BigInt && g.BigInt.prototype,\n Boolean, Boolean.prototype,\n g.Symbol, g.Symbol && g.Symbol.prototype,\n RegExp, RegExp.prototype,\n Date, Date.prototype,\n Map, Map.prototype,\n Set, Set.prototype,\n WeakMap, WeakMap.prototype,\n WeakSet, WeakSet.prototype,\n Promise, Promise.prototype,\n ArrayBuffer, ArrayBuffer.prototype,\n g.DataView, g.DataView && g.DataView.prototype,\n JSON, Math, g.Reflect, g.Proxy,\n ];\n for (const name of [\n 'Int8Array','Uint8Array','Uint8ClampedArray',\n 'Int16Array','Uint16Array','Int32Array','Uint32Array',\n 'Float32Array','Float64Array',\n 'BigInt64Array','BigUint64Array',\n ]) {\n if (g[name]) toFreeze.push(g[name], g[name].prototype);\n }\n for (const obj of toFreeze) {\n if (obj != null) {\n try { Object.freeze(obj); } catch {}\n }\n }\n})();\n`;\n\nconst DETERMINISTIC_APIS_SOURCE = `\nvar __codeModeResetDateNow = (function(config) {\n var OriginalDate = Date;\n var dateNowMs = Number(config && config.dateNowMs);\n if (!Number.isFinite(dateNowMs)) dateNowMs = 0;\n\n function resetDateNow(value) {\n var next = Number(value);\n if (Number.isFinite(next)) dateNowMs = Math.trunc(next);\n }\n\n function nextDateMs() {\n var value = dateNowMs;\n dateNowMs += 1;\n return value;\n }\n\n function CodeModeDate() {\n if (new.target) {\n if (arguments.length === 0) return new OriginalDate(nextDateMs());\n return Reflect.construct(OriginalDate, arguments, new.target);\n }\n return new OriginalDate(nextDateMs()).toString();\n }\n\n Object.defineProperty(CodeModeDate, 'prototype', {\n value: OriginalDate.prototype,\n writable: false,\n configurable: false,\n });\n Object.defineProperty(OriginalDate.prototype, 'constructor', {\n value: CodeModeDate,\n writable: false,\n configurable: false,\n });\n Object.defineProperty(CodeModeDate, 'now', {\n value: nextDateMs,\n writable: false,\n configurable: false,\n });\n Object.defineProperty(CodeModeDate, 'parse', {\n value: OriginalDate.parse,\n writable: false,\n configurable: false,\n });\n Object.defineProperty(CodeModeDate, 'UTC', {\n value: OriginalDate.UTC,\n writable: false,\n configurable: false,\n });\n Object.defineProperty(globalThis, 'Date', {\n value: CodeModeDate,\n writable: false,\n configurable: false,\n });\n\n var randomSeed = String(config && config.randomSeed || '');\n var mask64 = (1n << 64n) - 1n;\n function readSeedPart(offset, fallback) {\n var part = randomSeed.slice(offset, offset + 16);\n return /^[0-9a-fA-F]{16}$/.test(part) ? BigInt('0x' + part) : fallback;\n }\n var randomState0 = readSeedPart(0, 0x243f6a8885a308d3n);\n var randomState1 = readSeedPart(16, 0x13198a2e03707344n);\n if ((randomState0 | randomState1) === 0n) {\n randomState1 = 0x9e3779b97f4a7c15n;\n }\n function nextRandom64() {\n var s1 = randomState0;\n var s0 = randomState1;\n randomState0 = s0;\n s1 = (s1 ^ ((s1 << 23n) & mask64)) & mask64;\n randomState1 = (s1 ^ s0 ^ (s1 >> 17n) ^ (s0 >> 26n)) & mask64;\n return (randomState1 + s0) & mask64;\n }\n Object.defineProperty(Math, 'random', {\n value: function() {\n return Number(nextRandom64() >> 11n) / 9007199254740992;\n },\n writable: false,\n configurable: false,\n });\n\n return resetDateNow;\n})(__codeModeDeterminism);\n`;\n\nconst BRIDGE_TRACKING_SOURCE = `\n(function() {\n var nextRecordId = 0;\n var records = [];\n\n function detachedError(message, record) {\n var error = new Error(message);\n error.name = 'CodeModeDetachedBridgeRequestError';\n error.code = 'CODE_MODE_DETACHED_BRIDGE_REQUEST';\n error.details = {\n id: record.id,\n kind: record.kind,\n name: record.name,\n status: record.status\n };\n return error;\n }\n\n Object.defineProperty(globalThis, '__codeModeCreateBridgePromise', {\n value: function(kind, name, start) {\n var record = {\n id: ++nextRecordId,\n kind: String(kind),\n name: String(name || ''),\n observed: false,\n status: 'idle'\n };\n var promise;\n records.push(record);\n\n function getPromise() {\n record.observed = true;\n if (!promise) {\n record.status = 'pending';\n promise = Promise.resolve().then(start).then(\n function(value) {\n record.status = 'fulfilled';\n return value;\n },\n function(error) {\n record.status = 'rejected';\n throw error;\n }\n );\n }\n return promise;\n }\n\n return Object.freeze({\n then: function(onFulfilled, onRejected) {\n return getPromise().then(onFulfilled, onRejected);\n },\n catch: function(onRejected) {\n return getPromise().catch(onRejected);\n },\n finally: function(onFinally) {\n return getPromise().finally(onFinally);\n },\n get [Symbol.toStringTag]() {\n return 'Promise';\n }\n });\n },\n writable: false,\n configurable: false\n });\n\n Object.defineProperty(globalThis, '__codeModeAssertNoDetachedBridgeCalls', {\n value: function() {\n for (var i = 0; i < records.length; i++) {\n var record = records[i];\n if (!record.observed) {\n throw detachedError(\n 'Code mode created an unawaited ' + record.kind + ' bridge request: ' + record.name + '.',\n record\n );\n }\n if (record.status === 'pending') {\n throw detachedError(\n 'Code mode returned while a ' + record.kind + ' bridge request was still pending: ' + record.name + '.',\n record\n );\n }\n }\n },\n writable: false,\n configurable: false\n });\n})();\n`;\n\nconst TOOLS_PROXY_SOURCE = `\n(function(invokeTool) {\n globalThis.tools = (function makeProxy(path) {\n return new Proxy(function(){}, {\n get: function(_target, prop) {\n if (prop === 'then' || typeof prop === 'symbol') return undefined;\n return makeProxy(path.concat([String(prop)]));\n },\n apply: function(_target, _thisArg, args) {\n var toolPath = path.join('.');\n if (!toolPath) throw new Error('Tool path missing in invocation');\n var inputJson = args.length > 0 ? JSON.stringify(args[0]) : '';\n if (inputJson === undefined) {\n throw new Error('Tool input must be JSON-serializable');\n }\n return globalThis.__codeModeCreateBridgePromise('tool', toolPath, async function() {\n var resultJson = await invokeTool(toolPath, inputJson);\n return resultJson === '' ? undefined : JSON.parse(resultJson);\n });\n }\n });\n })([]);\n})(__codeModeInvokeTool);\n`;\n\nconst SERIALIZATION_GUARD_SOURCE = `\n(function() {\n function serializeJsonPayload(value) {\n if (typeof globalThis.__codeModeAssertNoDetachedBridgeCalls === 'function') {\n globalThis.__codeModeAssertNoDetachedBridgeCalls();\n }\n\n if (value === undefined) {\n return '';\n }\n\n var encoded;\n try {\n encoded = JSON.stringify(value);\n } catch (error) {\n var message = error && error.message ? String(error.message) : String(error);\n throw new TypeError('Code mode result is not JSON-serializable: ' + message);\n }\n\n if (encoded === undefined) {\n throw new TypeError('Code mode result is not JSON-serializable.');\n }\n\n return encoded;\n }\n\n Object.defineProperty(globalThis, '__codeModeSerializeJsonPayload', {\n value: serializeJsonPayload,\n writable: false,\n configurable: false,\n });\n})();\n`;\n\nexport function buildGuestRuntimeSetupSource(): string {\n return `\n(function(__codeModeInvokeTool, __codeModeDeterminism) {\n${DETERMINISTIC_APIS_SOURCE}\n${HARDENING_SOURCE}\n${BRIDGE_TRACKING_SOURCE}\n${TOOLS_PROXY_SOURCE}\n${SERIALIZATION_GUARD_SOURCE}\nreturn Object.freeze({\n resetDateNow: __codeModeResetDateNow,\n});\n})\n`;\n}\n\nexport function wrapUserCode(js: string): string {\n return `\nglobalThis.__codeModeResult = (async () => {\n${js}\n})();\n`;\n}\n"],"mappings":"AAAA,MAAM,mBAAmB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA4FzB,MAAM,4BAA4B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAuFlC,MAAM,yBAAyB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA2F/B,MAAM,qBAAqB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAyB3B,MAAM,6BAA6B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAkC5B,SAAS,+BAAuC;AACrD,SAAO;AAAA;AAAA,EAEP,yBAAyB;AAAA,EACzB,gBAAgB;AAAA,EAChB,sBAAsB;AAAA,EACtB,kBAAkB;AAAA,EAClB,0BAA0B;AAAA;AAAA;AAAA;AAAA;AAAA;AAM5B;AAEO,SAAS,aAAa,IAAoB;AAC/C,SAAO;AAAA;AAAA,EAEP,EAAE;AAAA;AAAA;AAGJ;","names":[]}