@ai-sdk/code-mode 0.0.0-2d998b35-20260731001744

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 (51) hide show
  1. package/LICENSE +13 -0
  2. package/README.md +99 -0
  3. package/dist/code-mode-tool.js +40 -0
  4. package/dist/code-mode-tool.js.map +1 -0
  5. package/dist/errors.js +192 -0
  6. package/dist/errors.js.map +1 -0
  7. package/dist/index.d.ts +179 -0
  8. package/dist/index.js +33 -0
  9. package/dist/index.js.map +1 -0
  10. package/dist/run-code-mode.js +8 -0
  11. package/dist/run-code-mode.js.map +1 -0
  12. package/dist/runtime/guest-sources.js +260 -0
  13. package/dist/runtime/guest-sources.js.map +1 -0
  14. package/dist/runtime/manager.js +414 -0
  15. package/dist/runtime/manager.js.map +1 -0
  16. package/dist/runtime/max-workers.js +40 -0
  17. package/dist/runtime/max-workers.js.map +1 -0
  18. package/dist/runtime/protocol.js +1 -0
  19. package/dist/runtime/protocol.js.map +1 -0
  20. package/dist/runtime/worker-source.d.ts +11 -0
  21. package/dist/runtime/worker-source.js +2 -0
  22. package/dist/tool-invocation.js +129 -0
  23. package/dist/tool-invocation.js.map +1 -0
  24. package/dist/tool-prompt.js +440 -0
  25. package/dist/tool-prompt.js.map +1 -0
  26. package/dist/types.js +1 -0
  27. package/dist/types.js.map +1 -0
  28. package/dist/utils/options.js +76 -0
  29. package/dist/utils/options.js.map +1 -0
  30. package/dist/utils/serialization.js +49 -0
  31. package/dist/utils/serialization.js.map +1 -0
  32. package/dist/utils/source-cache.js +77 -0
  33. package/dist/utils/source-cache.js.map +1 -0
  34. package/package.json +77 -0
  35. package/src/code-mode-tool.ts +60 -0
  36. package/src/errors.ts +267 -0
  37. package/src/index.ts +26 -0
  38. package/src/run-code-mode.ts +15 -0
  39. package/src/runtime/guest-sources.ts +260 -0
  40. package/src/runtime/manager.ts +498 -0
  41. package/src/runtime/max-workers.ts +65 -0
  42. package/src/runtime/protocol.ts +52 -0
  43. package/src/runtime/worker-source.ts +10 -0
  44. package/src/runtime/worker.ts +497 -0
  45. package/src/tool-invocation.ts +181 -0
  46. package/src/tool-prompt.ts +585 -0
  47. package/src/tsconfig.json +11 -0
  48. package/src/types.ts +111 -0
  49. package/src/utils/options.ts +83 -0
  50. package/src/utils/serialization.ts +66 -0
  51. package/src/utils/source-cache.ts +91 -0
@@ -0,0 +1,498 @@
1
+ import { AsyncResource } from 'node:async_hooks';
2
+ import { Buffer } from 'node:buffer';
3
+ import { Worker } from 'node:worker_threads';
4
+ import {
5
+ CodeModeAbortedError,
6
+ CodeModeBridgeLimitError,
7
+ CodeModeConcurrencyError,
8
+ CodeModeDetachedBridgeRequestError,
9
+ CodeModeProtocolError,
10
+ CodeModeTimeoutError,
11
+ deserializeError,
12
+ serializeBridgeErrorForGuest,
13
+ } from '../errors.js';
14
+ import { invokeHostTool } from '../tool-invocation.js';
15
+ import { normalizeOptions } from '../utils/options.js';
16
+ import { assertSourceSize, transformSource } from '../utils/source-cache.js';
17
+ import type {
18
+ CodeModeToolExecutionOptions,
19
+ NormalizedCodeModeOptions,
20
+ RunCodeModeInput,
21
+ } from '../types.js';
22
+ import { getMaxWorkers } from './max-workers.js';
23
+ import type {
24
+ MainToWorkerMessage,
25
+ WorkerBridgeResponse,
26
+ WorkerReadyMessage,
27
+ WorkerResultMessage,
28
+ WorkerToolRequest,
29
+ WorkerToMainMessage,
30
+ } from './protocol.js';
31
+ import { INLINE_CODE_MODE_WORKER_SOURCE } from './worker-source.js';
32
+
33
+ interface PooledWorker {
34
+ worker: Worker;
35
+ destroyed: boolean;
36
+ }
37
+
38
+ interface ManagedWorkerRun {
39
+ result: Promise<unknown>;
40
+ }
41
+
42
+ let invocationCounter = 0;
43
+ let activeInvocations = 0;
44
+ let inlineWorkerUrl: URL | undefined;
45
+ const idleWorkers: PooledWorker[] = [];
46
+
47
+ export async function runManagedCodeMode(
48
+ input: RunCodeModeInput,
49
+ ): Promise<unknown> {
50
+ const normalizedOptions = normalizeOptions(input.options);
51
+ const maxWorkers = getMaxWorkers({
52
+ memoryLimitBytes: normalizedOptions.memoryLimitBytes,
53
+ activeWorkers: activeInvocations,
54
+ });
55
+ if (activeInvocations >= maxWorkers) {
56
+ throw new CodeModeConcurrencyError(maxWorkers);
57
+ }
58
+
59
+ activeInvocations++;
60
+ try {
61
+ if (input.toolExecutionOptions?.abortSignal?.aborted) {
62
+ throw new CodeModeAbortedError();
63
+ }
64
+
65
+ assertSourceSize(input.js, normalizedOptions.maxSourceBytes);
66
+ const run = startWorkerRun({
67
+ ...input,
68
+ js: transformSource(input.js),
69
+ normalizedOptions,
70
+ maxWorkers,
71
+ });
72
+ return await run.result;
73
+ } finally {
74
+ releaseInvocationSlot(normalizedOptions.memoryLimitBytes);
75
+ }
76
+ }
77
+
78
+ function startWorkerRun({
79
+ js,
80
+ tools,
81
+ toolExecutionOptions,
82
+ normalizedOptions,
83
+ maxWorkers,
84
+ }: RunCodeModeInput & {
85
+ normalizedOptions: NormalizedCodeModeOptions;
86
+ maxWorkers: number;
87
+ }): ManagedWorkerRun {
88
+ const invocationId = `code-mode-${++invocationCounter}`;
89
+ const pooledWorker = acquireWorker(maxWorkers);
90
+ const worker = pooledWorker.worker;
91
+ const invocationContext = new AsyncResource('ai-sdk-code-mode:invocation');
92
+ const bindInvocationContext = <Args extends unknown[]>(
93
+ handler: (...args: Args) => void,
94
+ ): ((...args: Args) => void) => {
95
+ return (...args: Args): void => {
96
+ invocationContext.runInAsyncScope(handler, undefined, ...args);
97
+ };
98
+ };
99
+
100
+ const outerAbortSignal = toolExecutionOptions?.abortSignal;
101
+ const invocationAbortController = new AbortController();
102
+ const forwardedContext =
103
+ toolExecutionOptions?.context ?? toolExecutionOptions?.experimental_context;
104
+ const forwardedExperimentalContext =
105
+ toolExecutionOptions?.experimental_context ?? toolExecutionOptions?.context;
106
+ const baseExecutionOptions: CodeModeToolExecutionOptions = {
107
+ toolCallId: toolExecutionOptions?.toolCallId ?? invocationId,
108
+ messages: toolExecutionOptions?.messages ?? [],
109
+ abortSignal: invocationAbortController.signal,
110
+ ...(forwardedExperimentalContext !== undefined
111
+ ? { experimental_context: forwardedExperimentalContext }
112
+ : {}),
113
+ ...(forwardedContext !== undefined ? { context: forwardedContext } : {}),
114
+ };
115
+
116
+ let resultMessage: WorkerResultMessage | undefined;
117
+ let callerSettled = false;
118
+ let terminalReached = false;
119
+ let workerCleanedUp = false;
120
+ let totalBridgeRequests = 0;
121
+ let inFlightBridgeRequests = 0;
122
+ const seenWorkerRequestIds = new Set<string>();
123
+
124
+ let resolveResult!: (value: unknown) => void;
125
+ let rejectResult!: (reason?: unknown) => void;
126
+ const result = new Promise<unknown>((resolve, reject) => {
127
+ resolveResult = resolve;
128
+ rejectResult = reject;
129
+ });
130
+
131
+ const abortInvocation = (reason: unknown) => {
132
+ if (!invocationAbortController.signal.aborted) {
133
+ invocationAbortController.abort(reason);
134
+ }
135
+ };
136
+
137
+ const cleanupWorker = (reuseWorker: boolean) => {
138
+ if (workerCleanedUp) {
139
+ return;
140
+ }
141
+ workerCleanedUp = true;
142
+ clearTimeout(timeoutHandle);
143
+ outerAbortSignal?.removeEventListener('abort', onAbort);
144
+ worker.off('message', onMessage);
145
+ worker.off('error', onError);
146
+ worker.off('exit', onExit);
147
+ invocationContext.emitDestroy();
148
+ if (reuseWorker) {
149
+ releaseWorker(pooledWorker);
150
+ } else {
151
+ destroyWorker(pooledWorker);
152
+ }
153
+ };
154
+
155
+ const settleCaller = (settle: () => void) => {
156
+ if (callerSettled) {
157
+ return;
158
+ }
159
+ callerSettled = true;
160
+ try {
161
+ settle();
162
+ } catch (error) {
163
+ rejectResult(error);
164
+ }
165
+ };
166
+
167
+ const failTerminal = (error: unknown) => {
168
+ if (terminalReached) {
169
+ return;
170
+ }
171
+ terminalReached = true;
172
+ abortInvocation(error);
173
+ cleanupWorker(false);
174
+ settleCaller(() => rejectResult(error));
175
+ };
176
+
177
+ const onAbort = bindInvocationContext(() => {
178
+ failTerminal(new CodeModeAbortedError());
179
+ });
180
+
181
+ const timeoutHandle = setTimeout(
182
+ bindInvocationContext(() => {
183
+ failTerminal(new CodeModeTimeoutError(normalizedOptions.timeoutMs));
184
+ }),
185
+ normalizedOptions.timeoutMs,
186
+ );
187
+
188
+ const onMessage = bindInvocationContext((message: WorkerToMainMessage) => {
189
+ if (message.invocationId !== invocationId) {
190
+ failTerminal(
191
+ new CodeModeProtocolError(
192
+ `Worker message invocationId mismatch: expected ${invocationId}, received ${message.invocationId}.`,
193
+ {
194
+ expectedInvocationId: invocationId,
195
+ receivedInvocationId: message.invocationId,
196
+ messageType: message.type,
197
+ },
198
+ ),
199
+ );
200
+ return;
201
+ }
202
+
203
+ if (message.type === 'result') {
204
+ if (resultMessage !== undefined) {
205
+ failTerminal(
206
+ new CodeModeProtocolError(
207
+ `Worker sent duplicate result for invocation ${invocationId}.`,
208
+ { invocationId },
209
+ ),
210
+ );
211
+ return;
212
+ }
213
+ resultMessage = message;
214
+ return;
215
+ }
216
+
217
+ if (message.type === 'ready') {
218
+ handleReadyMessage(message);
219
+ return;
220
+ }
221
+
222
+ const bridgeIndex = markWorkerRequest(message);
223
+ if (bridgeIndex !== undefined) {
224
+ void handleToolRequest(message, bridgeIndex);
225
+ }
226
+ });
227
+
228
+ const onError = bindInvocationContext((error: Error) => {
229
+ failTerminal(error);
230
+ });
231
+
232
+ const onExit = bindInvocationContext((code: number) => {
233
+ if (!terminalReached) {
234
+ failTerminal(
235
+ new Error(
236
+ `Code mode worker exited before completion with code ${code}.`,
237
+ ),
238
+ );
239
+ }
240
+ });
241
+
242
+ worker.on('message', onMessage);
243
+ worker.on('error', onError);
244
+ worker.on('exit', onExit);
245
+ outerAbortSignal?.addEventListener('abort', onAbort, { once: true });
246
+ if (outerAbortSignal?.aborted) {
247
+ onAbort();
248
+ }
249
+
250
+ const runMessage: MainToWorkerMessage = {
251
+ type: 'run',
252
+ invocationId,
253
+ js,
254
+ options: {
255
+ timeoutMs: normalizedOptions.timeoutMs,
256
+ memoryLimitBytes: normalizedOptions.memoryLimitBytes,
257
+ maxStackSizeBytes: normalizedOptions.maxStackSizeBytes,
258
+ maxResultBytes: normalizedOptions.maxResultBytes,
259
+ maxConsoleOutputBytes: normalizedOptions.maxConsoleOutputBytes,
260
+ },
261
+ };
262
+
263
+ if (!terminalReached) {
264
+ try {
265
+ // eslint-disable-next-line unicorn/require-post-message-target-origin -- Node.js Worker has no targetOrigin parameter.
266
+ worker.postMessage(runMessage);
267
+ } catch (error) {
268
+ failTerminal(error);
269
+ }
270
+ }
271
+
272
+ return { result };
273
+
274
+ function markWorkerRequest(message: WorkerToolRequest): number | undefined {
275
+ if (terminalReached) {
276
+ return undefined;
277
+ }
278
+ if (seenWorkerRequestIds.has(message.requestId)) {
279
+ failTerminal(
280
+ new CodeModeProtocolError(
281
+ `Worker sent duplicate requestId ${message.requestId}.`,
282
+ { invocationId, requestId: message.requestId },
283
+ ),
284
+ );
285
+ return undefined;
286
+ }
287
+ seenWorkerRequestIds.add(message.requestId);
288
+
289
+ if (totalBridgeRequests >= normalizedOptions.maxBridgeRequests) {
290
+ failTerminal(
291
+ new CodeModeBridgeLimitError(
292
+ `Code mode exceeded the ${normalizedOptions.maxBridgeRequests} bridge request limit.`,
293
+ {
294
+ invocationId,
295
+ maxBridgeRequests: normalizedOptions.maxBridgeRequests,
296
+ },
297
+ ),
298
+ );
299
+ return undefined;
300
+ }
301
+ if (inFlightBridgeRequests >= normalizedOptions.maxInFlightBridgeRequests) {
302
+ failTerminal(
303
+ new CodeModeBridgeLimitError(
304
+ `Code mode exceeded the ${normalizedOptions.maxInFlightBridgeRequests} in-flight bridge request limit.`,
305
+ {
306
+ invocationId,
307
+ maxInFlightBridgeRequests:
308
+ normalizedOptions.maxInFlightBridgeRequests,
309
+ },
310
+ ),
311
+ );
312
+ return undefined;
313
+ }
314
+
315
+ totalBridgeRequests++;
316
+ inFlightBridgeRequests++;
317
+ return totalBridgeRequests;
318
+ }
319
+
320
+ async function handleToolRequest(
321
+ message: WorkerToolRequest,
322
+ bridgeIndex: number,
323
+ ): Promise<void> {
324
+ try {
325
+ const valueJson = await invokeHostTool({
326
+ toolName: message.toolName,
327
+ inputJson: message.inputJson,
328
+ tools,
329
+ baseExecutionOptions,
330
+ maxToolInputBytes: normalizedOptions.maxToolInputBytes,
331
+ maxToolOutputBytes: normalizedOptions.maxToolOutputBytes,
332
+ toolCallId: `${baseExecutionOptions.toolCallId}:tool-${bridgeIndex}`,
333
+ });
334
+ postBridgeResponse({
335
+ type: 'bridge-response',
336
+ invocationId,
337
+ requestId: message.requestId,
338
+ success: true,
339
+ valueJson,
340
+ });
341
+ } catch (error) {
342
+ postBridgeResponse({
343
+ type: 'bridge-response',
344
+ invocationId,
345
+ requestId: message.requestId,
346
+ success: false,
347
+ error: serializeBridgeErrorForGuest(error, 'tool'),
348
+ });
349
+ } finally {
350
+ inFlightBridgeRequests--;
351
+ }
352
+ }
353
+
354
+ function postBridgeResponse(message: WorkerBridgeResponse): void {
355
+ if (terminalReached) {
356
+ return;
357
+ }
358
+ try {
359
+ // eslint-disable-next-line unicorn/require-post-message-target-origin -- Node.js Worker has no targetOrigin parameter.
360
+ worker.postMessage(message);
361
+ } catch (error) {
362
+ failTerminal(error);
363
+ }
364
+ }
365
+
366
+ function handleReadyMessage(message: WorkerReadyMessage): void {
367
+ if (terminalReached) {
368
+ return;
369
+ }
370
+ if (resultMessage === undefined) {
371
+ failTerminal(
372
+ new CodeModeProtocolError(
373
+ `Code mode worker became ready without a result for ${message.invocationId}.`,
374
+ { invocationId: message.invocationId },
375
+ ),
376
+ );
377
+ return;
378
+ }
379
+
380
+ terminalReached = true;
381
+ const finalResultMessage = resultMessage;
382
+ if (inFlightBridgeRequests > 0) {
383
+ const error = finalResultMessage.success
384
+ ? new CodeModeDetachedBridgeRequestError(
385
+ `Code mode returned while ${inFlightBridgeRequests} bridge request(s) were still in flight.`,
386
+ {
387
+ invocationId,
388
+ inFlightBridgeRequests,
389
+ totalBridgeRequests,
390
+ },
391
+ )
392
+ : deserializeResultError(finalResultMessage);
393
+ abortInvocation(error);
394
+ cleanupWorker(false);
395
+ settleCaller(() => rejectResult(error));
396
+ return;
397
+ }
398
+
399
+ cleanupWorker(true);
400
+ settleCaller(() =>
401
+ settleWithResultMessage(finalResultMessage, resolveResult, rejectResult),
402
+ );
403
+ }
404
+ }
405
+
406
+ function acquireWorker(maxPoolSize: number): PooledWorker {
407
+ let pooledWorker = idleWorkers.pop();
408
+ while (pooledWorker?.destroyed) {
409
+ pooledWorker = idleWorkers.pop();
410
+ }
411
+ pooledWorker ??= createWorker();
412
+ pooledWorker.worker.removeAllListeners('exit');
413
+ pooledWorker.worker.ref();
414
+ trimIdleWorkers(Math.max(0, maxPoolSize - activeInvocations));
415
+ return pooledWorker;
416
+ }
417
+
418
+ function createWorker(): PooledWorker {
419
+ return {
420
+ worker: new Worker(getInlineWorkerUrl(), { execArgv: [] }),
421
+ destroyed: false,
422
+ };
423
+ }
424
+
425
+ function getInlineWorkerUrl(): URL {
426
+ inlineWorkerUrl ??= new URL(
427
+ `data:text/javascript;base64,${Buffer.from(INLINE_CODE_MODE_WORKER_SOURCE).toString('base64')}`,
428
+ );
429
+ return inlineWorkerUrl;
430
+ }
431
+
432
+ function releaseWorker(pooledWorker: PooledWorker): void {
433
+ if (pooledWorker.destroyed) {
434
+ return;
435
+ }
436
+ pooledWorker.worker.once('exit', () => {
437
+ pooledWorker.destroyed = true;
438
+ const index = idleWorkers.indexOf(pooledWorker);
439
+ if (index !== -1) {
440
+ idleWorkers.splice(index, 1);
441
+ }
442
+ });
443
+ pooledWorker.worker.unref();
444
+ idleWorkers.push(pooledWorker);
445
+ }
446
+
447
+ function destroyWorker(pooledWorker: PooledWorker): void {
448
+ if (pooledWorker.destroyed) {
449
+ return;
450
+ }
451
+ pooledWorker.destroyed = true;
452
+ pooledWorker.worker.removeAllListeners();
453
+ void pooledWorker.worker.terminate();
454
+ }
455
+
456
+ function trimIdleWorkers(maxIdleWorkers: number): void {
457
+ while (idleWorkers.length > maxIdleWorkers) {
458
+ const pooledWorker = idleWorkers.pop();
459
+ if (pooledWorker !== undefined) {
460
+ destroyWorker(pooledWorker);
461
+ }
462
+ }
463
+ }
464
+
465
+ function releaseInvocationSlot(memoryLimitBytes: number): void {
466
+ activeInvocations = Math.max(0, activeInvocations - 1);
467
+ const maxWorkers = getMaxWorkers({
468
+ memoryLimitBytes,
469
+ activeWorkers: activeInvocations,
470
+ });
471
+ trimIdleWorkers(Math.max(0, maxWorkers - activeInvocations));
472
+ }
473
+
474
+ function settleWithResultMessage(
475
+ message: WorkerResultMessage,
476
+ resolve: (value: unknown) => void,
477
+ reject: (reason?: unknown) => void,
478
+ ): void {
479
+ if (!message.success) {
480
+ reject(deserializeResultError(message));
481
+ return;
482
+ }
483
+ resolve(
484
+ message.valueJson === '' || message.valueJson === undefined
485
+ ? undefined
486
+ : JSON.parse(message.valueJson),
487
+ );
488
+ }
489
+
490
+ function deserializeResultError(message: WorkerResultMessage): Error {
491
+ if (message.error === undefined) {
492
+ return new CodeModeProtocolError(
493
+ `Code mode worker failed without an error for ${message.invocationId}.`,
494
+ { invocationId: message.invocationId },
495
+ );
496
+ }
497
+ return deserializeError(message.error);
498
+ }
@@ -0,0 +1,65 @@
1
+ import os from 'node:os';
2
+
3
+ const DEFAULT_MAX_WORKERS_CAP = 32;
4
+ const DEFAULT_WORKER_OVERHEAD_BYTES = 48 * 1024 * 1024;
5
+
6
+ let configuredMaxWorkers: number | undefined;
7
+
8
+ /**
9
+ * Sets the process-global maximum number of active code-mode workers.
10
+ *
11
+ * Pass `undefined` or call without an argument to restore the dynamic
12
+ * memory-based default. The default admits at least one invocation and admits
13
+ * additional workers only when available memory can cover another worker.
14
+ *
15
+ * @param maxWorkers - Positive integer worker cap, or `undefined` to reset.
16
+ */
17
+ export function setMaxWorkers(maxWorkers?: number): void {
18
+ if (maxWorkers === undefined) {
19
+ configuredMaxWorkers = undefined;
20
+ return;
21
+ }
22
+ if (!Number.isInteger(maxWorkers) || maxWorkers <= 0) {
23
+ throw new TypeError('maxWorkers must be a positive integer.');
24
+ }
25
+ configuredMaxWorkers = maxWorkers;
26
+ }
27
+
28
+ /**
29
+ * Returns the currently effective worker cap.
30
+ *
31
+ * @internal
32
+ */
33
+ export function getMaxWorkers({
34
+ memoryLimitBytes,
35
+ activeWorkers,
36
+ }: {
37
+ memoryLimitBytes: number;
38
+ activeWorkers: number;
39
+ }): number {
40
+ if (configuredMaxWorkers !== undefined) {
41
+ return configuredMaxWorkers;
42
+ }
43
+
44
+ const estimatedBytesPerWorker =
45
+ memoryLimitBytes + DEFAULT_WORKER_OVERHEAD_BYTES;
46
+ const additionalWorkers = Math.floor(
47
+ availableMemory() / estimatedBytesPerWorker,
48
+ );
49
+
50
+ return Math.max(
51
+ 1,
52
+ Math.min(DEFAULT_MAX_WORKERS_CAP, activeWorkers + additionalWorkers),
53
+ );
54
+ }
55
+
56
+ function availableMemory(): number {
57
+ const processWithAvailableMemory = process as typeof process & {
58
+ availableMemory?: () => number;
59
+ };
60
+ const bytes =
61
+ typeof processWithAvailableMemory.availableMemory === 'function'
62
+ ? processWithAvailableMemory.availableMemory()
63
+ : os.freemem();
64
+ return Number.isFinite(bytes) && bytes > 0 ? bytes : 0;
65
+ }
@@ -0,0 +1,52 @@
1
+ import type { NormalizedCodeModeOptions, SerializableError } from '../types.js';
2
+
3
+ export interface WorkerRunMessage {
4
+ type: 'run';
5
+ invocationId: string;
6
+ js: string;
7
+ options: Pick<
8
+ NormalizedCodeModeOptions,
9
+ | 'timeoutMs'
10
+ | 'memoryLimitBytes'
11
+ | 'maxStackSizeBytes'
12
+ | 'maxResultBytes'
13
+ | 'maxConsoleOutputBytes'
14
+ >;
15
+ }
16
+
17
+ export interface WorkerToolRequest {
18
+ type: 'tool-request';
19
+ invocationId: string;
20
+ requestId: string;
21
+ toolName: string;
22
+ inputJson: string;
23
+ }
24
+
25
+ export interface WorkerBridgeResponse {
26
+ type: 'bridge-response';
27
+ invocationId: string;
28
+ requestId: string;
29
+ success: boolean;
30
+ valueJson?: string;
31
+ error?: SerializableError;
32
+ }
33
+
34
+ export interface WorkerResultMessage {
35
+ type: 'result';
36
+ invocationId: string;
37
+ success: boolean;
38
+ valueJson?: string;
39
+ error?: SerializableError;
40
+ }
41
+
42
+ export interface WorkerReadyMessage {
43
+ type: 'ready';
44
+ invocationId: string;
45
+ }
46
+
47
+ export type WorkerToMainMessage =
48
+ | WorkerToolRequest
49
+ | WorkerResultMessage
50
+ | WorkerReadyMessage;
51
+
52
+ export type MainToWorkerMessage = WorkerRunMessage | WorkerBridgeResponse;
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Inline worker source generated into `dist/runtime/worker-source.js` during
3
+ * package builds.
4
+ *
5
+ * The source placeholder is intentionally unusable before the build step so a
6
+ * broken package build fails loudly instead of trying to run an empty worker.
7
+ *
8
+ */
9
+ export const INLINE_CODE_MODE_WORKER_SOURCE =
10
+ 'throw new Error("Code mode inline worker source was not generated.");';