@ai-sdk/code-mode 1.0.6 → 1.0.7
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/README.md +8 -5
- package/dist/approval-continuation.js +84 -0
- package/dist/approval-continuation.js.map +1 -0
- package/dist/approval.js +32 -0
- package/dist/approval.js.map +1 -0
- package/dist/continuation-capability.js +125 -0
- package/dist/continuation-capability.js.map +1 -0
- package/dist/direct-tool-call.js +5 -0
- package/dist/direct-tool-call.js.map +1 -0
- package/dist/errors.js +49 -0
- package/dist/errors.js.map +1 -1
- package/dist/host-interrupt.js +28 -0
- package/dist/host-interrupt.js.map +1 -0
- package/dist/index.d.ts +152 -1
- package/dist/index.js +31 -1
- package/dist/index.js.map +1 -1
- package/dist/interrupt-continuation.js +115 -0
- package/dist/interrupt-continuation.js.map +1 -0
- package/dist/runtime/guest-sources.js +91 -1
- package/dist/runtime/guest-sources.js.map +1 -1
- package/dist/runtime/manager.js +388 -8
- package/dist/runtime/manager.js.map +1 -1
- package/dist/runtime/worker-source.js +1 -1
- package/dist/tool-invocation.js +93 -16
- package/dist/tool-invocation.js.map +1 -1
- package/package.json +3 -3
- package/src/approval-continuation.ts +115 -0
- package/src/approval.ts +60 -0
- package/src/continuation-capability.ts +201 -0
- package/src/direct-tool-call.ts +6 -0
- package/src/errors.ts +65 -0
- package/src/host-interrupt.ts +49 -0
- package/src/index.ts +28 -0
- package/src/interrupt-continuation.ts +173 -0
- package/src/runtime/guest-sources.ts +92 -1
- package/src/runtime/manager.ts +473 -8
- package/src/runtime/protocol.ts +24 -2
- package/src/runtime/worker.ts +116 -6
- package/src/tool-invocation.ts +119 -18
- package/src/types.ts +139 -0
package/dist/runtime/manager.js
CHANGED
|
@@ -1,6 +1,16 @@
|
|
|
1
1
|
import { AsyncResource } from "node:async_hooks";
|
|
2
2
|
import { Buffer } from "node:buffer";
|
|
3
|
+
import { randomBytes } from "node:crypto";
|
|
3
4
|
import { Worker } from "node:worker_threads";
|
|
5
|
+
import {
|
|
6
|
+
isCodeModeApprovalInterruptPayload,
|
|
7
|
+
normalizeApprovalResolution
|
|
8
|
+
} from "../approval.js";
|
|
9
|
+
import {
|
|
10
|
+
resolveCodeModeContinuationSecurity,
|
|
11
|
+
signCodeModeContinuation,
|
|
12
|
+
verifyCodeModeContinuation
|
|
13
|
+
} from "../continuation-capability.js";
|
|
4
14
|
import {
|
|
5
15
|
CodeModeAbortedError,
|
|
6
16
|
CodeModeBridgeLimitError,
|
|
@@ -8,6 +18,7 @@ import {
|
|
|
8
18
|
CodeModeDetachedBridgeRequestError,
|
|
9
19
|
CodeModeProtocolError,
|
|
10
20
|
CodeModeTimeoutError,
|
|
21
|
+
CodeModeToolApprovalDeniedError,
|
|
11
22
|
deserializeError,
|
|
12
23
|
serializeBridgeErrorForGuest
|
|
13
24
|
} from "../errors.js";
|
|
@@ -22,6 +33,9 @@ let inlineWorkerUrl;
|
|
|
22
33
|
const idleWorkers = [];
|
|
23
34
|
async function runManagedCodeMode(input) {
|
|
24
35
|
const normalizedOptions = normalizeOptions(input.options);
|
|
36
|
+
const continuationSecurity = resolveCodeModeContinuationSecurity(
|
|
37
|
+
input.options?.continuationSecurity
|
|
38
|
+
);
|
|
25
39
|
const maxWorkers = getMaxWorkers({
|
|
26
40
|
memoryLimitBytes: normalizedOptions.memoryLimitBytes,
|
|
27
41
|
activeWorkers: activeInvocations
|
|
@@ -35,11 +49,19 @@ async function runManagedCodeMode(input) {
|
|
|
35
49
|
throw new CodeModeAbortedError();
|
|
36
50
|
}
|
|
37
51
|
assertSourceSize(input.js, normalizedOptions.maxSourceBytes);
|
|
52
|
+
const js = transformSource(input.js);
|
|
53
|
+
assertContinuationInput({
|
|
54
|
+
js,
|
|
55
|
+
continuation: input.continuation,
|
|
56
|
+
interruptResolution: input.interruptResolution,
|
|
57
|
+
continuationSecurity
|
|
58
|
+
});
|
|
38
59
|
const run = startWorkerRun({
|
|
39
60
|
...input,
|
|
40
|
-
js
|
|
61
|
+
js,
|
|
41
62
|
normalizedOptions,
|
|
42
|
-
maxWorkers
|
|
63
|
+
maxWorkers,
|
|
64
|
+
continuationSecurity
|
|
43
65
|
});
|
|
44
66
|
return await run.result;
|
|
45
67
|
} finally {
|
|
@@ -50,8 +72,12 @@ function startWorkerRun({
|
|
|
50
72
|
js,
|
|
51
73
|
tools,
|
|
52
74
|
toolExecutionOptions,
|
|
75
|
+
options,
|
|
76
|
+
continuation,
|
|
77
|
+
interruptResolution,
|
|
53
78
|
normalizedOptions,
|
|
54
|
-
maxWorkers
|
|
79
|
+
maxWorkers,
|
|
80
|
+
continuationSecurity
|
|
55
81
|
}) {
|
|
56
82
|
const invocationId = `code-mode-${++invocationCounter}`;
|
|
57
83
|
const pooledWorker = acquireWorker(maxWorkers);
|
|
@@ -64,10 +90,11 @@ function startWorkerRun({
|
|
|
64
90
|
};
|
|
65
91
|
const outerAbortSignal = toolExecutionOptions?.abortSignal;
|
|
66
92
|
const invocationAbortController = new AbortController();
|
|
93
|
+
let nestedToolCounter = getMaxNestedToolCounter(continuation?.ledger ?? []);
|
|
67
94
|
const forwardedContext = toolExecutionOptions?.context ?? toolExecutionOptions?.experimental_context;
|
|
68
95
|
const forwardedExperimentalContext = toolExecutionOptions?.experimental_context ?? toolExecutionOptions?.context;
|
|
69
96
|
const baseExecutionOptions = {
|
|
70
|
-
toolCallId: toolExecutionOptions?.toolCallId ?? invocationId,
|
|
97
|
+
toolCallId: toolExecutionOptions?.toolCallId ?? continuation?.outerToolCallId ?? invocationId,
|
|
71
98
|
messages: toolExecutionOptions?.messages ?? [],
|
|
72
99
|
abortSignal: invocationAbortController.signal,
|
|
73
100
|
...forwardedExperimentalContext !== void 0 ? { experimental_context: forwardedExperimentalContext } : {},
|
|
@@ -79,7 +106,13 @@ function startWorkerRun({
|
|
|
79
106
|
let workerCleanedUp = false;
|
|
80
107
|
let totalBridgeRequests = 0;
|
|
81
108
|
let inFlightBridgeRequests = 0;
|
|
109
|
+
let interruptEntryIndex;
|
|
110
|
+
let interruptDrainCounter = 0;
|
|
111
|
+
let pendingInterruptDrainId;
|
|
112
|
+
let interruptResolutionConsumed = interruptResolution === void 0;
|
|
82
113
|
const seenWorkerRequestIds = /* @__PURE__ */ new Set();
|
|
114
|
+
const bridgeLedger = cloneLedger(continuation?.ledger ?? []);
|
|
115
|
+
const determinism = continuation?.determinism ?? createDeterminismState();
|
|
83
116
|
let resolveResult;
|
|
84
117
|
let rejectResult;
|
|
85
118
|
const result = new Promise((resolve, reject) => {
|
|
@@ -168,6 +201,26 @@ function startWorkerRun({
|
|
|
168
201
|
handleReadyMessage(message);
|
|
169
202
|
return;
|
|
170
203
|
}
|
|
204
|
+
if (message.type === "bridge-drained") {
|
|
205
|
+
if (pendingInterruptDrainId === void 0 || message.drainId !== pendingInterruptDrainId) {
|
|
206
|
+
failTerminal(
|
|
207
|
+
new CodeModeProtocolError(
|
|
208
|
+
`Worker sent unexpected bridge drain acknowledgement ${message.drainId}.`,
|
|
209
|
+
{
|
|
210
|
+
invocationId,
|
|
211
|
+
expectedDrainId: pendingInterruptDrainId,
|
|
212
|
+
receivedDrainId: message.drainId
|
|
213
|
+
}
|
|
214
|
+
)
|
|
215
|
+
);
|
|
216
|
+
return;
|
|
217
|
+
}
|
|
218
|
+
pendingInterruptDrainId = void 0;
|
|
219
|
+
if (inFlightBridgeRequests === 0) {
|
|
220
|
+
settleInterrupt();
|
|
221
|
+
}
|
|
222
|
+
return;
|
|
223
|
+
}
|
|
171
224
|
const bridgeIndex = markWorkerRequest(message);
|
|
172
225
|
if (bridgeIndex !== void 0) {
|
|
173
226
|
void handleToolRequest(message, bridgeIndex);
|
|
@@ -196,6 +249,7 @@ function startWorkerRun({
|
|
|
196
249
|
type: "run",
|
|
197
250
|
invocationId,
|
|
198
251
|
js,
|
|
252
|
+
determinism,
|
|
199
253
|
options: {
|
|
200
254
|
timeoutMs: normalizedOptions.timeoutMs,
|
|
201
255
|
memoryLimitBytes: normalizedOptions.memoryLimitBytes,
|
|
@@ -255,35 +309,250 @@ function startWorkerRun({
|
|
|
255
309
|
return totalBridgeRequests;
|
|
256
310
|
}
|
|
257
311
|
async function handleToolRequest(message, bridgeIndex) {
|
|
312
|
+
const replayEntry = bridgeLedger[bridgeIndex - 1];
|
|
258
313
|
try {
|
|
259
|
-
|
|
314
|
+
if (replayEntry !== void 0) {
|
|
315
|
+
assertReplayEntryMatches(replayEntry, message, bridgeIndex);
|
|
316
|
+
if (replayEntry.status === "fulfilled") {
|
|
317
|
+
postBridgeResponse({
|
|
318
|
+
type: "bridge-response",
|
|
319
|
+
invocationId,
|
|
320
|
+
requestId: message.requestId,
|
|
321
|
+
success: true,
|
|
322
|
+
dateNowMs: replayEntry.dateNowMs,
|
|
323
|
+
valueJson: replayEntry.valueJson
|
|
324
|
+
});
|
|
325
|
+
return;
|
|
326
|
+
}
|
|
327
|
+
if (replayEntry.status === "rejected") {
|
|
328
|
+
postBridgeResponse({
|
|
329
|
+
type: "bridge-response",
|
|
330
|
+
invocationId,
|
|
331
|
+
requestId: message.requestId,
|
|
332
|
+
success: false,
|
|
333
|
+
dateNowMs: replayEntry.dateNowMs,
|
|
334
|
+
error: replayEntry.error
|
|
335
|
+
});
|
|
336
|
+
return;
|
|
337
|
+
}
|
|
338
|
+
if (interruptResolution?.interruptId !== replayEntry.interruptId) {
|
|
339
|
+
requestInterrupt(bridgeIndex - 1);
|
|
340
|
+
return;
|
|
341
|
+
}
|
|
342
|
+
interruptResolutionConsumed = true;
|
|
343
|
+
const isApproval = isCodeModeApprovalInterruptPayload(
|
|
344
|
+
replayEntry.interruptPayload
|
|
345
|
+
);
|
|
346
|
+
if (isApproval) {
|
|
347
|
+
const decision = normalizeApprovalResolution(
|
|
348
|
+
interruptResolution.resolution
|
|
349
|
+
);
|
|
350
|
+
if (!decision.approved) {
|
|
351
|
+
const error = new CodeModeToolApprovalDeniedError(
|
|
352
|
+
replayEntry.name,
|
|
353
|
+
fromJsonPayload(message.inputJson),
|
|
354
|
+
replayEntry.toolCallId,
|
|
355
|
+
decision.reason
|
|
356
|
+
);
|
|
357
|
+
const dateNowMs3 = Date.now();
|
|
358
|
+
const guestError = serializeBridgeErrorForGuest(error, "tool");
|
|
359
|
+
bridgeLedger[bridgeIndex - 1] = {
|
|
360
|
+
kind: "tool",
|
|
361
|
+
name: message.toolName,
|
|
362
|
+
inputJson: message.inputJson,
|
|
363
|
+
toolCallId: replayEntry.toolCallId,
|
|
364
|
+
status: "rejected",
|
|
365
|
+
dateNowMs: dateNowMs3,
|
|
366
|
+
error: guestError
|
|
367
|
+
};
|
|
368
|
+
postBridgeResponse({
|
|
369
|
+
type: "bridge-response",
|
|
370
|
+
invocationId,
|
|
371
|
+
requestId: message.requestId,
|
|
372
|
+
success: false,
|
|
373
|
+
dateNowMs: dateNowMs3,
|
|
374
|
+
error: guestError
|
|
375
|
+
});
|
|
376
|
+
return;
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
const codeModeInterrupt = isApproval ? void 0 : {
|
|
380
|
+
interruptId: replayEntry.interruptId,
|
|
381
|
+
payload: replayEntry.interruptPayload,
|
|
382
|
+
resolution: interruptResolution.resolution
|
|
383
|
+
};
|
|
384
|
+
const outcome2 = await invokeHostTool({
|
|
385
|
+
toolName: message.toolName,
|
|
386
|
+
inputJson: message.inputJson,
|
|
387
|
+
tools,
|
|
388
|
+
baseExecutionOptions,
|
|
389
|
+
codeModeOptions: options ?? {},
|
|
390
|
+
maxToolInputBytes: normalizedOptions.maxToolInputBytes,
|
|
391
|
+
maxToolOutputBytes: normalizedOptions.maxToolOutputBytes,
|
|
392
|
+
toolCallId: replayEntry.toolCallId,
|
|
393
|
+
...codeModeInterrupt !== void 0 ? { codeModeInterrupt } : {},
|
|
394
|
+
skipApproval: true
|
|
395
|
+
});
|
|
396
|
+
if (outcome2.type === "interrupted") {
|
|
397
|
+
bridgeLedger[bridgeIndex - 1] = {
|
|
398
|
+
kind: "tool",
|
|
399
|
+
name: message.toolName,
|
|
400
|
+
inputJson: message.inputJson,
|
|
401
|
+
toolCallId: replayEntry.toolCallId,
|
|
402
|
+
interruptId: `${replayEntry.toolCallId}:interrupt`,
|
|
403
|
+
interruptPayload: outcome2.payload,
|
|
404
|
+
status: "interrupted"
|
|
405
|
+
};
|
|
406
|
+
requestInterrupt(bridgeIndex - 1);
|
|
407
|
+
return;
|
|
408
|
+
}
|
|
409
|
+
const dateNowMs2 = Date.now();
|
|
410
|
+
bridgeLedger[bridgeIndex - 1] = {
|
|
411
|
+
kind: "tool",
|
|
412
|
+
name: message.toolName,
|
|
413
|
+
inputJson: message.inputJson,
|
|
414
|
+
toolCallId: replayEntry.toolCallId,
|
|
415
|
+
status: "fulfilled",
|
|
416
|
+
dateNowMs: dateNowMs2,
|
|
417
|
+
valueJson: outcome2.valueJson
|
|
418
|
+
};
|
|
419
|
+
postBridgeResponse({
|
|
420
|
+
type: "bridge-response",
|
|
421
|
+
invocationId,
|
|
422
|
+
requestId: message.requestId,
|
|
423
|
+
success: true,
|
|
424
|
+
dateNowMs: dateNowMs2,
|
|
425
|
+
valueJson: outcome2.valueJson
|
|
426
|
+
});
|
|
427
|
+
return;
|
|
428
|
+
}
|
|
429
|
+
const toolCallId = `${baseExecutionOptions.toolCallId}:tool-${++nestedToolCounter}`;
|
|
430
|
+
const outcome = await invokeHostTool({
|
|
260
431
|
toolName: message.toolName,
|
|
261
432
|
inputJson: message.inputJson,
|
|
262
433
|
tools,
|
|
263
434
|
baseExecutionOptions,
|
|
435
|
+
codeModeOptions: options ?? {},
|
|
264
436
|
maxToolInputBytes: normalizedOptions.maxToolInputBytes,
|
|
265
437
|
maxToolOutputBytes: normalizedOptions.maxToolOutputBytes,
|
|
266
|
-
toolCallId
|
|
438
|
+
toolCallId
|
|
267
439
|
});
|
|
440
|
+
if (outcome.type === "interrupted") {
|
|
441
|
+
bridgeLedger[bridgeIndex - 1] = {
|
|
442
|
+
kind: "tool",
|
|
443
|
+
name: message.toolName,
|
|
444
|
+
inputJson: message.inputJson,
|
|
445
|
+
toolCallId,
|
|
446
|
+
interruptId: `${toolCallId}:interrupt`,
|
|
447
|
+
interruptPayload: outcome.payload,
|
|
448
|
+
status: "interrupted"
|
|
449
|
+
};
|
|
450
|
+
requestInterrupt(bridgeIndex - 1);
|
|
451
|
+
return;
|
|
452
|
+
}
|
|
453
|
+
const dateNowMs = Date.now();
|
|
454
|
+
bridgeLedger[bridgeIndex - 1] = {
|
|
455
|
+
kind: "tool",
|
|
456
|
+
name: message.toolName,
|
|
457
|
+
inputJson: message.inputJson,
|
|
458
|
+
toolCallId,
|
|
459
|
+
status: "fulfilled",
|
|
460
|
+
dateNowMs,
|
|
461
|
+
valueJson: outcome.valueJson
|
|
462
|
+
};
|
|
268
463
|
postBridgeResponse({
|
|
269
464
|
type: "bridge-response",
|
|
270
465
|
invocationId,
|
|
271
466
|
requestId: message.requestId,
|
|
272
467
|
success: true,
|
|
273
|
-
|
|
468
|
+
dateNowMs,
|
|
469
|
+
valueJson: outcome.valueJson
|
|
274
470
|
});
|
|
275
471
|
} catch (error) {
|
|
472
|
+
if (error instanceof CodeModeProtocolError) {
|
|
473
|
+
failTerminal(error);
|
|
474
|
+
return;
|
|
475
|
+
}
|
|
476
|
+
const dateNowMs = Date.now();
|
|
477
|
+
const guestError = serializeBridgeErrorForGuest(error, "tool");
|
|
478
|
+
const toolCallId = replayEntry?.toolCallId ?? `${baseExecutionOptions.toolCallId}:tool-${nestedToolCounter}`;
|
|
479
|
+
if (replayEntry === void 0 || replayEntry.status === "interrupted" && interruptResolution?.interruptId === replayEntry.interruptId) {
|
|
480
|
+
bridgeLedger[bridgeIndex - 1] = {
|
|
481
|
+
kind: "tool",
|
|
482
|
+
name: message.toolName,
|
|
483
|
+
inputJson: message.inputJson,
|
|
484
|
+
toolCallId,
|
|
485
|
+
status: "rejected",
|
|
486
|
+
dateNowMs,
|
|
487
|
+
error: guestError
|
|
488
|
+
};
|
|
489
|
+
}
|
|
276
490
|
postBridgeResponse({
|
|
277
491
|
type: "bridge-response",
|
|
278
492
|
invocationId,
|
|
279
493
|
requestId: message.requestId,
|
|
280
494
|
success: false,
|
|
281
|
-
|
|
495
|
+
dateNowMs,
|
|
496
|
+
error: guestError
|
|
282
497
|
});
|
|
283
498
|
} finally {
|
|
284
499
|
inFlightBridgeRequests--;
|
|
500
|
+
settleInterruptIfReady();
|
|
285
501
|
}
|
|
286
502
|
}
|
|
503
|
+
function requestInterrupt(entryIndex) {
|
|
504
|
+
interruptEntryIndex ??= entryIndex;
|
|
505
|
+
}
|
|
506
|
+
function settleInterruptIfReady() {
|
|
507
|
+
if (interruptEntryIndex === void 0 || terminalReached || inFlightBridgeRequests > 0 || pendingInterruptDrainId !== void 0 || !interruptResolutionConsumed) {
|
|
508
|
+
return;
|
|
509
|
+
}
|
|
510
|
+
pendingInterruptDrainId = `${invocationId}:drain-${++interruptDrainCounter}`;
|
|
511
|
+
postBridgeResponse({
|
|
512
|
+
type: "bridge-drain",
|
|
513
|
+
invocationId,
|
|
514
|
+
drainId: pendingInterruptDrainId
|
|
515
|
+
});
|
|
516
|
+
}
|
|
517
|
+
function settleInterrupt() {
|
|
518
|
+
if (interruptEntryIndex === void 0 || terminalReached || inFlightBridgeRequests > 0 || !interruptResolutionConsumed) {
|
|
519
|
+
return;
|
|
520
|
+
}
|
|
521
|
+
const entry = bridgeLedger[interruptEntryIndex];
|
|
522
|
+
if (entry === void 0 || entry.status !== "interrupted") {
|
|
523
|
+
failTerminal(
|
|
524
|
+
new CodeModeProtocolError(
|
|
525
|
+
"Code mode interruption references a missing or resolved ledger entry.",
|
|
526
|
+
{ invocationId, interruptEntryIndex }
|
|
527
|
+
)
|
|
528
|
+
);
|
|
529
|
+
return;
|
|
530
|
+
}
|
|
531
|
+
const continuationState = signCodeModeContinuation(
|
|
532
|
+
{
|
|
533
|
+
version: 1,
|
|
534
|
+
js,
|
|
535
|
+
outerToolCallId: baseExecutionOptions.toolCallId,
|
|
536
|
+
determinism: { ...determinism },
|
|
537
|
+
ledger: cloneLedger(bridgeLedger)
|
|
538
|
+
},
|
|
539
|
+
continuationSecurity
|
|
540
|
+
);
|
|
541
|
+
const interrupt = {
|
|
542
|
+
type: "code-mode-interrupt",
|
|
543
|
+
interruptId: entry.interruptId,
|
|
544
|
+
toolName: entry.name,
|
|
545
|
+
toolCallId: entry.toolCallId,
|
|
546
|
+
outerToolCallId: continuationState.outerToolCallId,
|
|
547
|
+
input: fromJsonPayload(entry.inputJson),
|
|
548
|
+
payload: structuredClone(entry.interruptPayload),
|
|
549
|
+
continuation: continuationState
|
|
550
|
+
};
|
|
551
|
+
terminalReached = true;
|
|
552
|
+
abortInvocation(interrupt);
|
|
553
|
+
cleanupWorker(false);
|
|
554
|
+
settleCaller(() => resolveResult(interrupt));
|
|
555
|
+
}
|
|
287
556
|
function postBridgeResponse(message) {
|
|
288
557
|
if (terminalReached) {
|
|
289
558
|
return;
|
|
@@ -298,6 +567,10 @@ function startWorkerRun({
|
|
|
298
567
|
if (terminalReached) {
|
|
299
568
|
return;
|
|
300
569
|
}
|
|
570
|
+
if (interruptEntryIndex !== void 0) {
|
|
571
|
+
settleInterruptIfReady();
|
|
572
|
+
return;
|
|
573
|
+
}
|
|
301
574
|
if (resultMessage === void 0) {
|
|
302
575
|
failTerminal(
|
|
303
576
|
new CodeModeProtocolError(
|
|
@@ -307,6 +580,27 @@ function startWorkerRun({
|
|
|
307
580
|
);
|
|
308
581
|
return;
|
|
309
582
|
}
|
|
583
|
+
if (!interruptResolutionConsumed) {
|
|
584
|
+
failTerminal(
|
|
585
|
+
new CodeModeProtocolError(
|
|
586
|
+
"Code mode continuation completed without consuming its interrupt resolution.",
|
|
587
|
+
{ interruptId: interruptResolution?.interruptId }
|
|
588
|
+
)
|
|
589
|
+
);
|
|
590
|
+
return;
|
|
591
|
+
}
|
|
592
|
+
if (continuation !== void 0 && totalBridgeRequests < bridgeLedger.length) {
|
|
593
|
+
failTerminal(
|
|
594
|
+
new CodeModeProtocolError(
|
|
595
|
+
"Code mode continuation returned before replaying the full bridge ledger.",
|
|
596
|
+
{
|
|
597
|
+
replayedBridgeRequests: totalBridgeRequests,
|
|
598
|
+
ledgerEntries: bridgeLedger.length
|
|
599
|
+
}
|
|
600
|
+
)
|
|
601
|
+
);
|
|
602
|
+
return;
|
|
603
|
+
}
|
|
310
604
|
terminalReached = true;
|
|
311
605
|
const finalResultMessage = resultMessage;
|
|
312
606
|
if (inFlightBridgeRequests > 0) {
|
|
@@ -329,6 +623,92 @@ function startWorkerRun({
|
|
|
329
623
|
);
|
|
330
624
|
}
|
|
331
625
|
}
|
|
626
|
+
function assertContinuationInput({
|
|
627
|
+
js,
|
|
628
|
+
continuation,
|
|
629
|
+
interruptResolution,
|
|
630
|
+
continuationSecurity
|
|
631
|
+
}) {
|
|
632
|
+
if (continuation === void 0) {
|
|
633
|
+
if (interruptResolution !== void 0) {
|
|
634
|
+
throw new CodeModeProtocolError(
|
|
635
|
+
"A code-mode interrupt resolution was provided without continuation state."
|
|
636
|
+
);
|
|
637
|
+
}
|
|
638
|
+
return;
|
|
639
|
+
}
|
|
640
|
+
verifyCodeModeContinuation(continuation, continuationSecurity);
|
|
641
|
+
if (continuation.version !== 1) {
|
|
642
|
+
throw new CodeModeProtocolError(
|
|
643
|
+
"Unsupported code-mode continuation version."
|
|
644
|
+
);
|
|
645
|
+
}
|
|
646
|
+
if (continuation.js !== js) {
|
|
647
|
+
throw new CodeModeProtocolError(
|
|
648
|
+
"Code mode continuation source does not match the resumed source."
|
|
649
|
+
);
|
|
650
|
+
}
|
|
651
|
+
if (!Number.isInteger(continuation.determinism.dateNowMs) || !/^[0-9a-f]{32}$/i.test(continuation.determinism.randomSeed)) {
|
|
652
|
+
throw new CodeModeProtocolError(
|
|
653
|
+
"Code mode continuation determinism state is malformed."
|
|
654
|
+
);
|
|
655
|
+
}
|
|
656
|
+
for (const entry of continuation.ledger) {
|
|
657
|
+
if (entry.kind !== "tool" || typeof entry.name !== "string" || typeof entry.inputJson !== "string" || typeof entry.toolCallId !== "string") {
|
|
658
|
+
throw new CodeModeProtocolError(
|
|
659
|
+
"Code mode continuation ledger is malformed."
|
|
660
|
+
);
|
|
661
|
+
}
|
|
662
|
+
}
|
|
663
|
+
if (interruptResolution !== void 0) {
|
|
664
|
+
const matches = continuation.ledger.filter(
|
|
665
|
+
(entry) => entry.status === "interrupted" && entry.interruptId === interruptResolution.interruptId
|
|
666
|
+
);
|
|
667
|
+
if (matches.length !== 1) {
|
|
668
|
+
throw new CodeModeProtocolError(
|
|
669
|
+
"Interrupt resolution does not match exactly one pending continuation ledger entry.",
|
|
670
|
+
{
|
|
671
|
+
interruptId: interruptResolution.interruptId,
|
|
672
|
+
matches: matches.length
|
|
673
|
+
}
|
|
674
|
+
);
|
|
675
|
+
}
|
|
676
|
+
}
|
|
677
|
+
}
|
|
678
|
+
function assertReplayEntryMatches(entry, message, bridgeIndex) {
|
|
679
|
+
if (entry.name !== message.toolName || entry.inputJson !== message.inputJson) {
|
|
680
|
+
throw new CodeModeProtocolError(
|
|
681
|
+
"Code mode continuation replay diverged from its bridge ledger.",
|
|
682
|
+
{
|
|
683
|
+
bridgeIndex,
|
|
684
|
+
expectedToolName: entry.name,
|
|
685
|
+
receivedToolName: message.toolName
|
|
686
|
+
}
|
|
687
|
+
);
|
|
688
|
+
}
|
|
689
|
+
}
|
|
690
|
+
function createDeterminismState() {
|
|
691
|
+
return {
|
|
692
|
+
dateNowMs: Date.now(),
|
|
693
|
+
randomSeed: randomBytes(16).toString("hex")
|
|
694
|
+
};
|
|
695
|
+
}
|
|
696
|
+
function cloneLedger(ledger) {
|
|
697
|
+
return structuredClone(ledger);
|
|
698
|
+
}
|
|
699
|
+
function getMaxNestedToolCounter(ledger) {
|
|
700
|
+
let max = 0;
|
|
701
|
+
for (const entry of ledger) {
|
|
702
|
+
const match = /:tool-(\d+)$/u.exec(entry.toolCallId);
|
|
703
|
+
if (match !== null) {
|
|
704
|
+
max = Math.max(max, Number(match[1]));
|
|
705
|
+
}
|
|
706
|
+
}
|
|
707
|
+
return max;
|
|
708
|
+
}
|
|
709
|
+
function fromJsonPayload(valueJson) {
|
|
710
|
+
return valueJson === "" ? void 0 : JSON.parse(valueJson);
|
|
711
|
+
}
|
|
332
712
|
function acquireWorker(maxPoolSize) {
|
|
333
713
|
let pooledWorker = idleWorkers.pop();
|
|
334
714
|
while (pooledWorker?.destroyed) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/runtime/manager.ts"],"sourcesContent":["import { AsyncResource } from 'node:async_hooks';\nimport { Buffer } from 'node:buffer';\nimport { Worker } from 'node:worker_threads';\nimport {\n CodeModeAbortedError,\n CodeModeBridgeLimitError,\n CodeModeConcurrencyError,\n CodeModeDetachedBridgeRequestError,\n CodeModeProtocolError,\n CodeModeTimeoutError,\n deserializeError,\n serializeBridgeErrorForGuest,\n} from '../errors.js';\nimport { invokeHostTool } from '../tool-invocation.js';\nimport { normalizeOptions } from '../utils/options.js';\nimport { assertSourceSize, transformSource } from '../utils/source-cache.js';\nimport type {\n CodeModeToolExecutionOptions,\n NormalizedCodeModeOptions,\n RunCodeModeInput,\n} from '../types.js';\nimport { getMaxWorkers } from './max-workers.js';\nimport type {\n MainToWorkerMessage,\n WorkerBridgeResponse,\n WorkerReadyMessage,\n WorkerResultMessage,\n WorkerToolRequest,\n WorkerToMainMessage,\n} from './protocol.js';\nimport { INLINE_CODE_MODE_WORKER_SOURCE } from './worker-source.js';\n\ninterface PooledWorker {\n worker: Worker;\n destroyed: boolean;\n}\n\ninterface ManagedWorkerRun {\n result: Promise<unknown>;\n}\n\nlet invocationCounter = 0;\nlet activeInvocations = 0;\nlet inlineWorkerUrl: URL | undefined;\nconst idleWorkers: PooledWorker[] = [];\n\nexport async function runManagedCodeMode(\n input: RunCodeModeInput,\n): Promise<unknown> {\n const normalizedOptions = normalizeOptions(input.options);\n const maxWorkers = getMaxWorkers({\n memoryLimitBytes: normalizedOptions.memoryLimitBytes,\n activeWorkers: activeInvocations,\n });\n if (activeInvocations >= maxWorkers) {\n throw new CodeModeConcurrencyError(maxWorkers);\n }\n\n activeInvocations++;\n try {\n if (input.toolExecutionOptions?.abortSignal?.aborted) {\n throw new CodeModeAbortedError();\n }\n\n assertSourceSize(input.js, normalizedOptions.maxSourceBytes);\n const run = startWorkerRun({\n ...input,\n js: transformSource(input.js),\n normalizedOptions,\n maxWorkers,\n });\n return await run.result;\n } finally {\n releaseInvocationSlot(normalizedOptions.memoryLimitBytes);\n }\n}\n\nfunction startWorkerRun({\n js,\n tools,\n toolExecutionOptions,\n normalizedOptions,\n maxWorkers,\n}: RunCodeModeInput & {\n normalizedOptions: NormalizedCodeModeOptions;\n maxWorkers: number;\n}): ManagedWorkerRun {\n const invocationId = `code-mode-${++invocationCounter}`;\n const pooledWorker = acquireWorker(maxWorkers);\n const worker = pooledWorker.worker;\n const invocationContext = new AsyncResource('ai-sdk-code-mode:invocation');\n const bindInvocationContext = <Args extends unknown[]>(\n handler: (...args: Args) => void,\n ): ((...args: Args) => void) => {\n return (...args: Args): void => {\n invocationContext.runInAsyncScope(handler, undefined, ...args);\n };\n };\n\n const outerAbortSignal = toolExecutionOptions?.abortSignal;\n const invocationAbortController = new AbortController();\n const forwardedContext =\n toolExecutionOptions?.context ?? toolExecutionOptions?.experimental_context;\n const forwardedExperimentalContext =\n toolExecutionOptions?.experimental_context ?? toolExecutionOptions?.context;\n const baseExecutionOptions: CodeModeToolExecutionOptions = {\n toolCallId: toolExecutionOptions?.toolCallId ?? invocationId,\n messages: toolExecutionOptions?.messages ?? [],\n abortSignal: invocationAbortController.signal,\n ...(forwardedExperimentalContext !== undefined\n ? { experimental_context: forwardedExperimentalContext }\n : {}),\n ...(forwardedContext !== undefined ? { context: forwardedContext } : {}),\n };\n\n let resultMessage: WorkerResultMessage | undefined;\n let callerSettled = false;\n let terminalReached = false;\n let workerCleanedUp = false;\n let totalBridgeRequests = 0;\n let inFlightBridgeRequests = 0;\n const seenWorkerRequestIds = new Set<string>();\n\n let resolveResult!: (value: unknown) => void;\n let rejectResult!: (reason?: unknown) => void;\n const result = new Promise<unknown>((resolve, reject) => {\n resolveResult = resolve;\n rejectResult = reject;\n });\n\n const abortInvocation = (reason: unknown) => {\n if (!invocationAbortController.signal.aborted) {\n invocationAbortController.abort(reason);\n }\n };\n\n const cleanupWorker = (reuseWorker: boolean) => {\n if (workerCleanedUp) {\n return;\n }\n workerCleanedUp = true;\n clearTimeout(timeoutHandle);\n outerAbortSignal?.removeEventListener('abort', onAbort);\n worker.off('message', onMessage);\n worker.off('error', onError);\n worker.off('exit', onExit);\n invocationContext.emitDestroy();\n if (reuseWorker) {\n releaseWorker(pooledWorker);\n } else {\n destroyWorker(pooledWorker);\n }\n };\n\n const settleCaller = (settle: () => void) => {\n if (callerSettled) {\n return;\n }\n callerSettled = true;\n try {\n settle();\n } catch (error) {\n rejectResult(error);\n }\n };\n\n const failTerminal = (error: unknown) => {\n if (terminalReached) {\n return;\n }\n terminalReached = true;\n abortInvocation(error);\n cleanupWorker(false);\n settleCaller(() => rejectResult(error));\n };\n\n const onAbort = bindInvocationContext(() => {\n failTerminal(new CodeModeAbortedError());\n });\n\n const timeoutHandle = setTimeout(\n bindInvocationContext(() => {\n failTerminal(new CodeModeTimeoutError(normalizedOptions.timeoutMs));\n }),\n normalizedOptions.timeoutMs,\n );\n\n const onMessage = bindInvocationContext((message: WorkerToMainMessage) => {\n if (message.invocationId !== invocationId) {\n failTerminal(\n new CodeModeProtocolError(\n `Worker message invocationId mismatch: expected ${invocationId}, received ${message.invocationId}.`,\n {\n expectedInvocationId: invocationId,\n receivedInvocationId: message.invocationId,\n messageType: message.type,\n },\n ),\n );\n return;\n }\n\n if (message.type === 'result') {\n if (resultMessage !== undefined) {\n failTerminal(\n new CodeModeProtocolError(\n `Worker sent duplicate result for invocation ${invocationId}.`,\n { invocationId },\n ),\n );\n return;\n }\n resultMessage = message;\n return;\n }\n\n if (message.type === 'ready') {\n handleReadyMessage(message);\n return;\n }\n\n const bridgeIndex = markWorkerRequest(message);\n if (bridgeIndex !== undefined) {\n void handleToolRequest(message, bridgeIndex);\n }\n });\n\n const onError = bindInvocationContext((error: Error) => {\n failTerminal(error);\n });\n\n const onExit = bindInvocationContext((code: number) => {\n if (!terminalReached) {\n failTerminal(\n new Error(\n `Code mode worker exited before completion with code ${code}.`,\n ),\n );\n }\n });\n\n worker.on('message', onMessage);\n worker.on('error', onError);\n worker.on('exit', onExit);\n outerAbortSignal?.addEventListener('abort', onAbort, { once: true });\n if (outerAbortSignal?.aborted) {\n onAbort();\n }\n\n const runMessage: MainToWorkerMessage = {\n type: 'run',\n invocationId,\n js,\n options: {\n timeoutMs: normalizedOptions.timeoutMs,\n memoryLimitBytes: normalizedOptions.memoryLimitBytes,\n maxStackSizeBytes: normalizedOptions.maxStackSizeBytes,\n maxResultBytes: normalizedOptions.maxResultBytes,\n maxConsoleOutputBytes: normalizedOptions.maxConsoleOutputBytes,\n },\n };\n\n if (!terminalReached) {\n try {\n // eslint-disable-next-line unicorn/require-post-message-target-origin -- Node.js Worker has no targetOrigin parameter.\n worker.postMessage(runMessage);\n } catch (error) {\n failTerminal(error);\n }\n }\n\n return { result };\n\n function markWorkerRequest(message: WorkerToolRequest): number | undefined {\n if (terminalReached) {\n return undefined;\n }\n if (seenWorkerRequestIds.has(message.requestId)) {\n failTerminal(\n new CodeModeProtocolError(\n `Worker sent duplicate requestId ${message.requestId}.`,\n { invocationId, requestId: message.requestId },\n ),\n );\n return undefined;\n }\n seenWorkerRequestIds.add(message.requestId);\n\n if (totalBridgeRequests >= normalizedOptions.maxBridgeRequests) {\n failTerminal(\n new CodeModeBridgeLimitError(\n `Code mode exceeded the ${normalizedOptions.maxBridgeRequests} bridge request limit.`,\n {\n invocationId,\n maxBridgeRequests: normalizedOptions.maxBridgeRequests,\n },\n ),\n );\n return undefined;\n }\n if (inFlightBridgeRequests >= normalizedOptions.maxInFlightBridgeRequests) {\n failTerminal(\n new CodeModeBridgeLimitError(\n `Code mode exceeded the ${normalizedOptions.maxInFlightBridgeRequests} in-flight bridge request limit.`,\n {\n invocationId,\n maxInFlightBridgeRequests:\n normalizedOptions.maxInFlightBridgeRequests,\n },\n ),\n );\n return undefined;\n }\n\n totalBridgeRequests++;\n inFlightBridgeRequests++;\n return totalBridgeRequests;\n }\n\n async function handleToolRequest(\n message: WorkerToolRequest,\n bridgeIndex: number,\n ): Promise<void> {\n try {\n const valueJson = await invokeHostTool({\n toolName: message.toolName,\n inputJson: message.inputJson,\n tools,\n baseExecutionOptions,\n maxToolInputBytes: normalizedOptions.maxToolInputBytes,\n maxToolOutputBytes: normalizedOptions.maxToolOutputBytes,\n toolCallId: `${baseExecutionOptions.toolCallId}:tool-${bridgeIndex}`,\n });\n postBridgeResponse({\n type: 'bridge-response',\n invocationId,\n requestId: message.requestId,\n success: true,\n valueJson,\n });\n } catch (error) {\n postBridgeResponse({\n type: 'bridge-response',\n invocationId,\n requestId: message.requestId,\n success: false,\n error: serializeBridgeErrorForGuest(error, 'tool'),\n });\n } finally {\n inFlightBridgeRequests--;\n }\n }\n\n function postBridgeResponse(message: WorkerBridgeResponse): void {\n if (terminalReached) {\n return;\n }\n try {\n // eslint-disable-next-line unicorn/require-post-message-target-origin -- Node.js Worker has no targetOrigin parameter.\n worker.postMessage(message);\n } catch (error) {\n failTerminal(error);\n }\n }\n\n function handleReadyMessage(message: WorkerReadyMessage): void {\n if (terminalReached) {\n return;\n }\n if (resultMessage === undefined) {\n failTerminal(\n new CodeModeProtocolError(\n `Code mode worker became ready without a result for ${message.invocationId}.`,\n { invocationId: message.invocationId },\n ),\n );\n return;\n }\n\n terminalReached = true;\n const finalResultMessage = resultMessage;\n if (inFlightBridgeRequests > 0) {\n const error = finalResultMessage.success\n ? new CodeModeDetachedBridgeRequestError(\n `Code mode returned while ${inFlightBridgeRequests} bridge request(s) were still in flight.`,\n {\n invocationId,\n inFlightBridgeRequests,\n totalBridgeRequests,\n },\n )\n : deserializeResultError(finalResultMessage);\n abortInvocation(error);\n cleanupWorker(false);\n settleCaller(() => rejectResult(error));\n return;\n }\n\n cleanupWorker(true);\n settleCaller(() =>\n settleWithResultMessage(finalResultMessage, resolveResult, rejectResult),\n );\n }\n}\n\nfunction acquireWorker(maxPoolSize: number): PooledWorker {\n let pooledWorker = idleWorkers.pop();\n while (pooledWorker?.destroyed) {\n pooledWorker = idleWorkers.pop();\n }\n pooledWorker ??= createWorker();\n pooledWorker.worker.removeAllListeners('exit');\n pooledWorker.worker.ref();\n trimIdleWorkers(Math.max(0, maxPoolSize - activeInvocations));\n return pooledWorker;\n}\n\nfunction createWorker(): PooledWorker {\n return {\n worker: new Worker(getInlineWorkerUrl(), { execArgv: [] }),\n destroyed: false,\n };\n}\n\nfunction getInlineWorkerUrl(): URL {\n inlineWorkerUrl ??= new URL(\n `data:text/javascript;base64,${Buffer.from(INLINE_CODE_MODE_WORKER_SOURCE).toString('base64')}`,\n );\n return inlineWorkerUrl;\n}\n\nfunction releaseWorker(pooledWorker: PooledWorker): void {\n if (pooledWorker.destroyed) {\n return;\n }\n pooledWorker.worker.once('exit', () => {\n pooledWorker.destroyed = true;\n const index = idleWorkers.indexOf(pooledWorker);\n if (index !== -1) {\n idleWorkers.splice(index, 1);\n }\n });\n pooledWorker.worker.unref();\n idleWorkers.push(pooledWorker);\n}\n\nfunction destroyWorker(pooledWorker: PooledWorker): void {\n if (pooledWorker.destroyed) {\n return;\n }\n pooledWorker.destroyed = true;\n pooledWorker.worker.removeAllListeners();\n void pooledWorker.worker.terminate();\n}\n\nfunction trimIdleWorkers(maxIdleWorkers: number): void {\n while (idleWorkers.length > maxIdleWorkers) {\n const pooledWorker = idleWorkers.pop();\n if (pooledWorker !== undefined) {\n destroyWorker(pooledWorker);\n }\n }\n}\n\nfunction releaseInvocationSlot(memoryLimitBytes: number): void {\n activeInvocations = Math.max(0, activeInvocations - 1);\n const maxWorkers = getMaxWorkers({\n memoryLimitBytes,\n activeWorkers: activeInvocations,\n });\n trimIdleWorkers(Math.max(0, maxWorkers - activeInvocations));\n}\n\nfunction settleWithResultMessage(\n message: WorkerResultMessage,\n resolve: (value: unknown) => void,\n reject: (reason?: unknown) => void,\n): void {\n if (!message.success) {\n reject(deserializeResultError(message));\n return;\n }\n resolve(\n message.valueJson === '' || message.valueJson === undefined\n ? undefined\n : JSON.parse(message.valueJson),\n );\n}\n\nfunction deserializeResultError(message: WorkerResultMessage): Error {\n if (message.error === undefined) {\n return new CodeModeProtocolError(\n `Code mode worker failed without an error for ${message.invocationId}.`,\n { invocationId: message.invocationId },\n );\n }\n return deserializeError(message.error);\n}\n"],"mappings":"AAAA,SAAS,qBAAqB;AAC9B,SAAS,cAAc;AACvB,SAAS,cAAc;AACvB;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,sBAAsB;AAC/B,SAAS,wBAAwB;AACjC,SAAS,kBAAkB,uBAAuB;AAMlD,SAAS,qBAAqB;AAS9B,SAAS,sCAAsC;AAW/C,IAAI,oBAAoB;AACxB,IAAI,oBAAoB;AACxB,IAAI;AACJ,MAAM,cAA8B,CAAC;AAErC,eAAsB,mBACpB,OACkB;AAClB,QAAM,oBAAoB,iBAAiB,MAAM,OAAO;AACxD,QAAM,aAAa,cAAc;AAAA,IAC/B,kBAAkB,kBAAkB;AAAA,IACpC,eAAe;AAAA,EACjB,CAAC;AACD,MAAI,qBAAqB,YAAY;AACnC,UAAM,IAAI,yBAAyB,UAAU;AAAA,EAC/C;AAEA;AACA,MAAI;AACF,QAAI,MAAM,sBAAsB,aAAa,SAAS;AACpD,YAAM,IAAI,qBAAqB;AAAA,IACjC;AAEA,qBAAiB,MAAM,IAAI,kBAAkB,cAAc;AAC3D,UAAM,MAAM,eAAe;AAAA,MACzB,GAAG;AAAA,MACH,IAAI,gBAAgB,MAAM,EAAE;AAAA,MAC5B;AAAA,MACA;AAAA,IACF,CAAC;AACD,WAAO,MAAM,IAAI;AAAA,EACnB,UAAE;AACA,0BAAsB,kBAAkB,gBAAgB;AAAA,EAC1D;AACF;AAEA,SAAS,eAAe;AAAA,EACtB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAGqB;AACnB,QAAM,eAAe,aAAa,EAAE,iBAAiB;AACrD,QAAM,eAAe,cAAc,UAAU;AAC7C,QAAM,SAAS,aAAa;AAC5B,QAAM,oBAAoB,IAAI,cAAc,6BAA6B;AACzE,QAAM,wBAAwB,CAC5B,YAC8B;AAC9B,WAAO,IAAI,SAAqB;AAC9B,wBAAkB,gBAAgB,SAAS,QAAW,GAAG,IAAI;AAAA,IAC/D;AAAA,EACF;AAEA,QAAM,mBAAmB,sBAAsB;AAC/C,QAAM,4BAA4B,IAAI,gBAAgB;AACtD,QAAM,mBACJ,sBAAsB,WAAW,sBAAsB;AACzD,QAAM,+BACJ,sBAAsB,wBAAwB,sBAAsB;AACtE,QAAM,uBAAqD;AAAA,IACzD,YAAY,sBAAsB,cAAc;AAAA,IAChD,UAAU,sBAAsB,YAAY,CAAC;AAAA,IAC7C,aAAa,0BAA0B;AAAA,IACvC,GAAI,iCAAiC,SACjC,EAAE,sBAAsB,6BAA6B,IACrD,CAAC;AAAA,IACL,GAAI,qBAAqB,SAAY,EAAE,SAAS,iBAAiB,IAAI,CAAC;AAAA,EACxE;AAEA,MAAI;AACJ,MAAI,gBAAgB;AACpB,MAAI,kBAAkB;AACtB,MAAI,kBAAkB;AACtB,MAAI,sBAAsB;AAC1B,MAAI,yBAAyB;AAC7B,QAAM,uBAAuB,oBAAI,IAAY;AAE7C,MAAI;AACJ,MAAI;AACJ,QAAM,SAAS,IAAI,QAAiB,CAAC,SAAS,WAAW;AACvD,oBAAgB;AAChB,mBAAe;AAAA,EACjB,CAAC;AAED,QAAM,kBAAkB,CAAC,WAAoB;AAC3C,QAAI,CAAC,0BAA0B,OAAO,SAAS;AAC7C,gCAA0B,MAAM,MAAM;AAAA,IACxC;AAAA,EACF;AAEA,QAAM,gBAAgB,CAAC,gBAAyB;AAC9C,QAAI,iBAAiB;AACnB;AAAA,IACF;AACA,sBAAkB;AAClB,iBAAa,aAAa;AAC1B,sBAAkB,oBAAoB,SAAS,OAAO;AACtD,WAAO,IAAI,WAAW,SAAS;AAC/B,WAAO,IAAI,SAAS,OAAO;AAC3B,WAAO,IAAI,QAAQ,MAAM;AACzB,sBAAkB,YAAY;AAC9B,QAAI,aAAa;AACf,oBAAc,YAAY;AAAA,IAC5B,OAAO;AACL,oBAAc,YAAY;AAAA,IAC5B;AAAA,EACF;AAEA,QAAM,eAAe,CAAC,WAAuB;AAC3C,QAAI,eAAe;AACjB;AAAA,IACF;AACA,oBAAgB;AAChB,QAAI;AACF,aAAO;AAAA,IACT,SAAS,OAAO;AACd,mBAAa,KAAK;AAAA,IACpB;AAAA,EACF;AAEA,QAAM,eAAe,CAAC,UAAmB;AACvC,QAAI,iBAAiB;AACnB;AAAA,IACF;AACA,sBAAkB;AAClB,oBAAgB,KAAK;AACrB,kBAAc,KAAK;AACnB,iBAAa,MAAM,aAAa,KAAK,CAAC;AAAA,EACxC;AAEA,QAAM,UAAU,sBAAsB,MAAM;AAC1C,iBAAa,IAAI,qBAAqB,CAAC;AAAA,EACzC,CAAC;AAED,QAAM,gBAAgB;AAAA,IACpB,sBAAsB,MAAM;AAC1B,mBAAa,IAAI,qBAAqB,kBAAkB,SAAS,CAAC;AAAA,IACpE,CAAC;AAAA,IACD,kBAAkB;AAAA,EACpB;AAEA,QAAM,YAAY,sBAAsB,CAAC,YAAiC;AACxE,QAAI,QAAQ,iBAAiB,cAAc;AACzC;AAAA,QACE,IAAI;AAAA,UACF,kDAAkD,YAAY,cAAc,QAAQ,YAAY;AAAA,UAChG;AAAA,YACE,sBAAsB;AAAA,YACtB,sBAAsB,QAAQ;AAAA,YAC9B,aAAa,QAAQ;AAAA,UACvB;AAAA,QACF;AAAA,MACF;AACA;AAAA,IACF;AAEA,QAAI,QAAQ,SAAS,UAAU;AAC7B,UAAI,kBAAkB,QAAW;AAC/B;AAAA,UACE,IAAI;AAAA,YACF,+CAA+C,YAAY;AAAA,YAC3D,EAAE,aAAa;AAAA,UACjB;AAAA,QACF;AACA;AAAA,MACF;AACA,sBAAgB;AAChB;AAAA,IACF;AAEA,QAAI,QAAQ,SAAS,SAAS;AAC5B,yBAAmB,OAAO;AAC1B;AAAA,IACF;AAEA,UAAM,cAAc,kBAAkB,OAAO;AAC7C,QAAI,gBAAgB,QAAW;AAC7B,WAAK,kBAAkB,SAAS,WAAW;AAAA,IAC7C;AAAA,EACF,CAAC;AAED,QAAM,UAAU,sBAAsB,CAAC,UAAiB;AACtD,iBAAa,KAAK;AAAA,EACpB,CAAC;AAED,QAAM,SAAS,sBAAsB,CAAC,SAAiB;AACrD,QAAI,CAAC,iBAAiB;AACpB;AAAA,QACE,IAAI;AAAA,UACF,uDAAuD,IAAI;AAAA,QAC7D;AAAA,MACF;AAAA,IACF;AAAA,EACF,CAAC;AAED,SAAO,GAAG,WAAW,SAAS;AAC9B,SAAO,GAAG,SAAS,OAAO;AAC1B,SAAO,GAAG,QAAQ,MAAM;AACxB,oBAAkB,iBAAiB,SAAS,SAAS,EAAE,MAAM,KAAK,CAAC;AACnE,MAAI,kBAAkB,SAAS;AAC7B,YAAQ;AAAA,EACV;AAEA,QAAM,aAAkC;AAAA,IACtC,MAAM;AAAA,IACN;AAAA,IACA;AAAA,IACA,SAAS;AAAA,MACP,WAAW,kBAAkB;AAAA,MAC7B,kBAAkB,kBAAkB;AAAA,MACpC,mBAAmB,kBAAkB;AAAA,MACrC,gBAAgB,kBAAkB;AAAA,MAClC,uBAAuB,kBAAkB;AAAA,IAC3C;AAAA,EACF;AAEA,MAAI,CAAC,iBAAiB;AACpB,QAAI;AAEF,aAAO,YAAY,UAAU;AAAA,IAC/B,SAAS,OAAO;AACd,mBAAa,KAAK;AAAA,IACpB;AAAA,EACF;AAEA,SAAO,EAAE,OAAO;AAEhB,WAAS,kBAAkB,SAAgD;AACzE,QAAI,iBAAiB;AACnB,aAAO;AAAA,IACT;AACA,QAAI,qBAAqB,IAAI,QAAQ,SAAS,GAAG;AAC/C;AAAA,QACE,IAAI;AAAA,UACF,mCAAmC,QAAQ,SAAS;AAAA,UACpD,EAAE,cAAc,WAAW,QAAQ,UAAU;AAAA,QAC/C;AAAA,MACF;AACA,aAAO;AAAA,IACT;AACA,yBAAqB,IAAI,QAAQ,SAAS;AAE1C,QAAI,uBAAuB,kBAAkB,mBAAmB;AAC9D;AAAA,QACE,IAAI;AAAA,UACF,0BAA0B,kBAAkB,iBAAiB;AAAA,UAC7D;AAAA,YACE;AAAA,YACA,mBAAmB,kBAAkB;AAAA,UACvC;AAAA,QACF;AAAA,MACF;AACA,aAAO;AAAA,IACT;AACA,QAAI,0BAA0B,kBAAkB,2BAA2B;AACzE;AAAA,QACE,IAAI;AAAA,UACF,0BAA0B,kBAAkB,yBAAyB;AAAA,UACrE;AAAA,YACE;AAAA,YACA,2BACE,kBAAkB;AAAA,UACtB;AAAA,QACF;AAAA,MACF;AACA,aAAO;AAAA,IACT;AAEA;AACA;AACA,WAAO;AAAA,EACT;AAEA,iBAAe,kBACb,SACA,aACe;AACf,QAAI;AACF,YAAM,YAAY,MAAM,eAAe;AAAA,QACrC,UAAU,QAAQ;AAAA,QAClB,WAAW,QAAQ;AAAA,QACnB;AAAA,QACA;AAAA,QACA,mBAAmB,kBAAkB;AAAA,QACrC,oBAAoB,kBAAkB;AAAA,QACtC,YAAY,GAAG,qBAAqB,UAAU,SAAS,WAAW;AAAA,MACpE,CAAC;AACD,yBAAmB;AAAA,QACjB,MAAM;AAAA,QACN;AAAA,QACA,WAAW,QAAQ;AAAA,QACnB,SAAS;AAAA,QACT;AAAA,MACF,CAAC;AAAA,IACH,SAAS,OAAO;AACd,yBAAmB;AAAA,QACjB,MAAM;AAAA,QACN;AAAA,QACA,WAAW,QAAQ;AAAA,QACnB,SAAS;AAAA,QACT,OAAO,6BAA6B,OAAO,MAAM;AAAA,MACnD,CAAC;AAAA,IACH,UAAE;AACA;AAAA,IACF;AAAA,EACF;AAEA,WAAS,mBAAmB,SAAqC;AAC/D,QAAI,iBAAiB;AACnB;AAAA,IACF;AACA,QAAI;AAEF,aAAO,YAAY,OAAO;AAAA,IAC5B,SAAS,OAAO;AACd,mBAAa,KAAK;AAAA,IACpB;AAAA,EACF;AAEA,WAAS,mBAAmB,SAAmC;AAC7D,QAAI,iBAAiB;AACnB;AAAA,IACF;AACA,QAAI,kBAAkB,QAAW;AAC/B;AAAA,QACE,IAAI;AAAA,UACF,sDAAsD,QAAQ,YAAY;AAAA,UAC1E,EAAE,cAAc,QAAQ,aAAa;AAAA,QACvC;AAAA,MACF;AACA;AAAA,IACF;AAEA,sBAAkB;AAClB,UAAM,qBAAqB;AAC3B,QAAI,yBAAyB,GAAG;AAC9B,YAAM,QAAQ,mBAAmB,UAC7B,IAAI;AAAA,QACF,4BAA4B,sBAAsB;AAAA,QAClD;AAAA,UACE;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,MACF,IACA,uBAAuB,kBAAkB;AAC7C,sBAAgB,KAAK;AACrB,oBAAc,KAAK;AACnB,mBAAa,MAAM,aAAa,KAAK,CAAC;AACtC;AAAA,IACF;AAEA,kBAAc,IAAI;AAClB;AAAA,MAAa,MACX,wBAAwB,oBAAoB,eAAe,YAAY;AAAA,IACzE;AAAA,EACF;AACF;AAEA,SAAS,cAAc,aAAmC;AACxD,MAAI,eAAe,YAAY,IAAI;AACnC,SAAO,cAAc,WAAW;AAC9B,mBAAe,YAAY,IAAI;AAAA,EACjC;AACA,mBAAiB,aAAa;AAC9B,eAAa,OAAO,mBAAmB,MAAM;AAC7C,eAAa,OAAO,IAAI;AACxB,kBAAgB,KAAK,IAAI,GAAG,cAAc,iBAAiB,CAAC;AAC5D,SAAO;AACT;AAEA,SAAS,eAA6B;AACpC,SAAO;AAAA,IACL,QAAQ,IAAI,OAAO,mBAAmB,GAAG,EAAE,UAAU,CAAC,EAAE,CAAC;AAAA,IACzD,WAAW;AAAA,EACb;AACF;AAEA,SAAS,qBAA0B;AACjC,sBAAoB,IAAI;AAAA,IACtB,+BAA+B,OAAO,KAAK,8BAA8B,EAAE,SAAS,QAAQ,CAAC;AAAA,EAC/F;AACA,SAAO;AACT;AAEA,SAAS,cAAc,cAAkC;AACvD,MAAI,aAAa,WAAW;AAC1B;AAAA,EACF;AACA,eAAa,OAAO,KAAK,QAAQ,MAAM;AACrC,iBAAa,YAAY;AACzB,UAAM,QAAQ,YAAY,QAAQ,YAAY;AAC9C,QAAI,UAAU,IAAI;AAChB,kBAAY,OAAO,OAAO,CAAC;AAAA,IAC7B;AAAA,EACF,CAAC;AACD,eAAa,OAAO,MAAM;AAC1B,cAAY,KAAK,YAAY;AAC/B;AAEA,SAAS,cAAc,cAAkC;AACvD,MAAI,aAAa,WAAW;AAC1B;AAAA,EACF;AACA,eAAa,YAAY;AACzB,eAAa,OAAO,mBAAmB;AACvC,OAAK,aAAa,OAAO,UAAU;AACrC;AAEA,SAAS,gBAAgB,gBAA8B;AACrD,SAAO,YAAY,SAAS,gBAAgB;AAC1C,UAAM,eAAe,YAAY,IAAI;AACrC,QAAI,iBAAiB,QAAW;AAC9B,oBAAc,YAAY;AAAA,IAC5B;AAAA,EACF;AACF;AAEA,SAAS,sBAAsB,kBAAgC;AAC7D,sBAAoB,KAAK,IAAI,GAAG,oBAAoB,CAAC;AACrD,QAAM,aAAa,cAAc;AAAA,IAC/B;AAAA,IACA,eAAe;AAAA,EACjB,CAAC;AACD,kBAAgB,KAAK,IAAI,GAAG,aAAa,iBAAiB,CAAC;AAC7D;AAEA,SAAS,wBACP,SACA,SACA,QACM;AACN,MAAI,CAAC,QAAQ,SAAS;AACpB,WAAO,uBAAuB,OAAO,CAAC;AACtC;AAAA,EACF;AACA;AAAA,IACE,QAAQ,cAAc,MAAM,QAAQ,cAAc,SAC9C,SACA,KAAK,MAAM,QAAQ,SAAS;AAAA,EAClC;AACF;AAEA,SAAS,uBAAuB,SAAqC;AACnE,MAAI,QAAQ,UAAU,QAAW;AAC/B,WAAO,IAAI;AAAA,MACT,gDAAgD,QAAQ,YAAY;AAAA,MACpE,EAAE,cAAc,QAAQ,aAAa;AAAA,IACvC;AAAA,EACF;AACA,SAAO,iBAAiB,QAAQ,KAAK;AACvC;","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../src/runtime/manager.ts"],"sourcesContent":["import { AsyncResource } from 'node:async_hooks';\nimport { Buffer } from 'node:buffer';\nimport { randomBytes } from 'node:crypto';\nimport { Worker } from 'node:worker_threads';\nimport {\n isCodeModeApprovalInterruptPayload,\n normalizeApprovalResolution,\n} from '../approval.js';\nimport {\n resolveCodeModeContinuationSecurity,\n signCodeModeContinuation,\n verifyCodeModeContinuation,\n type ResolvedCodeModeContinuationSecurity,\n} from '../continuation-capability.js';\nimport {\n CodeModeAbortedError,\n CodeModeBridgeLimitError,\n CodeModeConcurrencyError,\n CodeModeDetachedBridgeRequestError,\n CodeModeProtocolError,\n CodeModeTimeoutError,\n CodeModeToolApprovalDeniedError,\n deserializeError,\n serializeBridgeErrorForGuest,\n} from '../errors.js';\nimport { invokeHostTool } from '../tool-invocation.js';\nimport { normalizeOptions } from '../utils/options.js';\nimport { assertSourceSize, transformSource } from '../utils/source-cache.js';\nimport type {\n CodeModeContinuationLedgerEntry,\n CodeModeInterrupt,\n CodeModeInterruptExecutionContext,\n CodeModeToolExecutionOptions,\n NormalizedCodeModeOptions,\n RunCodeModeInput,\n} from '../types.js';\nimport { getMaxWorkers } from './max-workers.js';\nimport type {\n MainToWorkerMessage,\n WorkerReadyMessage,\n WorkerResultMessage,\n WorkerToolRequest,\n WorkerToMainMessage,\n} from './protocol.js';\nimport { INLINE_CODE_MODE_WORKER_SOURCE } from './worker-source.js';\n\ninterface PooledWorker {\n worker: Worker;\n destroyed: boolean;\n}\n\ninterface ManagedWorkerRun {\n result: Promise<unknown>;\n}\n\nlet invocationCounter = 0;\nlet activeInvocations = 0;\nlet inlineWorkerUrl: URL | undefined;\nconst idleWorkers: PooledWorker[] = [];\n\nexport async function runManagedCodeMode(\n input: RunCodeModeInput,\n): Promise<unknown> {\n const normalizedOptions = normalizeOptions(input.options);\n const continuationSecurity = resolveCodeModeContinuationSecurity(\n input.options?.continuationSecurity,\n );\n const maxWorkers = getMaxWorkers({\n memoryLimitBytes: normalizedOptions.memoryLimitBytes,\n activeWorkers: activeInvocations,\n });\n if (activeInvocations >= maxWorkers) {\n throw new CodeModeConcurrencyError(maxWorkers);\n }\n\n activeInvocations++;\n try {\n if (input.toolExecutionOptions?.abortSignal?.aborted) {\n throw new CodeModeAbortedError();\n }\n\n assertSourceSize(input.js, normalizedOptions.maxSourceBytes);\n const js = transformSource(input.js);\n assertContinuationInput({\n js,\n continuation: input.continuation,\n interruptResolution: input.interruptResolution,\n continuationSecurity,\n });\n const run = startWorkerRun({\n ...input,\n js,\n normalizedOptions,\n maxWorkers,\n continuationSecurity,\n });\n return await run.result;\n } finally {\n releaseInvocationSlot(normalizedOptions.memoryLimitBytes);\n }\n}\n\nfunction startWorkerRun({\n js,\n tools,\n toolExecutionOptions,\n options,\n continuation,\n interruptResolution,\n normalizedOptions,\n maxWorkers,\n continuationSecurity,\n}: RunCodeModeInput & {\n normalizedOptions: NormalizedCodeModeOptions;\n maxWorkers: number;\n continuationSecurity: ResolvedCodeModeContinuationSecurity;\n}): ManagedWorkerRun {\n const invocationId = `code-mode-${++invocationCounter}`;\n const pooledWorker = acquireWorker(maxWorkers);\n const worker = pooledWorker.worker;\n const invocationContext = new AsyncResource('ai-sdk-code-mode:invocation');\n const bindInvocationContext = <Args extends unknown[]>(\n handler: (...args: Args) => void,\n ): ((...args: Args) => void) => {\n return (...args: Args): void => {\n invocationContext.runInAsyncScope(handler, undefined, ...args);\n };\n };\n\n const outerAbortSignal = toolExecutionOptions?.abortSignal;\n const invocationAbortController = new AbortController();\n let nestedToolCounter = getMaxNestedToolCounter(continuation?.ledger ?? []);\n const forwardedContext =\n toolExecutionOptions?.context ?? toolExecutionOptions?.experimental_context;\n const forwardedExperimentalContext =\n toolExecutionOptions?.experimental_context ?? toolExecutionOptions?.context;\n const baseExecutionOptions: CodeModeToolExecutionOptions = {\n toolCallId:\n toolExecutionOptions?.toolCallId ??\n continuation?.outerToolCallId ??\n invocationId,\n messages: toolExecutionOptions?.messages ?? [],\n abortSignal: invocationAbortController.signal,\n ...(forwardedExperimentalContext !== undefined\n ? { experimental_context: forwardedExperimentalContext }\n : {}),\n ...(forwardedContext !== undefined ? { context: forwardedContext } : {}),\n };\n\n let resultMessage: WorkerResultMessage | undefined;\n let callerSettled = false;\n let terminalReached = false;\n let workerCleanedUp = false;\n let totalBridgeRequests = 0;\n let inFlightBridgeRequests = 0;\n let interruptEntryIndex: number | undefined;\n let interruptDrainCounter = 0;\n let pendingInterruptDrainId: string | undefined;\n let interruptResolutionConsumed = interruptResolution === undefined;\n const seenWorkerRequestIds = new Set<string>();\n const bridgeLedger = cloneLedger(continuation?.ledger ?? []);\n const determinism = continuation?.determinism ?? createDeterminismState();\n\n let resolveResult!: (value: unknown) => void;\n let rejectResult!: (reason?: unknown) => void;\n const result = new Promise<unknown>((resolve, reject) => {\n resolveResult = resolve;\n rejectResult = reject;\n });\n\n const abortInvocation = (reason: unknown) => {\n if (!invocationAbortController.signal.aborted) {\n invocationAbortController.abort(reason);\n }\n };\n\n const cleanupWorker = (reuseWorker: boolean) => {\n if (workerCleanedUp) {\n return;\n }\n workerCleanedUp = true;\n clearTimeout(timeoutHandle);\n outerAbortSignal?.removeEventListener('abort', onAbort);\n worker.off('message', onMessage);\n worker.off('error', onError);\n worker.off('exit', onExit);\n invocationContext.emitDestroy();\n if (reuseWorker) {\n releaseWorker(pooledWorker);\n } else {\n destroyWorker(pooledWorker);\n }\n };\n\n const settleCaller = (settle: () => void) => {\n if (callerSettled) {\n return;\n }\n callerSettled = true;\n try {\n settle();\n } catch (error) {\n rejectResult(error);\n }\n };\n\n const failTerminal = (error: unknown) => {\n if (terminalReached) {\n return;\n }\n terminalReached = true;\n abortInvocation(error);\n cleanupWorker(false);\n settleCaller(() => rejectResult(error));\n };\n\n const onAbort = bindInvocationContext(() => {\n failTerminal(new CodeModeAbortedError());\n });\n\n const timeoutHandle = setTimeout(\n bindInvocationContext(() => {\n failTerminal(new CodeModeTimeoutError(normalizedOptions.timeoutMs));\n }),\n normalizedOptions.timeoutMs,\n );\n\n const onMessage = bindInvocationContext((message: WorkerToMainMessage) => {\n if (message.invocationId !== invocationId) {\n failTerminal(\n new CodeModeProtocolError(\n `Worker message invocationId mismatch: expected ${invocationId}, received ${message.invocationId}.`,\n {\n expectedInvocationId: invocationId,\n receivedInvocationId: message.invocationId,\n messageType: message.type,\n },\n ),\n );\n return;\n }\n\n if (message.type === 'result') {\n if (resultMessage !== undefined) {\n failTerminal(\n new CodeModeProtocolError(\n `Worker sent duplicate result for invocation ${invocationId}.`,\n { invocationId },\n ),\n );\n return;\n }\n resultMessage = message;\n return;\n }\n\n if (message.type === 'ready') {\n handleReadyMessage(message);\n return;\n }\n\n if (message.type === 'bridge-drained') {\n if (\n pendingInterruptDrainId === undefined ||\n message.drainId !== pendingInterruptDrainId\n ) {\n failTerminal(\n new CodeModeProtocolError(\n `Worker sent unexpected bridge drain acknowledgement ${message.drainId}.`,\n {\n invocationId,\n expectedDrainId: pendingInterruptDrainId,\n receivedDrainId: message.drainId,\n },\n ),\n );\n return;\n }\n pendingInterruptDrainId = undefined;\n if (inFlightBridgeRequests === 0) {\n settleInterrupt();\n }\n return;\n }\n\n const bridgeIndex = markWorkerRequest(message);\n if (bridgeIndex !== undefined) {\n void handleToolRequest(message, bridgeIndex);\n }\n });\n\n const onError = bindInvocationContext((error: Error) => {\n failTerminal(error);\n });\n\n const onExit = bindInvocationContext((code: number) => {\n if (!terminalReached) {\n failTerminal(\n new Error(\n `Code mode worker exited before completion with code ${code}.`,\n ),\n );\n }\n });\n\n worker.on('message', onMessage);\n worker.on('error', onError);\n worker.on('exit', onExit);\n outerAbortSignal?.addEventListener('abort', onAbort, { once: true });\n if (outerAbortSignal?.aborted) {\n onAbort();\n }\n\n const runMessage: MainToWorkerMessage = {\n type: 'run',\n invocationId,\n js,\n determinism,\n options: {\n timeoutMs: normalizedOptions.timeoutMs,\n memoryLimitBytes: normalizedOptions.memoryLimitBytes,\n maxStackSizeBytes: normalizedOptions.maxStackSizeBytes,\n maxResultBytes: normalizedOptions.maxResultBytes,\n maxConsoleOutputBytes: normalizedOptions.maxConsoleOutputBytes,\n },\n };\n\n if (!terminalReached) {\n try {\n // eslint-disable-next-line unicorn/require-post-message-target-origin -- Node.js Worker has no targetOrigin parameter.\n worker.postMessage(runMessage);\n } catch (error) {\n failTerminal(error);\n }\n }\n\n return { result };\n\n function markWorkerRequest(message: WorkerToolRequest): number | undefined {\n if (terminalReached) {\n return undefined;\n }\n if (seenWorkerRequestIds.has(message.requestId)) {\n failTerminal(\n new CodeModeProtocolError(\n `Worker sent duplicate requestId ${message.requestId}.`,\n { invocationId, requestId: message.requestId },\n ),\n );\n return undefined;\n }\n seenWorkerRequestIds.add(message.requestId);\n\n if (totalBridgeRequests >= normalizedOptions.maxBridgeRequests) {\n failTerminal(\n new CodeModeBridgeLimitError(\n `Code mode exceeded the ${normalizedOptions.maxBridgeRequests} bridge request limit.`,\n {\n invocationId,\n maxBridgeRequests: normalizedOptions.maxBridgeRequests,\n },\n ),\n );\n return undefined;\n }\n if (inFlightBridgeRequests >= normalizedOptions.maxInFlightBridgeRequests) {\n failTerminal(\n new CodeModeBridgeLimitError(\n `Code mode exceeded the ${normalizedOptions.maxInFlightBridgeRequests} in-flight bridge request limit.`,\n {\n invocationId,\n maxInFlightBridgeRequests:\n normalizedOptions.maxInFlightBridgeRequests,\n },\n ),\n );\n return undefined;\n }\n\n totalBridgeRequests++;\n inFlightBridgeRequests++;\n return totalBridgeRequests;\n }\n\n async function handleToolRequest(\n message: WorkerToolRequest,\n bridgeIndex: number,\n ): Promise<void> {\n const replayEntry = bridgeLedger[bridgeIndex - 1];\n try {\n if (replayEntry !== undefined) {\n assertReplayEntryMatches(replayEntry, message, bridgeIndex);\n\n if (replayEntry.status === 'fulfilled') {\n postBridgeResponse({\n type: 'bridge-response',\n invocationId,\n requestId: message.requestId,\n success: true,\n dateNowMs: replayEntry.dateNowMs,\n valueJson: replayEntry.valueJson,\n });\n return;\n }\n\n if (replayEntry.status === 'rejected') {\n postBridgeResponse({\n type: 'bridge-response',\n invocationId,\n requestId: message.requestId,\n success: false,\n dateNowMs: replayEntry.dateNowMs,\n error: replayEntry.error,\n });\n return;\n }\n\n if (interruptResolution?.interruptId !== replayEntry.interruptId) {\n requestInterrupt(bridgeIndex - 1);\n return;\n }\n\n interruptResolutionConsumed = true;\n const isApproval = isCodeModeApprovalInterruptPayload(\n replayEntry.interruptPayload,\n );\n if (isApproval) {\n const decision = normalizeApprovalResolution(\n interruptResolution.resolution,\n );\n if (!decision.approved) {\n const error = new CodeModeToolApprovalDeniedError(\n replayEntry.name,\n fromJsonPayload(message.inputJson),\n replayEntry.toolCallId,\n decision.reason,\n );\n const dateNowMs = Date.now();\n const guestError = serializeBridgeErrorForGuest(error, 'tool');\n bridgeLedger[bridgeIndex - 1] = {\n kind: 'tool',\n name: message.toolName,\n inputJson: message.inputJson,\n toolCallId: replayEntry.toolCallId,\n status: 'rejected',\n dateNowMs,\n error: guestError,\n };\n postBridgeResponse({\n type: 'bridge-response',\n invocationId,\n requestId: message.requestId,\n success: false,\n dateNowMs,\n error: guestError,\n });\n return;\n }\n }\n\n const codeModeInterrupt: CodeModeInterruptExecutionContext | undefined =\n isApproval\n ? undefined\n : {\n interruptId: replayEntry.interruptId,\n payload: replayEntry.interruptPayload,\n resolution: interruptResolution.resolution,\n };\n const outcome = await invokeHostTool({\n toolName: message.toolName,\n inputJson: message.inputJson,\n tools,\n baseExecutionOptions,\n codeModeOptions: options ?? {},\n maxToolInputBytes: normalizedOptions.maxToolInputBytes,\n maxToolOutputBytes: normalizedOptions.maxToolOutputBytes,\n toolCallId: replayEntry.toolCallId,\n ...(codeModeInterrupt !== undefined ? { codeModeInterrupt } : {}),\n skipApproval: true,\n });\n if (outcome.type === 'interrupted') {\n bridgeLedger[bridgeIndex - 1] = {\n kind: 'tool',\n name: message.toolName,\n inputJson: message.inputJson,\n toolCallId: replayEntry.toolCallId,\n interruptId: `${replayEntry.toolCallId}:interrupt`,\n interruptPayload: outcome.payload,\n status: 'interrupted',\n };\n requestInterrupt(bridgeIndex - 1);\n return;\n }\n\n const dateNowMs = Date.now();\n bridgeLedger[bridgeIndex - 1] = {\n kind: 'tool',\n name: message.toolName,\n inputJson: message.inputJson,\n toolCallId: replayEntry.toolCallId,\n status: 'fulfilled',\n dateNowMs,\n valueJson: outcome.valueJson,\n };\n postBridgeResponse({\n type: 'bridge-response',\n invocationId,\n requestId: message.requestId,\n success: true,\n dateNowMs,\n valueJson: outcome.valueJson,\n });\n return;\n }\n\n const toolCallId = `${baseExecutionOptions.toolCallId}:tool-${++nestedToolCounter}`;\n const outcome = await invokeHostTool({\n toolName: message.toolName,\n inputJson: message.inputJson,\n tools,\n baseExecutionOptions,\n codeModeOptions: options ?? {},\n maxToolInputBytes: normalizedOptions.maxToolInputBytes,\n maxToolOutputBytes: normalizedOptions.maxToolOutputBytes,\n toolCallId,\n });\n if (outcome.type === 'interrupted') {\n bridgeLedger[bridgeIndex - 1] = {\n kind: 'tool',\n name: message.toolName,\n inputJson: message.inputJson,\n toolCallId,\n interruptId: `${toolCallId}:interrupt`,\n interruptPayload: outcome.payload,\n status: 'interrupted',\n };\n requestInterrupt(bridgeIndex - 1);\n return;\n }\n\n const dateNowMs = Date.now();\n bridgeLedger[bridgeIndex - 1] = {\n kind: 'tool',\n name: message.toolName,\n inputJson: message.inputJson,\n toolCallId,\n status: 'fulfilled',\n dateNowMs,\n valueJson: outcome.valueJson,\n };\n postBridgeResponse({\n type: 'bridge-response',\n invocationId,\n requestId: message.requestId,\n success: true,\n dateNowMs,\n valueJson: outcome.valueJson,\n });\n } catch (error) {\n if (error instanceof CodeModeProtocolError) {\n failTerminal(error);\n return;\n }\n const dateNowMs = Date.now();\n const guestError = serializeBridgeErrorForGuest(error, 'tool');\n const toolCallId =\n replayEntry?.toolCallId ??\n `${baseExecutionOptions.toolCallId}:tool-${nestedToolCounter}`;\n if (\n replayEntry === undefined ||\n (replayEntry.status === 'interrupted' &&\n interruptResolution?.interruptId === replayEntry.interruptId)\n ) {\n bridgeLedger[bridgeIndex - 1] = {\n kind: 'tool',\n name: message.toolName,\n inputJson: message.inputJson,\n toolCallId,\n status: 'rejected',\n dateNowMs,\n error: guestError,\n };\n }\n postBridgeResponse({\n type: 'bridge-response',\n invocationId,\n requestId: message.requestId,\n success: false,\n dateNowMs,\n error: guestError,\n });\n } finally {\n inFlightBridgeRequests--;\n settleInterruptIfReady();\n }\n }\n\n function requestInterrupt(entryIndex: number): void {\n interruptEntryIndex ??= entryIndex;\n }\n\n function settleInterruptIfReady(): void {\n if (\n interruptEntryIndex === undefined ||\n terminalReached ||\n inFlightBridgeRequests > 0 ||\n pendingInterruptDrainId !== undefined ||\n !interruptResolutionConsumed\n ) {\n return;\n }\n pendingInterruptDrainId = `${invocationId}:drain-${++interruptDrainCounter}`;\n postBridgeResponse({\n type: 'bridge-drain',\n invocationId,\n drainId: pendingInterruptDrainId,\n });\n }\n\n function settleInterrupt(): void {\n if (\n interruptEntryIndex === undefined ||\n terminalReached ||\n inFlightBridgeRequests > 0 ||\n !interruptResolutionConsumed\n ) {\n return;\n }\n\n const entry = bridgeLedger[interruptEntryIndex];\n if (entry === undefined || entry.status !== 'interrupted') {\n failTerminal(\n new CodeModeProtocolError(\n 'Code mode interruption references a missing or resolved ledger entry.',\n { invocationId, interruptEntryIndex },\n ),\n );\n return;\n }\n\n const continuationState = signCodeModeContinuation(\n {\n version: 1,\n js,\n outerToolCallId: baseExecutionOptions.toolCallId,\n determinism: { ...determinism },\n ledger: cloneLedger(bridgeLedger),\n },\n continuationSecurity,\n );\n const interrupt: CodeModeInterrupt = {\n type: 'code-mode-interrupt',\n interruptId: entry.interruptId,\n toolName: entry.name,\n toolCallId: entry.toolCallId,\n outerToolCallId: continuationState.outerToolCallId,\n input: fromJsonPayload(entry.inputJson),\n payload: structuredClone(entry.interruptPayload),\n continuation: continuationState,\n };\n\n terminalReached = true;\n abortInvocation(interrupt);\n cleanupWorker(false);\n settleCaller(() => resolveResult(interrupt));\n }\n\n function postBridgeResponse(message: MainToWorkerMessage): void {\n if (terminalReached) {\n return;\n }\n try {\n // eslint-disable-next-line unicorn/require-post-message-target-origin -- Node.js Worker has no targetOrigin parameter.\n worker.postMessage(message);\n } catch (error) {\n failTerminal(error);\n }\n }\n\n function handleReadyMessage(message: WorkerReadyMessage): void {\n if (terminalReached) {\n return;\n }\n if (interruptEntryIndex !== undefined) {\n settleInterruptIfReady();\n return;\n }\n if (resultMessage === undefined) {\n failTerminal(\n new CodeModeProtocolError(\n `Code mode worker became ready without a result for ${message.invocationId}.`,\n { invocationId: message.invocationId },\n ),\n );\n return;\n }\n\n if (!interruptResolutionConsumed) {\n failTerminal(\n new CodeModeProtocolError(\n 'Code mode continuation completed without consuming its interrupt resolution.',\n { interruptId: interruptResolution?.interruptId },\n ),\n );\n return;\n }\n if (\n continuation !== undefined &&\n totalBridgeRequests < bridgeLedger.length\n ) {\n failTerminal(\n new CodeModeProtocolError(\n 'Code mode continuation returned before replaying the full bridge ledger.',\n {\n replayedBridgeRequests: totalBridgeRequests,\n ledgerEntries: bridgeLedger.length,\n },\n ),\n );\n return;\n }\n\n terminalReached = true;\n const finalResultMessage = resultMessage;\n if (inFlightBridgeRequests > 0) {\n const error = finalResultMessage.success\n ? new CodeModeDetachedBridgeRequestError(\n `Code mode returned while ${inFlightBridgeRequests} bridge request(s) were still in flight.`,\n {\n invocationId,\n inFlightBridgeRequests,\n totalBridgeRequests,\n },\n )\n : deserializeResultError(finalResultMessage);\n abortInvocation(error);\n cleanupWorker(false);\n settleCaller(() => rejectResult(error));\n return;\n }\n\n cleanupWorker(true);\n settleCaller(() =>\n settleWithResultMessage(finalResultMessage, resolveResult, rejectResult),\n );\n }\n}\n\nfunction assertContinuationInput({\n js,\n continuation,\n interruptResolution,\n continuationSecurity,\n}: {\n js: string;\n continuation: RunCodeModeInput['continuation'];\n interruptResolution: RunCodeModeInput['interruptResolution'];\n continuationSecurity: ResolvedCodeModeContinuationSecurity;\n}): void {\n if (continuation === undefined) {\n if (interruptResolution !== undefined) {\n throw new CodeModeProtocolError(\n 'A code-mode interrupt resolution was provided without continuation state.',\n );\n }\n return;\n }\n\n verifyCodeModeContinuation(continuation, continuationSecurity);\n if (continuation.version !== 1) {\n throw new CodeModeProtocolError(\n 'Unsupported code-mode continuation version.',\n );\n }\n if (continuation.js !== js) {\n throw new CodeModeProtocolError(\n 'Code mode continuation source does not match the resumed source.',\n );\n }\n if (\n !Number.isInteger(continuation.determinism.dateNowMs) ||\n !/^[0-9a-f]{32}$/i.test(continuation.determinism.randomSeed)\n ) {\n throw new CodeModeProtocolError(\n 'Code mode continuation determinism state is malformed.',\n );\n }\n for (const entry of continuation.ledger) {\n if (\n entry.kind !== 'tool' ||\n typeof entry.name !== 'string' ||\n typeof entry.inputJson !== 'string' ||\n typeof entry.toolCallId !== 'string'\n ) {\n throw new CodeModeProtocolError(\n 'Code mode continuation ledger is malformed.',\n );\n }\n }\n if (interruptResolution !== undefined) {\n const matches = continuation.ledger.filter(\n entry =>\n entry.status === 'interrupted' &&\n entry.interruptId === interruptResolution.interruptId,\n );\n if (matches.length !== 1) {\n throw new CodeModeProtocolError(\n 'Interrupt resolution does not match exactly one pending continuation ledger entry.',\n {\n interruptId: interruptResolution.interruptId,\n matches: matches.length,\n },\n );\n }\n }\n}\n\nfunction assertReplayEntryMatches(\n entry: CodeModeContinuationLedgerEntry,\n message: WorkerToolRequest,\n bridgeIndex: number,\n): void {\n if (\n entry.name !== message.toolName ||\n entry.inputJson !== message.inputJson\n ) {\n throw new CodeModeProtocolError(\n 'Code mode continuation replay diverged from its bridge ledger.',\n {\n bridgeIndex,\n expectedToolName: entry.name,\n receivedToolName: message.toolName,\n },\n );\n }\n}\n\nfunction createDeterminismState(): {\n dateNowMs: number;\n randomSeed: string;\n} {\n return {\n dateNowMs: Date.now(),\n randomSeed: randomBytes(16).toString('hex'),\n };\n}\n\nfunction cloneLedger(\n ledger: CodeModeContinuationLedgerEntry[],\n): CodeModeContinuationLedgerEntry[] {\n return structuredClone(ledger);\n}\n\nfunction getMaxNestedToolCounter(\n ledger: CodeModeContinuationLedgerEntry[],\n): number {\n let max = 0;\n for (const entry of ledger) {\n const match = /:tool-(\\d+)$/u.exec(entry.toolCallId);\n if (match !== null) {\n max = Math.max(max, Number(match[1]));\n }\n }\n return max;\n}\n\nfunction fromJsonPayload(valueJson: string): unknown {\n return valueJson === '' ? undefined : JSON.parse(valueJson);\n}\n\nfunction acquireWorker(maxPoolSize: number): PooledWorker {\n let pooledWorker = idleWorkers.pop();\n while (pooledWorker?.destroyed) {\n pooledWorker = idleWorkers.pop();\n }\n pooledWorker ??= createWorker();\n pooledWorker.worker.removeAllListeners('exit');\n pooledWorker.worker.ref();\n trimIdleWorkers(Math.max(0, maxPoolSize - activeInvocations));\n return pooledWorker;\n}\n\nfunction createWorker(): PooledWorker {\n return {\n worker: new Worker(getInlineWorkerUrl(), { execArgv: [] }),\n destroyed: false,\n };\n}\n\nfunction getInlineWorkerUrl(): URL {\n inlineWorkerUrl ??= new URL(\n `data:text/javascript;base64,${Buffer.from(INLINE_CODE_MODE_WORKER_SOURCE).toString('base64')}`,\n );\n return inlineWorkerUrl;\n}\n\nfunction releaseWorker(pooledWorker: PooledWorker): void {\n if (pooledWorker.destroyed) {\n return;\n }\n pooledWorker.worker.once('exit', () => {\n pooledWorker.destroyed = true;\n const index = idleWorkers.indexOf(pooledWorker);\n if (index !== -1) {\n idleWorkers.splice(index, 1);\n }\n });\n pooledWorker.worker.unref();\n idleWorkers.push(pooledWorker);\n}\n\nfunction destroyWorker(pooledWorker: PooledWorker): void {\n if (pooledWorker.destroyed) {\n return;\n }\n pooledWorker.destroyed = true;\n pooledWorker.worker.removeAllListeners();\n void pooledWorker.worker.terminate();\n}\n\nfunction trimIdleWorkers(maxIdleWorkers: number): void {\n while (idleWorkers.length > maxIdleWorkers) {\n const pooledWorker = idleWorkers.pop();\n if (pooledWorker !== undefined) {\n destroyWorker(pooledWorker);\n }\n }\n}\n\nfunction releaseInvocationSlot(memoryLimitBytes: number): void {\n activeInvocations = Math.max(0, activeInvocations - 1);\n const maxWorkers = getMaxWorkers({\n memoryLimitBytes,\n activeWorkers: activeInvocations,\n });\n trimIdleWorkers(Math.max(0, maxWorkers - activeInvocations));\n}\n\nfunction settleWithResultMessage(\n message: WorkerResultMessage,\n resolve: (value: unknown) => void,\n reject: (reason?: unknown) => void,\n): void {\n if (!message.success) {\n reject(deserializeResultError(message));\n return;\n }\n resolve(\n message.valueJson === '' || message.valueJson === undefined\n ? undefined\n : JSON.parse(message.valueJson),\n );\n}\n\nfunction deserializeResultError(message: WorkerResultMessage): Error {\n if (message.error === undefined) {\n return new CodeModeProtocolError(\n `Code mode worker failed without an error for ${message.invocationId}.`,\n { invocationId: message.invocationId },\n );\n }\n return deserializeError(message.error);\n}\n"],"mappings":"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","names":["dateNowMs","outcome"]}
|