subharness 0.0.4 → 0.0.5
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 +36 -6
- package/dist/adapters/claude-process.d.ts +3 -0
- package/dist/adapters/claude-process.js +11 -1
- package/dist/adapters/claude-process.js.map +1 -1
- package/dist/adapters/claude-result.d.ts +2 -0
- package/dist/adapters/claude-result.js +22 -0
- package/dist/adapters/claude-result.js.map +1 -0
- package/dist/adapters/claude.js +30 -11
- package/dist/adapters/claude.js.map +1 -1
- package/dist/adapters/codex.js +4 -1
- package/dist/adapters/codex.js.map +1 -1
- package/dist/adapters/copilot-permissions.d.ts +26 -0
- package/dist/adapters/copilot-permissions.js +121 -0
- package/dist/adapters/copilot-permissions.js.map +1 -0
- package/dist/adapters/copilot-tools.d.ts +12 -0
- package/dist/adapters/copilot-tools.js +61 -0
- package/dist/adapters/copilot-tools.js.map +1 -0
- package/dist/adapters/copilot.d.ts +108 -0
- package/dist/adapters/copilot.js +819 -0
- package/dist/adapters/copilot.js.map +1 -0
- package/dist/adapters/cursor-cli-approvals.d.ts +2 -0
- package/dist/adapters/cursor-cli-approvals.js +83 -0
- package/dist/adapters/cursor-cli-approvals.js.map +1 -0
- package/dist/adapters/cursor-cli-model.d.ts +4 -0
- package/dist/adapters/cursor-cli-model.js +64 -0
- package/dist/adapters/cursor-cli-model.js.map +1 -0
- package/dist/adapters/cursor-cli-session.d.ts +32 -0
- package/dist/adapters/cursor-cli-session.js +316 -0
- package/dist/adapters/cursor-cli-session.js.map +1 -0
- package/dist/adapters/cursor-cli-tools.d.ts +20 -0
- package/dist/adapters/cursor-cli-tools.js +181 -0
- package/dist/adapters/cursor-cli-tools.js.map +1 -0
- package/dist/adapters/cursor-cli.d.ts +2 -0
- package/dist/adapters/cursor-cli.js +306 -0
- package/dist/adapters/cursor-cli.js.map +1 -0
- package/dist/adapters/cursor-model.d.ts +7 -0
- package/dist/adapters/cursor-model.js +67 -0
- package/dist/adapters/cursor-model.js.map +1 -0
- package/dist/adapters/cursor-rpc.d.ts +42 -0
- package/dist/adapters/cursor-rpc.js +271 -0
- package/dist/adapters/cursor-rpc.js.map +1 -0
- package/dist/adapters/cursor-session.d.ts +4 -0
- package/dist/adapters/cursor-session.js +327 -0
- package/dist/adapters/cursor-session.js.map +1 -0
- package/dist/adapters/cursor-startup.d.ts +16 -0
- package/dist/adapters/cursor-startup.js +74 -0
- package/dist/adapters/cursor-startup.js.map +1 -0
- package/dist/adapters/cursor-tools.d.ts +11 -0
- package/dist/adapters/cursor-tools.js +49 -0
- package/dist/adapters/cursor-tools.js.map +1 -0
- package/dist/adapters/cursor.d.ts +6 -0
- package/dist/adapters/cursor.js +17 -0
- package/dist/adapters/cursor.js.map +1 -0
- package/dist/adapters/fx-auth.d.ts +12 -2
- package/dist/adapters/fx-auth.js +51 -61
- package/dist/adapters/fx-auth.js.map +1 -1
- package/dist/adapters/fx-profile.d.ts +8 -0
- package/dist/adapters/fx-profile.js +101 -0
- package/dist/adapters/fx-profile.js.map +1 -0
- package/dist/adapters/fx-rpc.d.ts +2 -0
- package/dist/adapters/fx-rpc.js +30 -4
- package/dist/adapters/fx-rpc.js.map +1 -1
- package/dist/adapters/fx-status.d.ts +2 -0
- package/dist/adapters/fx-status.js +96 -0
- package/dist/adapters/fx-status.js.map +1 -0
- package/dist/adapters/fx.js +28 -12
- package/dist/adapters/fx.js.map +1 -1
- package/dist/adapters/opencode-access.d.ts +13 -0
- package/dist/adapters/opencode-access.js +76 -0
- package/dist/adapters/opencode-access.js.map +1 -0
- package/dist/adapters/opencode-config.d.ts +11 -0
- package/dist/adapters/opencode-config.js +238 -0
- package/dist/adapters/opencode-config.js.map +1 -0
- package/dist/adapters/opencode-http.d.ts +28 -0
- package/dist/adapters/opencode-http.js +297 -0
- package/dist/adapters/opencode-http.js.map +1 -0
- package/dist/adapters/opencode-tools.d.ts +19 -0
- package/dist/adapters/opencode-tools.js +127 -0
- package/dist/adapters/opencode-tools.js.map +1 -0
- package/dist/adapters/opencode.d.ts +2 -0
- package/dist/adapters/opencode.js +569 -0
- package/dist/adapters/opencode.js.map +1 -0
- package/dist/adapters/rpc.d.ts +3 -0
- package/dist/adapters/rpc.js +45 -4
- package/dist/adapters/rpc.js.map +1 -1
- package/dist/adapters/types.d.ts +5 -0
- package/dist/adapters/types.js.map +1 -1
- package/dist/approvals/types.d.ts +1 -1
- package/dist/approvals/types.js.map +1 -1
- package/dist/cli/args.d.ts +1 -1
- package/dist/cli/args.js +4 -1
- package/dist/cli/args.js.map +1 -1
- package/dist/cli/dashboard-client.js +1 -1
- package/dist/cli/dashboard-client.js.map +1 -1
- package/dist/cli/dashboard-controller.d.ts +7 -0
- package/dist/cli/dashboard-controller.js +27 -0
- package/dist/cli/dashboard-controller.js.map +1 -0
- package/dist/cli/dashboard-detail-view.d.ts +1 -1
- package/dist/cli/dashboard-detail-view.js +3 -4
- package/dist/cli/dashboard-detail-view.js.map +1 -1
- package/dist/cli/dashboard-history-view.js.map +1 -1
- package/dist/cli/dashboard-input.d.ts +1 -1
- package/dist/cli/dashboard-input.js +11 -1
- package/dist/cli/dashboard-input.js.map +1 -1
- package/dist/cli/dashboard-layout.js +3 -3
- package/dist/cli/dashboard-layout.js.map +1 -1
- package/dist/cli/dashboard-renderer.js.map +1 -1
- package/dist/cli/dashboard-style.js +2 -2
- package/dist/cli/dashboard-style.js.map +1 -1
- package/dist/cli/dashboard.d.ts +2 -2
- package/dist/cli/dashboard.js +7 -32
- package/dist/cli/dashboard.js.map +1 -1
- package/dist/cli/help.d.ts +1 -1
- package/dist/cli/help.js +30 -12
- package/dist/cli/help.js.map +1 -1
- package/dist/cli/main.js +5 -1
- package/dist/cli/main.js.map +1 -1
- package/dist/config/access-provenance.d.ts +10 -0
- package/dist/config/access-provenance.js +31 -0
- package/dist/config/access-provenance.js.map +1 -0
- package/dist/config/access.d.ts +12 -2
- package/dist/config/access.js +125 -27
- package/dist/config/access.js.map +1 -1
- package/dist/config/loader.js +1 -0
- package/dist/config/loader.js.map +1 -1
- package/dist/config/oidc.js +4 -2
- package/dist/config/oidc.js.map +1 -1
- package/dist/config/project.js +2 -1
- package/dist/config/project.js.map +1 -1
- package/dist/config/resolve-access.js +24 -10
- package/dist/config/resolve-access.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/process-diagnostics.d.ts +2 -0
- package/dist/process-diagnostics.js +11 -0
- package/dist/process-diagnostics.js.map +1 -0
- package/dist/runtime/access-errors.d.ts +4 -0
- package/dist/runtime/access-errors.js +25 -0
- package/dist/runtime/access-errors.js.map +1 -0
- package/dist/runtime/approval-registry.js +1 -1
- package/dist/runtime/approval-registry.js.map +1 -1
- package/dist/runtime/client.js +54 -14
- package/dist/runtime/client.js.map +1 -1
- package/dist/runtime/dashboard-sanitize.d.ts +2 -0
- package/dist/runtime/dashboard-sanitize.js +7 -0
- package/dist/runtime/dashboard-sanitize.js.map +1 -0
- package/dist/runtime/dashboard.d.ts +1 -1
- package/dist/runtime/dashboard.js +2 -3
- package/dist/runtime/dashboard.js.map +1 -1
- package/dist/runtime/definition.js +11 -1
- package/dist/runtime/definition.js.map +1 -1
- package/dist/runtime/select-native.js +26 -8
- package/dist/runtime/select-native.js.map +1 -1
- package/dist/runtime/worker-client.js +38 -13
- package/dist/runtime/worker-client.js.map +1 -1
- package/dist/sdk/definitions.d.ts +4 -1
- package/dist/sdk/definitions.js +16 -2
- package/dist/sdk/definitions.js.map +1 -1
- package/dist/sdk/permission-validation.js +10 -1
- package/dist/sdk/permission-validation.js.map +1 -1
- package/dist/sdk/types.d.ts +29 -1
- package/dist/sdk/types.js.map +1 -1
- package/package.json +4 -1
- package/sdk/access-config.md +58 -4
- package/sdk/adapter-contract.md +5 -3
- package/sdk/additional-harnesses.md +43 -0
- package/sdk/agent-skill.md +2 -2
- package/sdk/agent.md +5 -3
- package/sdk/approvals.md +3 -1
- package/sdk/authentication.md +1 -1
- package/sdk/cli/dashboard-design.md +6 -0
- package/sdk/cli/index.md +9 -6
- package/sdk/cli/output.md +3 -1
- package/sdk/config.md +1 -1
- package/sdk/copilot.md +53 -0
- package/sdk/cursor.md +68 -0
- package/sdk/diagnostics.md +29 -0
- package/sdk/distribution.md +1 -1
- package/sdk/evals.md +1 -1
- package/sdk/fx.md +50 -5
- package/sdk/harnesses.md +13 -13
- package/sdk/index.md +3 -2
- package/sdk/opencode.md +57 -0
- package/sdk/permissions.md +4 -2
- package/sdk/project-team.md +2 -0
- package/sdk/tools.md +1 -1
- package/sdk/v1-runtime.md +3 -3
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fx-profile.js","sourceRoot":"","sources":["../../src/adapters/fx-profile.ts"],"names":[],"mappings":"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","sourcesContent":["import { constants } from \"node:fs\";\nimport { open } from \"node:fs/promises\";\nimport { createHash } from \"node:crypto\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { AgentError } from \"../errors.js\";\n\nconst profileLimit = 1024 * 1024;\n\nfunction record(value: unknown): value is Record<string, unknown> {\n return value !== null && typeof value === \"object\" && !Array.isArray(value);\n}\n\nexport function fxCustomConnection(settings: Record<string, unknown>, provider: string): { endpoint: string; keySlot: string } {\n if (!/^[A-Za-z][A-Za-z0-9_-]{0,63}$/u.test(provider) || [\"gateway\", \"codex\", \"grok\"].includes(provider.toLowerCase())) {\n throw new AgentError(\"INVALID_CONFIG\", \"fx direct API keys require a valid native custom connection name.\");\n }\n const definitions = settings.providers;\n const selected = record(definitions) && Object.hasOwn(definitions, provider) ? definitions[provider] : undefined;\n if (!record(selected)) throw new AgentError(\"INVALID_CONFIG\", \"The selected fx custom connection is not configured in the native profile.\");\n if (selected.protocol !== \"openai-chat-completions\" || !record(selected.auth) || selected.auth.type !== \"bearer\") {\n throw new AgentError(\"UNSUPPORTED_OPTION\", \"fx direct API keys require a native Chat Completions connection with bearer environment authentication.\");\n }\n const slot = selected.auth.env;\n if (typeof slot !== \"string\" || !/^[A-Za-z_][A-Za-z0-9_]{0,127}$/u.test(slot) || unsafeCredentialSlot(slot)) {\n throw new AgentError(\"INVALID_CONFIG\", \"The fx custom connection credential slot cannot control the process, routing, or diagnostics.\");\n }\n const raw = selected.base_url;\n try {\n if (typeof raw !== \"string\" || raw.length > 2048 || /[^\\x21-\\x7e]|[\\\\?#]/u.test(raw) || !/^https?:\\/\\//iu.test(raw)\n || /^https?:\\/\\/[^/]*@/iu.test(raw)) throw new Error();\n const url = new URL(raw);\n if (!url.hostname || url.username || url.password || url.port === \"0\"\n || (url.protocol === \"http:\" && ![\"localhost\", \"127.0.0.1\", \"[::1]\"].includes(url.hostname))) throw new Error();\n return { endpoint: raw.endsWith(\"/\") ? raw.slice(0, -1) : raw, keySlot: slot };\n } catch { throw new AgentError(\"INVALID_CONFIG\", \"The fx custom connection requires a valid HTTPS or loopback HTTP endpoint without credentials, query, or fragment.\"); }\n}\n\nfunction unsafeCredentialSlot(slot: string): boolean {\n const upper = slot.toUpperCase();\n return [\"HOME\", \"PATH\", \"SHELL\", \"ENV\", \"BASH_ENV\", \"ZDOTDIR\", \"PWD\", \"OLDPWD\", \"USER\", \"LOGNAME\", \"TMPDIR\", \"TMP\", \"TEMP\",\n \"AI_GATEWAY_API_KEY\", \"VERCEL_OIDC_TOKEN\", \"HTTP_PROXY\", \"HTTPS_PROXY\", \"ALL_PROXY\", \"NO_PROXY\"].includes(upper)\n || /^(?:FX_|NODE_|LD_|DYLD_|XDG_|SSL_|OPENSSL_|SUBHARNESS_)/u.test(upper);\n}\n\nexport async function readFxProfile(env: NodeJS.ProcessEnv): Promise<{ settings: Record<string, unknown>; fingerprint: string }> {\n let file;\n try {\n file = await open(join(env.HOME || homedir(), \".fx/settings.json\"), constants.O_RDONLY | constants.O_NONBLOCK | (constants.O_NOFOLLOW ?? 0));\n const stat = await file.stat();\n if (!stat.isFile() || stat.size > profileLimit) throw new Error(\"Invalid profile size or type\");\n const buffer = Buffer.alloc(profileLimit + 1);\n let length = 0;\n while (length < buffer.length) {\n const { bytesRead } = await file.read(buffer, length, buffer.length - length, length);\n if (!bytesRead) break;\n length += bytesRead;\n }\n if (length > profileLimit) throw new Error(\"Profile exceeds limit\");\n const bytes = buffer.subarray(0, length);\n const text = new TextDecoder(\"utf-8\", { fatal: true }).decode(bytes);\n const settings: unknown = JSON.parse(text);\n rejectDuplicateKeys(text);\n if (!settings || typeof settings !== \"object\" || Array.isArray(settings)) throw new Error(\"Invalid profile shape\");\n return { settings: settings as Record<string, unknown>, fingerprint: createHash(\"sha256\").update(bytes).digest(\"hex\") };\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") return { settings: {}, fingerprint: \"missing\" };\n throw new AgentError(\"INVALID_CONFIG\", \"fx native settings must be a valid bounded JSON object in a regular profile file.\");\n } finally { await file?.close(); }\n}\n\n/** JSON.parse validates syntax first; this scan retains duplicate-key evidence. */\nfunction rejectDuplicateKeys(text: string): void {\n const containers: (Set<string> | undefined)[] = [];\n for (const match of text.matchAll(/\"(?:\\\\.|[^\"\\\\])*\"|[{}\\[\\]]/gu)) {\n const token = match[0];\n if (token === \"{\") containers.push(new Set());\n else if (token === \"[\") containers.push(undefined);\n else if (token === \"}\" || token === \"]\") containers.pop();\n else if (/^\\s*:/u.test(text.slice(match.index! + token.length))) {\n const keys = containers.at(-1)!;\n const key = JSON.parse(token) as string;\n if (keys.has(key)) throw new Error(\"Duplicate native profile key\");\n keys.add(key);\n }\n }\n}\n"]}
|
|
@@ -14,6 +14,7 @@ export declare class FxRpc {
|
|
|
14
14
|
private sequence;
|
|
15
15
|
private buffer;
|
|
16
16
|
private failure?;
|
|
17
|
+
private closing;
|
|
17
18
|
private readonly exited;
|
|
18
19
|
private failureHandler;
|
|
19
20
|
onMessage: (message: AcpEnvelope) => void;
|
|
@@ -26,4 +27,5 @@ export declare class FxRpc {
|
|
|
26
27
|
private read;
|
|
27
28
|
private invalid;
|
|
28
29
|
private fail;
|
|
30
|
+
private closedError;
|
|
29
31
|
}
|
package/dist/adapters/fx-rpc.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { spawn } from "node:child_process";
|
|
2
2
|
import { AgentError } from "../errors.js";
|
|
3
|
+
import { processExitDescription } from "../process-diagnostics.js";
|
|
4
|
+
import { nativeRpcErrorDescription } from "./rpc.js";
|
|
3
5
|
/** A JSON-RPC 2.0 newline transport for fx's native ACP process. */
|
|
4
6
|
export class FxRpc {
|
|
5
7
|
child;
|
|
@@ -7,6 +9,7 @@ export class FxRpc {
|
|
|
7
9
|
sequence = 0;
|
|
8
10
|
buffer = "";
|
|
9
11
|
failure;
|
|
12
|
+
closing = false;
|
|
10
13
|
exited;
|
|
11
14
|
failureHandler = () => { };
|
|
12
15
|
onMessage = () => { };
|
|
@@ -15,16 +18,30 @@ export class FxRpc {
|
|
|
15
18
|
this.child.stdout.setEncoding("utf8");
|
|
16
19
|
this.child.stdout.on("data", chunk => this.read(chunk));
|
|
17
20
|
this.child.stderr.resume();
|
|
18
|
-
this.child.stdin.on("error", () =>
|
|
21
|
+
this.child.stdin.on("error", () => setImmediate(() => {
|
|
22
|
+
if (!this.closing && this.child.exitCode === null && this.child.signalCode === null) {
|
|
23
|
+
this.fail(new AgentError("HARNESS_FAILED", "The fx ACP input connection closed."));
|
|
24
|
+
}
|
|
25
|
+
}));
|
|
19
26
|
this.child.on("error", () => this.fail(new AgentError("HARNESS_UNAVAILABLE", "Cannot start fx. Install fx 0.0.9 or a compatible release and make it available on PATH.")));
|
|
20
|
-
this.exited = new Promise(resolve => this.child.once("close", () => {
|
|
21
|
-
|
|
27
|
+
this.exited = new Promise(resolve => this.child.once("close", (code, signal) => {
|
|
28
|
+
if (this.closing) {
|
|
29
|
+
if (this.pending.size > 0)
|
|
30
|
+
this.fail(new AgentError("HARNESS_FAILED", "The fx session closed before the native operation completed."));
|
|
31
|
+
else
|
|
32
|
+
this.fail(this.closedError());
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
this.fail(new AgentError("HARNESS_FAILED", `fx exited before the native operation completed${processExitDescription(code, signal)}.`));
|
|
36
|
+
}
|
|
22
37
|
resolve();
|
|
23
38
|
}));
|
|
24
39
|
}
|
|
25
40
|
request(method, params) {
|
|
26
41
|
if (this.failure)
|
|
27
42
|
return Promise.reject(this.failure);
|
|
43
|
+
if (this.closing)
|
|
44
|
+
return Promise.reject(this.closedError());
|
|
28
45
|
const id = ++this.sequence;
|
|
29
46
|
return new Promise((resolve, reject) => {
|
|
30
47
|
this.pending.set(id, { method, resolve, reject });
|
|
@@ -34,6 +51,8 @@ export class FxRpc {
|
|
|
34
51
|
send(message) {
|
|
35
52
|
if (this.failure)
|
|
36
53
|
throw this.failure;
|
|
54
|
+
if (this.closing)
|
|
55
|
+
throw this.closedError();
|
|
37
56
|
this.child.stdin.write(`${JSON.stringify({ jsonrpc: "2.0", ...message })}\n`);
|
|
38
57
|
}
|
|
39
58
|
abort(error) {
|
|
@@ -48,6 +67,7 @@ export class FxRpc {
|
|
|
48
67
|
async close() {
|
|
49
68
|
if (this.child.exitCode !== null || this.child.signalCode !== null)
|
|
50
69
|
return this.exited;
|
|
70
|
+
this.closing = true;
|
|
51
71
|
this.child.kill("SIGTERM");
|
|
52
72
|
const timer = setTimeout(() => this.child.kill("SIGKILL"), 2_000);
|
|
53
73
|
timer.unref();
|
|
@@ -100,7 +120,10 @@ export class FxRpc {
|
|
|
100
120
|
const nativeCode = message.error?.code;
|
|
101
121
|
const unsupported = pending.method === "session/set_config_option" && (nativeCode === -32601 || nativeCode === -32602);
|
|
102
122
|
const code = unsupported ? "UNSUPPORTED_OPTION" : "NATIVE_ERROR";
|
|
103
|
-
|
|
123
|
+
const diagnostic = `fx rejected ${pending.method}${nativeRpcErrorDescription(message.error)}.`;
|
|
124
|
+
pending.reject(new AgentError(code, code === "UNSUPPORTED_OPTION"
|
|
125
|
+
? `${diagnostic} The requested session option is unsupported.`
|
|
126
|
+
: diagnostic));
|
|
104
127
|
}
|
|
105
128
|
else {
|
|
106
129
|
pending.resolve(message.result);
|
|
@@ -120,5 +143,8 @@ export class FxRpc {
|
|
|
120
143
|
this.pending.clear();
|
|
121
144
|
this.failureHandler(error);
|
|
122
145
|
}
|
|
146
|
+
closedError() {
|
|
147
|
+
return new AgentError("HARNESS_FAILED", "The fx session is closed.");
|
|
148
|
+
}
|
|
123
149
|
}
|
|
124
150
|
//# sourceMappingURL=fx-rpc.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fx-rpc.js","sourceRoot":"","sources":["../../src/adapters/fx-rpc.ts"],"names":[],"mappings":"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","sourcesContent":["import { spawn, type ChildProcessWithoutNullStreams } from \"node:child_process\";\nimport { AgentError } from \"../errors.js\";\n\nexport type AcpEnvelope = {\n jsonrpc?: string;\n id?: string | number;\n method?: string;\n params?: any;\n result?: any;\n error?: unknown;\n};\n\ntype Pending = { method: string; resolve(value: any): void; reject(error: Error): void };\n\n/** A JSON-RPC 2.0 newline transport for fx's native ACP process. */\nexport class FxRpc {\n private readonly child: ChildProcessWithoutNullStreams;\n private readonly pending = new Map<number, Pending>();\n private sequence = 0;\n private buffer = \"\";\n private failure?: AgentError;\n private readonly exited: Promise<void>;\n private failureHandler: (error: AgentError) => void = () => {};\n onMessage: (message: AcpEnvelope) => void = () => {};\n\n constructor(cwd: string, env: NodeJS.ProcessEnv, model?: string) {\n this.child = spawn(\"fx\", model ? [\"acp\", \"--model\", model] : [\"acp\"], { cwd, env, stdio: [\"pipe\", \"pipe\", \"pipe\"] });\n this.child.stdout.setEncoding(\"utf8\");\n this.child.stdout.on(\"data\", chunk => this.read(chunk));\n this.child.stderr.resume();\n this.child.stdin.on(\"error\", () => this.fail(new AgentError(\"HARNESS_FAILED\", \"The fx ACP input connection closed.\")));\n this.child.on(\"error\", () => this.fail(new AgentError(\"HARNESS_UNAVAILABLE\", \"Cannot start fx. Install fx 0.0.9 or a compatible release and make it available on PATH.\")));\n this.exited = new Promise(resolve => this.child.once(\"close\", () => {\n this.fail(new AgentError(\"HARNESS_FAILED\", \"fx exited before the native operation completed.\"));\n resolve();\n }));\n }\n\n request(method: string, params: unknown): Promise<any> {\n if (this.failure) return Promise.reject(this.failure);\n const id = ++this.sequence;\n return new Promise((resolve, reject) => {\n this.pending.set(id, { method, resolve, reject });\n this.send({ id, method, params });\n });\n }\n\n send(message: AcpEnvelope): void {\n if (this.failure) throw this.failure;\n this.child.stdin.write(`${JSON.stringify({ jsonrpc: \"2.0\", ...message })}\\n`);\n }\n\n abort(error: AgentError): void {\n this.fail(error);\n void this.close();\n }\n\n setFailureHandler(handler: (error: AgentError) => void): void {\n this.failureHandler = handler;\n if (this.failure) handler(this.failure);\n }\n\n async close(): Promise<void> {\n if (this.child.exitCode !== null || this.child.signalCode !== null) return this.exited;\n this.child.kill(\"SIGTERM\");\n const timer = setTimeout(() => this.child.kill(\"SIGKILL\"), 2_000);\n timer.unref();\n await this.exited;\n clearTimeout(timer);\n }\n\n private read(chunk: string): void {\n this.buffer += chunk;\n if (this.buffer.length > 16 * 1024 * 1024) return this.invalid();\n let newline: number;\n while ((newline = this.buffer.indexOf(\"\\n\")) >= 0) {\n const line = this.buffer.slice(0, newline);\n this.buffer = this.buffer.slice(newline + 1);\n if (!line.trim()) continue;\n let message: AcpEnvelope;\n try { message = JSON.parse(line); } catch { return this.invalid(); }\n if (!message || typeof message !== \"object\" || Array.isArray(message) || message.jsonrpc !== \"2.0\") return this.invalid();\n if (typeof message.method === \"string\") {\n if (Object.hasOwn(message, \"result\") || Object.hasOwn(message, \"error\")) return this.invalid();\n this.onMessage(message);\n continue;\n }\n if (typeof message.id !== \"number\") return this.invalid();\n const hasResult = Object.hasOwn(message, \"result\");\n const hasError = Object.hasOwn(message, \"error\");\n if (hasResult === hasError) return this.invalid();\n if (hasError) {\n const error = message.error;\n if (!error || typeof error !== \"object\" || Array.isArray(error)\n || !Number.isInteger((error as { code?: unknown }).code)\n || typeof (error as { message?: unknown }).message !== \"string\") return this.invalid();\n }\n const pending = this.pending.get(message.id);\n if (!pending) continue;\n this.pending.delete(message.id);\n if (hasError) {\n const nativeCode = (message.error as { code?: unknown } | null)?.code;\n const unsupported = pending.method === \"session/set_config_option\" && (nativeCode === -32601 || nativeCode === -32602);\n const code = unsupported ? \"UNSUPPORTED_OPTION\" : \"NATIVE_ERROR\";\n pending.reject(new AgentError(code, code === \"UNSUPPORTED_OPTION\" ? \"fx rejected the requested session option.\" : `fx rejected ${pending.method}. Check the native harness configuration.`));\n } else {\n pending.resolve(message.result);\n }\n }\n }\n\n private invalid(): void {\n this.fail(new AgentError(\"PROTOCOL_ERROR\", \"fx returned invalid ACP protocol data.\"));\n void this.close();\n }\n\n private fail(error: AgentError): void {\n if (this.failure) return;\n this.failure = error;\n for (const pending of this.pending.values()) pending.reject(error);\n this.pending.clear();\n this.failureHandler(error);\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"fx-rpc.js","sourceRoot":"","sources":["../../src/adapters/fx-rpc.ts"],"names":[],"mappings":"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","sourcesContent":["import { spawn, type ChildProcessWithoutNullStreams } from \"node:child_process\";\nimport { AgentError } from \"../errors.js\";\nimport { processExitDescription } from \"../process-diagnostics.js\";\nimport { nativeRpcErrorDescription } from \"./rpc.js\";\n\nexport type AcpEnvelope = {\n jsonrpc?: string;\n id?: string | number;\n method?: string;\n params?: any;\n result?: any;\n error?: unknown;\n};\n\ntype Pending = { method: string; resolve(value: any): void; reject(error: Error): void };\n\n/** A JSON-RPC 2.0 newline transport for fx's native ACP process. */\nexport class FxRpc {\n private readonly child: ChildProcessWithoutNullStreams;\n private readonly pending = new Map<number, Pending>();\n private sequence = 0;\n private buffer = \"\";\n private failure?: AgentError;\n private closing = false;\n private readonly exited: Promise<void>;\n private failureHandler: (error: AgentError) => void = () => {};\n onMessage: (message: AcpEnvelope) => void = () => {};\n\n constructor(cwd: string, env: NodeJS.ProcessEnv, model?: string) {\n this.child = spawn(\"fx\", model ? [\"acp\", \"--model\", model] : [\"acp\"], { cwd, env, stdio: [\"pipe\", \"pipe\", \"pipe\"] });\n this.child.stdout.setEncoding(\"utf8\");\n this.child.stdout.on(\"data\", chunk => this.read(chunk));\n this.child.stderr.resume();\n this.child.stdin.on(\"error\", () => setImmediate(() => {\n if (!this.closing && this.child.exitCode === null && this.child.signalCode === null) {\n this.fail(new AgentError(\"HARNESS_FAILED\", \"The fx ACP input connection closed.\"));\n }\n }));\n this.child.on(\"error\", () => this.fail(new AgentError(\"HARNESS_UNAVAILABLE\", \"Cannot start fx. Install fx 0.0.9 or a compatible release and make it available on PATH.\")));\n this.exited = new Promise(resolve => this.child.once(\"close\", (code, signal) => {\n if (this.closing) {\n if (this.pending.size > 0) this.fail(new AgentError(\"HARNESS_FAILED\",\"The fx session closed before the native operation completed.\"));\n else this.fail(this.closedError());\n } else {\n this.fail(new AgentError(\"HARNESS_FAILED\",\n `fx exited before the native operation completed${processExitDescription(code, signal)}.`));\n }\n resolve();\n }));\n }\n\n request(method: string, params: unknown): Promise<any> {\n if (this.failure) return Promise.reject(this.failure);\n if (this.closing) return Promise.reject(this.closedError());\n const id = ++this.sequence;\n return new Promise((resolve, reject) => {\n this.pending.set(id, { method, resolve, reject });\n this.send({ id, method, params });\n });\n }\n\n send(message: AcpEnvelope): void {\n if (this.failure) throw this.failure;\n if (this.closing) throw this.closedError();\n this.child.stdin.write(`${JSON.stringify({ jsonrpc: \"2.0\", ...message })}\\n`);\n }\n\n abort(error: AgentError): void {\n this.fail(error);\n void this.close();\n }\n\n setFailureHandler(handler: (error: AgentError) => void): void {\n this.failureHandler = handler;\n if (this.failure) handler(this.failure);\n }\n\n async close(): Promise<void> {\n if (this.child.exitCode !== null || this.child.signalCode !== null) return this.exited;\n this.closing = true;\n this.child.kill(\"SIGTERM\");\n const timer = setTimeout(() => this.child.kill(\"SIGKILL\"), 2_000);\n timer.unref();\n await this.exited;\n clearTimeout(timer);\n }\n\n private read(chunk: string): void {\n this.buffer += chunk;\n if (this.buffer.length > 16 * 1024 * 1024) return this.invalid();\n let newline: number;\n while ((newline = this.buffer.indexOf(\"\\n\")) >= 0) {\n const line = this.buffer.slice(0, newline);\n this.buffer = this.buffer.slice(newline + 1);\n if (!line.trim()) continue;\n let message: AcpEnvelope;\n try { message = JSON.parse(line); } catch { return this.invalid(); }\n if (!message || typeof message !== \"object\" || Array.isArray(message) || message.jsonrpc !== \"2.0\") return this.invalid();\n if (typeof message.method === \"string\") {\n if (Object.hasOwn(message, \"result\") || Object.hasOwn(message, \"error\")) return this.invalid();\n this.onMessage(message);\n continue;\n }\n if (typeof message.id !== \"number\") return this.invalid();\n const hasResult = Object.hasOwn(message, \"result\");\n const hasError = Object.hasOwn(message, \"error\");\n if (hasResult === hasError) return this.invalid();\n if (hasError) {\n const error = message.error;\n if (!error || typeof error !== \"object\" || Array.isArray(error)\n || !Number.isInteger((error as { code?: unknown }).code)\n || typeof (error as { message?: unknown }).message !== \"string\") return this.invalid();\n }\n const pending = this.pending.get(message.id);\n if (!pending) continue;\n this.pending.delete(message.id);\n if (hasError) {\n const nativeCode = (message.error as { code?: unknown } | null)?.code;\n const unsupported = pending.method === \"session/set_config_option\" && (nativeCode === -32601 || nativeCode === -32602);\n const code = unsupported ? \"UNSUPPORTED_OPTION\" : \"NATIVE_ERROR\";\n const diagnostic = `fx rejected ${pending.method}${nativeRpcErrorDescription(message.error)}.`;\n pending.reject(new AgentError(code, code === \"UNSUPPORTED_OPTION\"\n ? `${diagnostic} The requested session option is unsupported.`\n : diagnostic));\n } else {\n pending.resolve(message.result);\n }\n }\n }\n\n private invalid(): void {\n this.fail(new AgentError(\"PROTOCOL_ERROR\", \"fx returned invalid ACP protocol data.\"));\n void this.close();\n }\n\n private fail(error: AgentError): void {\n if (this.failure) return;\n this.failure = error;\n for (const pending of this.pending.values()) pending.reject(error);\n this.pending.clear();\n this.failureHandler(error);\n }\n\n private closedError(): AgentError {\n return new AgentError(\"HARNESS_FAILED\", \"The fx session is closed.\");\n }\n}\n"]}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { spawn } from "node:child_process";
|
|
2
|
+
import { AgentError } from "../errors.js";
|
|
3
|
+
const outputLimit = 1024 * 1024;
|
|
4
|
+
const ownsGroup = process.platform !== "win32";
|
|
5
|
+
/** Credential diagnostics never release ownership on a timeout or unknown exit. */
|
|
6
|
+
export async function captureFxStatus(cwd, env) {
|
|
7
|
+
const child = (() => {
|
|
8
|
+
try {
|
|
9
|
+
return spawn("fx", ["status", "--json"], { cwd, env, detached: ownsGroup, stdio: ["ignore", "pipe", "pipe"] });
|
|
10
|
+
}
|
|
11
|
+
catch {
|
|
12
|
+
throw new AgentError("INVALID_CONFIG", "fx credential-source verification could not start with the selected process configuration.");
|
|
13
|
+
}
|
|
14
|
+
})();
|
|
15
|
+
let failure;
|
|
16
|
+
let exitCode = null;
|
|
17
|
+
let exitSeen = false;
|
|
18
|
+
let bytes = 0;
|
|
19
|
+
const chunks = [];
|
|
20
|
+
let resolveExited;
|
|
21
|
+
let rejectRetirement;
|
|
22
|
+
const exited = new Promise(resolve => { resolveExited = resolve; });
|
|
23
|
+
const unconfirmed = new Promise((_resolve, reject) => { rejectRetirement = reject; });
|
|
24
|
+
const closed = new Promise(resolve => child.once("close", resolve));
|
|
25
|
+
let killTimer;
|
|
26
|
+
let retirementTimer;
|
|
27
|
+
const signal = (value) => {
|
|
28
|
+
if (child.pid === undefined)
|
|
29
|
+
return;
|
|
30
|
+
try {
|
|
31
|
+
if (ownsGroup)
|
|
32
|
+
process.kill(-child.pid, value);
|
|
33
|
+
else if (!exitSeen)
|
|
34
|
+
child.kill(value);
|
|
35
|
+
}
|
|
36
|
+
catch (error) {
|
|
37
|
+
if (error.code !== "ESRCH")
|
|
38
|
+
failure = new AgentError("CANCELLATION_FAILED", "fx credential-source verification could not retire its owned process.");
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
const stop = (error) => {
|
|
42
|
+
if (failure)
|
|
43
|
+
return;
|
|
44
|
+
failure = error;
|
|
45
|
+
signal("SIGTERM");
|
|
46
|
+
killTimer = setTimeout(() => signal("SIGKILL"), 250);
|
|
47
|
+
retirementTimer = setTimeout(() => rejectRetirement(new AgentError("CANCELLATION_FAILED", "fx credential-source verification did not confirm process termination.")), 1_250);
|
|
48
|
+
};
|
|
49
|
+
child.stdout.on("data", (chunk) => {
|
|
50
|
+
if (failure)
|
|
51
|
+
return;
|
|
52
|
+
bytes += chunk.byteLength;
|
|
53
|
+
if (bytes > outputLimit)
|
|
54
|
+
stop(new AgentError("PROTOCOL_ERROR", "fx returned oversized credential-source status."));
|
|
55
|
+
else
|
|
56
|
+
chunks.push(chunk);
|
|
57
|
+
});
|
|
58
|
+
child.stderr.resume();
|
|
59
|
+
child.once("error", error => {
|
|
60
|
+
const absent = error.code === "ENOENT";
|
|
61
|
+
stop(new AgentError(absent ? "HARNESS_UNAVAILABLE" : "PROTOCOL_ERROR", absent
|
|
62
|
+
? "Cannot start fx. Install a compatible fx release and make it available on PATH."
|
|
63
|
+
: "fx credential-source verification failed to communicate with the native process."));
|
|
64
|
+
if (child.pid === undefined)
|
|
65
|
+
resolveExited();
|
|
66
|
+
});
|
|
67
|
+
child.once("exit", code => { exitSeen = true; exitCode = code; resolveExited(); });
|
|
68
|
+
const timer = setTimeout(() => stop(new AgentError("PROTOCOL_ERROR", "fx credential-source verification timed out.")), 2_000);
|
|
69
|
+
try {
|
|
70
|
+
await Promise.race([exited, unconfirmed]);
|
|
71
|
+
}
|
|
72
|
+
finally {
|
|
73
|
+
clearTimeout(timer);
|
|
74
|
+
clearTimeout(killTimer);
|
|
75
|
+
clearTimeout(retirementTimer);
|
|
76
|
+
signal("SIGKILL");
|
|
77
|
+
await retireStreams(child, closed);
|
|
78
|
+
}
|
|
79
|
+
if (failure)
|
|
80
|
+
throw failure;
|
|
81
|
+
if (exitCode !== 0)
|
|
82
|
+
throw new AgentError("PROTOCOL_ERROR", "fx credential-source verification exited without usable native status.");
|
|
83
|
+
return Buffer.concat(chunks).toString("utf8");
|
|
84
|
+
}
|
|
85
|
+
async function retireStreams(child, closed) {
|
|
86
|
+
let timer;
|
|
87
|
+
try {
|
|
88
|
+
await Promise.race([closed, new Promise(resolve => {
|
|
89
|
+
timer = setTimeout(() => { child.stdout.destroy(); child.stderr.destroy(); resolve(); }, 250);
|
|
90
|
+
})]);
|
|
91
|
+
}
|
|
92
|
+
finally {
|
|
93
|
+
clearTimeout(timer);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
//# sourceMappingURL=fx-status.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fx-status.js","sourceRoot":"","sources":["../../src/adapters/fx-status.ts"],"names":[],"mappings":"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","sourcesContent":["import { spawn, type ChildProcessWithoutNullStreams } from \"node:child_process\";\nimport { AgentError } from \"../errors.js\";\n\nconst outputLimit = 1024 * 1024;\nconst ownsGroup = process.platform !== \"win32\";\n\n/** Credential diagnostics never release ownership on a timeout or unknown exit. */\nexport async function captureFxStatus(cwd: string, env: NodeJS.ProcessEnv): Promise<string> {\n const child = (() => {\n try { return spawn(\"fx\", [\"status\", \"--json\"], { cwd, env, detached: ownsGroup, stdio: [\"ignore\", \"pipe\", \"pipe\"] }); }\n catch { throw new AgentError(\"INVALID_CONFIG\", \"fx credential-source verification could not start with the selected process configuration.\"); }\n })();\n let failure: AgentError | undefined;\n let exitCode: number | null = null;\n let exitSeen = false;\n let bytes = 0;\n const chunks: Buffer[] = [];\n let resolveExited!: () => void;\n let rejectRetirement!: (error: AgentError) => void;\n const exited = new Promise<void>(resolve => { resolveExited = resolve; });\n const unconfirmed = new Promise<never>((_resolve, reject) => { rejectRetirement = reject; });\n const closed = new Promise<void>(resolve => child.once(\"close\", resolve));\n let killTimer: NodeJS.Timeout | undefined;\n let retirementTimer: NodeJS.Timeout | undefined;\n\n const signal = (value: NodeJS.Signals) => {\n if (child.pid === undefined) return;\n try {\n if (ownsGroup) process.kill(-child.pid, value);\n else if (!exitSeen) child.kill(value);\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== \"ESRCH\") failure = new AgentError(\"CANCELLATION_FAILED\", \"fx credential-source verification could not retire its owned process.\");\n }\n };\n const stop = (error: AgentError) => {\n if (failure) return;\n failure = error;\n signal(\"SIGTERM\");\n killTimer = setTimeout(() => signal(\"SIGKILL\"), 250);\n retirementTimer = setTimeout(() => rejectRetirement(new AgentError(\"CANCELLATION_FAILED\", \"fx credential-source verification did not confirm process termination.\")), 1_250);\n };\n child.stdout.on(\"data\", (chunk: Buffer) => {\n if (failure) return;\n bytes += chunk.byteLength;\n if (bytes > outputLimit) stop(new AgentError(\"PROTOCOL_ERROR\", \"fx returned oversized credential-source status.\"));\n else chunks.push(chunk);\n });\n child.stderr.resume();\n child.once(\"error\", error => {\n const absent = (error as NodeJS.ErrnoException).code === \"ENOENT\";\n stop(new AgentError(absent ? \"HARNESS_UNAVAILABLE\" : \"PROTOCOL_ERROR\", absent\n ? \"Cannot start fx. Install a compatible fx release and make it available on PATH.\"\n : \"fx credential-source verification failed to communicate with the native process.\"));\n if (child.pid === undefined) resolveExited();\n });\n child.once(\"exit\", code => { exitSeen = true; exitCode = code; resolveExited(); });\n const timer = setTimeout(() => stop(new AgentError(\"PROTOCOL_ERROR\", \"fx credential-source verification timed out.\")), 2_000);\n try { await Promise.race([exited, unconfirmed]); }\n finally {\n clearTimeout(timer);\n clearTimeout(killTimer);\n clearTimeout(retirementTimer);\n signal(\"SIGKILL\");\n await retireStreams(child, closed);\n }\n if (failure) throw failure;\n if (exitCode !== 0) throw new AgentError(\"PROTOCOL_ERROR\", \"fx credential-source verification exited without usable native status.\");\n return Buffer.concat(chunks).toString(\"utf8\");\n}\n\nasync function retireStreams(child: Pick<ChildProcessWithoutNullStreams, \"stdout\" | \"stderr\">, closed: Promise<void>): Promise<void> {\n let timer: NodeJS.Timeout | undefined;\n try {\n await Promise.race([closed, new Promise<void>(resolve => {\n timer = setTimeout(() => { child.stdout.destroy(); child.stderr.destroy(); resolve(); }, 250);\n })]);\n } finally { clearTimeout(timer); }\n}\n"]}
|
package/dist/adapters/fx.js
CHANGED
|
@@ -1,17 +1,20 @@
|
|
|
1
1
|
import { NativeApprovals } from "./approval-lifetime.js";
|
|
2
2
|
import { fxApproval } from "./fx-approvals.js";
|
|
3
3
|
import { AgentError } from "../errors.js";
|
|
4
|
-
import { fxEnvironment, fxSettingsFingerprint, verifyFxAccess } from "./fx-auth.js";
|
|
4
|
+
import { fxAccessRoute, fxEnvironment, fxSettingsFingerprint, verifyFxAccess } from "./fx-auth.js";
|
|
5
5
|
import { FxRpc } from "./fx-rpc.js";
|
|
6
6
|
import { verifyFxPermissionMode } from "./fx-permissions.js";
|
|
7
7
|
import { startFxTools } from "./fx-tools.js";
|
|
8
8
|
export async function openFx(options, createRpc = (cwd, env, model) => new FxRpc(cwd, env, model)) {
|
|
9
9
|
if (options.harness.kind !== "fx")
|
|
10
10
|
throw new AgentError("INVALID_CONFIG", "fx received configuration for a different harness.");
|
|
11
|
-
const
|
|
12
|
-
const baseline = await fxSettingsFingerprint(env);
|
|
13
|
-
|
|
11
|
+
const route = await fxAccessRoute(options);
|
|
12
|
+
const baseline = route.settingsFingerprint ?? await fxSettingsFingerprint(options.env);
|
|
13
|
+
const env = fxEnvironment(options, route);
|
|
14
|
+
await verifyFxAccess(options.cwd, env, route, options.harness.model);
|
|
14
15
|
await verifyFxPermissionMode(options.cwd, env, options.harness.permissionMode);
|
|
16
|
+
if (await fxSettingsFingerprint(env) !== baseline)
|
|
17
|
+
throw new AgentError("INVALID_CONFIG", "fx native settings changed during access verification. Start a new session.");
|
|
15
18
|
const tools = await startFxTools(options.agent);
|
|
16
19
|
let rpc;
|
|
17
20
|
try {
|
|
@@ -33,17 +36,17 @@ export async function openFx(options, createRpc = (cwd, env, model) => new FxRpc
|
|
|
33
36
|
});
|
|
34
37
|
if (typeof created?.sessionId !== "string" || created.sessionId.length === 0)
|
|
35
38
|
throw new AgentError("PROTOCOL_ERROR", "fx did not return a native session identifier.");
|
|
36
|
-
const selectedModel = verifySelection(created.configOptions, options.harness.model);
|
|
39
|
+
const selectedModel = verifySelection(created.configOptions, route.provider, options.harness.model);
|
|
37
40
|
if (options.harness.effort !== undefined) {
|
|
38
41
|
verifyEffortAvailable(created.configOptions, options.harness.effort);
|
|
39
42
|
const configured = await startedRpc.request("session/set_config_option", { sessionId: created.sessionId, configId: "effort", value: options.harness.effort });
|
|
40
|
-
verifySelection(configured?.configOptions, selectedModel, options.harness.effort);
|
|
43
|
+
verifySelection(configured?.configOptions, route.provider, selectedModel, options.harness.effort);
|
|
41
44
|
}
|
|
42
45
|
if (await fxSettingsFingerprint(env) !== baseline)
|
|
43
46
|
throw new AgentError("INVALID_CONFIG", "fx native settings changed during session startup. Start a new session.");
|
|
44
47
|
if (startupFailure)
|
|
45
48
|
throw startupFailure;
|
|
46
|
-
return new FxSession(startedRpc, created.sessionId, options, env, baseline, tools);
|
|
49
|
+
return new FxSession(startedRpc, created.sessionId, options, env, baseline, tools, route.provider, selectedModel);
|
|
47
50
|
}
|
|
48
51
|
catch (error) {
|
|
49
52
|
await rpc?.close();
|
|
@@ -67,21 +70,21 @@ function option(options, id) {
|
|
|
67
70
|
throw new AgentError("PROTOCOL_ERROR", "fx returned invalid native session options.");
|
|
68
71
|
return options.find(value => value && typeof value === "object" && value.id === id);
|
|
69
72
|
}
|
|
70
|
-
function verifySelection(configOptions, requestedModel, effort) {
|
|
73
|
+
function verifySelection(configOptions, requestedProvider, requestedModel, effort) {
|
|
71
74
|
const provider = option(configOptions, "provider");
|
|
72
75
|
const selectedModel = option(configOptions, "model");
|
|
73
76
|
if (!provider || !selectedModel) {
|
|
74
77
|
throw new AgentError("PROTOCOL_ERROR", "fx did not expose compatible native provider and model selectors.");
|
|
75
78
|
}
|
|
76
|
-
if (provider.currentValue !==
|
|
77
|
-
throw new AgentError("INVALID_CONFIG", "fx selected a provider outside the authorized
|
|
79
|
+
if (provider.currentValue !== requestedProvider) {
|
|
80
|
+
throw new AgentError("INVALID_CONFIG", "fx selected a provider outside the authorized route.");
|
|
78
81
|
}
|
|
79
82
|
const model = selectedModel.currentValue;
|
|
80
83
|
if (typeof model !== "string" || model.length === 0) {
|
|
81
84
|
throw new AgentError("INVALID_CONFIG", "fx could not select a verifiable native default for this connection. Supply --model <model>.");
|
|
82
85
|
}
|
|
83
86
|
if (requestedModel && model !== requestedModel) {
|
|
84
|
-
throw new AgentError("INVALID_CONFIG", "fx changed the explicitly selected
|
|
87
|
+
throw new AgentError("INVALID_CONFIG", "fx changed the explicitly selected model.");
|
|
85
88
|
}
|
|
86
89
|
if (effort !== undefined && option(configOptions, "effort")?.currentValue !== effort) {
|
|
87
90
|
throw new AgentError("INVALID_CONFIG", "fx did not apply the explicitly selected effort.");
|
|
@@ -101,18 +104,22 @@ class FxSession {
|
|
|
101
104
|
env;
|
|
102
105
|
settingsFingerprint;
|
|
103
106
|
tools;
|
|
107
|
+
selectedProvider;
|
|
108
|
+
selectedModel;
|
|
104
109
|
active;
|
|
105
110
|
failure;
|
|
106
111
|
retirement;
|
|
107
112
|
first = true;
|
|
108
113
|
closed = false;
|
|
109
|
-
constructor(rpc, sessionId, options, env, settingsFingerprint, tools) {
|
|
114
|
+
constructor(rpc, sessionId, options, env, settingsFingerprint, tools, selectedProvider, selectedModel) {
|
|
110
115
|
this.rpc = rpc;
|
|
111
116
|
this.sessionId = sessionId;
|
|
112
117
|
this.options = options;
|
|
113
118
|
this.env = env;
|
|
114
119
|
this.settingsFingerprint = settingsFingerprint;
|
|
115
120
|
this.tools = tools;
|
|
121
|
+
this.selectedProvider = selectedProvider;
|
|
122
|
+
this.selectedModel = selectedModel;
|
|
116
123
|
rpc.setFailureHandler(error => {
|
|
117
124
|
this.failure ??= error;
|
|
118
125
|
const active = this.active;
|
|
@@ -153,6 +160,15 @@ class FxSession {
|
|
|
153
160
|
}
|
|
154
161
|
if (params?.sessionId !== this.sessionId)
|
|
155
162
|
return;
|
|
163
|
+
if (message.method === "session/update" && params.update?.sessionUpdate === "config_option_update") {
|
|
164
|
+
try {
|
|
165
|
+
verifySelection(params.update.configOptions, this.selectedProvider, this.selectedModel, this.options.harness.effort);
|
|
166
|
+
}
|
|
167
|
+
catch (error) {
|
|
168
|
+
this.rpc.abort(error);
|
|
169
|
+
}
|
|
170
|
+
return;
|
|
171
|
+
}
|
|
156
172
|
if (!active || message.method !== "session/update")
|
|
157
173
|
return;
|
|
158
174
|
const update = params.update;
|
package/dist/adapters/fx.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fx.js","sourceRoot":"","sources":["../../src/adapters/fx.ts"],"names":[],"mappings":"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","sourcesContent":["import { NativeApprovals } from \"./approval-lifetime.js\";\nimport { fxApproval } from \"./fx-approvals.js\";\nimport { AgentError } from \"../errors.js\";\nimport { fxEnvironment, fxSettingsFingerprint, verifyFxAccess } from \"./fx-auth.js\";\nimport { FxRpc, type AcpEnvelope } from \"./fx-rpc.js\";\nimport { verifyFxPermissionMode } from \"./fx-permissions.js\";\nimport { startFxTools, type FxToolEndpoint } from \"./fx-tools.js\";\nimport type { AdapterOptions, NativeSession } from \"./types.js\";\n\ntype ActiveTurn = {\n lastMessageId?: string;\n text: string;\n responseBytes: number;\n responseTooLarge: boolean;\n completion: Promise<string>;\n resolve(text: string): void;\n reject(error: Error): void;\n terminal: boolean;\n submitted: boolean;\n cancelRequested: boolean;\n admission: Promise<void>;\n releaseAdmission(): void;\n nativeStopped: Promise<void>;\n resolveNativeStopped(): void;\n cancellationTimer?: NodeJS.Timeout;\n failure?: AgentError;\n approvals: NativeApprovals;\n withdrawnApprovals: Set<string | number>;\n};\n\nexport async function openFx(\n options: AdapterOptions,\n createRpc: (cwd: string, env: NodeJS.ProcessEnv, model?: string) => FxRpc = (cwd, env, model) => new FxRpc(cwd, env, model),\n): Promise<NativeSession> {\n if (options.harness.kind !== \"fx\") throw new AgentError(\"INVALID_CONFIG\", \"fx received configuration for a different harness.\");\n const env = fxEnvironment(options);\n const baseline = await fxSettingsFingerprint(env);\n await verifyFxAccess(options.cwd, env, options.access.type);\n await verifyFxPermissionMode(options.cwd, env, options.harness.permissionMode);\n const tools = await startFxTools(options.agent);\n let rpc: FxRpc | undefined;\n try {\n const startedRpc = createRpc(options.cwd, env, options.harness.model);\n rpc = startedRpc;\n let startupFailure: AgentError | undefined;\n startedRpc.setFailureHandler(error => { startupFailure ??= error; });\n tools.onFailure(error => startedRpc.abort(error));\n startedRpc.onMessage = message => startupRequest(startedRpc, message);\n const initialized = await startedRpc.request(\"initialize\", { protocolVersion: 1, clientInfo: { name: \"subharness\", version: \"0.1.0\" }, clientCapabilities: {} });\n if (!initialized || typeof initialized !== \"object\" || Array.isArray(initialized) || typeof initialized.protocolVersion !== \"number\") {\n throw new AgentError(\"PROTOCOL_ERROR\", \"fx returned an invalid ACP initialization response.\");\n }\n if (initialized.protocolVersion !== 1) throw new AgentError(\"HARNESS_UNAVAILABLE\", \"The installed fx ACP protocol is not compatible with version 1.\");\n const created = await startedRpc.request(\"session/new\", {\n cwd: options.cwd,\n mcpServers: tools.descriptor ? [tools.descriptor] : [],\n });\n if (typeof created?.sessionId !== \"string\" || created.sessionId.length === 0) throw new AgentError(\"PROTOCOL_ERROR\", \"fx did not return a native session identifier.\");\n const selectedModel = verifySelection(created.configOptions, options.harness.model);\n if (options.harness.effort !== undefined) {\n verifyEffortAvailable(created.configOptions, options.harness.effort);\n const configured = await startedRpc.request(\"session/set_config_option\", { sessionId: created.sessionId, configId: \"effort\", value: options.harness.effort });\n verifySelection(configured?.configOptions, selectedModel, options.harness.effort);\n }\n if (await fxSettingsFingerprint(env) !== baseline) throw new AgentError(\"INVALID_CONFIG\", \"fx native settings changed during session startup. Start a new session.\");\n if (startupFailure) throw startupFailure;\n return new FxSession(startedRpc, created.sessionId, options, env, baseline, tools);\n } catch (error) {\n await rpc?.close();\n await tools.close();\n if (error instanceof AgentError) throw error;\n throw new AgentError(\"HARNESS_UNAVAILABLE\", \"Cannot start fx. Check the native executable and session configuration.\");\n }\n}\n\nfunction startupRequest(rpc: FxRpc, message: AcpEnvelope): void {\n if (message.id === undefined) return;\n try { rpc.send({ id: message.id, result: { outcome: { outcome: \"cancelled\" } } }); } catch { /* process may already be closing */ }\n rpc.abort(new AgentError(\"INPUT_REQUIRED\", \"fx requested interactive input during startup. Complete its native setup before running an agent.\"));\n}\n\nfunction option(options: unknown, id: string): any {\n if (!Array.isArray(options)) throw new AgentError(\"PROTOCOL_ERROR\", \"fx returned invalid native session options.\");\n return options.find(value => value && typeof value === \"object\" && (value as any).id === id);\n}\n\nfunction verifySelection(configOptions: unknown, requestedModel?: string, effort?: string): string {\n const provider = option(configOptions, \"provider\");\n const selectedModel = option(configOptions, \"model\");\n if (!provider || !selectedModel) {\n throw new AgentError(\"PROTOCOL_ERROR\", \"fx did not expose compatible native provider and model selectors.\");\n }\n if (provider.currentValue !== \"gateway\") {\n throw new AgentError(\"INVALID_CONFIG\", \"fx selected a provider outside the authorized Gateway route.\");\n }\n const model = selectedModel.currentValue;\n if (typeof model !== \"string\" || model.length === 0) {\n throw new AgentError(\"INVALID_CONFIG\", \"fx could not select a verifiable native default for this connection. Supply --model <model>.\");\n }\n if (requestedModel && model !== requestedModel) {\n throw new AgentError(\"INVALID_CONFIG\", \"fx changed the explicitly selected Gateway model.\");\n }\n if (effort !== undefined && option(configOptions, \"effort\")?.currentValue !== effort) {\n throw new AgentError(\"INVALID_CONFIG\", \"fx did not apply the explicitly selected effort.\");\n }\n return model;\n}\n\nfunction verifyEffortAvailable(configOptions: unknown, effort: string): void {\n const configured = option(configOptions, \"effort\");\n if (!configured || !Array.isArray(configured.options) || !configured.options.some((value: any) => value?.value === effort)) {\n throw new AgentError(\"UNSUPPORTED_OPTION\", \"The requested fx effort is not supported by the selected model.\");\n }\n}\n\nclass FxSession implements NativeSession {\n private active?: ActiveTurn;\n private failure?: AgentError;\n private retirement?: Promise<void>;\n private first = true;\n private closed = false;\n\n constructor(\n private readonly rpc: FxRpc,\n private readonly sessionId: string,\n private readonly options: AdapterOptions,\n private readonly env: NodeJS.ProcessEnv,\n private readonly settingsFingerprint: string,\n private readonly tools: FxToolEndpoint,\n ) {\n rpc.setFailureHandler(error => {\n this.failure ??= error;\n const active = this.active;\n active?.approvals.clear();\n this.retirement ??= this.rpc.close();\n if (active) void this.retirement.then(() => this.finish(active, undefined, error));\n });\n rpc.onMessage = message => this.message(message);\n }\n\n private message(message: AcpEnvelope): void {\n const active = this.active;\n const params = message.params;\n if (message.method === \"$/cancel_request\" && active && (typeof params?.requestId === \"string\" || typeof params?.requestId === \"number\")) {\n active.withdrawnApprovals.add(params.requestId);\n active.approvals.withdraw(params.requestId);\n return;\n }\n if (message.id !== undefined) {\n if (active && active.submitted && !active.terminal && !active.cancelRequested && !active.failure && params?.sessionId === this.sessionId\n && message.method === \"session/request_permission\" && this.options.onApproval) {\n try {\n const request = fxApproval(params);\n void active.approvals.request(message.id, request, this.options.onApproval).then(content => {\n if (this.active === active && !active.terminal && !active.cancelRequested && !active.failure && !active.withdrawnApprovals.has(message.id!)) {\n this.rpc.send({id:message.id,result:{outcome:{outcome:\"selected\",optionId:content.decision}}});\n }\n }).catch(error => {\n if (!(error instanceof AgentError && error.code === \"REQUEST_EXPIRED\")) this.unsupportedRequest(message, active);\n });\n return;\n } catch { /* Unsupported requests retain the explicit input failure path. */ }\n }\n this.unsupportedRequest(message, active);\n return;\n }\n if (params?.sessionId !== this.sessionId) return;\n if (!active || message.method !== \"session/update\") return;\n const update = params.update;\n if (!update || typeof update !== \"object\" || typeof update.sessionUpdate !== \"string\") {\n this.rpc.abort(new AgentError(\"PROTOCOL_ERROR\", \"fx returned an invalid ACP session update.\"));\n return;\n }\n if (update.sessionUpdate !== \"agent_message_chunk\") return;\n if (typeof update.messageId !== \"string\" || update.content?.type !== \"text\" || typeof update.content.text !== \"string\") {\n this.rpc.abort(new AgentError(\"PROTOCOL_ERROR\", \"fx returned an invalid agent message chunk.\"));\n return;\n }\n if (active.lastMessageId !== update.messageId) {\n active.lastMessageId = update.messageId;\n active.text = \"\";\n active.responseBytes = 0;\n active.responseTooLarge = false;\n }\n active.responseBytes += Buffer.byteLength(update.content.text, \"utf8\");\n if (active.responseBytes > 1024 * 1024) active.responseTooLarge = true;\n else active.text += update.content.text;\n }\n\n private unsupportedRequest(message: AcpEnvelope, active: ActiveTurn | undefined): void {\n try { this.rpc.send({ id: message.id, result: { outcome: { outcome: \"cancelled\" } } }); } catch { /* cancellation will surface the transport failure */ }\n if (!active) {\n this.rpc.abort(new AgentError(\"INPUT_REQUIRED\", \"fx requested interactive input outside an active task.\"));\n } else if (!active.failure) {\n active.failure = new AgentError(\"INPUT_REQUIRED\", \"fx requested interactive input or approval. Configure native permissions before retrying; no approval was granted.\");\n active.approvals.clear();\n this.tools.stopAdmission();\n try { this.rpc.send({ method: \"session/cancel\", params: { sessionId: this.sessionId } }); } catch { /* onFailure settles the turn */ }\n active.cancellationTimer = setTimeout(() => {\n if (this.active === active && !active.terminal) this.rpc.abort(new AgentError(\"CANCELLATION_FAILED\", \"fx did not stop after requesting interactive input.\"));\n }, 2_000);\n active.cancellationTimer.unref();\n }\n }\n\n private async finish(active: ActiveTurn, result?: any, failure?: AgentError): Promise<void> {\n if (active.terminal) return;\n active.terminal = true;\n active.approvals.clear();\n active.resolveNativeStopped();\n if (active.cancellationTimer) clearTimeout(active.cancellationTimer);\n this.tools.stopAdmission();\n await this.tools.drain();\n if (this.active === active) this.active = undefined;\n if (failure) return active.reject(failure);\n if (active.failure) return active.reject(active.failure);\n if (active.responseTooLarge) return active.reject(new AgentError(\"RESPONSE_TOO_LARGE\", \"fx response exceeds 1 MiB.\"));\n if (result?.stopReason === \"end_turn\") active.resolve(active.text);\n else active.reject(new AgentError(result?.stopReason === \"cancelled\" ? \"INTERRUPTED\" : \"HARNESS_FAILED\", \"fx did not complete the turn successfully.\"));\n }\n\n async turn(prompt: string): Promise<string> {\n if (this.closed) throw new AgentError(\"HARNESS_FAILED\", \"The fx session is closed.\");\n if (this.failure) throw this.failure;\n if (this.active) throw new AgentError(\"SESSION_BUSY\", \"fx already has an active turn.\");\n let resolve!: (text: string) => void, reject!: (error: Error) => void;\n let releaseAdmission!: () => void;\n let resolveNativeStopped!: () => void;\n const completion = new Promise<string>((a, b) => { resolve = a; reject = b; });\n const admission = new Promise<void>(resolveAdmission => { releaseAdmission = resolveAdmission; });\n const nativeStopped = new Promise<void>(resolveStopped => { resolveNativeStopped = resolveStopped; });\n const active: ActiveTurn = { approvals: new NativeApprovals(), withdrawnApprovals: new Set(), text: \"\", responseBytes: 0, responseTooLarge: false, completion, resolve, reject, terminal: false, submitted: false, cancelRequested: false, admission, releaseAdmission, nativeStopped, resolveNativeStopped };\n this.active = active;\n void completion.catch(() => {});\n try {\n if (await fxSettingsFingerprint(this.env) !== this.settingsFingerprint) {\n throw new AgentError(\"INVALID_CONFIG\", \"fx native settings changed while the session was active. Start a new session.\");\n }\n if (this.failure) throw this.failure;\n if (active.terminal || this.active !== active) throw new AgentError(\"HARNESS_FAILED\", \"fx stopped while preparing the native prompt.\");\n if (active.cancelRequested || this.closed) throw new AgentError(\"INTERRUPTED\", \"The fx turn was interrupted before submission.\");\n this.tools.beginTurn();\n const includeInstructions = this.first;\n const text = includeInstructions && this.options.agent.instructions ? firstPrompt(this.options.agent.instructions, prompt) : prompt;\n active.submitted = true;\n active.releaseAdmission();\n const result = await this.rpc.request(\"session/prompt\", { sessionId: this.sessionId, prompt: [{ type: \"text\", text }] });\n if (includeInstructions) this.first = false;\n await this.finish(active, result);\n return await completion;\n } catch (error) {\n active.releaseAdmission();\n if (this.failure && this.retirement) await this.retirement;\n await this.finish(active, undefined, error instanceof AgentError ? error : new AgentError(\"HARNESS_FAILED\", \"fx could not complete the native prompt.\"));\n return await completion;\n }\n }\n\n async steer(_prompt: string): Promise<void> {\n throw new AgentError(\"UNSUPPORTED_DELIVERY\", \"fx does not expose verified active steering.\");\n }\n\n async interrupt(): Promise<void> {\n const active = this.active;\n if (!active) return;\n active.cancelRequested = true;\n active.approvals.clear();\n this.tools.stopAdmission();\n await bounded(active.admission, 2_000);\n const admittedTools = this.tools.drain();\n let cancellationFailure: unknown;\n try {\n if (active.submitted && !active.terminal) this.rpc.send({ method: \"session/cancel\", params: { sessionId: this.sessionId } });\n } catch (error) {\n cancellationFailure = error;\n }\n await admittedTools;\n if (cancellationFailure && !this.failure) throw cancellationFailure;\n await bounded(active.nativeStopped, 3_000);\n await active.completion.catch(() => {});\n }\n\n async resume(): Promise<string> {\n throw new AgentError(\"RECOVERY_UNSUPPORTED\", \"fx recovery without a new prompt is unavailable.\");\n }\n\n async close(): Promise<void> {\n if (this.closed) return;\n this.closed = true;\n this.tools.stopAdmission();\n try {\n if (this.active) {\n this.active.cancelRequested = true;\n this.active.approvals.clear();\n await bounded(this.active.admission, 2_000);\n if (this.active.submitted && !this.active.terminal) this.rpc.send({ method: \"session/cancel\", params: { sessionId: this.sessionId } });\n }\n await bounded(this.rpc.request(\"session/close\", { sessionId: this.sessionId }), 2_000);\n } catch { /* process termination below still retires the session */ }\n await this.rpc.close();\n await this.tools.close();\n }\n}\n\nfunction firstPrompt(instructions: string, prompt: string): string {\n return `<subharness-instructions>\\n${instructions}\\n</subharness-instructions>\\n\\n${prompt}`;\n}\n\nasync function bounded<T>(promise: Promise<T>, milliseconds: number): Promise<T> {\n let timer!: NodeJS.Timeout;\n const timeout = new Promise<never>((_resolve, reject) => {\n timer = setTimeout(() => reject(new AgentError(\"CANCELLATION_FAILED\", \"fx did not confirm that native execution stopped.\")), milliseconds);\n timer.unref();\n });\n try { return await Promise.race([promise, timeout]); }\n finally { clearTimeout(timer); }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"fx.js","sourceRoot":"","sources":["../../src/adapters/fx.ts"],"names":[],"mappings":"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","sourcesContent":["import { NativeApprovals } from \"./approval-lifetime.js\";\nimport { fxApproval } from \"./fx-approvals.js\";\nimport { AgentError } from \"../errors.js\";\nimport { fxAccessRoute, fxEnvironment, fxSettingsFingerprint, verifyFxAccess } from \"./fx-auth.js\";\nimport { FxRpc, type AcpEnvelope } from \"./fx-rpc.js\";\nimport { verifyFxPermissionMode } from \"./fx-permissions.js\";\nimport { startFxTools, type FxToolEndpoint } from \"./fx-tools.js\";\nimport type { AdapterOptions, NativeSession } from \"./types.js\";\n\ntype ActiveTurn = {\n lastMessageId?: string;\n text: string;\n responseBytes: number;\n responseTooLarge: boolean;\n completion: Promise<string>;\n resolve(text: string): void;\n reject(error: Error): void;\n terminal: boolean;\n submitted: boolean;\n cancelRequested: boolean;\n admission: Promise<void>;\n releaseAdmission(): void;\n nativeStopped: Promise<void>;\n resolveNativeStopped(): void;\n cancellationTimer?: NodeJS.Timeout;\n failure?: AgentError;\n approvals: NativeApprovals;\n withdrawnApprovals: Set<string | number>;\n};\n\nexport async function openFx(\n options: AdapterOptions,\n createRpc: (cwd: string, env: NodeJS.ProcessEnv, model?: string) => FxRpc = (cwd, env, model) => new FxRpc(cwd, env, model),\n): Promise<NativeSession> {\n if (options.harness.kind !== \"fx\") throw new AgentError(\"INVALID_CONFIG\", \"fx received configuration for a different harness.\");\n const route = await fxAccessRoute(options);\n const baseline = route.settingsFingerprint ?? await fxSettingsFingerprint(options.env);\n const env = fxEnvironment(options, route);\n await verifyFxAccess(options.cwd, env, route, options.harness.model);\n await verifyFxPermissionMode(options.cwd, env, options.harness.permissionMode);\n if (await fxSettingsFingerprint(env) !== baseline) throw new AgentError(\"INVALID_CONFIG\", \"fx native settings changed during access verification. Start a new session.\");\n const tools = await startFxTools(options.agent);\n let rpc: FxRpc | undefined;\n try {\n const startedRpc = createRpc(options.cwd, env, options.harness.model);\n rpc = startedRpc;\n let startupFailure: AgentError | undefined;\n startedRpc.setFailureHandler(error => { startupFailure ??= error; });\n tools.onFailure(error => startedRpc.abort(error));\n startedRpc.onMessage = message => startupRequest(startedRpc, message);\n const initialized = await startedRpc.request(\"initialize\", { protocolVersion: 1, clientInfo: { name: \"subharness\", version: \"0.1.0\" }, clientCapabilities: {} });\n if (!initialized || typeof initialized !== \"object\" || Array.isArray(initialized) || typeof initialized.protocolVersion !== \"number\") {\n throw new AgentError(\"PROTOCOL_ERROR\", \"fx returned an invalid ACP initialization response.\");\n }\n if (initialized.protocolVersion !== 1) throw new AgentError(\"HARNESS_UNAVAILABLE\", \"The installed fx ACP protocol is not compatible with version 1.\");\n const created = await startedRpc.request(\"session/new\", {\n cwd: options.cwd,\n mcpServers: tools.descriptor ? [tools.descriptor] : [],\n });\n if (typeof created?.sessionId !== \"string\" || created.sessionId.length === 0) throw new AgentError(\"PROTOCOL_ERROR\", \"fx did not return a native session identifier.\");\n const selectedModel = verifySelection(created.configOptions, route.provider, options.harness.model);\n if (options.harness.effort !== undefined) {\n verifyEffortAvailable(created.configOptions, options.harness.effort);\n const configured = await startedRpc.request(\"session/set_config_option\", { sessionId: created.sessionId, configId: \"effort\", value: options.harness.effort });\n verifySelection(configured?.configOptions, route.provider, selectedModel, options.harness.effort);\n }\n if (await fxSettingsFingerprint(env) !== baseline) throw new AgentError(\"INVALID_CONFIG\", \"fx native settings changed during session startup. Start a new session.\");\n if (startupFailure) throw startupFailure;\n return new FxSession(startedRpc, created.sessionId, options, env, baseline, tools, route.provider, selectedModel);\n } catch (error) {\n await rpc?.close();\n await tools.close();\n if (error instanceof AgentError) throw error;\n throw new AgentError(\"HARNESS_UNAVAILABLE\", \"Cannot start fx. Check the native executable and session configuration.\");\n }\n}\n\nfunction startupRequest(rpc: FxRpc, message: AcpEnvelope): void {\n if (message.id === undefined) return;\n try { rpc.send({ id: message.id, result: { outcome: { outcome: \"cancelled\" } } }); } catch { /* process may already be closing */ }\n rpc.abort(new AgentError(\"INPUT_REQUIRED\", \"fx requested interactive input during startup. Complete its native setup before running an agent.\"));\n}\n\nfunction option(options: unknown, id: string): any {\n if (!Array.isArray(options)) throw new AgentError(\"PROTOCOL_ERROR\", \"fx returned invalid native session options.\");\n return options.find(value => value && typeof value === \"object\" && (value as any).id === id);\n}\n\nfunction verifySelection(configOptions: unknown, requestedProvider: string, requestedModel?: string, effort?: string): string {\n const provider = option(configOptions, \"provider\");\n const selectedModel = option(configOptions, \"model\");\n if (!provider || !selectedModel) {\n throw new AgentError(\"PROTOCOL_ERROR\", \"fx did not expose compatible native provider and model selectors.\");\n }\n if (provider.currentValue !== requestedProvider) {\n throw new AgentError(\"INVALID_CONFIG\", \"fx selected a provider outside the authorized route.\");\n }\n const model = selectedModel.currentValue;\n if (typeof model !== \"string\" || model.length === 0) {\n throw new AgentError(\"INVALID_CONFIG\", \"fx could not select a verifiable native default for this connection. Supply --model <model>.\");\n }\n if (requestedModel && model !== requestedModel) {\n throw new AgentError(\"INVALID_CONFIG\", \"fx changed the explicitly selected model.\");\n }\n if (effort !== undefined && option(configOptions, \"effort\")?.currentValue !== effort) {\n throw new AgentError(\"INVALID_CONFIG\", \"fx did not apply the explicitly selected effort.\");\n }\n return model;\n}\n\nfunction verifyEffortAvailable(configOptions: unknown, effort: string): void {\n const configured = option(configOptions, \"effort\");\n if (!configured || !Array.isArray(configured.options) || !configured.options.some((value: any) => value?.value === effort)) {\n throw new AgentError(\"UNSUPPORTED_OPTION\", \"The requested fx effort is not supported by the selected model.\");\n }\n}\n\nclass FxSession implements NativeSession {\n private active?: ActiveTurn;\n private failure?: AgentError;\n private retirement?: Promise<void>;\n private first = true;\n private closed = false;\n\n constructor(\n private readonly rpc: FxRpc,\n private readonly sessionId: string,\n private readonly options: AdapterOptions,\n private readonly env: NodeJS.ProcessEnv,\n private readonly settingsFingerprint: string,\n private readonly tools: FxToolEndpoint,\n private readonly selectedProvider: string,\n private readonly selectedModel: string,\n ) {\n rpc.setFailureHandler(error => {\n this.failure ??= error;\n const active = this.active;\n active?.approvals.clear();\n this.retirement ??= this.rpc.close();\n if (active) void this.retirement.then(() => this.finish(active, undefined, error));\n });\n rpc.onMessage = message => this.message(message);\n }\n\n private message(message: AcpEnvelope): void {\n const active = this.active;\n const params = message.params;\n if (message.method === \"$/cancel_request\" && active && (typeof params?.requestId === \"string\" || typeof params?.requestId === \"number\")) {\n active.withdrawnApprovals.add(params.requestId);\n active.approvals.withdraw(params.requestId);\n return;\n }\n if (message.id !== undefined) {\n if (active && active.submitted && !active.terminal && !active.cancelRequested && !active.failure && params?.sessionId === this.sessionId\n && message.method === \"session/request_permission\" && this.options.onApproval) {\n try {\n const request = fxApproval(params);\n void active.approvals.request(message.id, request, this.options.onApproval).then(content => {\n if (this.active === active && !active.terminal && !active.cancelRequested && !active.failure && !active.withdrawnApprovals.has(message.id!)) {\n this.rpc.send({id:message.id,result:{outcome:{outcome:\"selected\",optionId:content.decision}}});\n }\n }).catch(error => {\n if (!(error instanceof AgentError && error.code === \"REQUEST_EXPIRED\")) this.unsupportedRequest(message, active);\n });\n return;\n } catch { /* Unsupported requests retain the explicit input failure path. */ }\n }\n this.unsupportedRequest(message, active);\n return;\n }\n if (params?.sessionId !== this.sessionId) return;\n if (message.method === \"session/update\" && params.update?.sessionUpdate === \"config_option_update\") {\n try { verifySelection(params.update.configOptions, this.selectedProvider, this.selectedModel, this.options.harness.effort); }\n catch (error) { this.rpc.abort(error as AgentError); }\n return;\n }\n if (!active || message.method !== \"session/update\") return;\n const update = params.update;\n if (!update || typeof update !== \"object\" || typeof update.sessionUpdate !== \"string\") {\n this.rpc.abort(new AgentError(\"PROTOCOL_ERROR\", \"fx returned an invalid ACP session update.\"));\n return;\n }\n if (update.sessionUpdate !== \"agent_message_chunk\") return;\n if (typeof update.messageId !== \"string\" || update.content?.type !== \"text\" || typeof update.content.text !== \"string\") {\n this.rpc.abort(new AgentError(\"PROTOCOL_ERROR\", \"fx returned an invalid agent message chunk.\"));\n return;\n }\n if (active.lastMessageId !== update.messageId) {\n active.lastMessageId = update.messageId;\n active.text = \"\";\n active.responseBytes = 0;\n active.responseTooLarge = false;\n }\n active.responseBytes += Buffer.byteLength(update.content.text, \"utf8\");\n if (active.responseBytes > 1024 * 1024) active.responseTooLarge = true;\n else active.text += update.content.text;\n }\n\n private unsupportedRequest(message: AcpEnvelope, active: ActiveTurn | undefined): void {\n try { this.rpc.send({ id: message.id, result: { outcome: { outcome: \"cancelled\" } } }); } catch { /* cancellation will surface the transport failure */ }\n if (!active) {\n this.rpc.abort(new AgentError(\"INPUT_REQUIRED\", \"fx requested interactive input outside an active task.\"));\n } else if (!active.failure) {\n active.failure = new AgentError(\"INPUT_REQUIRED\", \"fx requested interactive input or approval. Configure native permissions before retrying; no approval was granted.\");\n active.approvals.clear();\n this.tools.stopAdmission();\n try { this.rpc.send({ method: \"session/cancel\", params: { sessionId: this.sessionId } }); } catch { /* onFailure settles the turn */ }\n active.cancellationTimer = setTimeout(() => {\n if (this.active === active && !active.terminal) this.rpc.abort(new AgentError(\"CANCELLATION_FAILED\", \"fx did not stop after requesting interactive input.\"));\n }, 2_000);\n active.cancellationTimer.unref();\n }\n }\n\n private async finish(active: ActiveTurn, result?: any, failure?: AgentError): Promise<void> {\n if (active.terminal) return;\n active.terminal = true;\n active.approvals.clear();\n active.resolveNativeStopped();\n if (active.cancellationTimer) clearTimeout(active.cancellationTimer);\n this.tools.stopAdmission();\n await this.tools.drain();\n if (this.active === active) this.active = undefined;\n if (failure) return active.reject(failure);\n if (active.failure) return active.reject(active.failure);\n if (active.responseTooLarge) return active.reject(new AgentError(\"RESPONSE_TOO_LARGE\", \"fx response exceeds 1 MiB.\"));\n if (result?.stopReason === \"end_turn\") active.resolve(active.text);\n else active.reject(new AgentError(result?.stopReason === \"cancelled\" ? \"INTERRUPTED\" : \"HARNESS_FAILED\", \"fx did not complete the turn successfully.\"));\n }\n\n async turn(prompt: string): Promise<string> {\n if (this.closed) throw new AgentError(\"HARNESS_FAILED\", \"The fx session is closed.\");\n if (this.failure) throw this.failure;\n if (this.active) throw new AgentError(\"SESSION_BUSY\", \"fx already has an active turn.\");\n let resolve!: (text: string) => void, reject!: (error: Error) => void;\n let releaseAdmission!: () => void;\n let resolveNativeStopped!: () => void;\n const completion = new Promise<string>((a, b) => { resolve = a; reject = b; });\n const admission = new Promise<void>(resolveAdmission => { releaseAdmission = resolveAdmission; });\n const nativeStopped = new Promise<void>(resolveStopped => { resolveNativeStopped = resolveStopped; });\n const active: ActiveTurn = { approvals: new NativeApprovals(), withdrawnApprovals: new Set(), text: \"\", responseBytes: 0, responseTooLarge: false, completion, resolve, reject, terminal: false, submitted: false, cancelRequested: false, admission, releaseAdmission, nativeStopped, resolveNativeStopped };\n this.active = active;\n void completion.catch(() => {});\n try {\n if (await fxSettingsFingerprint(this.env) !== this.settingsFingerprint) {\n throw new AgentError(\"INVALID_CONFIG\", \"fx native settings changed while the session was active. Start a new session.\");\n }\n if (this.failure) throw this.failure;\n if (active.terminal || this.active !== active) throw new AgentError(\"HARNESS_FAILED\", \"fx stopped while preparing the native prompt.\");\n if (active.cancelRequested || this.closed) throw new AgentError(\"INTERRUPTED\", \"The fx turn was interrupted before submission.\");\n this.tools.beginTurn();\n const includeInstructions = this.first;\n const text = includeInstructions && this.options.agent.instructions ? firstPrompt(this.options.agent.instructions, prompt) : prompt;\n active.submitted = true;\n active.releaseAdmission();\n const result = await this.rpc.request(\"session/prompt\", { sessionId: this.sessionId, prompt: [{ type: \"text\", text }] });\n if (includeInstructions) this.first = false;\n await this.finish(active, result);\n return await completion;\n } catch (error) {\n active.releaseAdmission();\n if (this.failure && this.retirement) await this.retirement;\n await this.finish(active, undefined, error instanceof AgentError ? error : new AgentError(\"HARNESS_FAILED\", \"fx could not complete the native prompt.\"));\n return await completion;\n }\n }\n\n async steer(_prompt: string): Promise<void> {\n throw new AgentError(\"UNSUPPORTED_DELIVERY\", \"fx does not expose verified active steering.\");\n }\n\n async interrupt(): Promise<void> {\n const active = this.active;\n if (!active) return;\n active.cancelRequested = true;\n active.approvals.clear();\n this.tools.stopAdmission();\n await bounded(active.admission, 2_000);\n const admittedTools = this.tools.drain();\n let cancellationFailure: unknown;\n try {\n if (active.submitted && !active.terminal) this.rpc.send({ method: \"session/cancel\", params: { sessionId: this.sessionId } });\n } catch (error) {\n cancellationFailure = error;\n }\n await admittedTools;\n if (cancellationFailure && !this.failure) throw cancellationFailure;\n await bounded(active.nativeStopped, 3_000);\n await active.completion.catch(() => {});\n }\n\n async resume(): Promise<string> {\n throw new AgentError(\"RECOVERY_UNSUPPORTED\", \"fx recovery without a new prompt is unavailable.\");\n }\n\n async close(): Promise<void> {\n if (this.closed) return;\n this.closed = true;\n this.tools.stopAdmission();\n try {\n if (this.active) {\n this.active.cancelRequested = true;\n this.active.approvals.clear();\n await bounded(this.active.admission, 2_000);\n if (this.active.submitted && !this.active.terminal) this.rpc.send({ method: \"session/cancel\", params: { sessionId: this.sessionId } });\n }\n await bounded(this.rpc.request(\"session/close\", { sessionId: this.sessionId }), 2_000);\n } catch { /* process termination below still retires the session */ }\n await this.rpc.close();\n await this.tools.close();\n }\n}\n\nfunction firstPrompt(instructions: string, prompt: string): string {\n return `<subharness-instructions>\\n${instructions}\\n</subharness-instructions>\\n\\n${prompt}`;\n}\n\nasync function bounded<T>(promise: Promise<T>, milliseconds: number): Promise<T> {\n let timer!: NodeJS.Timeout;\n const timeout = new Promise<never>((_resolve, reject) => {\n timer = setTimeout(() => reject(new AgentError(\"CANCELLATION_FAILED\", \"fx did not confirm that native execution stopped.\")), milliseconds);\n timer.unref();\n });\n try { return await Promise.race([promise, timeout]); }\n finally { clearTimeout(timer); }\n}\n"]}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { ResolvedAccess } from "./types.js";
|
|
2
|
+
export type OpencodeRoute = {
|
|
3
|
+
readonly kind: "gateway" | "direct" | "subscription";
|
|
4
|
+
readonly providerID: string;
|
|
5
|
+
readonly modelID: string;
|
|
6
|
+
readonly nativeModel: string;
|
|
7
|
+
readonly packages: readonly string[];
|
|
8
|
+
readonly unavailablePackages?: readonly string[];
|
|
9
|
+
readonly configPackage?: string;
|
|
10
|
+
readonly baseUrl?: string;
|
|
11
|
+
readonly oauthMarker?: string;
|
|
12
|
+
};
|
|
13
|
+
export declare function resolveOpencodeRoute(model: string, access: ResolvedAccess): OpencodeRoute;
|