@finalai/final-agent-provider 0.10.1 → 0.11.0
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/HOSTING.md +334 -245
- package/README.md +126 -40
- package/WORKSPACE-EGRESS.md +11 -11
- package/dist/modules/catalog.d.mts +9 -0
- package/dist/modules/catalog.mjs +21 -0
- package/dist/modules/catalog.mjs.map +7 -0
- package/dist/modules/harnesses/acp-agent.d.mts +4 -0
- package/dist/modules/harnesses/acp-agent.mjs +35 -0
- package/dist/modules/harnesses/acp-agent.mjs.map +7 -0
- package/dist/modules/harnesses/adapters.d.mts +7 -0
- package/dist/modules/harnesses/adapters.mjs +74 -0
- package/dist/modules/harnesses/adapters.mjs.map +7 -0
- package/dist/modules/harnesses/claude-code.d.mts +14 -0
- package/dist/modules/harnesses/claude-code.mjs +79 -0
- package/dist/modules/harnesses/claude-code.mjs.map +7 -0
- package/dist/modules/harnesses/codex.d.mts +12 -0
- package/dist/modules/harnesses/codex.mjs +90 -0
- package/dist/modules/harnesses/codex.mjs.map +7 -0
- package/dist/modules/harnesses/config-fields.d.mts +98 -57
- package/dist/modules/harnesses/config-fields.mjs +58 -35
- package/dist/modules/harnesses/config-fields.mjs.map +3 -3
- package/dist/modules/harnesses/definitions.d.mts +3 -0
- package/dist/modules/harnesses/definitions.mjs +21 -0
- package/dist/modules/harnesses/definitions.mjs.map +7 -0
- package/dist/modules/harnesses/fidelity.d.mts +1 -1
- package/dist/modules/harnesses/fidelity.mjs +17 -14
- package/dist/modules/harnesses/fidelity.mjs.map +2 -2
- package/dist/modules/harnesses/final.d.mts +12 -0
- package/dist/modules/harnesses/final.mjs +70 -0
- package/dist/modules/harnesses/final.mjs.map +7 -0
- package/dist/modules/harnesses/index.d.mts +13 -12
- package/dist/modules/harnesses/index.mjs +86 -45
- package/dist/modules/harnesses/index.mjs.map +3 -3
- package/dist/modules/harnesses/names.d.mts +43 -0
- package/dist/modules/harnesses/names.mjs +59 -0
- package/dist/modules/harnesses/names.mjs.map +7 -0
- package/dist/modules/harnesses/nanocode-claude.d.mts +18 -0
- package/dist/modules/harnesses/nanocode-claude.mjs +101 -0
- package/dist/modules/harnesses/nanocode-claude.mjs.map +7 -0
- package/dist/modules/harnesses/nanocode-codex.d.mts +13 -0
- package/dist/modules/harnesses/nanocode-codex.mjs +64 -0
- package/dist/modules/harnesses/nanocode-codex.mjs.map +7 -0
- package/dist/modules/harnesses/pi.d.mts +12 -0
- package/dist/modules/harnesses/pi.mjs +71 -0
- package/dist/modules/harnesses/pi.mjs.map +7 -0
- package/dist/modules/integrations.d.mts +9 -0
- package/dist/modules/integrations.mjs +29 -0
- package/dist/modules/integrations.mjs.map +7 -0
- package/dist/modules/provider/general.bundle.d.mts +1 -0
- package/dist/modules/provider/general.bundle.mjs +5 -0
- package/dist/modules/provider/general.bundle.mjs.map +7 -0
- package/dist/modules/provider/general.d.mts +11 -0
- package/dist/modules/provider/general.mjs +130 -0
- package/dist/modules/provider/general.mjs.map +7 -0
- package/dist/modules/provider/index.d.mts +3 -0
- package/dist/modules/provider/index.mjs +13 -0
- package/dist/modules/provider/index.mjs.map +7 -0
- package/dist/modules/sandboxes/access.d.mts +34 -0
- package/dist/modules/sandboxes/access.mjs +15 -0
- package/dist/modules/sandboxes/access.mjs.map +7 -0
- package/dist/modules/sandboxes/computer.d.mts +24 -51
- package/dist/modules/sandboxes/computer.mjs +523 -888
- package/dist/modules/sandboxes/computer.mjs.map +3 -3
- package/dist/modules/sandboxes/computers-api.d.mts +3 -2
- package/dist/modules/sandboxes/computers-api.mjs +2 -4
- package/dist/modules/sandboxes/computers-api.mjs.map +2 -2
- package/dist/modules/sandboxes/device-api.d.mts +4 -3
- package/dist/modules/sandboxes/device-api.mjs +2 -4
- package/dist/modules/sandboxes/device-api.mjs.map +2 -2
- package/dist/modules/sandboxes/device.d.mts +6 -6
- package/dist/modules/sandboxes/device.mjs +126 -121
- package/dist/modules/sandboxes/device.mjs.map +3 -3
- package/dist/modules/sandboxes/egress.d.mts +10 -9
- package/dist/modules/sandboxes/egress.mjs +73 -56
- package/dist/modules/sandboxes/egress.mjs.map +2 -2
- package/dist/modules/sandboxes/environment.d.mts +35 -269
- package/dist/modules/sandboxes/environment.mjs +27 -104
- package/dist/modules/sandboxes/environment.mjs.map +3 -3
- package/dist/modules/sandboxes/index.d.mts +9 -69
- package/dist/modules/sandboxes/index.mjs +35 -95
- package/dist/modules/sandboxes/index.mjs.map +3 -3
- package/dist/modules/sandboxes/local.d.mts +28 -0
- package/dist/modules/sandboxes/local.mjs +499 -0
- package/dist/modules/sandboxes/local.mjs.map +7 -0
- package/dist/modules/sandboxes/session.d.mts +0 -3
- package/dist/modules/sandboxes/session.mjs +2 -22
- package/dist/modules/sandboxes/session.mjs.map +2 -2
- package/dist/modules/sandboxes/testing/fake-machine.mjs +0 -28
- package/dist/modules/sandboxes/testing/fake-machine.mjs.map +2 -2
- package/package.json +76 -104
- package/dist/modules/connections.d.mts +0 -11
- package/dist/modules/connections.mjs +0 -16
- package/dist/modules/connections.mjs.map +0 -7
- package/dist/modules/harnesses/acp-describe.d.mts +0 -20
- package/dist/modules/harnesses/acp-describe.mjs +0 -110
- package/dist/modules/harnesses/acp-describe.mjs.map +0 -7
- package/dist/modules/harnesses/local-stdio.d.mts +0 -47
- package/dist/modules/harnesses/local-stdio.mjs +0 -41
- package/dist/modules/harnesses/local-stdio.mjs.map +0 -7
- package/dist/modules/harnesses/remote-acp.d.mts +0 -76
- package/dist/modules/harnesses/remote-acp.mjs +0 -83
- package/dist/modules/harnesses/remote-acp.mjs.map +0 -7
- package/dist/modules/harnesses/remote-claude-code.d.mts +0 -88
- package/dist/modules/harnesses/remote-claude-code.mjs +0 -113
- package/dist/modules/harnesses/remote-claude-code.mjs.map +0 -7
- package/dist/modules/harnesses/remote-client-tls.d.mts +0 -35
- package/dist/modules/harnesses/remote-client-tls.mjs +0 -37
- package/dist/modules/harnesses/remote-client-tls.mjs.map +0 -7
- package/dist/modules/harnesses/remote-codex.d.mts +0 -98
- package/dist/modules/harnesses/remote-codex.mjs +0 -128
- package/dist/modules/harnesses/remote-codex.mjs.map +0 -7
- package/dist/modules/harnesses/remote-pi.d.mts +0 -78
- package/dist/modules/harnesses/remote-pi.mjs +0 -104
- package/dist/modules/harnesses/remote-pi.mjs.map +0 -7
- package/dist/modules/harnesses/remote-url.d.mts +0 -5
- package/dist/modules/harnesses/remote-url.mjs +0 -19
- package/dist/modules/harnesses/remote-url.mjs.map +0 -7
- package/dist/modules/harnesses/serverless-final.d.mts +0 -63
- package/dist/modules/harnesses/serverless-final.mjs +0 -88
- package/dist/modules/harnesses/serverless-final.mjs.map +0 -7
- package/dist/modules/harnesses/serverless-nanocode-claude.d.mts +0 -64
- package/dist/modules/harnesses/serverless-nanocode-claude.mjs +0 -105
- package/dist/modules/harnesses/serverless-nanocode-claude.mjs.map +0 -7
- package/dist/modules/harnesses/serverless-nanocode-codex.d.mts +0 -66
- package/dist/modules/harnesses/serverless-nanocode-codex.mjs +0 -113
- package/dist/modules/harnesses/serverless-nanocode-codex.mjs.map +0 -7
- package/dist/modules/harnesses/serverless-pi.d.mts +0 -64
- package/dist/modules/harnesses/serverless-pi.mjs +0 -98
- package/dist/modules/harnesses/serverless-pi.mjs.map +0 -7
- package/dist/modules/runtime/index.d.mts +0 -7
- package/dist/modules/runtime/index.mjs +0 -18
- package/dist/modules/runtime/index.mjs.map +0 -7
- package/dist/modules/runtime/local-stdio.d.mts +0 -10
- package/dist/modules/runtime/local-stdio.mjs +0 -106
- package/dist/modules/runtime/local-stdio.mjs.map +0 -7
- package/dist/modules/runtime/remote-acp.d.mts +0 -16
- package/dist/modules/runtime/remote-acp.mjs +0 -152
- package/dist/modules/runtime/remote-acp.mjs.map +0 -7
- package/dist/modules/runtime/remote-claude-code.d.mts +0 -5
- package/dist/modules/runtime/remote-claude-code.mjs +0 -47
- package/dist/modules/runtime/remote-claude-code.mjs.map +0 -7
- package/dist/modules/runtime/remote-codex.d.mts +0 -5
- package/dist/modules/runtime/remote-codex.mjs +0 -47
- package/dist/modules/runtime/remote-codex.mjs.map +0 -7
- package/dist/modules/runtime/remote-host.d.mts +0 -127
- package/dist/modules/runtime/remote-host.mjs +0 -387
- package/dist/modules/runtime/remote-host.mjs.map +0 -7
- package/dist/modules/runtime/remote-pi.d.mts +0 -5
- package/dist/modules/runtime/remote-pi.mjs +0 -44
- package/dist/modules/runtime/remote-pi.mjs.map +0 -7
- package/dist/modules/sandboxes/guide.d.mts +0 -35
- package/dist/modules/sandboxes/guide.mjs +0 -119
- package/dist/modules/sandboxes/guide.mjs.map +0 -7
- package/dist/modules/sandboxes/workspace-setup.d.mts +0 -42
- package/dist/modules/sandboxes/workspace-setup.mjs +0 -242
- package/dist/modules/sandboxes/workspace-setup.mjs.map +0 -7
- package/dist/modules/testing/harness.d.mts +0 -9
- package/dist/modules/testing/harness.mjs +0 -123
- package/dist/modules/testing/harness.mjs.map +0 -7
|
@@ -1,387 +0,0 @@
|
|
|
1
|
-
import { RequestError } from "@agentclientprotocol/sdk/experimental/v2";
|
|
2
|
-
import {
|
|
3
|
-
AcpTransport,
|
|
4
|
-
BaseCapability,
|
|
5
|
-
BaseToolProvision,
|
|
6
|
-
CredentialDelivery,
|
|
7
|
-
CredentialRoute,
|
|
8
|
-
formatProviderRef,
|
|
9
|
-
harnessDescriptionSchema,
|
|
10
|
-
InferenceCredentialKind,
|
|
11
|
-
InstructionRole,
|
|
12
|
-
packageRef,
|
|
13
|
-
SandboxWire
|
|
14
|
-
} from "@finalai/agent-provider";
|
|
15
|
-
import { createNodeClientTlsFetch } from "@finalai/websockets/node-client-tls";
|
|
16
|
-
import { createHmac } from "node:crypto";
|
|
17
|
-
import * as z from "zod";
|
|
18
|
-
import { toJsonObject } from "../harnesses/config-fields.mjs";
|
|
19
|
-
import {
|
|
20
|
-
resolveRemoteClientTls
|
|
21
|
-
} from "../harnesses/remote-client-tls.mjs";
|
|
22
|
-
const unavailableSchema = z.object({
|
|
23
|
-
code: z.literal("harness_unavailable"),
|
|
24
|
-
executable: z.string(),
|
|
25
|
-
foundVersion: z.string().nullable(),
|
|
26
|
-
requiredVersion: z.string(),
|
|
27
|
-
detail: z.string()
|
|
28
|
-
});
|
|
29
|
-
const unavailableOf = (text) => {
|
|
30
|
-
try {
|
|
31
|
-
return unavailableSchema.safeParse(JSON.parse(text)).data ?? null;
|
|
32
|
-
} catch {
|
|
33
|
-
return null;
|
|
34
|
-
}
|
|
35
|
-
};
|
|
36
|
-
const DEFAULT_HEALTH_TIMEOUT_MS = 5e3;
|
|
37
|
-
const DEFAULT_REGISTER_TIMEOUT_MS = 1e4;
|
|
38
|
-
const DEFAULT_CLOSE_TIMEOUT_MS = 15e3;
|
|
39
|
-
const PROGRAM_CONFIG_HEADER = "x-final-program-config";
|
|
40
|
-
const HEALTH_TOKEN_HEADER = "x-final-health-token";
|
|
41
|
-
const CLOSE_TOKEN_HEADER = "x-final-close-token";
|
|
42
|
-
const healthTokenFor = (args) => createHmac("sha256", args.hop).update(`final-harness-health:${args.id}`).digest("base64url");
|
|
43
|
-
const closeTokenFor = (args) => createHmac("sha256", args.hop).update(`final-harness-close:${args.id}`).digest("base64url");
|
|
44
|
-
const PROGRAM_CONFIGS_PATH = "/v1/program-configs/";
|
|
45
|
-
var RemoteProgram = /* @__PURE__ */ ((RemoteProgram2) => {
|
|
46
|
-
RemoteProgram2["ClaudeCode"] = "claude-code";
|
|
47
|
-
RemoteProgram2["Codex"] = "codex";
|
|
48
|
-
RemoteProgram2["Pi"] = "pi";
|
|
49
|
-
return RemoteProgram2;
|
|
50
|
-
})(RemoteProgram || {});
|
|
51
|
-
const formatRemoteRef = (args) => args.closeToken != null && args.healthToken != null ? `${args.id}|${args.healthToken}|${args.closeToken}|${args.url}` : args.healthToken == null ? `${args.id}|${args.url}` : `${args.id}|${args.healthToken}|${args.url}`;
|
|
52
|
-
const HEALTH_TOKEN_PATTERN = /^[A-Za-z0-9_-]{43}$/u;
|
|
53
|
-
const parseRemoteRef = (ref) => {
|
|
54
|
-
const bar = ref.indexOf("|");
|
|
55
|
-
if (bar < 0) return { id: ref, url: null, healthToken: null, closeToken: null };
|
|
56
|
-
const id = ref.slice(0, bar);
|
|
57
|
-
const rest = ref.slice(bar + 1);
|
|
58
|
-
const next = rest.indexOf("|");
|
|
59
|
-
const token = next < 0 ? null : rest.slice(0, next);
|
|
60
|
-
if (token == null || !HEALTH_TOKEN_PATTERN.test(token))
|
|
61
|
-
return { id, url: rest, healthToken: null, closeToken: null };
|
|
62
|
-
const remaining = rest.slice(next + 1);
|
|
63
|
-
const separator = remaining.indexOf("|");
|
|
64
|
-
const closeToken = separator < 0 ? null : remaining.slice(0, separator);
|
|
65
|
-
return closeToken != null && HEALTH_TOKEN_PATTERN.test(closeToken) ? { id, url: remaining.slice(separator + 1), healthToken: token, closeToken } : { id, url: remaining, healthToken: token, closeToken: null };
|
|
66
|
-
};
|
|
67
|
-
const transportForUrl = (url) => /^wss?:\/\//.test(url) ? AcpTransport.Ws : AcpTransport.Http;
|
|
68
|
-
const httpUrlOf = (url) => url.replace(/^ws(s?):\/\//, (_match, secure) => `http${secure}://`);
|
|
69
|
-
const runtimeUrlFor = (args) => {
|
|
70
|
-
const endpoint = new URL(httpUrlOf(args.url));
|
|
71
|
-
if (endpoint.pathname !== "/") endpoint.pathname = endpoint.pathname.replace(/\/+$/, "");
|
|
72
|
-
return new URL(args.path.replace(/^\/+/, ""), endpoint).toString();
|
|
73
|
-
};
|
|
74
|
-
const healthUrlFor = (url) => runtimeUrlFor({ url, path: "healthz" });
|
|
75
|
-
const programConfigUrlFor = (args) => runtimeUrlFor({ url: args.url, path: `${PROGRAM_CONFIGS_PATH}${encodeURIComponent(args.id)}` });
|
|
76
|
-
const resolveSecretRef = async (args) => {
|
|
77
|
-
const value = await args.secrets.get(args.ref.secretKey);
|
|
78
|
-
if (value == null || value.length === 0) {
|
|
79
|
-
throw new Error(
|
|
80
|
-
`${args.specifier}: secret '${args.ref.secretKey}' for ${args.field} is not bound`
|
|
81
|
-
);
|
|
82
|
-
}
|
|
83
|
-
return value;
|
|
84
|
-
};
|
|
85
|
-
const buildRemoteProgramConfig = (args) => {
|
|
86
|
-
const settings = args.spec.settings(args.open.config);
|
|
87
|
-
const description = args.spec.description;
|
|
88
|
-
const routesTargets = description.consumes.includes(SandboxWire.HandleRpc);
|
|
89
|
-
const baseTools = {};
|
|
90
|
-
for (const capability of Object.values(BaseCapability)) {
|
|
91
|
-
const endpoint = args.open.baseTools[capability];
|
|
92
|
-
const declaration = description.baseTools[capability];
|
|
93
|
-
if (declaration == null) continue;
|
|
94
|
-
if (endpoint != null) {
|
|
95
|
-
baseTools[capability] = { provision: declaration.provision, target: endpoint.target };
|
|
96
|
-
continue;
|
|
97
|
-
}
|
|
98
|
-
if (declaration.provision === BaseToolProvision.Bound) continue;
|
|
99
|
-
const onHost = args.open.manifest.tools.host?.includes(capability) === true;
|
|
100
|
-
const unroutedTarget = args.open.manifest.tools.base[capability] != null && !routesTargets;
|
|
101
|
-
if (onHost || unroutedTarget) {
|
|
102
|
-
baseTools[capability] = { provision: declaration.provision, target: null };
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
const delivery = description.inference.delivery;
|
|
106
|
-
const modelGrant = args.open.credentials.grants.find(
|
|
107
|
-
(grant) => grant.route === CredentialRoute.Model
|
|
108
|
-
);
|
|
109
|
-
const sandboxGrant = args.open.credentials.grants.find(
|
|
110
|
-
(grant) => grant.route === CredentialRoute.Sandbox
|
|
111
|
-
);
|
|
112
|
-
return {
|
|
113
|
-
attachments: (() => {
|
|
114
|
-
const grant = args.open.credentials.grants.find(
|
|
115
|
-
(entry) => entry.route === CredentialRoute.Mcp
|
|
116
|
-
);
|
|
117
|
-
return grant == null ? null : {
|
|
118
|
-
url: `${args.open.credentials.brokerUrl.replace(/\/+$/, "")}/attachment`,
|
|
119
|
-
token: grant.token
|
|
120
|
-
};
|
|
121
|
-
})(),
|
|
122
|
-
version: 1,
|
|
123
|
-
program: args.spec.program,
|
|
124
|
-
cwd: settings.cwd,
|
|
125
|
-
executable: settings.executable,
|
|
126
|
-
model: settings.model,
|
|
127
|
-
reasoning: settings.reasoning,
|
|
128
|
-
permissionMode: settings.permissionMode,
|
|
129
|
-
approvalPolicy: settings.approvalPolicy,
|
|
130
|
-
sandboxMode: settings.sandboxMode,
|
|
131
|
-
allowedTools: settings.allowedTools,
|
|
132
|
-
instructions: settings.instructions.filter((fragment) => fragment.role === InstructionRole.System).map((fragment) => ({ role: fragment.role, content: fragment.content })),
|
|
133
|
-
skills: settings.skills,
|
|
134
|
-
baseTools,
|
|
135
|
-
sandboxes: Object.fromEntries(
|
|
136
|
-
Object.entries(args.open.sandboxes).map(([target, endpoint]) => [
|
|
137
|
-
target,
|
|
138
|
-
{
|
|
139
|
-
bindingId: endpoint.bindingId,
|
|
140
|
-
capabilities: [...endpoint.capabilities],
|
|
141
|
-
rpc: endpoint.rpc,
|
|
142
|
-
mcp: endpoint.mcp
|
|
143
|
-
}
|
|
144
|
-
])
|
|
145
|
-
),
|
|
146
|
-
toolPolicy: { ...args.open.manifest.toolPolicy },
|
|
147
|
-
// The harness's own login (`credentials.harness()`) is configured by its
|
|
148
|
-
// user, not by Final: nothing is handed over and the CLI's settings apply.
|
|
149
|
-
credentials: delivery === CredentialDelivery.AtOpen && args.open.credentials.atOpen?.kind !== InferenceCredentialKind.HarnessOwned ? args.open.credentials.atOpen : null,
|
|
150
|
-
broker: delivery === CredentialDelivery.PerRequest && modelGrant != null ? {
|
|
151
|
-
url: args.open.credentials.brokerUrl,
|
|
152
|
-
token: modelGrant.token,
|
|
153
|
-
sandboxToken: sandboxGrant?.token ?? null,
|
|
154
|
-
harnessSessionId: args.open.harnessSessionId
|
|
155
|
-
} : null,
|
|
156
|
-
refresh: args.open.credentials.refresh
|
|
157
|
-
};
|
|
158
|
-
};
|
|
159
|
-
const createRemoteHarness = (spec, config = {}) => {
|
|
160
|
-
const fetchImpl = config.fetch ?? fetch;
|
|
161
|
-
const fetchFor = (tls) => tls == null ? fetchImpl : config.tlsFetch?.(tls) ?? createNodeClientTlsFetch({ tls });
|
|
162
|
-
const now = config.now ?? Date.now;
|
|
163
|
-
const healthTimeoutMs = config.healthTimeoutMs ?? DEFAULT_HEALTH_TIMEOUT_MS;
|
|
164
|
-
const registerTimeoutMs = config.registerTimeoutMs ?? DEFAULT_REGISTER_TIMEOUT_MS;
|
|
165
|
-
const clientTls = /* @__PURE__ */ new Map();
|
|
166
|
-
const register = async (args) => {
|
|
167
|
-
const source = args.open.forkSource;
|
|
168
|
-
const forkSource = source == null ? null : parseRemoteRef(source.ref.harnessSessionRef);
|
|
169
|
-
if (source != null && (!spec.description.supports.fork || formatProviderRef(source.ref.harness) !== formatProviderRef(packageRef(spec.specifier))))
|
|
170
|
-
throw new Error(`${spec.specifier}: the source does not support this harness's native fork`);
|
|
171
|
-
if (forkSource != null && (forkSource.id === args.id || forkSource.url !== args.url))
|
|
172
|
-
throw new Error(
|
|
173
|
-
`${spec.specifier}: a fork requires a distinct registration on the source host`
|
|
174
|
-
);
|
|
175
|
-
const target = programConfigUrlFor({ url: args.url, id: args.id });
|
|
176
|
-
const registration = {
|
|
177
|
-
program: toJsonObject(buildRemoteProgramConfig({ spec, open: args.open }))
|
|
178
|
-
};
|
|
179
|
-
if (source != null && forkSource != null)
|
|
180
|
-
registration["forkSource"] = {
|
|
181
|
-
programConfigId: forkSource.id,
|
|
182
|
-
sessionId: source.acpSessionId,
|
|
183
|
-
childSessionId: args.open.session.sessionId
|
|
184
|
-
};
|
|
185
|
-
let response;
|
|
186
|
-
try {
|
|
187
|
-
response = await fetchFor(args.tls)(target, {
|
|
188
|
-
method: "PUT",
|
|
189
|
-
headers: { authorization: `Bearer ${args.hop}`, "content-type": "application/json" },
|
|
190
|
-
body: JSON.stringify(registration),
|
|
191
|
-
signal: AbortSignal.timeout(registerTimeoutMs)
|
|
192
|
-
});
|
|
193
|
-
} catch (error) {
|
|
194
|
-
throw new Error(
|
|
195
|
-
`${spec.specifier}: registering the program config failed: ${error instanceof Error ? error.message : String(error)}`
|
|
196
|
-
);
|
|
197
|
-
}
|
|
198
|
-
const body = await response.text().catch(() => "");
|
|
199
|
-
if (!response.ok) {
|
|
200
|
-
const unavailable = unavailableOf(body);
|
|
201
|
-
if (unavailable != null) throw RequestError.internalError(unavailable, unavailable.detail);
|
|
202
|
-
throw new Error(
|
|
203
|
-
`${spec.specifier}: the runtime refused the program config (HTTP ${response.status}) ${body.slice(0, 200)}`.trim()
|
|
204
|
-
);
|
|
205
|
-
}
|
|
206
|
-
};
|
|
207
|
-
const endpointFor = async (args) => {
|
|
208
|
-
const settings = spec.settings(args.open.config);
|
|
209
|
-
const hop = await resolveSecretRef({
|
|
210
|
-
specifier: spec.specifier,
|
|
211
|
-
field: "hop",
|
|
212
|
-
ref: settings.hop,
|
|
213
|
-
secrets: args.open.secrets
|
|
214
|
-
});
|
|
215
|
-
const { id } = parseRemoteRef(args.ref.harnessSessionRef);
|
|
216
|
-
const tls = await resolveRemoteClientTls({
|
|
217
|
-
config: settings.tls,
|
|
218
|
-
secrets: args.open.secrets,
|
|
219
|
-
url: settings.url
|
|
220
|
-
});
|
|
221
|
-
await register({ url: settings.url, hop, id, open: args.open, tls });
|
|
222
|
-
if (tls != null) clientTls.set(id, tls);
|
|
223
|
-
else clientTls.delete(id);
|
|
224
|
-
return {
|
|
225
|
-
// Re-minted on every open and resume: a rotated hop or a legacy ref gets a current token.
|
|
226
|
-
ref: {
|
|
227
|
-
...args.ref,
|
|
228
|
-
harnessSessionRef: formatRemoteRef({
|
|
229
|
-
id,
|
|
230
|
-
url: settings.url,
|
|
231
|
-
healthToken: healthTokenFor({ hop, id }),
|
|
232
|
-
closeToken: closeTokenFor({ hop, id })
|
|
233
|
-
})
|
|
234
|
-
},
|
|
235
|
-
transport: transportForUrl(settings.url),
|
|
236
|
-
url: settings.url,
|
|
237
|
-
tls,
|
|
238
|
-
headers: { authorization: `Bearer ${hop}`, [PROGRAM_CONFIG_HEADER]: id }
|
|
239
|
-
};
|
|
240
|
-
};
|
|
241
|
-
return {
|
|
242
|
-
describe: async (binding) => {
|
|
243
|
-
if (binding == null) return spec.description;
|
|
244
|
-
const settings = spec.settings(binding.config);
|
|
245
|
-
const hop = await resolveSecretRef({
|
|
246
|
-
specifier: spec.specifier,
|
|
247
|
-
field: "hop",
|
|
248
|
-
ref: settings.hop,
|
|
249
|
-
secrets: binding.secrets
|
|
250
|
-
});
|
|
251
|
-
const tls = await resolveRemoteClientTls({
|
|
252
|
-
config: settings.tls,
|
|
253
|
-
secrets: binding.secrets,
|
|
254
|
-
url: settings.url
|
|
255
|
-
});
|
|
256
|
-
const response = await fetchFor(tls)(
|
|
257
|
-
runtimeUrlFor({ url: settings.url, path: "v1/describe" }),
|
|
258
|
-
{
|
|
259
|
-
method: "POST",
|
|
260
|
-
headers: { authorization: `Bearer ${hop}`, "content-type": "application/json" },
|
|
261
|
-
body: JSON.stringify({ program: { executable: settings.executable } }),
|
|
262
|
-
signal: AbortSignal.timeout(registerTimeoutMs)
|
|
263
|
-
}
|
|
264
|
-
);
|
|
265
|
-
const text = await response.text();
|
|
266
|
-
if (!response.ok) {
|
|
267
|
-
const unavailable = unavailableOf(text);
|
|
268
|
-
if (unavailable != null) throw RequestError.internalError(unavailable, unavailable.detail);
|
|
269
|
-
throw new Error(
|
|
270
|
-
`${spec.specifier}: describe failed (HTTP ${response.status}) ${text.slice(0, 200)}`
|
|
271
|
-
);
|
|
272
|
-
}
|
|
273
|
-
const description = harnessDescriptionSchema.parse(JSON.parse(text));
|
|
274
|
-
return {
|
|
275
|
-
...description,
|
|
276
|
-
configSchema: spec.description.configSchema,
|
|
277
|
-
trust: spec.description.trust,
|
|
278
|
-
inference: spec.description.inference,
|
|
279
|
-
consumes: spec.description.consumes
|
|
280
|
-
};
|
|
281
|
-
},
|
|
282
|
-
open: async (args) => {
|
|
283
|
-
const ref = {
|
|
284
|
-
harness: packageRef(spec.specifier),
|
|
285
|
-
// endpointFor() completes the ref with the url and health token.
|
|
286
|
-
harnessSessionRef: args.harnessSessionId,
|
|
287
|
-
generation: 1
|
|
288
|
-
};
|
|
289
|
-
return endpointFor({ open: args, ref });
|
|
290
|
-
},
|
|
291
|
-
// The runtime resumes the program's own session (Claude Code session, Codex
|
|
292
|
-
// rollout); re-registering hands it the fresh grants.
|
|
293
|
-
resume: async (args) => endpointFor({ open: args, ref: args.ref }),
|
|
294
|
-
park: async () => void 0,
|
|
295
|
-
close: async (ref, options) => {
|
|
296
|
-
const { id, url: retainedUrl, closeToken } = parseRemoteRef(ref.harnessSessionRef);
|
|
297
|
-
const context = options?.context;
|
|
298
|
-
const settings = context == null ? null : spec.settings(context.config);
|
|
299
|
-
const url = retainedUrl ?? settings?.url ?? null;
|
|
300
|
-
if (url == null) {
|
|
301
|
-
if (options?.force === true)
|
|
302
|
-
throw new Error(`${spec.specifier}: the legacy ref must be resumed before forced close`);
|
|
303
|
-
return;
|
|
304
|
-
}
|
|
305
|
-
const hop = context == null || settings == null ? null : await context.secrets.get(settings.hop.secretKey);
|
|
306
|
-
const scopedToken = hop == null || hop.length === 0 ? closeToken : closeTokenFor({ hop, id });
|
|
307
|
-
if (scopedToken == null) {
|
|
308
|
-
if (options?.force === true)
|
|
309
|
-
throw new Error(
|
|
310
|
-
`${spec.specifier}: the legacy ref needs close context or resume before forced close`
|
|
311
|
-
);
|
|
312
|
-
return;
|
|
313
|
-
}
|
|
314
|
-
const tls = context == null || settings == null ? clientTls.get(id) : await resolveRemoteClientTls({
|
|
315
|
-
config: settings.tls,
|
|
316
|
-
secrets: context.secrets,
|
|
317
|
-
url
|
|
318
|
-
});
|
|
319
|
-
const response = await fetchFor(tls)(programConfigUrlFor({ url, id }), {
|
|
320
|
-
method: "DELETE",
|
|
321
|
-
headers: { [CLOSE_TOKEN_HEADER]: scopedToken, "content-type": "application/json" },
|
|
322
|
-
body: JSON.stringify({ force: options?.force === true }),
|
|
323
|
-
signal: AbortSignal.timeout(config.closeTimeoutMs ?? DEFAULT_CLOSE_TIMEOUT_MS)
|
|
324
|
-
});
|
|
325
|
-
const body = await response.text();
|
|
326
|
-
if (!response.ok && response.status !== 404)
|
|
327
|
-
throw new Error(
|
|
328
|
-
`${spec.specifier}: remote close failed (HTTP ${response.status}) ${body.slice(0, 200)}`
|
|
329
|
-
);
|
|
330
|
-
clientTls.delete(id);
|
|
331
|
-
},
|
|
332
|
-
health: async (ref, context) => {
|
|
333
|
-
const { id, url, healthToken } = parseRemoteRef(ref.harnessSessionRef);
|
|
334
|
-
const checkedAt = new Date(now()).toISOString();
|
|
335
|
-
if (url == null)
|
|
336
|
-
return { ok: false, detail: "harness session ref has no runtime url", checkedAt };
|
|
337
|
-
try {
|
|
338
|
-
const headers = new Headers({ [PROGRAM_CONFIG_HEADER]: id });
|
|
339
|
-
if (healthToken != null) headers.set(HEALTH_TOKEN_HEADER, healthToken);
|
|
340
|
-
const tls = context == null ? void 0 : await resolveRemoteClientTls({
|
|
341
|
-
config: spec.settings(context.config).tls,
|
|
342
|
-
secrets: context.secrets,
|
|
343
|
-
url
|
|
344
|
-
});
|
|
345
|
-
const response = await fetchFor(tls)(healthUrlFor(url), {
|
|
346
|
-
method: "GET",
|
|
347
|
-
headers,
|
|
348
|
-
signal: AbortSignal.timeout(healthTimeoutMs)
|
|
349
|
-
});
|
|
350
|
-
const body = await response.text();
|
|
351
|
-
const unavailable = response.ok ? null : unavailableOf(body);
|
|
352
|
-
return response.ok ? { ok: true, checkedAt } : {
|
|
353
|
-
ok: false,
|
|
354
|
-
detail: unavailable?.detail ?? `healthz returned HTTP ${response.status}`,
|
|
355
|
-
checkedAt
|
|
356
|
-
};
|
|
357
|
-
} catch (error) {
|
|
358
|
-
return {
|
|
359
|
-
ok: false,
|
|
360
|
-
detail: `healthz failed: ${error instanceof Error ? error.message : String(error)}`,
|
|
361
|
-
checkedAt
|
|
362
|
-
};
|
|
363
|
-
}
|
|
364
|
-
}
|
|
365
|
-
};
|
|
366
|
-
};
|
|
367
|
-
import { REMOTE_URL_SCHEMES, remoteUrlJson, remoteUrlZod } from "../harnesses/remote-url.mjs";
|
|
368
|
-
export {
|
|
369
|
-
CLOSE_TOKEN_HEADER,
|
|
370
|
-
HEALTH_TOKEN_HEADER,
|
|
371
|
-
PROGRAM_CONFIG_HEADER,
|
|
372
|
-
REMOTE_URL_SCHEMES,
|
|
373
|
-
RemoteProgram,
|
|
374
|
-
buildRemoteProgramConfig,
|
|
375
|
-
closeTokenFor,
|
|
376
|
-
createRemoteHarness,
|
|
377
|
-
formatRemoteRef,
|
|
378
|
-
healthTokenFor,
|
|
379
|
-
healthUrlFor,
|
|
380
|
-
parseRemoteRef,
|
|
381
|
-
programConfigUrlFor,
|
|
382
|
-
remoteUrlJson,
|
|
383
|
-
remoteUrlZod,
|
|
384
|
-
resolveSecretRef,
|
|
385
|
-
transportForUrl
|
|
386
|
-
};
|
|
387
|
-
//# sourceMappingURL=remote-host.mjs.map
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../../../../src/runtime/remote-host.ts"],
|
|
4
|
-
"sourcesContent": ["import { RequestError } from '@agentclientprotocol/sdk/experimental/v2';\n\nimport {\n AcpTransport,\n BaseCapability,\n BaseToolProvision,\n CredentialDelivery,\n CredentialRoute,\n formatProviderRef,\n harnessDescriptionSchema,\n InferenceCredentialKind,\n InstructionRole,\n packageRef,\n SandboxWire,\n type HarnessClientTlsIface,\n type HarnessDescriptionIface,\n type HarnessEndpointIface,\n type HarnessHealthIface,\n type HarnessIface,\n type HarnessSessionRefIface,\n type InstructionFragmentIface,\n type JsonObject,\n type OpenHarnessSessionArgsIface,\n type ResumeHarnessSessionArgsIface,\n type SecretReaderIface,\n type SkillBundleIface,\n type ToolApproval,\n} from '@finalai/agent-provider';\n\nimport { createNodeClientTlsFetch } from '@finalai/websockets/node-client-tls';\n\nimport { createHmac } from 'node:crypto';\n\nimport * as z from 'zod';\n\nimport { toJsonObject, type SecretRefIface } from \"../harnesses/config-fields.mjs\";\n\nimport {\n resolveRemoteClientTls,\n type RemoteClientTlsInputIface,\n} from \"../harnesses/remote-client-tls.mjs\";\n\nconst unavailableSchema = z.object({\n code: z.literal('harness_unavailable'),\n executable: z.string(),\n foundVersion: z.string().nullable(),\n requiredVersion: z.string(),\n detail: z.string(),\n});\n\nconst unavailableOf = (text: string) => {\n try {\n return unavailableSchema.safeParse(JSON.parse(text)).data ?? null;\n } catch {\n return null;\n }\n};\n\nconst DEFAULT_HEALTH_TIMEOUT_MS = 5_000;\n\nconst DEFAULT_REGISTER_TIMEOUT_MS = 10_000;\n\nconst DEFAULT_CLOSE_TIMEOUT_MS = 15_000;\n\n// Authentication modes supported by remote harness servers.\nexport const PROGRAM_CONFIG_HEADER = 'x-final-program-config';\n\nexport const HEALTH_TOKEN_HEADER = 'x-final-health-token';\n\nexport const CLOSE_TOKEN_HEADER = 'x-final-close-token';\n\n// The runtime's registration-scoped health credential (HMAC of the registration id under the\n// hop token): health(ref) has no secrets, so open/resume put it in the ref instead of the hop.\nexport const healthTokenFor = (args: { hop: string; id: string }): string =>\n createHmac('sha256', args.hop).update(`final-harness-health:${args.id}`).digest('base64url');\n\nexport const closeTokenFor = (args: { hop: string; id: string }): string =>\n createHmac('sha256', args.hop).update(`final-harness-close:${args.id}`).digest('base64url');\n\nconst PROGRAM_CONFIGS_PATH = '/v1/program-configs/';\n\nexport enum RemoteProgram {\n ClaudeCode = 'claude-code',\n Codex = 'codex',\n Pi = 'pi',\n}\n\nexport interface RemoteHarnessFactoryConfigIface {\n fetch?: typeof fetch;\n tlsFetch?: (tls: HarnessClientTlsIface) => typeof fetch;\n // Test seams.\n now?: () => number;\n newId?: () => string;\n healthTimeoutMs?: number;\n registerTimeoutMs?: number;\n closeTimeoutMs?: number;\n}\n\nexport interface RemoteSettingsIface {\n url: string;\n tls: RemoteClientTlsInputIface | null;\n hop: SecretRefIface;\n cwd: string | null;\n executable: string | null;\n model: string | null;\n reasoning: string | null;\n permissionMode: string | null;\n approvalPolicy: string | null;\n sandboxMode: string | null;\n allowedTools: string[] | null;\n instructions: InstructionFragmentIface[];\n skills: SkillBundleIface[];\n}\n\nexport interface RemoteProgramSpecIface {\n specifier: string;\n program: RemoteProgram;\n description: HarnessDescriptionIface;\n settings: (config: OpenHarnessSessionArgsIface['config']) => RemoteSettingsIface;\n}\n\n// The provider-private program config this harness registers with the runtime\n// Remote harness program configuration, version 1.\n// `credentials`, `broker` and `refresh` carry route grants (and, for at-open\n// harnesses, the resolved model credential); they travel only between this\n// provider and the runtime, over the hop-authenticated registration.\nexport interface RemoteProgramConfigIface {\n version: 1;\n program: RemoteProgram;\n // Absolute path on the runtime host; null = the runtime's own working directory.\n cwd: string | null;\n executable: string | null;\n model: string | null;\n reasoning: string | null;\n permissionMode: string | null;\n approvalPolicy: string | null;\n sandboxMode: string | null;\n allowedTools: string[] | null;\n // System fragments only; user fragments arrive as _final/session/observe.\n instructions: Pick<InstructionFragmentIface, 'role' | 'content'>[];\n skills: SkillBundleIface[];\n // Declared capabilities this harness provides, with the target a bound one\n // routes to; null runs it natively on the host. A host-disableable capability\n // absent here must be disabled through the program's own allow-lists.\n baseTools: Record<string, { provision: BaseToolProvision; target: string | null }>;\n sandboxes: Record<\n string,\n {\n bindingId: string;\n capabilities: string[];\n rpc: { url: string; token: string; expiresAt: string } | null;\n mcp: { url: string; token: string; expiresAt: string } | null;\n }\n >;\n toolPolicy: Record<string, ToolApproval>;\n attachments: { url: string; token: string } | null;\n // In the remote program configuration, the model credential\n // handed over at open (claude-code, codex), or the broker `model` route grant\n // for per-request programs (pi), which post to `<broker.url>/model`.\n credentials: OpenHarnessSessionArgsIface['credentials']['atOpen'];\n // `sandboxToken` is the broker `sandbox` route grant, for renewing sandbox endpoints.\n broker: {\n url: string;\n token: string;\n sandboxToken: string | null;\n harnessSessionId: string;\n } | null;\n // The grant's standard refresh route: the runtime pulls the next generation\n // of `credentials` and `broker` from it before they expire.\n refresh: OpenHarnessSessionArgsIface['credentials']['refresh'];\n}\n\nexport type RemoteOpenArgsIface = OpenHarnessSessionArgsIface;\n\nexport type RemoteHarnessIface = HarnessIface;\n\n// Scoped capabilities survive a session-service restart without retaining the hop or TLS keys.\nexport const formatRemoteRef = (args: {\n id: string;\n url: string;\n healthToken: string | null;\n closeToken?: string | null;\n}): string =>\n args.closeToken != null && args.healthToken != null\n ? `${args.id}|${args.healthToken}|${args.closeToken}|${args.url}`\n : args.healthToken == null\n ? `${args.id}|${args.url}`\n : `${args.id}|${args.healthToken}|${args.url}`;\n\nconst HEALTH_TOKEN_PATTERN = /^[A-Za-z0-9_-]{43}$/u;\n\nexport interface RemoteRefIface {\n id: string;\n url: string | null;\n healthToken: string | null;\n closeToken: string | null;\n}\n\nexport const parseRemoteRef = (ref: string): RemoteRefIface => {\n const bar = ref.indexOf('|');\n if (bar < 0) return { id: ref, url: null, healthToken: null, closeToken: null };\n const id = ref.slice(0, bar);\n const rest = ref.slice(bar + 1);\n const next = rest.indexOf('|');\n const token = next < 0 ? null : rest.slice(0, next);\n if (token == null || !HEALTH_TOKEN_PATTERN.test(token))\n return { id, url: rest, healthToken: null, closeToken: null };\n const remaining = rest.slice(next + 1);\n const separator = remaining.indexOf('|');\n const closeToken = separator < 0 ? null : remaining.slice(0, separator);\n return closeToken != null && HEALTH_TOKEN_PATTERN.test(closeToken)\n ? { id, url: remaining.slice(separator + 1), healthToken: token, closeToken }\n : { id, url: remaining, healthToken: token, closeToken: null };\n};\n\nexport const transportForUrl = (url: string): AcpTransport.Ws | AcpTransport.Http =>\n /^wss?:\\/\\//.test(url) ? AcpTransport.Ws : AcpTransport.Http;\n\nconst httpUrlOf = (url: string): string =>\n url.replace(/^ws(s?):\\/\\//, (_match, secure) => `http${secure}://`);\n\n// Lifecycle routes are siblings of /acp, including a reverse proxy's path prefix.\nconst runtimeUrlFor = (args: { url: string; path: string }): string => {\n const endpoint = new URL(httpUrlOf(args.url));\n if (endpoint.pathname !== '/') endpoint.pathname = endpoint.pathname.replace(/\\/+$/, '');\n return new URL(args.path.replace(/^\\/+/, ''), endpoint).toString();\n};\n\nexport const healthUrlFor = (url: string): string => runtimeUrlFor({ url, path: 'healthz' });\n\nexport const programConfigUrlFor = (args: { url: string; id: string }): string =>\n runtimeUrlFor({ url: args.url, path: `${PROGRAM_CONFIGS_PATH}${encodeURIComponent(args.id)}` });\n\nexport const resolveSecretRef = async (args: {\n specifier: string;\n field: string;\n ref: SecretRefIface;\n secrets: SecretReaderIface;\n}): Promise<string> => {\n const value = await args.secrets.get(args.ref.secretKey);\n if (value == null || value.length === 0) {\n throw new Error(\n `${args.specifier}: secret '${args.ref.secretKey}' for ${args.field} is not bound`,\n );\n }\n return value;\n};\n\nexport const buildRemoteProgramConfig = (args: {\n spec: RemoteProgramSpecIface;\n open: OpenHarnessSessionArgsIface;\n}): RemoteProgramConfigIface => {\n const settings = args.spec.settings(args.open.config);\n const description = args.spec.description;\n // A capability bound to a resolved target routes there. One declared on the\n // harness host (`harnessHost`), or bound to a target a harness that cannot\n // route it ignores (not reboundable), runs natively on the host.\n const routesTargets = description.consumes.includes(SandboxWire.HandleRpc);\n const baseTools: RemoteProgramConfigIface['baseTools'] = {};\n for (const capability of Object.values(BaseCapability)) {\n const endpoint = args.open.baseTools[capability];\n const declaration = description.baseTools[capability];\n if (declaration == null) continue;\n if (endpoint != null) {\n baseTools[capability] = { provision: declaration.provision, target: endpoint.target };\n continue;\n }\n if (declaration.provision === BaseToolProvision.Bound) continue;\n const onHost = args.open.manifest.tools.host?.includes(capability) === true;\n const unroutedTarget = args.open.manifest.tools.base[capability] != null && !routesTargets;\n if (onHost || unroutedTarget) {\n baseTools[capability] = { provision: declaration.provision, target: null };\n }\n }\n const delivery = description.inference.delivery;\n const modelGrant = args.open.credentials.grants.find(\n (grant) => grant.route === CredentialRoute.Model,\n );\n // The broker's sandbox route renews sandbox endpoints; it accepts only this grant.\n const sandboxGrant = args.open.credentials.grants.find(\n (grant) => grant.route === CredentialRoute.Sandbox,\n );\n return {\n attachments: (() => {\n const grant = args.open.credentials.grants.find(\n (entry) => entry.route === CredentialRoute.Mcp,\n );\n return grant == null\n ? null\n : {\n url: `${args.open.credentials.brokerUrl.replace(/\\/+$/, '')}/attachment`,\n token: grant.token,\n };\n })(),\n version: 1,\n program: args.spec.program,\n cwd: settings.cwd,\n executable: settings.executable,\n model: settings.model,\n reasoning: settings.reasoning,\n permissionMode: settings.permissionMode,\n approvalPolicy: settings.approvalPolicy,\n sandboxMode: settings.sandboxMode,\n allowedTools: settings.allowedTools,\n instructions: settings.instructions\n .filter((fragment) => fragment.role === InstructionRole.System)\n .map((fragment) => ({ role: fragment.role, content: fragment.content })),\n skills: settings.skills,\n baseTools,\n sandboxes: Object.fromEntries(\n Object.entries(args.open.sandboxes).map(([target, endpoint]) => [\n target,\n {\n bindingId: endpoint.bindingId,\n capabilities: [...endpoint.capabilities],\n rpc: endpoint.rpc,\n mcp: endpoint.mcp,\n },\n ]),\n ),\n toolPolicy: { ...args.open.manifest.toolPolicy },\n // The harness's own login (`credentials.harness()`) is configured by its\n // user, not by Final: nothing is handed over and the CLI's settings apply.\n credentials:\n delivery === CredentialDelivery.AtOpen &&\n args.open.credentials.atOpen?.kind !== InferenceCredentialKind.HarnessOwned\n ? args.open.credentials.atOpen\n : null,\n broker:\n delivery === CredentialDelivery.PerRequest && modelGrant != null\n ? {\n url: args.open.credentials.brokerUrl,\n token: modelGrant.token,\n sandboxToken: sandboxGrant?.token ?? null,\n harnessSessionId: args.open.harnessSessionId,\n }\n : null,\n refresh: args.open.credentials.refresh,\n };\n};\n\nexport const createRemoteHarness = (\n spec: RemoteProgramSpecIface,\n config: RemoteHarnessFactoryConfigIface = {},\n): RemoteHarnessIface => {\n const fetchImpl = config.fetch ?? fetch;\n const fetchFor = (tls: HarnessClientTlsIface | undefined) =>\n tls == null ? fetchImpl : (config.tlsFetch?.(tls) ?? createNodeClientTlsFetch({ tls }));\n const now = config.now ?? Date.now;\n const healthTimeoutMs = config.healthTimeoutMs ?? DEFAULT_HEALTH_TIMEOUT_MS;\n const registerTimeoutMs = config.registerTimeoutMs ?? DEFAULT_REGISTER_TIMEOUT_MS;\n const clientTls = new Map<string, HarnessClientTlsIface>();\n\n // Registers the program config (fresh credentials included) under the\n // harness session's id; the runtime applies it to session/new and\n // session/resume on connections that name it.\n const register = async (args: {\n url: string;\n hop: string;\n id: string;\n open: OpenHarnessSessionArgsIface;\n tls?: HarnessClientTlsIface;\n }): Promise<void> => {\n const source = args.open.forkSource;\n const forkSource = source == null ? null : parseRemoteRef(source.ref.harnessSessionRef);\n if (\n source != null &&\n (!spec.description.supports.fork ||\n formatProviderRef(source.ref.harness) !== formatProviderRef(packageRef(spec.specifier)))\n )\n throw new Error(`${spec.specifier}: the source does not support this harness's native fork`);\n if (forkSource != null && (forkSource.id === args.id || forkSource.url !== args.url))\n throw new Error(\n `${spec.specifier}: a fork requires a distinct registration on the source host`,\n );\n const target = programConfigUrlFor({ url: args.url, id: args.id });\n const registration: JsonObject = {\n program: toJsonObject(buildRemoteProgramConfig({ spec, open: args.open })),\n };\n if (source != null && forkSource != null)\n registration['forkSource'] = {\n programConfigId: forkSource.id,\n sessionId: source.acpSessionId,\n childSessionId: args.open.session.sessionId,\n };\n let response: Response;\n try {\n response = await fetchFor(args.tls)(target, {\n method: 'PUT',\n headers: { authorization: `Bearer ${args.hop}`, 'content-type': 'application/json' },\n body: JSON.stringify(registration),\n signal: AbortSignal.timeout(registerTimeoutMs),\n });\n } catch (error) {\n throw new Error(\n `${spec.specifier}: registering the program config failed: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n const body = await response.text().catch(() => '');\n if (!response.ok) {\n const unavailable = unavailableOf(body);\n if (unavailable != null) throw RequestError.internalError(unavailable, unavailable.detail);\n throw new Error(\n `${spec.specifier}: the runtime refused the program config (HTTP ${response.status}) ${body.slice(0, 200)}`.trim(),\n );\n }\n };\n\n const endpointFor = async (args: {\n open: OpenHarnessSessionArgsIface;\n ref: HarnessSessionRefIface;\n }): Promise<HarnessEndpointIface> => {\n const settings = spec.settings(args.open.config);\n const hop = await resolveSecretRef({\n specifier: spec.specifier,\n field: 'hop',\n ref: settings.hop,\n secrets: args.open.secrets,\n });\n const { id } = parseRemoteRef(args.ref.harnessSessionRef);\n const tls = await resolveRemoteClientTls({\n config: settings.tls,\n secrets: args.open.secrets,\n url: settings.url,\n });\n await register({ url: settings.url, hop, id, open: args.open, tls });\n if (tls != null) clientTls.set(id, tls);\n else clientTls.delete(id);\n return {\n // Re-minted on every open and resume: a rotated hop or a legacy ref gets a current token.\n ref: {\n ...args.ref,\n harnessSessionRef: formatRemoteRef({\n id,\n url: settings.url,\n healthToken: healthTokenFor({ hop, id }),\n closeToken: closeTokenFor({ hop, id }),\n }),\n },\n transport: transportForUrl(settings.url),\n url: settings.url,\n tls,\n headers: { authorization: `Bearer ${hop}`, [PROGRAM_CONFIG_HEADER]: id },\n };\n };\n\n return {\n describe: async (binding) => {\n if (binding == null) return spec.description;\n const settings = spec.settings(binding.config);\n const hop = await resolveSecretRef({\n specifier: spec.specifier,\n field: 'hop',\n ref: settings.hop,\n secrets: binding.secrets,\n });\n const tls = await resolveRemoteClientTls({\n config: settings.tls,\n secrets: binding.secrets,\n url: settings.url,\n });\n const response = await fetchFor(tls)(\n runtimeUrlFor({ url: settings.url, path: 'v1/describe' }),\n {\n method: 'POST',\n headers: { authorization: `Bearer ${hop}`, 'content-type': 'application/json' },\n body: JSON.stringify({ program: { executable: settings.executable } }),\n signal: AbortSignal.timeout(registerTimeoutMs),\n },\n );\n const text = await response.text();\n if (!response.ok) {\n const unavailable = unavailableOf(text);\n if (unavailable != null) throw RequestError.internalError(unavailable, unavailable.detail);\n throw new Error(\n `${spec.specifier}: describe failed (HTTP ${response.status}) ${text.slice(0, 200)}`,\n );\n }\n const description = harnessDescriptionSchema.parse(JSON.parse(text));\n return {\n ...description,\n configSchema: spec.description.configSchema,\n trust: spec.description.trust,\n inference: spec.description.inference,\n consumes: spec.description.consumes,\n };\n },\n open: async (args) => {\n const ref: HarnessSessionRefIface = {\n harness: packageRef(spec.specifier),\n // endpointFor() completes the ref with the url and health token.\n harnessSessionRef: args.harnessSessionId,\n generation: 1,\n };\n return endpointFor({ open: args, ref });\n },\n // The runtime resumes the program's own session (Claude Code session, Codex\n // rollout); re-registering hands it the fresh grants.\n resume: async (args: ResumeHarnessSessionArgsIface) =>\n endpointFor({ open: args, ref: args.ref }),\n park: async () => undefined,\n close: async (ref, options) => {\n const { id, url: retainedUrl, closeToken } = parseRemoteRef(ref.harnessSessionRef);\n const context = options?.context;\n const settings = context == null ? null : spec.settings(context.config);\n const url = retainedUrl ?? settings?.url ?? null;\n if (url == null) {\n if (options?.force === true)\n throw new Error(`${spec.specifier}: the legacy ref must be resumed before forced close`);\n return;\n }\n const hop =\n context == null || settings == null\n ? null\n : await context.secrets.get(settings.hop.secretKey);\n const scopedToken = hop == null || hop.length === 0 ? closeToken : closeTokenFor({ hop, id });\n if (scopedToken == null) {\n if (options?.force === true)\n throw new Error(\n `${spec.specifier}: the legacy ref needs close context or resume before forced close`,\n );\n return;\n }\n const tls =\n context == null || settings == null\n ? clientTls.get(id)\n : await resolveRemoteClientTls({\n config: settings.tls,\n secrets: context.secrets,\n url,\n });\n const response = await fetchFor(tls)(programConfigUrlFor({ url, id }), {\n method: 'DELETE',\n headers: { [CLOSE_TOKEN_HEADER]: scopedToken, 'content-type': 'application/json' },\n body: JSON.stringify({ force: options?.force === true }),\n signal: AbortSignal.timeout(config.closeTimeoutMs ?? DEFAULT_CLOSE_TIMEOUT_MS),\n });\n const body = await response.text();\n if (!response.ok && response.status !== 404)\n throw new Error(\n `${spec.specifier}: remote close failed (HTTP ${response.status}) ${body.slice(0, 200)}`,\n );\n clientTls.delete(id);\n },\n health: async (ref, context): Promise<HarnessHealthIface> => {\n const { id, url, healthToken } = parseRemoteRef(ref.harnessSessionRef);\n const checkedAt = new Date(now()).toISOString();\n if (url == null)\n return { ok: false, detail: 'harness session ref has no runtime url', checkedAt };\n try {\n const headers = new Headers({ [PROGRAM_CONFIG_HEADER]: id });\n if (healthToken != null) headers.set(HEALTH_TOKEN_HEADER, healthToken);\n const tls =\n context == null\n ? undefined\n : await resolveRemoteClientTls({\n config: spec.settings(context.config).tls,\n secrets: context.secrets,\n url,\n });\n const response = await fetchFor(tls)(healthUrlFor(url), {\n method: 'GET',\n headers,\n signal: AbortSignal.timeout(healthTimeoutMs),\n });\n const body = await response.text();\n const unavailable = response.ok ? null : unavailableOf(body);\n return response.ok\n ? { ok: true, checkedAt }\n : {\n ok: false,\n detail: unavailable?.detail ?? `healthz returned HTTP ${response.status}`,\n checkedAt,\n };\n } catch (error) {\n return {\n ok: false,\n detail: `healthz failed: ${error instanceof Error ? error.message : String(error)}`,\n checkedAt,\n };\n }\n },\n };\n};\nexport { REMOTE_URL_SCHEMES, remoteUrlJson, remoteUrlZod } from \"../harnesses/remote-url.mjs\";\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": ["RemoteProgram"]
|
|
7
|
-
}
|
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
import { type JsonObject, type OpenHarnessSessionArgsIface } from '@finalai/agent-provider';
|
|
2
|
-
import { type RemoteHarnessFactoryConfigIface, type RemoteHarnessIface } from "./remote-host.mjs";
|
|
3
|
-
export declare const programConfig: (args: OpenHarnessSessionArgsIface) => JsonObject;
|
|
4
|
-
export declare const createRemotePiHarness: (config?: RemoteHarnessFactoryConfigIface) => RemoteHarnessIface;
|
|
5
|
-
export * from "../harnesses/remote-pi.mjs";
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
import {} from "@finalai/agent-provider";
|
|
2
|
-
import { parseHarnessConfig, toJsonObject } from "../harnesses/config-fields.mjs";
|
|
3
|
-
import {
|
|
4
|
-
buildRemoteProgramConfig,
|
|
5
|
-
createRemoteHarness,
|
|
6
|
-
RemoteProgram
|
|
7
|
-
} from "./remote-host.mjs";
|
|
8
|
-
import { SPECIFIER, remotePiConfigSchema, REMOTE_PI_DESCRIPTION } from "../harnesses/remote-pi.mjs";
|
|
9
|
-
const spec = {
|
|
10
|
-
specifier: SPECIFIER,
|
|
11
|
-
program: RemoteProgram.Pi,
|
|
12
|
-
description: REMOTE_PI_DESCRIPTION,
|
|
13
|
-
settings: (raw) => {
|
|
14
|
-
const parsed = parseHarnessConfig({
|
|
15
|
-
specifier: SPECIFIER,
|
|
16
|
-
schema: remotePiConfigSchema,
|
|
17
|
-
config: raw
|
|
18
|
-
});
|
|
19
|
-
return {
|
|
20
|
-
url: parsed.url,
|
|
21
|
-
tls: parsed.tls ?? null,
|
|
22
|
-
hop: parsed.hop,
|
|
23
|
-
cwd: parsed.cwd ?? null,
|
|
24
|
-
executable: parsed.executable ?? null,
|
|
25
|
-
// The runtime's Pi program takes `<provider>/<vendor model id>`.
|
|
26
|
-
model: parsed.model ?? null,
|
|
27
|
-
reasoning: parsed.reasoning ?? null,
|
|
28
|
-
permissionMode: parsed.permissionMode ?? null,
|
|
29
|
-
approvalPolicy: null,
|
|
30
|
-
sandboxMode: null,
|
|
31
|
-
allowedTools: null,
|
|
32
|
-
instructions: parsed.instructions,
|
|
33
|
-
skills: []
|
|
34
|
-
};
|
|
35
|
-
}
|
|
36
|
-
};
|
|
37
|
-
const programConfig = (args) => toJsonObject(buildRemoteProgramConfig({ spec, open: args }));
|
|
38
|
-
const createRemotePiHarness = (config = {}) => createRemoteHarness(spec, config);
|
|
39
|
-
export * from "../harnesses/remote-pi.mjs";
|
|
40
|
-
export {
|
|
41
|
-
createRemotePiHarness,
|
|
42
|
-
programConfig
|
|
43
|
-
};
|
|
44
|
-
//# sourceMappingURL=remote-pi.mjs.map
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../../../../src/runtime/remote-pi.ts"],
|
|
4
|
-
"sourcesContent": ["import { type JsonObject, type OpenHarnessSessionArgsIface } from '@finalai/agent-provider';\nimport { parseHarnessConfig, toJsonObject } from \"../harnesses/config-fields.mjs\";\n\nimport {\n buildRemoteProgramConfig,\n createRemoteHarness,\n RemoteProgram,\n type RemoteHarnessFactoryConfigIface,\n type RemoteHarnessIface,\n type RemoteProgramSpecIface,\n} from \"./remote-host.mjs\";\nimport { SPECIFIER, remotePiConfigSchema, REMOTE_PI_DESCRIPTION } from \"../harnesses/remote-pi.mjs\";\n\nconst spec: RemoteProgramSpecIface = {\n specifier: SPECIFIER,\n program: RemoteProgram.Pi,\n description: REMOTE_PI_DESCRIPTION,\n settings: (raw) => {\n const parsed = parseHarnessConfig({\n specifier: SPECIFIER,\n schema: remotePiConfigSchema,\n config: raw,\n });\n return {\n url: parsed.url,\n tls: parsed.tls ?? null,\n hop: parsed.hop,\n cwd: parsed.cwd ?? null,\n executable: parsed.executable ?? null,\n // The runtime's Pi program takes `<provider>/<vendor model id>`.\n model: parsed.model ?? null,\n reasoning: parsed.reasoning ?? null,\n permissionMode: parsed.permissionMode ?? null,\n approvalPolicy: null,\n sandboxMode: null,\n allowedTools: null,\n instructions: parsed.instructions,\n skills: [],\n };\n },\n};\n\n// The program config this harness registers with the runtime.\nexport const programConfig = (args: OpenHarnessSessionArgsIface): JsonObject =>\n toJsonObject(buildRemoteProgramConfig({ spec, open: args }));\n\nexport const createRemotePiHarness = (\n config: RemoteHarnessFactoryConfigIface = {},\n): RemoteHarnessIface => createRemoteHarness(spec, config);\n\nexport * from \"../harnesses/remote-pi.mjs\";\n"],
|
|
5
|
-
"mappings": "AAAA,eAAkE;AAClE,SAAS,oBAAoB,oBAAoB;AAEjD;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OAIK;AACP,SAAS,WAAW,sBAAsB,6BAA6B;AAEvE,MAAM,OAA+B;AAAA,EACnC,WAAW;AAAA,EACX,SAAS,cAAc;AAAA,EACvB,aAAa;AAAA,EACb,UAAU,CAAC,QAAQ;AACjB,UAAM,SAAS,mBAAmB;AAAA,MAChC,WAAW;AAAA,MACX,QAAQ;AAAA,MACR,QAAQ;AAAA,IACV,CAAC;AACD,WAAO;AAAA,MACL,KAAK,OAAO;AAAA,MACZ,KAAK,OAAO,OAAO;AAAA,MACnB,KAAK,OAAO;AAAA,MACZ,KAAK,OAAO,OAAO;AAAA,MACnB,YAAY,OAAO,cAAc;AAAA;AAAA,MAEjC,OAAO,OAAO,SAAS;AAAA,MACvB,WAAW,OAAO,aAAa;AAAA,MAC/B,gBAAgB,OAAO,kBAAkB;AAAA,MACzC,gBAAgB;AAAA,MAChB,aAAa;AAAA,MACb,cAAc;AAAA,MACd,cAAc,OAAO;AAAA,MACrB,QAAQ,CAAC;AAAA,IACX;AAAA,EACF;AACF;AAGO,MAAM,gBAAgB,CAAC,SAC5B,aAAa,yBAAyB,EAAE,MAAM,MAAM,KAAK,CAAC,CAAC;AAEtD,MAAM,wBAAwB,CACnC,SAA0C,CAAC,MACpB,oBAAoB,MAAM,MAAM;AAEzD,cAAc;",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
import { NetworkPolicy, type SandboxGuidesIface, type SandboxGuideVersionIface } from '@finalai/agent-provider';
|
|
2
|
-
import { ComputerWorkspacePolicy, type ComputerEnvironmentOptions, type ComputerParametersIface, type ComputerRepositoryIface, type ComputerTemplateIface } from "./environment.mjs";
|
|
3
|
-
export type ComputerGuideVersionIface = SandboxGuideVersionIface;
|
|
4
|
-
export interface ResolvedNetworkPolicyIface {
|
|
5
|
-
mode: NetworkPolicy;
|
|
6
|
-
allow: string[];
|
|
7
|
-
}
|
|
8
|
-
export interface ResolvedComputerParametersIface {
|
|
9
|
-
repositories: ComputerRepositoryIface[];
|
|
10
|
-
variables: string[];
|
|
11
|
-
workspace: ComputerWorkspacePolicy;
|
|
12
|
-
networkPolicy: ResolvedNetworkPolicyIface;
|
|
13
|
-
env: Record<string, string>;
|
|
14
|
-
}
|
|
15
|
-
export interface ResolvedComputerSpecIface {
|
|
16
|
-
image: string;
|
|
17
|
-
template: ComputerTemplateIface;
|
|
18
|
-
parameters: ResolvedComputerParametersIface;
|
|
19
|
-
guide: Pick<ComputerGuideVersionIface, 'guideId' | 'versionId' | 'slug' | 'title' | 'number' | 'preparedArtifact'> | null;
|
|
20
|
-
instructionsMarkdown: string | null;
|
|
21
|
-
}
|
|
22
|
-
export declare const DEFAULT_COMPUTER_IMAGE = "lineage:sandbox";
|
|
23
|
-
export interface ComputerBuildInputsIface {
|
|
24
|
-
image: string;
|
|
25
|
-
template: ComputerTemplateIface;
|
|
26
|
-
diskGb: number | null;
|
|
27
|
-
}
|
|
28
|
-
export declare const computerNeedsBuild: (inputs: Pick<ComputerBuildInputsIface, "template">) => boolean;
|
|
29
|
-
export declare const computeComputerArtifactKey: (inputs: ComputerBuildInputsIface) => Promise<string>;
|
|
30
|
-
export declare const mergeComputerParameters: (base: ComputerParametersIface, override: ComputerParametersIface) => ResolvedComputerParametersIface;
|
|
31
|
-
export declare const resolveComputerSpec: (args: {
|
|
32
|
-
options: ComputerEnvironmentOptions;
|
|
33
|
-
guides: SandboxGuidesIface;
|
|
34
|
-
defaultImage: string;
|
|
35
|
-
}) => Promise<ResolvedComputerSpecIface>;
|