hyperbrane 0.1.2 → 0.2.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/README.md +67 -25
- package/dist/agent/agentClient.d.ts +5 -0
- package/dist/agent/agentClient.js +4 -0
- package/dist/agent/agentService.d.ts +9 -37
- package/dist/agent/agentService.js +62 -322
- package/dist/agent/agentStorage.d.ts +1 -20
- package/dist/agent/agentStorage.js +0 -30
- package/dist/agent/api.d.ts +80 -151
- package/dist/agent/api.js +1 -8
- package/dist/agent/client.d.ts +3 -1
- package/dist/agent/client.js +2 -3
- package/dist/agent/control.d.ts +23 -0
- package/dist/agent/control.js +479 -0
- package/dist/agent/hostTranscript.d.ts +0 -6
- package/dist/agent/hostTranscript.js +3 -14
- package/dist/agent/session/backend.d.ts +17 -32
- package/dist/agent/session/claude/home.d.ts +0 -1
- package/dist/agent/session/claude/home.js +0 -1
- package/dist/agent/session/claude/provision.d.ts +10 -0
- package/dist/agent/session/claude/provision.js +17 -0
- package/dist/agent/session/claude/transcript.d.ts +2 -7
- package/dist/agent/session/claude/transcript.js +68 -14
- package/dist/agent/session/client.d.ts +1 -10
- package/dist/agent/session/client.js +0 -3
- package/dist/agent/session/codex/provision.d.ts +14 -0
- package/dist/agent/session/codex/provision.js +25 -0
- package/dist/agent/session/fileTranscript.d.ts +6 -49
- package/dist/agent/session/fileTranscript.js +26 -82
- package/dist/agent/session/install.d.ts +5 -0
- package/dist/agent/session/install.js +35 -0
- package/dist/agent/session/sessionStorage.d.ts +4 -35
- package/dist/agent/session/sessionStorage.js +10 -16
- package/dist/agent/session/sharedConnection.d.ts +0 -8
- package/dist/agent/session/sharedConnection.js +0 -7
- package/dist/agent/session/storedTranscripts.d.ts +1 -6
- package/dist/agent/session/storedTranscripts.js +0 -3
- package/dist/agent/session/worker/jsonRpc.d.ts +2 -13
- package/dist/agent/session/worker/jsonRpc.js +2 -11
- package/dist/agent/session/worker/protocol.d.ts +26 -20
- package/dist/agent/session/worker/protocol.js +29 -18
- package/dist/agent/session/worker/workerParams.d.ts +0 -5
- package/dist/agent/session/worker/workerParams.js +14 -14
- package/dist/agent/session/workerConnection.d.ts +2 -13
- package/dist/agent/session/workerConnection.js +7 -12
- package/dist/agent/session/workerGatewayConnection.d.ts +18 -0
- package/dist/agent/session/workerGatewayConnection.js +86 -0
- package/dist/agent/vendor-types/manifest.json +87 -0
- package/dist/agent/workerBundle.d.ts +4 -19
- package/dist/agent/workerBundle.generated.js +1 -1
- package/dist/agent/workerBundle.js +3 -30
- package/dist/agent/workerReplacement.d.ts +3 -0
- package/dist/agent/workerReplacement.js +49 -0
- package/dist/cli/agent.js +31 -16
- package/dist/cli/command.d.ts +10 -11
- package/dist/cli/command.js +0 -4
- package/dist/cli/dimension.js +6 -6
- package/dist/cli/gateway.js +3 -6
- package/dist/cli/main.js +14 -31
- package/dist/cli/streamPrinter.d.ts +2 -10
- package/dist/cli/streamPrinter.js +16 -46
- package/dist/cli/table.d.ts +0 -3
- package/dist/cli/table.js +0 -4
- package/dist/dimension/api.d.ts +39 -27
- package/dist/dimension/api.js +28 -47
- package/dist/dimension/client.d.ts +5 -0
- package/dist/dimension/client.js +4 -0
- package/dist/dimension/control.d.ts +21 -0
- package/dist/dimension/control.js +328 -0
- package/dist/dimension/image.d.ts +0 -5
- package/dist/dimension/image.js +0 -8
- package/dist/dimension/imageFiles.generated.js +1 -1
- package/dist/dimension/paths.d.ts +5 -4
- package/dist/dimension/paths.js +15 -6
- package/dist/dimension/service.d.ts +8 -24
- package/dist/dimension/service.js +60 -228
- package/dist/dimension/transport-worker.d.ts +1 -0
- package/dist/dimension/transport-worker.js +151 -0
- package/dist/dimension/transportBundle.d.ts +2 -0
- package/dist/dimension/transportBundle.generated.d.ts +1 -0
- package/dist/dimension/transportBundle.generated.js +2 -0
- package/dist/dimension/transportBundle.js +4 -0
- package/dist/dimension/transportClient.d.ts +10 -0
- package/dist/dimension/transportClient.js +115 -0
- package/dist/dimension/transportProtocol.d.ts +53 -0
- package/dist/dimension/transportProtocol.js +8 -0
- package/dist/index.d.ts +5 -9
- package/dist/index.js +5 -19
- package/dist/lib/control.d.ts +8 -0
- package/dist/lib/control.js +62 -0
- package/dist/lib/docker.d.ts +0 -22
- package/dist/lib/docker.js +0 -10
- package/dist/lib/image.d.ts +0 -3
- package/dist/lib/image.js +0 -2
- package/dist/lib/jsonDirectory.d.ts +0 -13
- package/dist/lib/jsonDirectory.js +10 -15
- package/dist/lib/scriptBundle.d.ts +6 -0
- package/dist/lib/scriptBundle.js +28 -0
- package/dist/lib/sh.d.ts +2 -0
- package/dist/lib/sh.js +8 -0
- package/dist/lib/sleep.d.ts +0 -1
- package/dist/lib/sleep.js +0 -1
- package/dist/lib/streamFetch.d.ts +15 -0
- package/dist/lib/streamFetch.js +150 -0
- package/dist/lib/tar.d.ts +0 -1
- package/dist/lib/tar.js +5 -11
- package/dist/portal-gateway/api.d.ts +13 -44
- package/dist/portal-gateway/api.js +1 -3
- package/dist/portal-gateway/control.d.ts +42 -0
- package/dist/portal-gateway/control.js +657 -0
- package/dist/portal-gateway/gatewayClient.d.ts +5 -0
- package/dist/portal-gateway/gatewayClient.js +4 -0
- package/dist/portal-gateway/gatewayService.d.ts +8 -38
- package/dist/portal-gateway/gatewayService.js +68 -254
- package/dist/portal-gateway/image.d.ts +0 -1
- package/dist/portal-gateway/image.js +0 -2
- package/dist/portal-gateway/imageFiles.generated.js +2 -2
- package/dist/portal-gateway/portalClient.d.ts +5 -0
- package/dist/portal-gateway/portalClient.js +4 -0
- package/dist/portal-gateway/portalService.d.ts +5 -47
- package/dist/portal-gateway/portalService.js +19 -349
- package/dist/portal-gateway/transport-worker.d.ts +1 -0
- package/dist/portal-gateway/transport-worker.js +205 -0
- package/dist/portal-gateway/transportBundle.d.ts +2 -0
- package/dist/portal-gateway/transportBundle.generated.d.ts +1 -0
- package/dist/portal-gateway/transportBundle.generated.js +2 -0
- package/dist/portal-gateway/transportBundle.js +4 -0
- package/dist/portal-gateway/upstream.d.ts +0 -81
- package/dist/portal-gateway/upstream.js +0 -1
- package/dist/sandbox/api.d.ts +121 -187
- package/dist/sandbox/api.js +5 -7
- package/dist/sandbox/client.d.ts +2 -0
- package/dist/sandbox/client.js +4 -0
- package/dist/sandbox/data-endpoints/dataEndpoints.d.ts +13 -0
- package/dist/sandbox/data-endpoints/dataEndpoints.js +100 -0
- package/dist/sandbox/data-endpoints/firewalledPorts.d.ts +4 -0
- package/dist/sandbox/data-endpoints/firewalledPorts.js +28 -0
- package/dist/sandbox/lib/httpOverStream.d.ts +3 -0
- package/dist/sandbox/lib/httpOverStream.js +21 -0
- package/dist/sandbox/lib/remoteFileOperations.d.ts +10 -0
- package/dist/sandbox/lib/remoteFileOperations.js +70 -0
- package/dist/sandbox/lib/shellCommand.d.ts +3 -0
- package/dist/sandbox/lib/shellCommand.js +7 -0
- package/dist/sandbox/providers/boat/boatService.d.ts +2 -0
- package/dist/sandbox/providers/boat/boatService.js +321 -0
- package/dist/sandbox/providers/exedev/exeDevService.d.ts +2 -0
- package/dist/sandbox/providers/exedev/exeDevService.js +127 -0
- package/dist/sandbox/providers/exedev/exeDevToken.d.ts +1 -0
- package/dist/sandbox/providers/exedev/exeDevToken.js +54 -0
- package/dist/sandbox/providers/local/localService.d.ts +2 -0
- package/dist/sandbox/providers/local/localService.js +219 -0
- package/dist/sandbox/providers/ssh/sshService.d.ts +2 -0
- package/dist/sandbox/providers/ssh/sshService.js +82 -0
- package/dist/sandbox/providers/ssh/sshTransport.d.ts +12 -0
- package/dist/sandbox/providers/ssh/sshTransport.js +216 -0
- package/dist/sandbox/service.d.ts +2 -0
- package/dist/sandbox/service.js +18 -0
- package/dist/sandbox/storage/descriptors.d.ts +6 -0
- package/dist/sandbox/storage/descriptors.js +25 -0
- package/dist/sandbox/storage/sandboxStorage.d.ts +11 -0
- package/dist/sandbox/storage/sandboxStorage.js +42 -0
- package/dist/upstreams/anthropic.d.ts +0 -5
- package/dist/upstreams/anthropic.js +1 -8
- package/dist/upstreams/index.d.ts +2 -6
- package/dist/upstreams/index.js +0 -4
- package/dist/upstreams/openai.d.ts +0 -5
- package/dist/upstreams/openai.js +1 -13
- package/package.json +12 -4
- package/dist/agent/gatewaySignIns.d.ts +0 -5
- package/dist/agent/gatewaySignIns.js +0 -11
- package/dist/agent/session/codex/home.d.ts +0 -2
- package/dist/agent/session/codex/home.js +0 -4
- package/dist/agent/session/codex/messages.d.ts +0 -30
- package/dist/agent/session/codex/messages.js +0 -135
- package/dist/agent/session/codex/transcript.d.ts +0 -12
- package/dist/agent/session/codex/transcript.js +0 -22
- package/dist/agent/session/sdkMessages.d.ts +0 -15
- package/dist/agent/session/sdkMessages.js +0 -28
- package/dist/agent/session/workerSseConnection.d.ts +0 -31
- package/dist/agent/session/workerSseConnection.js +0 -76
- package/dist/agent/vendor-types/codex/app-server/AbsolutePathBuf.d.ts +0 -10
- package/dist/agent/vendor-types/codex/app-server/AbsolutePathBuf.js +0 -2
- package/dist/agent/vendor-types/codex/app-server/FunctionCallOutputBody.d.ts +0 -2
- package/dist/agent/vendor-types/codex/app-server/FunctionCallOutputBody.js +0 -2
- package/dist/agent/vendor-types/codex/app-server/FunctionCallOutputContentItem.d.ts +0 -22
- package/dist/agent/vendor-types/codex/app-server/FunctionCallOutputContentItem.js +0 -2
- package/dist/agent/vendor-types/codex/app-server/ImageDetail.d.ts +0 -1
- package/dist/agent/vendor-types/codex/app-server/ImageDetail.js +0 -2
- package/dist/agent/vendor-types/codex/app-server/ImageGenerationFailure.d.ts +0 -5
- package/dist/agent/vendor-types/codex/app-server/ImageGenerationFailure.js +0 -2
- package/dist/agent/vendor-types/codex/app-server/ImageGenerationItem.d.ts +0 -11
- package/dist/agent/vendor-types/codex/app-server/ImageGenerationItem.js +0 -2
- package/dist/agent/vendor-types/codex/app-server/LegacyAppPathString.d.ts +0 -23
- package/dist/agent/vendor-types/codex/app-server/LegacyAppPathString.js +0 -2
- package/dist/agent/vendor-types/codex/app-server/MessagePhase.d.ts +0 -7
- package/dist/agent/vendor-types/codex/app-server/MessagePhase.js +0 -2
- package/dist/agent/vendor-types/codex/app-server/ReasoningEffort.d.ts +0 -4
- package/dist/agent/vendor-types/codex/app-server/ReasoningEffort.js +0 -2
- package/dist/agent/vendor-types/codex/app-server/SleepItem.d.ts +0 -7
- package/dist/agent/vendor-types/codex/app-server/SleepItem.js +0 -2
- package/dist/agent/vendor-types/codex/app-server/WebSearchItem.d.ts +0 -14
- package/dist/agent/vendor-types/codex/app-server/WebSearchItem.js +0 -2
- package/dist/agent/vendor-types/codex/app-server/serde_json/JsonValue.d.ts +0 -3
- package/dist/agent/vendor-types/codex/app-server/serde_json/JsonValue.js +0 -2
- package/dist/agent/vendor-types/codex/app-server/v2/AgentMessageDelivery.d.ts +0 -1
- package/dist/agent/vendor-types/codex/app-server/v2/AgentMessageDelivery.js +0 -2
- package/dist/agent/vendor-types/codex/app-server/v2/AsyncUserInputQuestion.d.ts +0 -4
- package/dist/agent/vendor-types/codex/app-server/v2/AsyncUserInputQuestion.js +0 -2
- package/dist/agent/vendor-types/codex/app-server/v2/ByteRange.d.ts +0 -4
- package/dist/agent/vendor-types/codex/app-server/v2/ByteRange.js +0 -2
- package/dist/agent/vendor-types/codex/app-server/v2/CollabAgentState.d.ts +0 -5
- package/dist/agent/vendor-types/codex/app-server/v2/CollabAgentState.js +0 -2
- package/dist/agent/vendor-types/codex/app-server/v2/CollabAgentStatus.d.ts +0 -1
- package/dist/agent/vendor-types/codex/app-server/v2/CollabAgentStatus.js +0 -2
- package/dist/agent/vendor-types/codex/app-server/v2/CollabAgentTool.d.ts +0 -1
- package/dist/agent/vendor-types/codex/app-server/v2/CollabAgentTool.js +0 -2
- package/dist/agent/vendor-types/codex/app-server/v2/CollabAgentToolCallStatus.d.ts +0 -1
- package/dist/agent/vendor-types/codex/app-server/v2/CollabAgentToolCallStatus.js +0 -2
- package/dist/agent/vendor-types/codex/app-server/v2/CommandAction.d.ts +0 -19
- package/dist/agent/vendor-types/codex/app-server/v2/CommandAction.js +0 -2
- package/dist/agent/vendor-types/codex/app-server/v2/CommandExecutionSource.d.ts +0 -1
- package/dist/agent/vendor-types/codex/app-server/v2/CommandExecutionSource.js +0 -2
- package/dist/agent/vendor-types/codex/app-server/v2/CommandExecutionStatus.d.ts +0 -1
- package/dist/agent/vendor-types/codex/app-server/v2/CommandExecutionStatus.js +0 -2
- package/dist/agent/vendor-types/codex/app-server/v2/DynamicToolCallOutputContentItem.d.ts +0 -10
- package/dist/agent/vendor-types/codex/app-server/v2/DynamicToolCallOutputContentItem.js +0 -2
- package/dist/agent/vendor-types/codex/app-server/v2/DynamicToolCallStatus.d.ts +0 -1
- package/dist/agent/vendor-types/codex/app-server/v2/DynamicToolCallStatus.js +0 -2
- package/dist/agent/vendor-types/codex/app-server/v2/FileUpdateChange.d.ts +0 -6
- package/dist/agent/vendor-types/codex/app-server/v2/FileUpdateChange.js +0 -2
- package/dist/agent/vendor-types/codex/app-server/v2/HookPromptFragment.d.ts +0 -4
- package/dist/agent/vendor-types/codex/app-server/v2/HookPromptFragment.js +0 -2
- package/dist/agent/vendor-types/codex/app-server/v2/McpAppDisplayMode.d.ts +0 -1
- package/dist/agent/vendor-types/codex/app-server/v2/McpAppDisplayMode.js +0 -2
- package/dist/agent/vendor-types/codex/app-server/v2/McpAppUi.d.ts +0 -8
- package/dist/agent/vendor-types/codex/app-server/v2/McpAppUi.js +0 -2
- package/dist/agent/vendor-types/codex/app-server/v2/McpToolCallAppContext.d.ts +0 -7
- package/dist/agent/vendor-types/codex/app-server/v2/McpToolCallAppContext.js +0 -2
- package/dist/agent/vendor-types/codex/app-server/v2/McpToolCallError.d.ts +0 -3
- package/dist/agent/vendor-types/codex/app-server/v2/McpToolCallError.js +0 -2
- package/dist/agent/vendor-types/codex/app-server/v2/McpToolCallResult.d.ts +0 -6
- package/dist/agent/vendor-types/codex/app-server/v2/McpToolCallResult.js +0 -2
- package/dist/agent/vendor-types/codex/app-server/v2/McpToolCallStatus.d.ts +0 -1
- package/dist/agent/vendor-types/codex/app-server/v2/McpToolCallStatus.js +0 -2
- package/dist/agent/vendor-types/codex/app-server/v2/MemoryCitation.d.ts +0 -5
- package/dist/agent/vendor-types/codex/app-server/v2/MemoryCitation.js +0 -2
- package/dist/agent/vendor-types/codex/app-server/v2/MemoryCitationEntry.d.ts +0 -6
- package/dist/agent/vendor-types/codex/app-server/v2/MemoryCitationEntry.js +0 -2
- package/dist/agent/vendor-types/codex/app-server/v2/PatchApplyStatus.d.ts +0 -1
- package/dist/agent/vendor-types/codex/app-server/v2/PatchApplyStatus.js +0 -2
- package/dist/agent/vendor-types/codex/app-server/v2/PatchChangeKind.d.ts +0 -8
- package/dist/agent/vendor-types/codex/app-server/v2/PatchChangeKind.js +0 -2
- package/dist/agent/vendor-types/codex/app-server/v2/SubAgentActivityKind.d.ts +0 -1
- package/dist/agent/vendor-types/codex/app-server/v2/SubAgentActivityKind.js +0 -2
- package/dist/agent/vendor-types/codex/app-server/v2/TextElement.d.ts +0 -11
- package/dist/agent/vendor-types/codex/app-server/v2/TextElement.js +0 -2
- package/dist/agent/vendor-types/codex/app-server/v2/ThreadItem.d.ts +0 -215
- package/dist/agent/vendor-types/codex/app-server/v2/ThreadItem.js +0 -2
- package/dist/agent/vendor-types/codex/app-server/v2/UserInput.d.ts +0 -35
- package/dist/agent/vendor-types/codex/app-server/v2/UserInput.js +0 -2
- package/dist/agent/vendor-types/codex/app-server/v2/WebSearchAction.d.ts +0 -14
- package/dist/agent/vendor-types/codex/app-server/v2/WebSearchAction.js +0 -2
- package/dist/cli/services.d.ts +0 -19
- package/dist/cli/services.js +0 -34
- package/dist/dimension/http.d.ts +0 -7
- package/dist/dimension/http.js +0 -77
- package/dist/dimension/storage.d.ts +0 -39
- package/dist/dimension/storage.js +0 -79
- package/dist/portal-gateway/fakes.d.ts +0 -3
- package/dist/portal-gateway/fakes.js +0 -11
- package/dist/portal-gateway/gatewayStorage.d.ts +0 -66
- package/dist/portal-gateway/gatewayStorage.js +0 -125
- package/dist/portal-gateway/portalStorage.d.ts +0 -34
- package/dist/portal-gateway/portalStorage.js +0 -44
- package/dist/sandbox/boatService.d.ts +0 -52
- package/dist/sandbox/boatService.js +0 -343
- package/dist/sandbox/containerService.d.ts +0 -15
- package/dist/sandbox/containerService.js +0 -184
- package/dist/sandbox/endpointProxy.d.ts +0 -90
- package/dist/sandbox/endpointProxy.js +0 -716
- package/dist/sandbox/exeDevAuth.d.ts +0 -16
- package/dist/sandbox/exeDevAuth.js +0 -49
- package/dist/sandbox/localService.d.ts +0 -19
- package/dist/sandbox/localService.js +0 -200
- package/dist/sandbox/sseConnection.d.ts +0 -41
- package/dist/sandbox/sseConnection.js +0 -166
- package/dist/sandbox/sshService.d.ts +0 -30
- package/dist/sandbox/sshService.js +0 -680
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { existsSync } from "node:fs";
|
|
2
|
+
import manifest from "../vendor-types/manifest.json" with { type: "json" };
|
|
3
|
+
export function pinnedVersion(vendor, pkg, sourcePackage = pkg) {
|
|
4
|
+
const prefix = `npm:${sourcePackage}@`;
|
|
5
|
+
const source = manifest[vendor].sources.find((entry) => entry.source.startsWith(prefix));
|
|
6
|
+
if (!source)
|
|
7
|
+
throw new Error(`agent/vendor-types/manifest.json has no ${sourcePackage} for ${vendor} (needed for ${pkg})`);
|
|
8
|
+
return source.source.slice(prefix.length);
|
|
9
|
+
}
|
|
10
|
+
export async function installedPackage(installDir, pkg, version, executable) {
|
|
11
|
+
const manifest = Bun.file(`${installDir}/node_modules/${pkg}/package.json`);
|
|
12
|
+
const found = (await manifest.exists()) ? ((await manifest.json()).version ?? null) : null;
|
|
13
|
+
return { version: found, ready: found !== null && existsSync(executable()), pinned: version };
|
|
14
|
+
}
|
|
15
|
+
export async function installPackage(installDir, pkg, version, executable) {
|
|
16
|
+
const installed = await installedPackage(installDir, pkg, version, executable);
|
|
17
|
+
if (installed.ready && installed.version === version)
|
|
18
|
+
return;
|
|
19
|
+
const force = installed.version === version ? ["--force"] : [];
|
|
20
|
+
const proc = Bun.spawn(["flock", `${installDir}/.install.lock`, process.execPath, "add", "--exact", ...force, `${pkg}@${version}`], {
|
|
21
|
+
cwd: installDir,
|
|
22
|
+
stdin: "ignore",
|
|
23
|
+
stdout: "pipe",
|
|
24
|
+
stderr: "pipe",
|
|
25
|
+
});
|
|
26
|
+
const [stdout, stderr, exitCode] = await Promise.all([
|
|
27
|
+
new Response(proc.stdout).text(),
|
|
28
|
+
new Response(proc.stderr).text(),
|
|
29
|
+
proc.exited,
|
|
30
|
+
]);
|
|
31
|
+
if (exitCode !== 0)
|
|
32
|
+
throw new Error(`bun add ${pkg}@${version} failed (exit ${exitCode}): ${(stderr || stdout).trim()}`);
|
|
33
|
+
if (!existsSync(executable()))
|
|
34
|
+
throw new Error(`bun add ${pkg}@${version} left no ${executable()}: its platform package didn't install`);
|
|
35
|
+
}
|
|
@@ -1,69 +1,38 @@
|
|
|
1
1
|
import type { Sandbox } from "../../sandbox/api.ts";
|
|
2
|
-
import type { AgentAuthStatus, AgentBackend, AgentPermissionRequest, AgentQuestionRequest, AgentSession } from "../api.ts";
|
|
3
|
-
/** What the worker keeps of a session: never its messages, which are the backend's to store. */
|
|
2
|
+
import type { AgentAuthStatus, AgentBackend, AgentPermissionMode, AgentPermissionRequest, AgentQuestionRequest, AgentSession, AgentSessionState } from "../api.ts";
|
|
4
3
|
export type SessionRecord = {
|
|
5
4
|
spec: AgentSession;
|
|
6
|
-
/** The backend's id for the conversation, once known: what a new worker resumes. */
|
|
7
5
|
nativeId: string | null;
|
|
8
|
-
/** Chosen through AgentModels; null for the backend's default. */
|
|
9
6
|
model: string | null;
|
|
7
|
+
permissionMode?: AgentPermissionMode;
|
|
10
8
|
};
|
|
11
|
-
/** Where a session's CLI stands with its sign-in, as far as it outlives a request. */
|
|
12
9
|
export type SessionAuthRecord = {
|
|
13
|
-
/** Where the CLI's login in progress asked the user to sign in; null when none is. */
|
|
14
10
|
login: Extract<AgentAuthStatus, {
|
|
15
11
|
state: "pending";
|
|
16
12
|
}> | null;
|
|
17
|
-
/** Why the last login failed, if it did. */
|
|
18
13
|
error: string | null;
|
|
19
14
|
};
|
|
20
|
-
/** Every name must pass checkName; operations throw InvalidNameError otherwise. */
|
|
21
15
|
export interface SessionStorage {
|
|
22
16
|
getSessions(): Promise<SessionRecord[]>;
|
|
23
|
-
/** Stores the record unless one with that name exists; returns whichever record is stored afterwards. */
|
|
24
17
|
insertSession(record: SessionRecord): Promise<SessionRecord>;
|
|
25
|
-
/** Replaces the record. */
|
|
26
18
|
saveSession(record: SessionRecord): Promise<void>;
|
|
27
|
-
/** Removes the record and everything kept for the session. No-op if missing. */
|
|
28
19
|
removeSession(sessionName: string): Promise<void>;
|
|
29
|
-
/** The permission requests the session's CLI is waiting on, oldest first. */
|
|
30
20
|
getPermissionRequests(sessionName: string): Promise<AgentPermissionRequest[]>;
|
|
31
21
|
savePermissionRequest(sessionName: string, request: AgentPermissionRequest): Promise<void>;
|
|
32
|
-
/** No-op if missing. */
|
|
33
22
|
removePermissionRequest(sessionName: string, requestId: string): Promise<void>;
|
|
34
|
-
/** The questions the session's CLI is waiting on, oldest first. */
|
|
35
23
|
getQuestionRequests(sessionName: string): Promise<AgentQuestionRequest[]>;
|
|
36
24
|
saveQuestionRequest(sessionName: string, request: AgentQuestionRequest): Promise<void>;
|
|
37
|
-
/** No-op if missing. */
|
|
38
25
|
removeQuestionRequest(sessionName: string, requestId: string): Promise<void>;
|
|
39
|
-
/** Null until the session's CLI has been asked to sign in. */
|
|
40
26
|
readAuth(sessionName: string): Promise<SessionAuthRecord | null>;
|
|
41
27
|
saveAuth(sessionName: string, record: SessionAuthRecord): Promise<void>;
|
|
42
|
-
|
|
28
|
+
saveStatus(sessionName: string, status: AgentSessionState): Promise<void>;
|
|
43
29
|
socketPath(): Promise<string>;
|
|
44
|
-
/**
|
|
45
|
-
* Sandbox path of the backend CLI's home (claude's config directory, codex's CODEX_HOME): its
|
|
46
|
-
* sign-in, config and conversations, kept with the rest of the dimension's state. Shared by the
|
|
47
|
-
* dimension's agents, like a home would be. Creates it.
|
|
48
|
-
*/
|
|
49
30
|
backendHome(backend: AgentBackend): Promise<string>;
|
|
50
31
|
}
|
|
51
|
-
/**
|
|
52
|
-
* The agent's worker socket in a dimension's run directory: RUN_PATH inside the dimension, or the
|
|
53
|
-
* host side of that mount, so the host reaches the worker through it.
|
|
54
|
-
*/
|
|
55
32
|
export declare function workerSocketPath(runDirectory: string, agentName: string): string;
|
|
56
|
-
|
|
33
|
+
export declare function workerReadyPath(runDirectory: string, agentName: string): string;
|
|
57
34
|
export declare function sessionRecordPath(stateDirectory: string, agentName: string, sessionName: string): string;
|
|
58
|
-
/** Where the backend CLI's home is (SessionStorage.backendHome) in a dimension's state directory. */
|
|
59
35
|
export declare function backendHomePath(stateDirectory: string, backend: AgentBackend): string;
|
|
60
|
-
/**
|
|
61
|
-
* `stateDirectory` is a sandbox path: the dimension's state directory (STATE_PATH, mounted from the
|
|
62
|
-
* host's hyperbrane storage, so everything here lives there with the rest). Layout:
|
|
63
|
-
* agents/<agent>/sessions/<session>.json, and agents/<agent>/sessions/<session>/ holding
|
|
64
|
-
* permission-requests/<id>.json, question-requests/<id>.json and auth.json; backends/<backend>/
|
|
65
|
-
* (the CLIs' homes). The socket goes in `runDirectory`, the dimension's run directory.
|
|
66
|
-
*/
|
|
67
36
|
export declare function createSessionStorage(sandbox: Sandbox, agentName: string, { stateDirectory, runDirectory }?: {
|
|
68
37
|
stateDirectory?: string;
|
|
69
38
|
runDirectory?: string;
|
|
@@ -1,37 +1,28 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { dimensionLayout } from "../../dimension/api.js";
|
|
2
2
|
import { checkName, createJsonDirectory } from "../../lib/jsonDirectory.js";
|
|
3
|
-
/**
|
|
4
|
-
* The agent's worker socket in a dimension's run directory: RUN_PATH inside the dimension, or the
|
|
5
|
-
* host side of that mount, so the host reaches the worker through it.
|
|
6
|
-
*/
|
|
7
3
|
export function workerSocketPath(runDirectory, agentName) {
|
|
8
4
|
return `${runDirectory}/${agentName}.sock`;
|
|
9
5
|
}
|
|
6
|
+
export function workerReadyPath(runDirectory, agentName) {
|
|
7
|
+
return `${runDirectory}/${agentName}.ready`;
|
|
8
|
+
}
|
|
10
9
|
function sessionsDirectory(stateDirectory, agentName) {
|
|
11
10
|
return `${stateDirectory}/agents/${agentName}/sessions`;
|
|
12
11
|
}
|
|
13
|
-
/** Where the session's record is in a dimension's state directory (see createSessionStorage). */
|
|
14
12
|
export function sessionRecordPath(stateDirectory, agentName, sessionName) {
|
|
15
13
|
return `${sessionsDirectory(stateDirectory, agentName)}/${checkName(sessionName)}.json`;
|
|
16
14
|
}
|
|
17
|
-
/** Where the backend CLI's home is (SessionStorage.backendHome) in a dimension's state directory. */
|
|
18
15
|
export function backendHomePath(stateDirectory, backend) {
|
|
19
16
|
return `${stateDirectory}/backends/${backend}`;
|
|
20
17
|
}
|
|
21
|
-
|
|
22
|
-
* `stateDirectory` is a sandbox path: the dimension's state directory (STATE_PATH, mounted from the
|
|
23
|
-
* host's hyperbrane storage, so everything here lives there with the rest). Layout:
|
|
24
|
-
* agents/<agent>/sessions/<session>.json, and agents/<agent>/sessions/<session>/ holding
|
|
25
|
-
* permission-requests/<id>.json, question-requests/<id>.json and auth.json; backends/<backend>/
|
|
26
|
-
* (the CLIs' homes). The socket goes in `runDirectory`, the dimension's run directory.
|
|
27
|
-
*/
|
|
28
|
-
export function createSessionStorage(sandbox, agentName, { stateDirectory = STATE_PATH, runDirectory = RUN_PATH } = {}) {
|
|
18
|
+
export function createSessionStorage(sandbox, agentName, { stateDirectory = dimensionLayout.statePath(), runDirectory = dimensionLayout.runPath() } = {}) {
|
|
29
19
|
const sessionsDir = sessionsDirectory(stateDirectory, agentName);
|
|
30
20
|
const sessions = createJsonDirectory(sandbox, async () => sessionsDir);
|
|
31
21
|
const sessionDir = (sessionName) => `${sessionsDir}/${checkName(sessionName)}`;
|
|
32
22
|
const permissionRequests = (sessionName) => createJsonDirectory(sandbox, async () => `${sessionDir(sessionName)}/permission-requests`);
|
|
33
23
|
const questionRequests = (sessionName) => createJsonDirectory(sandbox, async () => `${sessionDir(sessionName)}/question-requests`);
|
|
34
24
|
const sessionFiles = (sessionName) => createJsonDirectory(sandbox, async () => sessionDir(sessionName));
|
|
25
|
+
const statusFiles = (sessionName) => createJsonDirectory(sandbox, async () => sessionDir(sessionName));
|
|
35
26
|
async function oldestFirst(stored) {
|
|
36
27
|
return (await stored).sort((a, b) => a.at - b.at).map((entry) => entry.request);
|
|
37
28
|
}
|
|
@@ -44,7 +35,6 @@ export function createSessionStorage(sandbox, agentName, { stateDirectory = STAT
|
|
|
44
35
|
async function saveSession(record) {
|
|
45
36
|
await sessions.save(record.spec.name, record);
|
|
46
37
|
}
|
|
47
|
-
// Everything kept for it first: while the record is there, the removal can be retried.
|
|
48
38
|
async function removeSession(sessionName) {
|
|
49
39
|
await sandbox.removeDirectory(sessionDir(sessionName));
|
|
50
40
|
await sessions.remove(sessionName);
|
|
@@ -73,6 +63,9 @@ export function createSessionStorage(sandbox, agentName, { stateDirectory = STAT
|
|
|
73
63
|
async function saveAuth(sessionName, record) {
|
|
74
64
|
await sessionFiles(sessionName).save("auth", record);
|
|
75
65
|
}
|
|
66
|
+
async function saveStatus(sessionName, status) {
|
|
67
|
+
await statusFiles(sessionName).save("status", { status });
|
|
68
|
+
}
|
|
76
69
|
async function socketPath() {
|
|
77
70
|
return workerSocketPath(runDirectory, agentName);
|
|
78
71
|
}
|
|
@@ -94,6 +87,7 @@ export function createSessionStorage(sandbox, agentName, { stateDirectory = STAT
|
|
|
94
87
|
removeQuestionRequest,
|
|
95
88
|
readAuth,
|
|
96
89
|
saveAuth,
|
|
90
|
+
saveStatus,
|
|
97
91
|
socketPath,
|
|
98
92
|
backendHome,
|
|
99
93
|
};
|
|
@@ -1,14 +1,6 @@
|
|
|
1
1
|
import type { ConnectWorker } from "./workerConnection.ts";
|
|
2
2
|
/** @sealed */
|
|
3
3
|
export type SharedConnector = ConnectWorker & {
|
|
4
|
-
/** Closes the connection they share (a later connect opens another). */
|
|
5
4
|
close(): void;
|
|
6
5
|
};
|
|
7
|
-
/**
|
|
8
|
-
* One connection to the worker, shared by everyone `connect`s through it: each gets a view of it
|
|
9
|
-
* (its requests go over it, the worker's notifications reach every view, closing a view only
|
|
10
|
-
* detaches it), so calls cost a round trip each rather than a connection each. Over an endpoint
|
|
11
|
-
* that's what matters (workerSseConnector opens an event stream per connection). The connection is
|
|
12
|
-
* opened on first use, and again after it closes.
|
|
13
|
-
*/
|
|
14
6
|
export declare function sharedConnector(connect: ConnectWorker): SharedConnector;
|
|
@@ -1,10 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* One connection to the worker, shared by everyone `connect`s through it: each gets a view of it
|
|
3
|
-
* (its requests go over it, the worker's notifications reach every view, closing a view only
|
|
4
|
-
* detaches it), so calls cost a round trip each rather than a connection each. Over an endpoint
|
|
5
|
-
* that's what matters (workerSseConnector opens an event stream per connection). The connection is
|
|
6
|
-
* opened on first use, and again after it closes.
|
|
7
|
-
*/
|
|
8
1
|
export function sharedConnector(connect) {
|
|
9
2
|
let current = null;
|
|
10
3
|
function open() {
|
|
@@ -1,13 +1,8 @@
|
|
|
1
1
|
import type { AgentBackend } from "../api.ts";
|
|
2
2
|
import type { SessionBackend } from "./backend.ts";
|
|
3
3
|
import type { LineMessages, TranscriptLayout } from "./fileTranscript.ts";
|
|
4
|
-
/**
|
|
5
|
-
* Each backend's conversations as it stores them: where (under the home homeEnvironment points it
|
|
6
|
-
* at) and how a line reads, for reading a transcript with nothing running, from the host. None of
|
|
7
|
-
* the backends' other code, which runs only in the dimension.
|
|
8
|
-
*/
|
|
9
4
|
export type StoredTranscripts = Pick<SessionBackend, "homeEnvironment"> & {
|
|
10
5
|
layout: TranscriptLayout;
|
|
11
6
|
lineMessages(nativeId: string): LineMessages;
|
|
12
7
|
};
|
|
13
|
-
export declare const STORED_TRANSCRIPTS: Record<AgentBackend, StoredTranscripts
|
|
8
|
+
export declare const STORED_TRANSCRIPTS: Partial<Record<AgentBackend, StoredTranscripts>>;
|
|
@@ -1,8 +1,5 @@
|
|
|
1
1
|
import { claudeHomeEnvironment } from "./claude/home.js";
|
|
2
2
|
import { CLAUDE_TRANSCRIPT_LAYOUT, claudeLineMessages } from "./claude/transcript.js";
|
|
3
|
-
import { codexHomeEnvironment } from "./codex/home.js";
|
|
4
|
-
import { CODEX_TRANSCRIPT_LAYOUT, codexLineMessages } from "./codex/transcript.js";
|
|
5
3
|
export const STORED_TRANSCRIPTS = {
|
|
6
4
|
claude: { homeEnvironment: claudeHomeEnvironment, layout: CLAUDE_TRANSCRIPT_LAYOUT, lineMessages: () => claudeLineMessages },
|
|
7
|
-
codex: { homeEnvironment: codexHomeEnvironment, layout: CODEX_TRANSCRIPT_LAYOUT, lineMessages: codexLineMessages },
|
|
8
5
|
};
|
|
@@ -1,7 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* JSON-RPC 2.0 over a byte stream, one JSON object per line (the framing codex's app-server uses).
|
|
3
|
-
* Either end can send requests and notifications; the worker protocol (protocol.ts) is built on it.
|
|
4
|
-
*/
|
|
5
1
|
export type JsonRpcId = string | number;
|
|
6
2
|
export type JsonRpcErrorObject = {
|
|
7
3
|
code: number;
|
|
@@ -9,29 +5,22 @@ export type JsonRpcErrorObject = {
|
|
|
9
5
|
data?: unknown;
|
|
10
6
|
};
|
|
11
7
|
export type JsonRpcPeerOptions = {
|
|
12
|
-
|
|
13
|
-
|
|
8
|
+
onRequest(method: string, params: unknown, protocol: number | undefined): Promise<unknown>;
|
|
9
|
+
protocol?: number;
|
|
14
10
|
onNotification?(method: string, params: unknown): void;
|
|
15
11
|
encodeError(error: unknown): JsonRpcErrorObject;
|
|
16
12
|
decodeError(error: JsonRpcErrorObject): Error;
|
|
17
13
|
};
|
|
18
14
|
export interface JsonRpcPeer {
|
|
19
|
-
/** Feeds text read from the connection; complete lines are handled as they arrive. */
|
|
20
15
|
receive(text: string): void;
|
|
21
16
|
request(method: string, params: unknown): Promise<unknown>;
|
|
22
17
|
notify(method: string, params: unknown): void;
|
|
23
|
-
/** Fails every request still waiting for its response. */
|
|
24
18
|
close(error: Error): void;
|
|
25
19
|
}
|
|
26
20
|
export declare function createJsonRpcPeer(write: (line: string) => void, options: JsonRpcPeerOptions): JsonRpcPeer;
|
|
27
|
-
/** The part of a Bun socket a writer needs. */
|
|
28
21
|
type WritableSocket = {
|
|
29
22
|
write(data: Uint8Array): number;
|
|
30
23
|
};
|
|
31
|
-
/**
|
|
32
|
-
* Writes to a Bun socket without losing what it can't take yet: the rest is kept and written on
|
|
33
|
-
* `drain`, which the socket's drain handler must call.
|
|
34
|
-
*/
|
|
35
24
|
export declare function createSocketWriter(socket: WritableSocket): {
|
|
36
25
|
write(text: string): void;
|
|
37
26
|
drain(): void;
|
|
@@ -1,8 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* JSON-RPC 2.0 over a byte stream, one JSON object per line (the framing codex's app-server uses).
|
|
3
|
-
* Either end can send requests and notifications; the worker protocol (protocol.ts) is built on it.
|
|
4
|
-
*/
|
|
5
|
-
/** Answer for a line that isn't JSON-RPC at all. */
|
|
6
1
|
const PARSE_ERROR = -32700;
|
|
7
2
|
export function createJsonRpcPeer(write, options) {
|
|
8
3
|
const pending = new Map();
|
|
@@ -31,7 +26,7 @@ export function createJsonRpcPeer(write, options) {
|
|
|
31
26
|
return;
|
|
32
27
|
}
|
|
33
28
|
const id = message.id;
|
|
34
|
-
options.onRequest(message.method, message.params).then((result) => send({ id, result: result ?? null }), (error) => send({ id, error: options.encodeError(error) }));
|
|
29
|
+
options.onRequest(message.method, message.params, message.protocol).then((result) => send({ id, result: result ?? null }), (error) => send({ id, error: options.encodeError(error) }));
|
|
35
30
|
}
|
|
36
31
|
function receive(text) {
|
|
37
32
|
buffered += text;
|
|
@@ -58,7 +53,7 @@ export function createJsonRpcPeer(write, options) {
|
|
|
58
53
|
const id = nextId++;
|
|
59
54
|
return new Promise((resolve, reject) => {
|
|
60
55
|
pending.set(id, { resolve, reject });
|
|
61
|
-
send({ id, method, params });
|
|
56
|
+
send({ id, method, params, ...(options.protocol === undefined ? {} : { protocol: options.protocol }) });
|
|
62
57
|
});
|
|
63
58
|
}
|
|
64
59
|
function notify(method, params) {
|
|
@@ -72,10 +67,6 @@ export function createJsonRpcPeer(write, options) {
|
|
|
72
67
|
}
|
|
73
68
|
return { receive, request, notify, close };
|
|
74
69
|
}
|
|
75
|
-
/**
|
|
76
|
-
* Writes to a Bun socket without losing what it can't take yet: the rest is kept and written on
|
|
77
|
-
* `drain`, which the socket's drain handler must call.
|
|
78
|
-
*/
|
|
79
70
|
export function createSocketWriter(socket) {
|
|
80
71
|
const encoder = new TextEncoder();
|
|
81
72
|
let backlog = null;
|
|
@@ -1,16 +1,8 @@
|
|
|
1
|
-
import { type AgentAuthStatus, type AgentBackend, type AgentBackendInfo, type AgentBackgroundTask, type AgentLastUserMessage, type AgentModelInfo, type AgentPermissionRequest, type AgentPermissionResult, type AgentQuestionRequest, type AgentQuestionResponse, type AgentSession, type AgentSessionInfo, type AgentSessionLimits, type AgentSessionState, type AgentStreamingMessage, type AgentTranscriptPage, type UserMessage } from "../../api.ts";
|
|
1
|
+
import { type AgentAuthStatus, type AgentBackend, type AgentBackendInfo, type AgentBackgroundTask, type AgentLastUserMessage, type AgentModelInfo, type AgentPermissionRequest, type AgentPermissionResult, type AgentQuestionRequest, type AgentQuestionResponse, type AgentSession, type AgentSessionInfo, type AgentSessionLimits, type AgentSessionState, type AgentPermissionMode, type AgentStreamingMessage, type AgentTranscriptPage, type UserMessage } from "../../api.ts";
|
|
2
2
|
import type { JsonRpcErrorObject } from "./jsonRpc.ts";
|
|
3
|
-
/**
|
|
4
|
-
* The worker's JSON-RPC protocol, spoken over its unix socket (see createWorkerServer): method ->
|
|
5
|
-
* [params, result]. Sessions are named by `session`; everything answers `null` unless it says.
|
|
6
|
-
* worker/health and worker/shutdown are how the host tells a worker's build and replaces it: they
|
|
7
|
-
* never change.
|
|
8
|
-
*
|
|
9
|
-
* @sealed
|
|
10
|
-
*/
|
|
3
|
+
/** @sealed */
|
|
11
4
|
export type WorkerRequests = {
|
|
12
5
|
"worker/health": [Record<string, never>, WorkerHealth];
|
|
13
|
-
/** Answers, then stops the sessions' CLIs and exits. */
|
|
14
6
|
"worker/shutdown": [Record<string, never>, null];
|
|
15
7
|
"backend/install": [{
|
|
16
8
|
backend: AgentBackend;
|
|
@@ -40,12 +32,6 @@ export type WorkerRequests = {
|
|
|
40
32
|
"session/lastUserMessages": [{
|
|
41
33
|
session: string;
|
|
42
34
|
}, AgentLastUserMessage[]];
|
|
43
|
-
/**
|
|
44
|
-
* Streams the session's messages as `session/message` notifications carrying `subscription` (the
|
|
45
|
-
* client's own id for the stream): first the complete messages after `after_id` (all of them when
|
|
46
|
-
* omitted) from the backend's transcript, then each message as it comes, until session/unsubscribe
|
|
47
|
-
* or the connection closes.
|
|
48
|
-
*/
|
|
49
35
|
"session/subscribe": [{
|
|
50
36
|
session: string;
|
|
51
37
|
subscription: string;
|
|
@@ -60,6 +46,12 @@ export type WorkerRequests = {
|
|
|
60
46
|
before?: string;
|
|
61
47
|
cursor?: string;
|
|
62
48
|
}, AgentTranscriptPage];
|
|
49
|
+
"session/subagentTranscript": [{
|
|
50
|
+
session: string;
|
|
51
|
+
toolUseId: string;
|
|
52
|
+
limit?: number;
|
|
53
|
+
before?: string;
|
|
54
|
+
}, AgentTranscriptPage];
|
|
63
55
|
"permission/list": [{
|
|
64
56
|
session: string;
|
|
65
57
|
}, AgentPermissionRequest[]];
|
|
@@ -76,7 +68,6 @@ export type WorkerRequests = {
|
|
|
76
68
|
request: string;
|
|
77
69
|
response: AgentQuestionResponse;
|
|
78
70
|
}, null];
|
|
79
|
-
/** Starts the session's CLI if it isn't running. */
|
|
80
71
|
"model/list": [{
|
|
81
72
|
session: string;
|
|
82
73
|
}, AgentModelInfo[]];
|
|
@@ -84,7 +75,10 @@ export type WorkerRequests = {
|
|
|
84
75
|
session: string;
|
|
85
76
|
model: string | null;
|
|
86
77
|
}, null];
|
|
87
|
-
|
|
78
|
+
"permission/mode": [{
|
|
79
|
+
session: string;
|
|
80
|
+
mode: AgentPermissionMode;
|
|
81
|
+
}, null];
|
|
88
82
|
"task/list": [{
|
|
89
83
|
session: string;
|
|
90
84
|
}, AgentBackgroundTask[]];
|
|
@@ -95,7 +89,6 @@ export type WorkerRequests = {
|
|
|
95
89
|
"auth/status": [{
|
|
96
90
|
session: string;
|
|
97
91
|
}, AgentAuthStatus];
|
|
98
|
-
/** `gatewaySignedIn`: the dimension's gateway holds the backend's upstream credential (the host knows; the worker can't). */
|
|
99
92
|
"auth/login": [{
|
|
100
93
|
session: string;
|
|
101
94
|
gatewaySignedIn: boolean;
|
|
@@ -112,13 +105,26 @@ export type WorkerNotifications = {
|
|
|
112
105
|
message: AgentStreamingMessage;
|
|
113
106
|
};
|
|
114
107
|
};
|
|
108
|
+
export declare const WORKER_PROTOCOL = 3;
|
|
115
109
|
export type WorkerHealth = {
|
|
116
110
|
agentName: string;
|
|
117
111
|
build: string;
|
|
112
|
+
protocol: number;
|
|
113
|
+
};
|
|
114
|
+
export declare const WorkerErrorCode: {
|
|
115
|
+
readonly methodNotFound: -32601;
|
|
116
|
+
readonly invalidParams: -32602;
|
|
117
|
+
readonly internalError: -32603;
|
|
118
|
+
readonly notFound: -32004;
|
|
119
|
+
readonly conflict: -32009;
|
|
120
|
+
readonly backendNotInstalled: -32010;
|
|
121
|
+
readonly protocolMismatch: -32011;
|
|
118
122
|
};
|
|
119
123
|
export declare class WorkerMethodNotFoundError extends Error {
|
|
120
124
|
name: string;
|
|
121
125
|
}
|
|
122
|
-
|
|
126
|
+
export declare class WorkerProtocolMismatchError extends Error {
|
|
127
|
+
name: string;
|
|
128
|
+
}
|
|
123
129
|
export declare function encodeWorkerError(error: unknown): JsonRpcErrorObject;
|
|
124
130
|
export declare function decodeWorkerError({ code, message }: JsonRpcErrorObject): Error;
|
|
@@ -1,37 +1,48 @@
|
|
|
1
1
|
import { AgentBackendNotInstalledError, AgentConflictError, AgentInvalidError, AgentNotFoundError, } from "../../api.js";
|
|
2
|
-
const
|
|
3
|
-
const
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
2
|
+
export const WORKER_PROTOCOL = 3;
|
|
3
|
+
export const WorkerErrorCode = {
|
|
4
|
+
methodNotFound: -32601,
|
|
5
|
+
invalidParams: -32602,
|
|
6
|
+
internalError: -32603,
|
|
7
|
+
notFound: -32004,
|
|
8
|
+
conflict: -32009,
|
|
9
|
+
backendNotInstalled: -32010,
|
|
10
|
+
protocolMismatch: -32011,
|
|
11
|
+
};
|
|
9
12
|
export class WorkerMethodNotFoundError extends Error {
|
|
10
13
|
name = "WorkerMethodNotFoundError";
|
|
11
14
|
}
|
|
12
|
-
|
|
15
|
+
export class WorkerProtocolMismatchError extends Error {
|
|
16
|
+
name = "WorkerProtocolMismatchError";
|
|
17
|
+
}
|
|
13
18
|
export function encodeWorkerError(error) {
|
|
14
19
|
const message = error instanceof Error ? error.message : String(error);
|
|
15
20
|
if (error instanceof AgentInvalidError)
|
|
16
|
-
return { code:
|
|
21
|
+
return { code: WorkerErrorCode.invalidParams, message };
|
|
17
22
|
if (error instanceof AgentNotFoundError)
|
|
18
|
-
return { code:
|
|
23
|
+
return { code: WorkerErrorCode.notFound, message };
|
|
19
24
|
if (error instanceof AgentBackendNotInstalledError)
|
|
20
|
-
return { code:
|
|
25
|
+
return { code: WorkerErrorCode.backendNotInstalled, message };
|
|
21
26
|
if (error instanceof AgentConflictError)
|
|
22
|
-
return { code:
|
|
27
|
+
return { code: WorkerErrorCode.conflict, message };
|
|
23
28
|
if (error instanceof WorkerMethodNotFoundError)
|
|
24
|
-
return { code:
|
|
25
|
-
|
|
29
|
+
return { code: WorkerErrorCode.methodNotFound, message };
|
|
30
|
+
if (error instanceof WorkerProtocolMismatchError)
|
|
31
|
+
return { code: WorkerErrorCode.protocolMismatch, message };
|
|
32
|
+
return { code: WorkerErrorCode.internalError, message };
|
|
26
33
|
}
|
|
27
34
|
export function decodeWorkerError({ code, message }) {
|
|
28
|
-
if (code ===
|
|
35
|
+
if (code === WorkerErrorCode.invalidParams)
|
|
29
36
|
return new AgentInvalidError(message);
|
|
30
|
-
if (code ===
|
|
37
|
+
if (code === WorkerErrorCode.notFound)
|
|
31
38
|
return new AgentNotFoundError(message);
|
|
32
|
-
if (code ===
|
|
39
|
+
if (code === WorkerErrorCode.conflict)
|
|
33
40
|
return new AgentConflictError(message);
|
|
34
|
-
if (code ===
|
|
41
|
+
if (code === WorkerErrorCode.backendNotInstalled)
|
|
35
42
|
return new AgentBackendNotInstalledError(message);
|
|
43
|
+
if (code === WorkerErrorCode.methodNotFound)
|
|
44
|
+
return new WorkerMethodNotFoundError(`worker: ${message}`);
|
|
45
|
+
if (code === WorkerErrorCode.protocolMismatch)
|
|
46
|
+
return new WorkerProtocolMismatchError(`worker: ${message}`);
|
|
36
47
|
return new Error(`worker: ${message}`);
|
|
37
48
|
}
|
|
@@ -1,10 +1,5 @@
|
|
|
1
1
|
import type { WorkerMethod, WorkerRequests } from "./protocol.ts";
|
|
2
2
|
type Fields = Record<string, unknown>;
|
|
3
|
-
/**
|
|
4
|
-
* Turns each method's params, as they arrived (JSON), into the protocol's types, or throws an
|
|
5
|
-
* AgentInvalidError saying what's wrong. Keeps only the fields the types have, so nothing unknown
|
|
6
|
-
* reaches the service (or its storage).
|
|
7
|
-
*/
|
|
8
3
|
export declare const WORKER_PARAMS: {
|
|
9
4
|
[M in WorkerMethod]: (params: Fields) => WorkerRequests[M][0];
|
|
10
5
|
};
|
|
@@ -1,9 +1,4 @@
|
|
|
1
|
-
import { AGENT_BACKENDS, AgentInvalidError, } from "../../api.js";
|
|
2
|
-
/**
|
|
3
|
-
* Turns each method's params, as they arrived (JSON), into the protocol's types, or throws an
|
|
4
|
-
* AgentInvalidError saying what's wrong. Keeps only the fields the types have, so nothing unknown
|
|
5
|
-
* reaches the service (or its storage).
|
|
6
|
-
*/
|
|
1
|
+
import { AGENT_BACKENDS, AGENT_PERMISSION_MODES, AgentInvalidError, } from "../../api.js";
|
|
7
2
|
export const WORKER_PARAMS = {
|
|
8
3
|
"worker/health": () => ({}),
|
|
9
4
|
"worker/shutdown": () => ({}),
|
|
@@ -26,9 +21,14 @@ export const WORKER_PARAMS = {
|
|
|
26
21
|
"session/transcript": (params) => ({
|
|
27
22
|
session: name(params),
|
|
28
23
|
limit: optional(params.limit, (value) => number(value, "limit")),
|
|
29
|
-
// `cursor`: `before`'s old name.
|
|
30
24
|
before: params.before === undefined ? optional(params.cursor, (value) => text(value, "cursor")) : text(params.before, "before"),
|
|
31
25
|
}),
|
|
26
|
+
"session/subagentTranscript": (params) => ({
|
|
27
|
+
session: name(params),
|
|
28
|
+
toolUseId: text(params.toolUseId, "toolUseId"),
|
|
29
|
+
limit: optional(params.limit, (value) => number(value, "limit")),
|
|
30
|
+
before: optional(params.before, (value) => text(value, "before")),
|
|
31
|
+
}),
|
|
32
32
|
"permission/list": (params) => ({ session: name(params) }),
|
|
33
33
|
"permission/respond": (params) => ({
|
|
34
34
|
session: name(params),
|
|
@@ -46,6 +46,7 @@ export const WORKER_PARAMS = {
|
|
|
46
46
|
session: name(params),
|
|
47
47
|
model: params.model === null ? null : text(params.model, "the model (a model name, or null for the backend's default)"),
|
|
48
48
|
}),
|
|
49
|
+
"permission/mode": (params) => ({ session: name(params), mode: permissionMode(params.mode) }),
|
|
49
50
|
"task/list": (params) => ({ session: name(params) }),
|
|
50
51
|
"task/stop": (params) => ({ session: name(params), task: text(params.task, "task") }),
|
|
51
52
|
"auth/status": (params) => ({ session: name(params) }),
|
|
@@ -64,10 +65,8 @@ function name(params) {
|
|
|
64
65
|
function object(value, what) {
|
|
65
66
|
if (value === null || typeof value !== "object" || Array.isArray(value))
|
|
66
67
|
invalid(`${what} must be an object`);
|
|
67
|
-
// type-bypass: a non-null, non-array object is a record of its fields.
|
|
68
68
|
return value;
|
|
69
69
|
}
|
|
70
|
-
/** A non-empty string. */
|
|
71
70
|
function text(value, what) {
|
|
72
71
|
if (typeof value !== "string" || value.trim() === "")
|
|
73
72
|
invalid(`${what} must be a non-empty string`);
|
|
@@ -86,6 +85,12 @@ function boolean(value, what) {
|
|
|
86
85
|
function optional(value, parse) {
|
|
87
86
|
return value === undefined ? undefined : parse(value);
|
|
88
87
|
}
|
|
88
|
+
function permissionMode(value) {
|
|
89
|
+
const known = AGENT_PERMISSION_MODES.find((mode) => mode === value);
|
|
90
|
+
if (!known)
|
|
91
|
+
invalid(`unknown permission mode "${String(value)}"; known: ${AGENT_PERMISSION_MODES.join(", ")}`);
|
|
92
|
+
return known;
|
|
93
|
+
}
|
|
89
94
|
function backend(value) {
|
|
90
95
|
const known = AGENT_BACKENDS.find((name) => name === value);
|
|
91
96
|
if (!known)
|
|
@@ -96,14 +101,12 @@ function memoryLimit(value) {
|
|
|
96
101
|
const bytes = number(value, "memoryLimit");
|
|
97
102
|
if (!(bytes > 0))
|
|
98
103
|
invalid("memoryLimit must be positive");
|
|
99
|
-
// type-bypass: a positive byte count is what a MemoryLimit is (MemoryLimit() parses the CLI's strings).
|
|
100
104
|
return bytes;
|
|
101
105
|
}
|
|
102
106
|
function cpuLimit(value) {
|
|
103
107
|
const cores = number(value, "cpuLimit");
|
|
104
108
|
if (!(cores > 0))
|
|
105
109
|
invalid("cpuLimit must be positive");
|
|
106
|
-
// type-bypass: a positive core count is what a CPULimit is (CPULimit() parses the CLI's strings).
|
|
107
110
|
return cores;
|
|
108
111
|
}
|
|
109
112
|
function environment(value) {
|
|
@@ -111,7 +114,6 @@ function environment(value) {
|
|
|
111
114
|
for (const [key, entry] of Object.entries(fields))
|
|
112
115
|
if (typeof entry !== "string")
|
|
113
116
|
invalid(`env.${key} must be a string`);
|
|
114
|
-
// type-bypass: every value was just checked to be a string.
|
|
115
117
|
return fields;
|
|
116
118
|
}
|
|
117
119
|
function session(fields) {
|
|
@@ -136,7 +138,6 @@ function userMessage(value) {
|
|
|
136
138
|
invalid('message.message.role must be "user"');
|
|
137
139
|
if (typeof message.content !== "string" && !Array.isArray(message.content))
|
|
138
140
|
invalid("message.message.content must be a string or an array of content blocks");
|
|
139
|
-
// type-bypass: the envelope is checked; the content blocks are the CLI's to judge.
|
|
140
141
|
return value;
|
|
141
142
|
}
|
|
142
143
|
function permissionResult(value) {
|
|
@@ -158,6 +159,5 @@ function questionResponse(value) {
|
|
|
158
159
|
for (const [question, answer] of Object.entries(answers))
|
|
159
160
|
if (typeof answer !== "string")
|
|
160
161
|
invalid(`the answer to "${question}" must be a string`);
|
|
161
|
-
// type-bypass: every answer was just checked to be a string.
|
|
162
162
|
return { answers: answers };
|
|
163
163
|
}
|
|
@@ -1,29 +1,18 @@
|
|
|
1
|
-
import type { Sandbox } from "../../sandbox/api.ts";
|
|
1
|
+
import type { Sandbox, SandboxConnection } from "../../sandbox/api.ts";
|
|
2
2
|
import { type WorkerMethod, type WorkerNotifications, type WorkerRequests } from "./worker/protocol.ts";
|
|
3
|
-
/** One connection to a worker: typed requests, and the notifications it pushes. */
|
|
4
3
|
export type WorkerConnection = {
|
|
5
4
|
request<M extends WorkerMethod>(method: M, params: WorkerRequests[M][0]): Promise<WorkerRequests[M][1]>;
|
|
6
|
-
/** Resolves when the worker closes the connection (or it fails). */
|
|
7
5
|
closed: Promise<void>;
|
|
8
6
|
close(): void;
|
|
9
7
|
};
|
|
10
8
|
export type WorkerNotificationHandler = <N extends keyof WorkerNotifications>(method: N, params: WorkerNotifications[N]) => void;
|
|
11
|
-
/** Opens a connection; notifications go to `onNotification`. */
|
|
12
9
|
export type ConnectWorker = (onNotification?: WorkerNotificationHandler) => Promise<WorkerConnection>;
|
|
13
|
-
/** A text stream to a worker that its JSON-RPC lines go out and come in on. */
|
|
14
10
|
export type WorkerTransport = {
|
|
15
11
|
write(text: string): void;
|
|
16
|
-
/** Receives the text read from the worker, in order. Registered before anything arrives. */
|
|
17
12
|
onText(listener: (text: string) => void): void;
|
|
18
|
-
/** Resolves once the transport is closed, by either side or by an error. */
|
|
19
13
|
closed: Promise<void>;
|
|
20
14
|
close(): void;
|
|
21
15
|
};
|
|
22
|
-
/** A connection speaking JSON-RPC over `transport` (`label` says where to, in errors). */
|
|
23
16
|
export declare function workerConnectionOver(transport: WorkerTransport, label: string, onNotification?: WorkerNotificationHandler): WorkerConnection;
|
|
24
|
-
/**
|
|
25
|
-
* Connects over the worker's unix socket at `socketPath` in `host` (the dimension's run directory is
|
|
26
|
-
* mounted on the host, wherever that is: this machine, or a server reached over SSH), speaking
|
|
27
|
-
* JSON-RPC.
|
|
28
|
-
*/
|
|
29
17
|
export declare function workerSocketConnector(host: Sandbox, socketPath: string): ConnectWorker;
|
|
18
|
+
export declare function workerStreamConnector(open: () => Promise<SandboxConnection>, label: string): ConnectWorker;
|