@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/README.md
CHANGED
|
@@ -19,7 +19,10 @@ This package runs on the server and requires Node.js 22 or newer.
|
|
|
19
19
|
## Usage
|
|
20
20
|
|
|
21
21
|
```ts
|
|
22
|
-
import {
|
|
22
|
+
import {
|
|
23
|
+
DIRECT_TOOL_CALL,
|
|
24
|
+
experimental_codeModeTool as codeModeTool,
|
|
25
|
+
} from '@ai-sdk/code-mode';
|
|
23
26
|
import { generateText, isStepCount, tool } from 'ai';
|
|
24
27
|
import { z } from 'zod';
|
|
25
28
|
|
|
@@ -62,10 +65,10 @@ const tools = {
|
|
|
62
65
|
const result = await generateText({
|
|
63
66
|
model,
|
|
64
67
|
tools,
|
|
65
|
-
experimental_toolCallers:
|
|
66
|
-
getInventory: [code_mode],
|
|
67
|
-
getDemand: [code_mode],
|
|
68
|
-
}
|
|
68
|
+
experimental_toolCallers: {
|
|
69
|
+
getInventory: ['code_mode', DIRECT_TOOL_CALL],
|
|
70
|
+
getDemand: ['code_mode'],
|
|
71
|
+
},
|
|
69
72
|
stopWhen: isStepCount(10),
|
|
70
73
|
prompt: 'Compare inventory and demand for product sku_123.',
|
|
71
74
|
});
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import {
|
|
2
|
+
assertCodeModeApprovalResponse,
|
|
3
|
+
CODE_MODE_TOOL_APPROVAL_KIND
|
|
4
|
+
} from "./approval.js";
|
|
5
|
+
import { CodeModeProtocolError } from "./errors.js";
|
|
6
|
+
import {
|
|
7
|
+
continueCodeModeInterrupt,
|
|
8
|
+
isCodeModeInterrupt
|
|
9
|
+
} from "./interrupt-continuation.js";
|
|
10
|
+
function isCodeModeApprovalInterrupt(value, continuationSecurity = {}) {
|
|
11
|
+
return isCodeModeInterrupt(value, continuationSecurity) && value.payload.kind === CODE_MODE_TOOL_APPROVAL_KIND;
|
|
12
|
+
}
|
|
13
|
+
async function continueCodeModeApproval({
|
|
14
|
+
interrupt,
|
|
15
|
+
approvalResponse,
|
|
16
|
+
tools,
|
|
17
|
+
options = {},
|
|
18
|
+
toolExecutionOptions
|
|
19
|
+
}) {
|
|
20
|
+
assertCodeModeApprovalResponse(approvalResponse);
|
|
21
|
+
if (approvalResponse.approvalId !== interrupt.interruptId) {
|
|
22
|
+
throw new CodeModeProtocolError(
|
|
23
|
+
`Approval response ${approvalResponse.approvalId} does not match pending code-mode approval ${interrupt.interruptId}.`
|
|
24
|
+
);
|
|
25
|
+
}
|
|
26
|
+
return await continueCodeModeInterrupt({
|
|
27
|
+
interrupt,
|
|
28
|
+
resolution: {
|
|
29
|
+
approved: approvalResponse.approved,
|
|
30
|
+
...approvalResponse.reason !== void 0 ? { reason: approvalResponse.reason } : {}
|
|
31
|
+
},
|
|
32
|
+
tools,
|
|
33
|
+
options: {
|
|
34
|
+
...options,
|
|
35
|
+
approval: { ...options.approval, mode: "interrupt" }
|
|
36
|
+
},
|
|
37
|
+
...toolExecutionOptions !== void 0 ? { toolExecutionOptions } : {}
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
function toCodeModeApprovalMessages(interrupt) {
|
|
41
|
+
return [
|
|
42
|
+
{
|
|
43
|
+
role: "assistant",
|
|
44
|
+
content: [
|
|
45
|
+
{
|
|
46
|
+
type: "tool-call",
|
|
47
|
+
toolCallId: interrupt.toolCallId,
|
|
48
|
+
toolName: interrupt.toolName,
|
|
49
|
+
input: interrupt.input
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
type: "tool-approval-request",
|
|
53
|
+
approvalId: interrupt.interruptId,
|
|
54
|
+
toolCallId: interrupt.toolCallId
|
|
55
|
+
}
|
|
56
|
+
]
|
|
57
|
+
}
|
|
58
|
+
];
|
|
59
|
+
}
|
|
60
|
+
function getCodeModeApprovalResponse(messages, interrupt) {
|
|
61
|
+
for (let index = messages.length - 1; index >= 0; index--) {
|
|
62
|
+
const message = messages[index];
|
|
63
|
+
if (message?.role !== "tool") {
|
|
64
|
+
continue;
|
|
65
|
+
}
|
|
66
|
+
for (const part of message.content) {
|
|
67
|
+
if (part.type === "tool-approval-response" && part.approvalId === interrupt.interruptId && typeof part.approved === "boolean" && (part.reason === void 0 || typeof part.reason === "string")) {
|
|
68
|
+
return {
|
|
69
|
+
approvalId: part.approvalId,
|
|
70
|
+
approved: part.approved,
|
|
71
|
+
...part.reason !== void 0 ? { reason: part.reason } : {}
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
return void 0;
|
|
77
|
+
}
|
|
78
|
+
export {
|
|
79
|
+
continueCodeModeApproval,
|
|
80
|
+
getCodeModeApprovalResponse,
|
|
81
|
+
isCodeModeApprovalInterrupt,
|
|
82
|
+
toCodeModeApprovalMessages
|
|
83
|
+
};
|
|
84
|
+
//# sourceMappingURL=approval-continuation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/approval-continuation.ts"],"sourcesContent":["import type { ModelMessage } from 'ai';\nimport {\n assertCodeModeApprovalResponse,\n CODE_MODE_TOOL_APPROVAL_KIND,\n} from './approval.js';\nimport { CodeModeProtocolError } from './errors.js';\nimport {\n continueCodeModeInterrupt,\n isCodeModeInterrupt,\n} from './interrupt-continuation.js';\nimport type {\n CodeModeApprovalInterrupt,\n CodeModeApprovalResponse,\n CodeModeContinuationSecurityOptions,\n CodeModeOptions,\n CodeModeToolExecutionOptions,\n CodeModeToolSet,\n} from './types.js';\n\nexport function isCodeModeApprovalInterrupt(\n value: unknown,\n continuationSecurity: CodeModeContinuationSecurityOptions = {},\n): value is CodeModeApprovalInterrupt {\n return (\n isCodeModeInterrupt(value, continuationSecurity) &&\n value.payload.kind === CODE_MODE_TOOL_APPROVAL_KIND\n );\n}\n\nexport async function continueCodeModeApproval({\n interrupt,\n approvalResponse,\n tools,\n options = {},\n toolExecutionOptions,\n}: {\n interrupt: CodeModeApprovalInterrupt;\n approvalResponse: CodeModeApprovalResponse;\n tools: CodeModeToolSet;\n options?: CodeModeOptions;\n toolExecutionOptions?: Partial<CodeModeToolExecutionOptions>;\n}): Promise<unknown> {\n assertCodeModeApprovalResponse(approvalResponse);\n if (approvalResponse.approvalId !== interrupt.interruptId) {\n throw new CodeModeProtocolError(\n `Approval response ${approvalResponse.approvalId} does not match pending code-mode approval ${interrupt.interruptId}.`,\n );\n }\n\n return await continueCodeModeInterrupt({\n interrupt,\n resolution: {\n approved: approvalResponse.approved,\n ...(approvalResponse.reason !== undefined\n ? { reason: approvalResponse.reason }\n : {}),\n },\n tools,\n options: {\n ...options,\n approval: { ...options.approval, mode: 'interrupt' },\n },\n ...(toolExecutionOptions !== undefined ? { toolExecutionOptions } : {}),\n });\n}\n\nexport function toCodeModeApprovalMessages(\n interrupt: CodeModeApprovalInterrupt,\n): ModelMessage[] {\n return [\n {\n role: 'assistant',\n content: [\n {\n type: 'tool-call',\n toolCallId: interrupt.toolCallId,\n toolName: interrupt.toolName,\n input: interrupt.input,\n },\n {\n type: 'tool-approval-request',\n approvalId: interrupt.interruptId,\n toolCallId: interrupt.toolCallId,\n },\n ],\n },\n ];\n}\n\nexport function getCodeModeApprovalResponse(\n messages: ModelMessage[],\n interrupt: CodeModeApprovalInterrupt,\n): CodeModeApprovalResponse | undefined {\n for (let index = messages.length - 1; index >= 0; index--) {\n const message = messages[index];\n if (message?.role !== 'tool') {\n continue;\n }\n for (const part of message.content) {\n if (\n part.type === 'tool-approval-response' &&\n part.approvalId === interrupt.interruptId &&\n typeof part.approved === 'boolean' &&\n (part.reason === undefined || typeof part.reason === 'string')\n ) {\n return {\n approvalId: part.approvalId,\n approved: part.approved,\n ...(part.reason !== undefined ? { reason: part.reason } : {}),\n };\n }\n }\n }\n return undefined;\n}\n"],"mappings":"AACA;AAAA,EACE;AAAA,EACA;AAAA,OACK;AACP,SAAS,6BAA6B;AACtC;AAAA,EACE;AAAA,EACA;AAAA,OACK;AAUA,SAAS,4BACd,OACA,uBAA4D,CAAC,GACzB;AACpC,SACE,oBAAoB,OAAO,oBAAoB,KAC/C,MAAM,QAAQ,SAAS;AAE3B;AAEA,eAAsB,yBAAyB;AAAA,EAC7C;AAAA,EACA;AAAA,EACA;AAAA,EACA,UAAU,CAAC;AAAA,EACX;AACF,GAMqB;AACnB,iCAA+B,gBAAgB;AAC/C,MAAI,iBAAiB,eAAe,UAAU,aAAa;AACzD,UAAM,IAAI;AAAA,MACR,qBAAqB,iBAAiB,UAAU,8CAA8C,UAAU,WAAW;AAAA,IACrH;AAAA,EACF;AAEA,SAAO,MAAM,0BAA0B;AAAA,IACrC;AAAA,IACA,YAAY;AAAA,MACV,UAAU,iBAAiB;AAAA,MAC3B,GAAI,iBAAiB,WAAW,SAC5B,EAAE,QAAQ,iBAAiB,OAAO,IAClC,CAAC;AAAA,IACP;AAAA,IACA;AAAA,IACA,SAAS;AAAA,MACP,GAAG;AAAA,MACH,UAAU,EAAE,GAAG,QAAQ,UAAU,MAAM,YAAY;AAAA,IACrD;AAAA,IACA,GAAI,yBAAyB,SAAY,EAAE,qBAAqB,IAAI,CAAC;AAAA,EACvE,CAAC;AACH;AAEO,SAAS,2BACd,WACgB;AAChB,SAAO;AAAA,IACL;AAAA,MACE,MAAM;AAAA,MACN,SAAS;AAAA,QACP;AAAA,UACE,MAAM;AAAA,UACN,YAAY,UAAU;AAAA,UACtB,UAAU,UAAU;AAAA,UACpB,OAAO,UAAU;AAAA,QACnB;AAAA,QACA;AAAA,UACE,MAAM;AAAA,UACN,YAAY,UAAU;AAAA,UACtB,YAAY,UAAU;AAAA,QACxB;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;AAEO,SAAS,4BACd,UACA,WACsC;AACtC,WAAS,QAAQ,SAAS,SAAS,GAAG,SAAS,GAAG,SAAS;AACzD,UAAM,UAAU,SAAS,KAAK;AAC9B,QAAI,SAAS,SAAS,QAAQ;AAC5B;AAAA,IACF;AACA,eAAW,QAAQ,QAAQ,SAAS;AAClC,UACE,KAAK,SAAS,4BACd,KAAK,eAAe,UAAU,eAC9B,OAAO,KAAK,aAAa,cACxB,KAAK,WAAW,UAAa,OAAO,KAAK,WAAW,WACrD;AACA,eAAO;AAAA,UACL,YAAY,KAAK;AAAA,UACjB,UAAU,KAAK;AAAA,UACf,GAAI,KAAK,WAAW,SAAY,EAAE,QAAQ,KAAK,OAAO,IAAI,CAAC;AAAA,QAC7D;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;","names":[]}
|
package/dist/approval.js
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { CodeModeProtocolError } from "./errors.js";
|
|
2
|
+
const CODE_MODE_TOOL_APPROVAL_KIND = "ai-sdk-code-mode/tool-approval";
|
|
3
|
+
function isCodeModeApprovalInterruptPayload(payload) {
|
|
4
|
+
return payload.kind === CODE_MODE_TOOL_APPROVAL_KIND;
|
|
5
|
+
}
|
|
6
|
+
function assertCodeModeApprovalResponse(value) {
|
|
7
|
+
if (typeof value !== "object" || value === null || Array.isArray(value) || typeof value.approvalId !== "string" || typeof value.approved !== "boolean" || "reason" in value && value.reason !== void 0 && typeof value.reason !== "string") {
|
|
8
|
+
throw new CodeModeProtocolError(
|
|
9
|
+
"Code mode approval response is malformed."
|
|
10
|
+
);
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
function normalizeApprovalResolution(resolution) {
|
|
14
|
+
if (typeof resolution !== "object" || resolution === null || Array.isArray(resolution) || typeof resolution.approved !== "boolean" || "reason" in resolution && resolution.reason !== void 0 && typeof resolution.reason !== "string") {
|
|
15
|
+
throw new CodeModeProtocolError(
|
|
16
|
+
"Code mode approval resolution must be a boolean approval decision.",
|
|
17
|
+
{ resolution }
|
|
18
|
+
);
|
|
19
|
+
}
|
|
20
|
+
const { approved, reason } = resolution;
|
|
21
|
+
return {
|
|
22
|
+
approved,
|
|
23
|
+
...reason !== void 0 ? { reason } : {}
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
export {
|
|
27
|
+
CODE_MODE_TOOL_APPROVAL_KIND,
|
|
28
|
+
assertCodeModeApprovalResponse,
|
|
29
|
+
isCodeModeApprovalInterruptPayload,
|
|
30
|
+
normalizeApprovalResolution
|
|
31
|
+
};
|
|
32
|
+
//# sourceMappingURL=approval.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/approval.ts"],"sourcesContent":["import { CodeModeProtocolError } from './errors.js';\nimport type {\n CodeModeApprovalInterruptPayload,\n CodeModeApprovalResolution,\n CodeModeApprovalResponse,\n CodeModeInterruptPayload,\n} from './types.js';\n\nexport const CODE_MODE_TOOL_APPROVAL_KIND =\n 'ai-sdk-code-mode/tool-approval' as const;\n\nexport function isCodeModeApprovalInterruptPayload(\n payload: CodeModeInterruptPayload,\n): payload is CodeModeApprovalInterruptPayload {\n return payload.kind === CODE_MODE_TOOL_APPROVAL_KIND;\n}\n\nexport function assertCodeModeApprovalResponse(\n value: unknown,\n): asserts value is CodeModeApprovalResponse {\n if (\n typeof value !== 'object' ||\n value === null ||\n Array.isArray(value) ||\n typeof (value as { approvalId?: unknown }).approvalId !== 'string' ||\n typeof (value as { approved?: unknown }).approved !== 'boolean' ||\n ('reason' in value &&\n (value as { reason?: unknown }).reason !== undefined &&\n typeof (value as { reason?: unknown }).reason !== 'string')\n ) {\n throw new CodeModeProtocolError(\n 'Code mode approval response is malformed.',\n );\n }\n}\n\nexport function normalizeApprovalResolution(\n resolution: unknown,\n): CodeModeApprovalResolution {\n if (\n typeof resolution !== 'object' ||\n resolution === null ||\n Array.isArray(resolution) ||\n typeof (resolution as { approved?: unknown }).approved !== 'boolean' ||\n ('reason' in resolution &&\n (resolution as { reason?: unknown }).reason !== undefined &&\n typeof (resolution as { reason?: unknown }).reason !== 'string')\n ) {\n throw new CodeModeProtocolError(\n 'Code mode approval resolution must be a boolean approval decision.',\n { resolution },\n );\n }\n\n const { approved, reason } = resolution as CodeModeApprovalResolution;\n return {\n approved,\n ...(reason !== undefined ? { reason } : {}),\n };\n}\n"],"mappings":"AAAA,SAAS,6BAA6B;AAQ/B,MAAM,+BACX;AAEK,SAAS,mCACd,SAC6C;AAC7C,SAAO,QAAQ,SAAS;AAC1B;AAEO,SAAS,+BACd,OAC2C;AAC3C,MACE,OAAO,UAAU,YACjB,UAAU,QACV,MAAM,QAAQ,KAAK,KACnB,OAAQ,MAAmC,eAAe,YAC1D,OAAQ,MAAiC,aAAa,aACrD,YAAY,SACV,MAA+B,WAAW,UAC3C,OAAQ,MAA+B,WAAW,UACpD;AACA,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AACF;AAEO,SAAS,4BACd,YAC4B;AAC5B,MACE,OAAO,eAAe,YACtB,eAAe,QACf,MAAM,QAAQ,UAAU,KACxB,OAAQ,WAAsC,aAAa,aAC1D,YAAY,cACV,WAAoC,WAAW,UAChD,OAAQ,WAAoC,WAAW,UACzD;AACA,UAAM,IAAI;AAAA,MACR;AAAA,MACA,EAAE,WAAW;AAAA,IACf;AAAA,EACF;AAEA,QAAM,EAAE,UAAU,OAAO,IAAI;AAC7B,SAAO;AAAA,IACL;AAAA,IACA,GAAI,WAAW,SAAY,EAAE,OAAO,IAAI,CAAC;AAAA,EAC3C;AACF;","names":[]}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import { createHmac, randomBytes, timingSafeEqual } from "node:crypto";
|
|
2
|
+
import { CodeModeProtocolError } from "./errors.js";
|
|
3
|
+
const SIGNATURE_ALGORITHM = "HMAC-SHA256";
|
|
4
|
+
const DEFAULT_MAX_AGE_MS = 60 * 60 * 1e3;
|
|
5
|
+
let defaultSigningKey = randomBytes(32);
|
|
6
|
+
let defaultMaxAgeMs = DEFAULT_MAX_AGE_MS;
|
|
7
|
+
function setCodeModeContinuationSigningKey(key, options = {}) {
|
|
8
|
+
const resolved = resolveCodeModeContinuationSecurity({
|
|
9
|
+
signingKey: key ?? randomBytes(32),
|
|
10
|
+
maxAgeMs: options.maxAgeMs ?? DEFAULT_MAX_AGE_MS
|
|
11
|
+
});
|
|
12
|
+
defaultSigningKey = resolved.signingKey;
|
|
13
|
+
defaultMaxAgeMs = resolved.maxAgeMs;
|
|
14
|
+
}
|
|
15
|
+
function resolveCodeModeContinuationSecurity(options = {}) {
|
|
16
|
+
const signingKey = options.signingKey === void 0 ? Buffer.from(defaultSigningKey) : typeof options.signingKey === "string" ? Buffer.from(options.signingKey) : Buffer.from(options.signingKey);
|
|
17
|
+
if (signingKey.byteLength === 0) {
|
|
18
|
+
throw new TypeError("Continuation signing key must not be empty.");
|
|
19
|
+
}
|
|
20
|
+
const maxAgeMs = options.maxAgeMs ?? defaultMaxAgeMs;
|
|
21
|
+
if (!Number.isInteger(maxAgeMs) || !Number.isFinite(maxAgeMs) || maxAgeMs <= 0) {
|
|
22
|
+
throw new TypeError("Continuation maxAgeMs must be a positive integer.");
|
|
23
|
+
}
|
|
24
|
+
return { signingKey, maxAgeMs };
|
|
25
|
+
}
|
|
26
|
+
function signCodeModeContinuation(continuation, security = resolveCodeModeContinuationSecurity()) {
|
|
27
|
+
const issuedAtMs = Date.now();
|
|
28
|
+
const auth = {
|
|
29
|
+
alg: SIGNATURE_ALGORITHM,
|
|
30
|
+
nonce: randomBytes(16).toString("hex"),
|
|
31
|
+
issuedAtMs,
|
|
32
|
+
expiresAtMs: issuedAtMs + security.maxAgeMs
|
|
33
|
+
};
|
|
34
|
+
return {
|
|
35
|
+
...structuredClone(continuation),
|
|
36
|
+
auth: {
|
|
37
|
+
...auth,
|
|
38
|
+
signature: signContinuationPayload(
|
|
39
|
+
{ ...continuation, auth },
|
|
40
|
+
security.signingKey
|
|
41
|
+
)
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
function verifyCodeModeContinuation(continuation, security = {}) {
|
|
46
|
+
assertAuthShape(continuation.auth);
|
|
47
|
+
const now = Date.now();
|
|
48
|
+
if (continuation.auth.expiresAtMs < now) {
|
|
49
|
+
throw new CodeModeProtocolError("Code mode continuation has expired.", {
|
|
50
|
+
expiresAtMs: continuation.auth.expiresAtMs,
|
|
51
|
+
now
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
if (continuation.auth.issuedAtMs > now + 6e4) {
|
|
55
|
+
throw new CodeModeProtocolError(
|
|
56
|
+
"Code mode continuation was issued in the future.",
|
|
57
|
+
{ issuedAtMs: continuation.auth.issuedAtMs, now }
|
|
58
|
+
);
|
|
59
|
+
}
|
|
60
|
+
const { signingKey } = resolveCodeModeContinuationSecurity(security);
|
|
61
|
+
const expected = signContinuationPayload(
|
|
62
|
+
stripSignature(continuation),
|
|
63
|
+
signingKey
|
|
64
|
+
);
|
|
65
|
+
if (!constantTimeEqual(continuation.auth.signature, expected)) {
|
|
66
|
+
throw new CodeModeProtocolError(
|
|
67
|
+
"Code mode continuation signature is invalid."
|
|
68
|
+
);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
function hasValidCodeModeContinuationCapability(value, security = {}) {
|
|
72
|
+
try {
|
|
73
|
+
verifyCodeModeContinuation(value, security);
|
|
74
|
+
return true;
|
|
75
|
+
} catch {
|
|
76
|
+
return false;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
function signContinuationPayload(continuation, signingKey) {
|
|
80
|
+
return createHmac("sha256", signingKey).update(canonicalJson(continuation)).digest("base64url");
|
|
81
|
+
}
|
|
82
|
+
function stripSignature(continuation) {
|
|
83
|
+
const { auth, ...rest } = continuation;
|
|
84
|
+
const { signature: _signature, ...unsignedAuth } = auth;
|
|
85
|
+
return { ...rest, auth: unsignedAuth };
|
|
86
|
+
}
|
|
87
|
+
function assertAuthShape(auth) {
|
|
88
|
+
if (typeof auth !== "object" || auth === null || Array.isArray(auth) || auth.alg !== SIGNATURE_ALGORITHM || typeof auth.nonce !== "string" || !/^[0-9a-f]{32}$/i.test(auth.nonce) || typeof auth.issuedAtMs !== "number" || !Number.isInteger(auth.issuedAtMs) || typeof auth.expiresAtMs !== "number" || !Number.isInteger(auth.expiresAtMs) || auth.expiresAtMs <= auth.issuedAtMs || typeof auth.signature !== "string" || auth.signature.length === 0) {
|
|
89
|
+
throw new CodeModeProtocolError(
|
|
90
|
+
"Code mode continuation is missing valid signed auth metadata."
|
|
91
|
+
);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
function constantTimeEqual(left, right) {
|
|
95
|
+
const leftBytes = Buffer.from(left);
|
|
96
|
+
const rightBytes = Buffer.from(right);
|
|
97
|
+
return leftBytes.byteLength === rightBytes.byteLength && timingSafeEqual(leftBytes, rightBytes);
|
|
98
|
+
}
|
|
99
|
+
function canonicalJson(value) {
|
|
100
|
+
if (value === null) {
|
|
101
|
+
return "null";
|
|
102
|
+
}
|
|
103
|
+
if (typeof value === "string") {
|
|
104
|
+
return JSON.stringify(value);
|
|
105
|
+
}
|
|
106
|
+
if (typeof value === "number" || typeof value === "boolean") {
|
|
107
|
+
return JSON.stringify(value);
|
|
108
|
+
}
|
|
109
|
+
if (Array.isArray(value)) {
|
|
110
|
+
return `[${value.map(canonicalJson).join(",")}]`;
|
|
111
|
+
}
|
|
112
|
+
if (typeof value === "object") {
|
|
113
|
+
const entries = Object.entries(value).filter(([, item]) => item !== void 0).sort(([left], [right]) => left.localeCompare(right));
|
|
114
|
+
return `{${entries.map(([key, item]) => `${JSON.stringify(key)}:${canonicalJson(item)}`).join(",")}}`;
|
|
115
|
+
}
|
|
116
|
+
throw new TypeError("Continuation contains a non-JSON-serializable value.");
|
|
117
|
+
}
|
|
118
|
+
export {
|
|
119
|
+
hasValidCodeModeContinuationCapability,
|
|
120
|
+
resolveCodeModeContinuationSecurity,
|
|
121
|
+
setCodeModeContinuationSigningKey,
|
|
122
|
+
signCodeModeContinuation,
|
|
123
|
+
verifyCodeModeContinuation
|
|
124
|
+
};
|
|
125
|
+
//# sourceMappingURL=continuation-capability.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/continuation-capability.ts"],"sourcesContent":["import { createHmac, randomBytes, timingSafeEqual } from 'node:crypto';\nimport { CodeModeProtocolError } from './errors.js';\nimport type {\n CodeModeContinuation,\n CodeModeContinuationAuth,\n CodeModeContinuationSecurityOptions,\n UnsignedCodeModeContinuation,\n} from './types.js';\n\nconst SIGNATURE_ALGORITHM = 'HMAC-SHA256';\nconst DEFAULT_MAX_AGE_MS = 60 * 60 * 1000;\n\nlet defaultSigningKey: Uint8Array = randomBytes(32);\nlet defaultMaxAgeMs = DEFAULT_MAX_AGE_MS;\n\nexport interface ResolvedCodeModeContinuationSecurity {\n signingKey: Buffer;\n maxAgeMs: number;\n}\n\nexport function setCodeModeContinuationSigningKey(\n key?: string | Uint8Array,\n options: { maxAgeMs?: number } = {},\n): void {\n const resolved = resolveCodeModeContinuationSecurity({\n signingKey: key ?? randomBytes(32),\n maxAgeMs: options.maxAgeMs ?? DEFAULT_MAX_AGE_MS,\n });\n defaultSigningKey = resolved.signingKey;\n defaultMaxAgeMs = resolved.maxAgeMs;\n}\n\nexport function resolveCodeModeContinuationSecurity(\n options: CodeModeContinuationSecurityOptions = {},\n): ResolvedCodeModeContinuationSecurity {\n const signingKey =\n options.signingKey === undefined\n ? Buffer.from(defaultSigningKey)\n : typeof options.signingKey === 'string'\n ? Buffer.from(options.signingKey)\n : Buffer.from(options.signingKey);\n if (signingKey.byteLength === 0) {\n throw new TypeError('Continuation signing key must not be empty.');\n }\n\n const maxAgeMs = options.maxAgeMs ?? defaultMaxAgeMs;\n if (\n !Number.isInteger(maxAgeMs) ||\n !Number.isFinite(maxAgeMs) ||\n maxAgeMs <= 0\n ) {\n throw new TypeError('Continuation maxAgeMs must be a positive integer.');\n }\n\n return { signingKey, maxAgeMs };\n}\n\nexport function signCodeModeContinuation(\n continuation: UnsignedCodeModeContinuation,\n security = resolveCodeModeContinuationSecurity(),\n): CodeModeContinuation {\n const issuedAtMs = Date.now();\n const auth: Omit<CodeModeContinuationAuth, 'signature'> = {\n alg: SIGNATURE_ALGORITHM,\n nonce: randomBytes(16).toString('hex'),\n issuedAtMs,\n expiresAtMs: issuedAtMs + security.maxAgeMs,\n };\n return {\n ...structuredClone(continuation),\n auth: {\n ...auth,\n signature: signContinuationPayload(\n { ...continuation, auth },\n security.signingKey,\n ),\n },\n };\n}\n\nexport function verifyCodeModeContinuation(\n continuation: CodeModeContinuation,\n security: CodeModeContinuationSecurityOptions = {},\n): void {\n assertAuthShape(continuation.auth);\n const now = Date.now();\n if (continuation.auth.expiresAtMs < now) {\n throw new CodeModeProtocolError('Code mode continuation has expired.', {\n expiresAtMs: continuation.auth.expiresAtMs,\n now,\n });\n }\n if (continuation.auth.issuedAtMs > now + 60_000) {\n throw new CodeModeProtocolError(\n 'Code mode continuation was issued in the future.',\n { issuedAtMs: continuation.auth.issuedAtMs, now },\n );\n }\n\n const { signingKey } = resolveCodeModeContinuationSecurity(security);\n const expected = signContinuationPayload(\n stripSignature(continuation),\n signingKey,\n );\n if (!constantTimeEqual(continuation.auth.signature, expected)) {\n throw new CodeModeProtocolError(\n 'Code mode continuation signature is invalid.',\n );\n }\n}\n\nexport function hasValidCodeModeContinuationCapability(\n value: unknown,\n security: CodeModeContinuationSecurityOptions = {},\n): value is CodeModeContinuation {\n try {\n verifyCodeModeContinuation(value as CodeModeContinuation, security);\n return true;\n } catch {\n return false;\n }\n}\n\nfunction signContinuationPayload(\n continuation: UnsignedCodeModeContinuation & {\n auth: Omit<CodeModeContinuationAuth, 'signature'>;\n },\n signingKey: Uint8Array,\n): string {\n return createHmac('sha256', signingKey)\n .update(canonicalJson(continuation))\n .digest('base64url');\n}\n\nfunction stripSignature(\n continuation: CodeModeContinuation,\n): UnsignedCodeModeContinuation & {\n auth: Omit<CodeModeContinuationAuth, 'signature'>;\n} {\n const { auth, ...rest } = continuation;\n const { signature: _signature, ...unsignedAuth } = auth;\n return { ...rest, auth: unsignedAuth };\n}\n\nfunction assertAuthShape(\n auth: unknown,\n): asserts auth is CodeModeContinuationAuth {\n if (\n typeof auth !== 'object' ||\n auth === null ||\n Array.isArray(auth) ||\n (auth as { alg?: unknown }).alg !== SIGNATURE_ALGORITHM ||\n typeof (auth as { nonce?: unknown }).nonce !== 'string' ||\n !/^[0-9a-f]{32}$/i.test((auth as { nonce: string }).nonce) ||\n typeof (auth as { issuedAtMs?: unknown }).issuedAtMs !== 'number' ||\n !Number.isInteger((auth as { issuedAtMs: number }).issuedAtMs) ||\n typeof (auth as { expiresAtMs?: unknown }).expiresAtMs !== 'number' ||\n !Number.isInteger((auth as { expiresAtMs: number }).expiresAtMs) ||\n (auth as { expiresAtMs: number }).expiresAtMs <=\n (auth as { issuedAtMs: number }).issuedAtMs ||\n typeof (auth as { signature?: unknown }).signature !== 'string' ||\n (auth as { signature: string }).signature.length === 0\n ) {\n throw new CodeModeProtocolError(\n 'Code mode continuation is missing valid signed auth metadata.',\n );\n }\n}\n\nfunction constantTimeEqual(left: string, right: string): boolean {\n const leftBytes = Buffer.from(left);\n const rightBytes = Buffer.from(right);\n return (\n leftBytes.byteLength === rightBytes.byteLength &&\n timingSafeEqual(leftBytes, rightBytes)\n );\n}\n\nfunction canonicalJson(value: unknown): string {\n if (value === null) {\n return 'null';\n }\n if (typeof value === 'string') {\n return JSON.stringify(value);\n }\n if (typeof value === 'number' || typeof value === 'boolean') {\n return JSON.stringify(value);\n }\n if (Array.isArray(value)) {\n return `[${value.map(canonicalJson).join(',')}]`;\n }\n if (typeof value === 'object') {\n const entries = Object.entries(value as Record<string, unknown>)\n .filter(([, item]) => item !== undefined)\n .sort(([left], [right]) => left.localeCompare(right));\n return `{${entries\n .map(([key, item]) => `${JSON.stringify(key)}:${canonicalJson(item)}`)\n .join(',')}}`;\n }\n throw new TypeError('Continuation contains a non-JSON-serializable value.');\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/direct-tool-call.ts"],"sourcesContent":["/**\n * Allows the model to call a tool directly.\n *\n * Use a string instead of a Symbol to allow for serializability.\n */\nexport const DIRECT_TOOL_CALL = 'AI_SDK_DIRECT_TOOL_CALL';\n"],"mappings":"AAKO,MAAM,mBAAmB;","names":[]}
|
package/dist/errors.js
CHANGED
|
@@ -66,6 +66,30 @@ class CodeModeToolError extends CodeModeError {
|
|
|
66
66
|
super(message, "CODE_MODE_TOOL_ERROR", details);
|
|
67
67
|
}
|
|
68
68
|
}
|
|
69
|
+
class CodeModeToolApprovalRequiredError extends CodeModeToolError {
|
|
70
|
+
constructor(toolName, input, toolCallId) {
|
|
71
|
+
super(`Tool "${toolName}" requires approval before execution.`, {
|
|
72
|
+
toolName,
|
|
73
|
+
input,
|
|
74
|
+
toolCallId
|
|
75
|
+
});
|
|
76
|
+
this.code = "CODE_MODE_TOOL_APPROVAL_REQUIRED";
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
class CodeModeToolApprovalDeniedError extends CodeModeToolError {
|
|
80
|
+
constructor(toolName, input, toolCallId, reason) {
|
|
81
|
+
super(
|
|
82
|
+
`Tool "${toolName}" approval was denied${reason ? `: ${reason}` : "."}`,
|
|
83
|
+
{
|
|
84
|
+
toolName,
|
|
85
|
+
input,
|
|
86
|
+
toolCallId,
|
|
87
|
+
...reason !== void 0 ? { reason } : {}
|
|
88
|
+
}
|
|
89
|
+
);
|
|
90
|
+
this.code = "CODE_MODE_TOOL_APPROVAL_DENIED";
|
|
91
|
+
}
|
|
92
|
+
}
|
|
69
93
|
function serializeError(error) {
|
|
70
94
|
if (error instanceof CodeModeError) {
|
|
71
95
|
const result = compactError({
|
|
@@ -161,6 +185,29 @@ function deserializeError(error) {
|
|
|
161
185
|
restoreStack(result2, error);
|
|
162
186
|
return result2;
|
|
163
187
|
}
|
|
188
|
+
if (error.code === "CODE_MODE_TOOL_APPROVAL_REQUIRED") {
|
|
189
|
+
const details = error.details;
|
|
190
|
+
const result2 = new CodeModeToolApprovalRequiredError(
|
|
191
|
+
details?.toolName ?? "unknown",
|
|
192
|
+
details?.input,
|
|
193
|
+
details?.toolCallId ?? "unknown"
|
|
194
|
+
);
|
|
195
|
+
result2.message = error.message;
|
|
196
|
+
restoreStack(result2, error);
|
|
197
|
+
return result2;
|
|
198
|
+
}
|
|
199
|
+
if (error.code === "CODE_MODE_TOOL_APPROVAL_DENIED") {
|
|
200
|
+
const details = error.details;
|
|
201
|
+
const result2 = new CodeModeToolApprovalDeniedError(
|
|
202
|
+
details?.toolName ?? "unknown",
|
|
203
|
+
details?.input,
|
|
204
|
+
details?.toolCallId ?? "unknown",
|
|
205
|
+
details?.reason
|
|
206
|
+
);
|
|
207
|
+
result2.message = error.message;
|
|
208
|
+
restoreStack(result2, error);
|
|
209
|
+
return result2;
|
|
210
|
+
}
|
|
164
211
|
const result = new CodeModeError(
|
|
165
212
|
error.message,
|
|
166
213
|
error.code ?? "CODE_MODE_ERROR",
|
|
@@ -184,6 +231,8 @@ export {
|
|
|
184
231
|
CodeModeProtocolError,
|
|
185
232
|
CodeModeSourceTooLargeError,
|
|
186
233
|
CodeModeTimeoutError,
|
|
234
|
+
CodeModeToolApprovalDeniedError,
|
|
235
|
+
CodeModeToolApprovalRequiredError,
|
|
187
236
|
CodeModeToolError,
|
|
188
237
|
deserializeError,
|
|
189
238
|
serializeBridgeErrorForGuest,
|
package/dist/errors.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/errors.ts"],"sourcesContent":["import type { SerializableError } from './types.js';\n\n/**\n * Base class for errors raised by code mode.\n *\n * All package-specific errors include a stable `code` string and may include\n * structured `details` for diagnostics.\n */\nexport class CodeModeError extends Error {\n /**\n * Stable machine-readable error code.\n */\n code: string;\n /**\n * Optional structured diagnostic details.\n */\n readonly details?: unknown;\n\n constructor(message: string, code = 'CODE_MODE_ERROR', details?: unknown) {\n super(message);\n this.name = new.target.name;\n this.code = code;\n this.details = details;\n }\n}\n\n/**\n * Raised when a sandbox invocation exceeds its timeout.\n */\nexport class CodeModeTimeoutError extends CodeModeError {\n constructor(timeoutMs: number) {\n super(\n `Code mode execution timed out after ${timeoutMs}ms.`,\n 'CODE_MODE_TIMEOUT',\n { timeoutMs },\n );\n }\n}\n\n/**\n * Raised when the outer AI SDK abort signal aborts a code-mode invocation.\n */\nexport class CodeModeAbortedError extends CodeModeError {\n constructor() {\n super('Code mode execution was aborted.', 'CODE_MODE_ABORTED');\n }\n}\n\n/**\n * Raised when the process-global worker cap has been reached.\n *\n * Configure the cap with `setMaxWorkers`.\n */\nexport class CodeModeConcurrencyError extends CodeModeError {\n constructor(maxWorkers: number) {\n super(\n `Code mode maxWorkers limit reached (${maxWorkers}).`,\n 'CODE_MODE_CONCURRENCY_LIMIT',\n { maxWorkers },\n );\n }\n}\n\n/**\n * Raised when the provided source exceeds `executionPolicy.maxSourceBytes`.\n */\nexport class CodeModeSourceTooLargeError extends CodeModeError {\n constructor(bytes: number, maxBytes: number) {\n super(\n `Code mode source exceeds the ${maxBytes} byte size limit.`,\n 'CODE_MODE_SOURCE_TOO_LARGE',\n { bytes, maxBytes },\n );\n }\n}\n\n/**\n * Raised when sandboxed code exceeds bridge request limits.\n */\nexport class CodeModeBridgeLimitError extends CodeModeError {\n constructor(message: string, details?: unknown) {\n super(message, 'CODE_MODE_BRIDGE_LIMIT', details);\n }\n}\n\n/**\n * Raised when sandboxed code starts host bridge work and returns without\n * awaiting or otherwise observing it.\n */\nexport class CodeModeDetachedBridgeRequestError extends CodeModeError {\n constructor(message: string, details?: unknown) {\n super(message, 'CODE_MODE_DETACHED_BRIDGE_REQUEST', details);\n }\n}\n\n/**\n * Raised when the main thread and worker protocol observes an invalid or\n * mismatched message.\n */\nexport class CodeModeProtocolError extends CodeModeError {\n constructor(message: string, details?: unknown) {\n super(message, 'CODE_MODE_PROTOCOL_ERROR', details);\n }\n}\n\n/**\n * Base class for failures caused by nested host tool execution.\n */\nexport class CodeModeToolError extends CodeModeError {\n constructor(message: string, details?: unknown) {\n super(message, 'CODE_MODE_TOOL_ERROR', details);\n }\n}\n\n/**\n * Converts an unknown thrown value into a worker-safe serializable shape.\n *\n * @internal\n */\nexport function serializeError(error: unknown): SerializableError {\n if (error instanceof CodeModeError) {\n const result = compactError({\n name: error.name,\n message: error.message,\n code: error.code,\n });\n if (error.stack !== undefined) {\n result.stack = error.stack;\n }\n if (error.details !== undefined) {\n result.details = error.details;\n }\n return result;\n }\n\n if (error instanceof Error) {\n const result = compactError({\n name: error.name,\n message: error.message,\n });\n if (error.stack !== undefined) {\n result.stack = error.stack;\n }\n const maybeCoded = error as Error & { code?: unknown; details?: unknown };\n if (typeof maybeCoded.code === 'string') {\n result.code = maybeCoded.code;\n }\n if (maybeCoded.details !== undefined) {\n result.details = maybeCoded.details;\n }\n return result;\n }\n\n return {\n name: 'Error',\n message: String(error),\n };\n}\n\n/**\n * Converts host bridge failures into a sandbox-visible sanitized shape.\n *\n * This intentionally omits stack traces and diagnostic details. Full host\n * diagnostics remain on the host side.\n *\n * @internal\n */\nexport function serializeBridgeErrorForGuest(\n error: unknown,\n context: 'tool' | 'bridge',\n): SerializableError {\n if (error instanceof CodeModeError) {\n return compactError({\n name: error.name,\n message: error.message,\n code: error.code,\n });\n }\n\n const fallback =\n context === 'tool'\n ? {\n message: 'Host tool failed.',\n code: 'CODE_MODE_HOST_TOOL_ERROR',\n }\n : {\n message: 'Host bridge request failed.',\n code: 'CODE_MODE_HOST_BRIDGE_ERROR',\n };\n\n return {\n name: 'Error',\n message: fallback.message,\n code: fallback.code,\n };\n}\n\nfunction compactError(error: {\n name: string;\n message: string;\n stack?: string;\n code?: string;\n details?: unknown;\n}): SerializableError {\n return {\n name: error.name,\n message: error.message,\n ...(error.stack !== undefined ? { stack: error.stack } : {}),\n ...(error.code !== undefined ? { code: error.code } : {}),\n ...(error.details !== undefined ? { details: error.details } : {}),\n };\n}\n\n/**\n * Rehydrates a serialized worker error into an Error instance.\n *\n * @internal\n */\nexport function deserializeError(error: SerializableError): Error {\n if (error.code === 'CODE_MODE_SOURCE_TOO_LARGE') {\n const details = error.details as\n | { bytes?: number; maxBytes?: number }\n | undefined;\n const result = new CodeModeSourceTooLargeError(\n details?.bytes ?? 0,\n details?.maxBytes ?? 0,\n );\n restoreStack(result, error);\n return result;\n }\n\n if (error.code === 'CODE_MODE_BRIDGE_LIMIT') {\n const result = new CodeModeBridgeLimitError(error.message, error.details);\n restoreStack(result, error);\n return result;\n }\n\n if (error.code === 'CODE_MODE_DETACHED_BRIDGE_REQUEST') {\n const result = new CodeModeDetachedBridgeRequestError(\n error.message,\n error.details,\n );\n restoreStack(result, error);\n return result;\n }\n\n if (error.code === 'CODE_MODE_PROTOCOL_ERROR') {\n const result = new CodeModeProtocolError(error.message, error.details);\n restoreStack(result, error);\n return result;\n }\n\n const result = new CodeModeError(\n error.message,\n error.code ?? 'CODE_MODE_ERROR',\n error.details,\n );\n result.name = error.name;\n restoreStack(result, error);\n return result;\n}\n\nfunction restoreStack(error: Error, serialized: SerializableError): void {\n if (serialized.stack) {\n error.stack = serialized.stack;\n }\n}\n"],"mappings":"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","names":["result"]}
|
|
1
|
+
{"version":3,"sources":["../src/errors.ts"],"sourcesContent":["import type { SerializableError } from './types.js';\n\n/**\n * Base class for errors raised by code mode.\n *\n * All package-specific errors include a stable `code` string and may include\n * structured `details` for diagnostics.\n */\nexport class CodeModeError extends Error {\n /**\n * Stable machine-readable error code.\n */\n code: string;\n /**\n * Optional structured diagnostic details.\n */\n readonly details?: unknown;\n\n constructor(message: string, code = 'CODE_MODE_ERROR', details?: unknown) {\n super(message);\n this.name = new.target.name;\n this.code = code;\n this.details = details;\n }\n}\n\n/**\n * Raised when a sandbox invocation exceeds its timeout.\n */\nexport class CodeModeTimeoutError extends CodeModeError {\n constructor(timeoutMs: number) {\n super(\n `Code mode execution timed out after ${timeoutMs}ms.`,\n 'CODE_MODE_TIMEOUT',\n { timeoutMs },\n );\n }\n}\n\n/**\n * Raised when the outer AI SDK abort signal aborts a code-mode invocation.\n */\nexport class CodeModeAbortedError extends CodeModeError {\n constructor() {\n super('Code mode execution was aborted.', 'CODE_MODE_ABORTED');\n }\n}\n\n/**\n * Raised when the process-global worker cap has been reached.\n *\n * Configure the cap with `setMaxWorkers`.\n */\nexport class CodeModeConcurrencyError extends CodeModeError {\n constructor(maxWorkers: number) {\n super(\n `Code mode maxWorkers limit reached (${maxWorkers}).`,\n 'CODE_MODE_CONCURRENCY_LIMIT',\n { maxWorkers },\n );\n }\n}\n\n/**\n * Raised when the provided source exceeds `executionPolicy.maxSourceBytes`.\n */\nexport class CodeModeSourceTooLargeError extends CodeModeError {\n constructor(bytes: number, maxBytes: number) {\n super(\n `Code mode source exceeds the ${maxBytes} byte size limit.`,\n 'CODE_MODE_SOURCE_TOO_LARGE',\n { bytes, maxBytes },\n );\n }\n}\n\n/**\n * Raised when sandboxed code exceeds bridge request limits.\n */\nexport class CodeModeBridgeLimitError extends CodeModeError {\n constructor(message: string, details?: unknown) {\n super(message, 'CODE_MODE_BRIDGE_LIMIT', details);\n }\n}\n\n/**\n * Raised when sandboxed code starts host bridge work and returns without\n * awaiting or otherwise observing it.\n */\nexport class CodeModeDetachedBridgeRequestError extends CodeModeError {\n constructor(message: string, details?: unknown) {\n super(message, 'CODE_MODE_DETACHED_BRIDGE_REQUEST', details);\n }\n}\n\n/**\n * Raised when the main thread and worker protocol observes an invalid or\n * mismatched message.\n */\nexport class CodeModeProtocolError extends CodeModeError {\n constructor(message: string, details?: unknown) {\n super(message, 'CODE_MODE_PROTOCOL_ERROR', details);\n }\n}\n\n/**\n * Base class for failures caused by nested host tool execution.\n */\nexport class CodeModeToolError extends CodeModeError {\n constructor(message: string, details?: unknown) {\n super(message, 'CODE_MODE_TOOL_ERROR', details);\n }\n}\n\nexport class CodeModeToolApprovalRequiredError extends CodeModeToolError {\n constructor(toolName: string, input: unknown, toolCallId: string) {\n super(`Tool \"${toolName}\" requires approval before execution.`, {\n toolName,\n input,\n toolCallId,\n });\n this.code = 'CODE_MODE_TOOL_APPROVAL_REQUIRED';\n }\n}\n\nexport class CodeModeToolApprovalDeniedError extends CodeModeToolError {\n constructor(\n toolName: string,\n input: unknown,\n toolCallId: string,\n reason?: string,\n ) {\n super(\n `Tool \"${toolName}\" approval was denied${reason ? `: ${reason}` : '.'}`,\n {\n toolName,\n input,\n toolCallId,\n ...(reason !== undefined ? { reason } : {}),\n },\n );\n this.code = 'CODE_MODE_TOOL_APPROVAL_DENIED';\n }\n}\n\n/**\n * Converts an unknown thrown value into a worker-safe serializable shape.\n *\n * @internal\n */\nexport function serializeError(error: unknown): SerializableError {\n if (error instanceof CodeModeError) {\n const result = compactError({\n name: error.name,\n message: error.message,\n code: error.code,\n });\n if (error.stack !== undefined) {\n result.stack = error.stack;\n }\n if (error.details !== undefined) {\n result.details = error.details;\n }\n return result;\n }\n\n if (error instanceof Error) {\n const result = compactError({\n name: error.name,\n message: error.message,\n });\n if (error.stack !== undefined) {\n result.stack = error.stack;\n }\n const maybeCoded = error as Error & { code?: unknown; details?: unknown };\n if (typeof maybeCoded.code === 'string') {\n result.code = maybeCoded.code;\n }\n if (maybeCoded.details !== undefined) {\n result.details = maybeCoded.details;\n }\n return result;\n }\n\n return {\n name: 'Error',\n message: String(error),\n };\n}\n\n/**\n * Converts host bridge failures into a sandbox-visible sanitized shape.\n *\n * This intentionally omits stack traces and diagnostic details. Full host\n * diagnostics remain on the host side.\n *\n * @internal\n */\nexport function serializeBridgeErrorForGuest(\n error: unknown,\n context: 'tool' | 'bridge',\n): SerializableError {\n if (error instanceof CodeModeError) {\n return compactError({\n name: error.name,\n message: error.message,\n code: error.code,\n });\n }\n\n const fallback =\n context === 'tool'\n ? {\n message: 'Host tool failed.',\n code: 'CODE_MODE_HOST_TOOL_ERROR',\n }\n : {\n message: 'Host bridge request failed.',\n code: 'CODE_MODE_HOST_BRIDGE_ERROR',\n };\n\n return {\n name: 'Error',\n message: fallback.message,\n code: fallback.code,\n };\n}\n\nfunction compactError(error: {\n name: string;\n message: string;\n stack?: string;\n code?: string;\n details?: unknown;\n}): SerializableError {\n return {\n name: error.name,\n message: error.message,\n ...(error.stack !== undefined ? { stack: error.stack } : {}),\n ...(error.code !== undefined ? { code: error.code } : {}),\n ...(error.details !== undefined ? { details: error.details } : {}),\n };\n}\n\n/**\n * Rehydrates a serialized worker error into an Error instance.\n *\n * @internal\n */\nexport function deserializeError(error: SerializableError): Error {\n if (error.code === 'CODE_MODE_SOURCE_TOO_LARGE') {\n const details = error.details as\n | { bytes?: number; maxBytes?: number }\n | undefined;\n const result = new CodeModeSourceTooLargeError(\n details?.bytes ?? 0,\n details?.maxBytes ?? 0,\n );\n restoreStack(result, error);\n return result;\n }\n\n if (error.code === 'CODE_MODE_BRIDGE_LIMIT') {\n const result = new CodeModeBridgeLimitError(error.message, error.details);\n restoreStack(result, error);\n return result;\n }\n\n if (error.code === 'CODE_MODE_DETACHED_BRIDGE_REQUEST') {\n const result = new CodeModeDetachedBridgeRequestError(\n error.message,\n error.details,\n );\n restoreStack(result, error);\n return result;\n }\n\n if (error.code === 'CODE_MODE_PROTOCOL_ERROR') {\n const result = new CodeModeProtocolError(error.message, error.details);\n restoreStack(result, error);\n return result;\n }\n\n if (error.code === 'CODE_MODE_TOOL_APPROVAL_REQUIRED') {\n const details = error.details as\n | { toolName?: string; input?: unknown; toolCallId?: string }\n | undefined;\n const result = new CodeModeToolApprovalRequiredError(\n details?.toolName ?? 'unknown',\n details?.input,\n details?.toolCallId ?? 'unknown',\n );\n result.message = error.message;\n restoreStack(result, error);\n return result;\n }\n\n if (error.code === 'CODE_MODE_TOOL_APPROVAL_DENIED') {\n const details = error.details as\n | {\n toolName?: string;\n input?: unknown;\n toolCallId?: string;\n reason?: string;\n }\n | undefined;\n const result = new CodeModeToolApprovalDeniedError(\n details?.toolName ?? 'unknown',\n details?.input,\n details?.toolCallId ?? 'unknown',\n details?.reason,\n );\n result.message = error.message;\n restoreStack(result, error);\n return result;\n }\n\n const result = new CodeModeError(\n error.message,\n error.code ?? 'CODE_MODE_ERROR',\n error.details,\n );\n result.name = error.name;\n restoreStack(result, error);\n return result;\n}\n\nfunction restoreStack(error: Error, serialized: SerializableError): void {\n if (serialized.stack) {\n error.stack = serialized.stack;\n }\n}\n"],"mappings":"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","names":["result"]}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
const CODE_MODE_HOST_INTERRUPT_SIGNAL = /* @__PURE__ */ Symbol.for(
|
|
2
|
+
"@ai-sdk/code-mode.host-interrupt"
|
|
3
|
+
);
|
|
4
|
+
function requestCodeModeInterrupt(payload) {
|
|
5
|
+
if (typeof payload !== "object" || payload === null || Array.isArray(payload)) {
|
|
6
|
+
throw new TypeError("Code mode interrupt payload must be an object.");
|
|
7
|
+
}
|
|
8
|
+
if (typeof payload.kind !== "string" || payload.kind.length === 0) {
|
|
9
|
+
throw new TypeError(
|
|
10
|
+
"Code mode interrupt payload must include a string kind."
|
|
11
|
+
);
|
|
12
|
+
}
|
|
13
|
+
const error = new Error("Code mode host interruption requested.");
|
|
14
|
+
error.name = "CodeModeHostInterruptSignal";
|
|
15
|
+
Object.defineProperties(error, {
|
|
16
|
+
[CODE_MODE_HOST_INTERRUPT_SIGNAL]: { value: true },
|
|
17
|
+
payload: { value: payload }
|
|
18
|
+
});
|
|
19
|
+
throw error;
|
|
20
|
+
}
|
|
21
|
+
function isCodeModeHostInterruptSignal(value) {
|
|
22
|
+
return typeof value === "object" && value !== null && value[CODE_MODE_HOST_INTERRUPT_SIGNAL] === true && typeof value.payload === "object" && value.payload !== null;
|
|
23
|
+
}
|
|
24
|
+
export {
|
|
25
|
+
isCodeModeHostInterruptSignal,
|
|
26
|
+
requestCodeModeInterrupt
|
|
27
|
+
};
|
|
28
|
+
//# sourceMappingURL=host-interrupt.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/host-interrupt.ts"],"sourcesContent":["import type { CodeModeInterruptPayload } from './types.js';\n\nconst CODE_MODE_HOST_INTERRUPT_SIGNAL = Symbol.for(\n '@ai-sdk/code-mode.host-interrupt',\n);\n\ninterface CodeModeHostInterruptSignal extends Error {\n readonly [CODE_MODE_HOST_INTERRUPT_SIGNAL]: true;\n readonly payload: CodeModeInterruptPayload;\n}\n\nexport function requestCodeModeInterrupt<\n TPayload extends CodeModeInterruptPayload,\n>(payload: TPayload): never {\n if (\n typeof payload !== 'object' ||\n payload === null ||\n Array.isArray(payload)\n ) {\n throw new TypeError('Code mode interrupt payload must be an object.');\n }\n if (typeof payload.kind !== 'string' || payload.kind.length === 0) {\n throw new TypeError(\n 'Code mode interrupt payload must include a string kind.',\n );\n }\n\n const error = new Error('Code mode host interruption requested.');\n error.name = 'CodeModeHostInterruptSignal';\n Object.defineProperties(error, {\n [CODE_MODE_HOST_INTERRUPT_SIGNAL]: { value: true },\n payload: { value: payload },\n });\n throw error;\n}\n\nexport function isCodeModeHostInterruptSignal(\n value: unknown,\n): value is CodeModeHostInterruptSignal {\n return (\n typeof value === 'object' &&\n value !== null &&\n (value as { [CODE_MODE_HOST_INTERRUPT_SIGNAL]?: unknown })[\n CODE_MODE_HOST_INTERRUPT_SIGNAL\n ] === true &&\n typeof (value as { payload?: unknown }).payload === 'object' &&\n (value as { payload?: unknown }).payload !== null\n );\n}\n"],"mappings":"AAEA,MAAM,kCAAkC,uBAAO;AAAA,EAC7C;AACF;AAOO,SAAS,yBAEd,SAA0B;AAC1B,MACE,OAAO,YAAY,YACnB,YAAY,QACZ,MAAM,QAAQ,OAAO,GACrB;AACA,UAAM,IAAI,UAAU,gDAAgD;AAAA,EACtE;AACA,MAAI,OAAO,QAAQ,SAAS,YAAY,QAAQ,KAAK,WAAW,GAAG;AACjE,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAEA,QAAM,QAAQ,IAAI,MAAM,wCAAwC;AAChE,QAAM,OAAO;AACb,SAAO,iBAAiB,OAAO;AAAA,IAC7B,CAAC,+BAA+B,GAAG,EAAE,OAAO,KAAK;AAAA,IACjD,SAAS,EAAE,OAAO,QAAQ;AAAA,EAC5B,CAAC;AACD,QAAM;AACR;AAEO,SAAS,8BACd,OACsC;AACtC,SACE,OAAO,UAAU,YACjB,UAAU,QACT,MACC,+BACF,MAAM,QACN,OAAQ,MAAgC,YAAY,YACnD,MAAgC,YAAY;AAEjD;","names":[]}
|