hyperbrane 0.1.2 → 0.2.1
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 +105 -23
- 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 +64 -323
- package/dist/agent/agentStorage.d.ts +1 -20
- package/dist/agent/agentStorage.js +0 -30
- package/dist/agent/api.d.ts +105 -152
- 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/dimensionAgentClient.d.ts +8 -0
- package/dist/agent/dimensionAgentClient.js +99 -0
- package/dist/agent/hostTranscript.d.ts +0 -6
- package/dist/agent/hostTranscript.js +3 -14
- package/dist/agent/session/backend.d.ts +18 -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 +3 -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 +30 -21
- 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 +24 -17
- 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 +32 -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 +42 -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 +22 -0
- package/dist/dimension/control.js +346 -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 +85 -227
- 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 +7 -9
- package/dist/index.js +7 -19
- package/dist/lib/control.d.ts +11 -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 +34 -18
- 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/lib/unixSocket.d.ts +2 -0
- package/dist/lib/unixSocket.js +28 -0
- package/dist/portal-gateway/api.d.ts +14 -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 +82 -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/restore.d.ts +9 -0
- package/dist/restore.js +10 -0
- package/dist/sandbox/api.d.ts +126 -187
- package/dist/sandbox/api.js +5 -7
- package/dist/sandbox/client.d.ts +3 -0
- package/dist/sandbox/client.js +7 -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/lib/sshKey.d.ts +6 -0
- package/dist/sandbox/lib/sshKey.js +75 -0
- package/dist/sandbox/providers/boat/boatService.d.ts +3 -0
- package/dist/sandbox/providers/boat/boatService.js +373 -0
- package/dist/sandbox/providers/exedev/exeDevService.d.ts +2 -0
- package/dist/sandbox/providers/exedev/exeDevService.js +129 -0
- package/dist/sandbox/providers/exedev/exeDevToken.d.ts +1 -0
- package/dist/sandbox/providers/exedev/exeDevToken.js +50 -0
- package/dist/sandbox/providers/local/localService.d.ts +2 -0
- package/dist/sandbox/providers/local/localService.js +197 -0
- package/dist/sandbox/providers/ssh/sshService.d.ts +2 -0
- package/dist/sandbox/providers/ssh/sshService.js +83 -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 +3 -0
- package/dist/sandbox/service.js +26 -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/dist/vendor-types/claude/agent-sdk/bridge.d.ts +20 -4
- package/dist/vendor-types/claude/agent-sdk/browser-sdk.d.ts +24 -0
- package/dist/vendor-types/claude/agent-sdk/core.d.ts +2 -0
- package/dist/vendor-types/claude/agent-sdk/sdk-tools.d.ts +75 -6
- package/dist/vendor-types/claude/agent-sdk/sdk.d.ts +569 -100
- package/package.json +13 -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
|
@@ -1,31 +1,4 @@
|
|
|
1
|
-
import { createHash } from "node:crypto";
|
|
2
|
-
import { existsSync } from "node:fs";
|
|
3
1
|
import { join } from "node:path";
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
* them; otherwise (Node, or the built package, which ships no sources) it comes from
|
|
8
|
-
* agent/workerBundle.generated.ts (scripts/bundle-worker.ts).
|
|
9
|
-
*/
|
|
10
|
-
export function workerBundle() {
|
|
11
|
-
bundled ??= load().catch((error) => {
|
|
12
|
-
bundled = undefined;
|
|
13
|
-
throw error;
|
|
14
|
-
});
|
|
15
|
-
return bundled;
|
|
16
|
-
}
|
|
17
|
-
async function load() {
|
|
18
|
-
const fromSources = "Bun" in globalThis && existsSync(join(import.meta.dirname, "session", "main.ts"));
|
|
19
|
-
const source = fromSources ? await buildWorkerSource() : (await import("./workerBundle.generated.js")).WORKER_SOURCE;
|
|
20
|
-
return { source, build: createHash("sha256").update(source).digest("hex").slice(0, 16) };
|
|
21
|
-
}
|
|
22
|
-
/** Bundles the worker with Bun.build. */
|
|
23
|
-
export async function buildWorkerSource() {
|
|
24
|
-
const result = await Bun.build({
|
|
25
|
-
entrypoints: [join(import.meta.dirname, "session", "main.ts")],
|
|
26
|
-
target: "bun",
|
|
27
|
-
});
|
|
28
|
-
if (!result.success)
|
|
29
|
-
throw new Error(`bundling the session worker failed:\n${result.logs.join("\n")}`);
|
|
30
|
-
return result.outputs[0].text();
|
|
31
|
-
}
|
|
2
|
+
import { scriptBundle } from "../lib/scriptBundle.js";
|
|
3
|
+
export const workerEntry = () => join(import.meta.dirname, "session", "main.ts");
|
|
4
|
+
export const workerBundle = scriptBundle(workerEntry, async () => (await import("./workerBundle.generated.js")).WORKER_SOURCE);
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { SandboxConnectionRefusedError } from "../sandbox/api.js";
|
|
2
|
+
import { createWorkerClient } from "./session/client.js";
|
|
3
|
+
import { WorkerMethodNotFoundError, WorkerProtocolMismatchError } from "./session/worker/protocol.js";
|
|
4
|
+
export function replacingWorkerClient(connect, replace) {
|
|
5
|
+
const reconnecting = async (onNotification) => {
|
|
6
|
+
try {
|
|
7
|
+
return await connect(onNotification);
|
|
8
|
+
}
|
|
9
|
+
catch (error) {
|
|
10
|
+
if (!(error instanceof SandboxConnectionRefusedError))
|
|
11
|
+
throw error;
|
|
12
|
+
await replace(false);
|
|
13
|
+
return connect(onNotification);
|
|
14
|
+
}
|
|
15
|
+
};
|
|
16
|
+
const client = createWorkerClient(reconnecting);
|
|
17
|
+
const outdated = async (error) => {
|
|
18
|
+
if (!(error instanceof WorkerProtocolMismatchError || error instanceof WorkerMethodNotFoundError))
|
|
19
|
+
throw error;
|
|
20
|
+
await replace(error instanceof WorkerMethodNotFoundError);
|
|
21
|
+
};
|
|
22
|
+
return {
|
|
23
|
+
async call(method, params) {
|
|
24
|
+
try {
|
|
25
|
+
return await client.call(method, params);
|
|
26
|
+
}
|
|
27
|
+
catch (error) {
|
|
28
|
+
await outdated(error);
|
|
29
|
+
return client.call(method, params);
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
async *stream(session, afterId) {
|
|
33
|
+
let streamed = false;
|
|
34
|
+
try {
|
|
35
|
+
for await (const message of client.stream(session, afterId)) {
|
|
36
|
+
streamed = true;
|
|
37
|
+
yield message;
|
|
38
|
+
}
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
catch (error) {
|
|
42
|
+
if (streamed)
|
|
43
|
+
throw error;
|
|
44
|
+
await outdated(error);
|
|
45
|
+
}
|
|
46
|
+
yield* client.stream(session, afterId);
|
|
47
|
+
},
|
|
48
|
+
};
|
|
49
|
+
}
|
package/dist/cli/agent.js
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
import { AGENT_BACKENDS } from "../agent/api.js";
|
|
1
|
+
import { AGENT_BACKENDS, AGENT_PERMISSION_MODES, } from "../agent/api.js";
|
|
2
2
|
import { CPULimit, MemoryLimit } from "../dimension/api.js";
|
|
3
3
|
import { QUIET_FLAG, UsageError, forEach, printList, requireFlag } from "./command.js";
|
|
4
4
|
import { createTerminalPrinter, preview } from "./streamPrinter.js";
|
|
5
5
|
import { formatTable } from "./table.js";
|
|
6
|
-
/** How often `session attach` looks for permission requests and questions to point out. */
|
|
7
6
|
const PENDING_POLL_MS = 1_000;
|
|
8
7
|
function backendArg(name) {
|
|
9
8
|
const backend = AGENT_BACKENDS.find((known) => known === name);
|
|
@@ -11,7 +10,6 @@ function backendArg(name) {
|
|
|
11
10
|
throw new UsageError(`unknown backend ${name}: use one of ${AGENT_BACKENDS.join(", ")}`);
|
|
12
11
|
return backend;
|
|
13
12
|
}
|
|
14
|
-
/** "AGENT/SESSION" -> the session's ref. */
|
|
15
13
|
function sessionRef(arg) {
|
|
16
14
|
const slash = arg.indexOf("/");
|
|
17
15
|
if (slash <= 0 || slash === arg.length - 1)
|
|
@@ -21,7 +19,6 @@ function sessionRef(arg) {
|
|
|
21
19
|
function refName({ agentName, sessionName }) {
|
|
22
20
|
return `${agentName}/${sessionName}`;
|
|
23
21
|
}
|
|
24
|
-
/** --env KEY=VALUE flags -> an environment. */
|
|
25
22
|
function envFlag(flags) {
|
|
26
23
|
const entries = flags.env;
|
|
27
24
|
if (!Array.isArray(entries) || entries.length === 0)
|
|
@@ -35,10 +32,6 @@ function envFlag(flags) {
|
|
|
35
32
|
}
|
|
36
33
|
return env;
|
|
37
34
|
}
|
|
38
|
-
/**
|
|
39
|
-
* Points out, once each, the permission requests and questions the session is waiting on, with the
|
|
40
|
-
* command that answers them. Returns the function that stops looking.
|
|
41
|
-
*/
|
|
42
35
|
function watchPending(agents, ref) {
|
|
43
36
|
const seen = new Set();
|
|
44
37
|
const name = refName(ref);
|
|
@@ -97,7 +90,7 @@ export const agentCommands = {
|
|
|
97
90
|
summary: `Install or update backends in an agent's dimension (${AGENT_BACKENDS.join(", ")})`,
|
|
98
91
|
args: ["AGENT", "BACKEND..."],
|
|
99
92
|
async run([agent, ...backends], _flags, { agents }) {
|
|
100
|
-
backends.forEach(backendArg);
|
|
93
|
+
backends.forEach(backendArg);
|
|
101
94
|
await forEach(backends, (backend) => agents.install(agent, backendArg(backend)));
|
|
102
95
|
},
|
|
103
96
|
},
|
|
@@ -150,7 +143,15 @@ const modelCommands = {
|
|
|
150
143
|
},
|
|
151
144
|
},
|
|
152
145
|
};
|
|
153
|
-
|
|
146
|
+
function describeStatus(status) {
|
|
147
|
+
if (status.state === "tool")
|
|
148
|
+
return `tool: ${status.tools.join(", ")}`;
|
|
149
|
+
if (status.state !== "exited")
|
|
150
|
+
return status.state;
|
|
151
|
+
if (status.signal)
|
|
152
|
+
return `exited (${status.signal})`;
|
|
153
|
+
return status.code === null ? "exited" : `exited (code ${status.code})`;
|
|
154
|
+
}
|
|
154
155
|
function describeAuth(name, status) {
|
|
155
156
|
if (status.state === "signedIn")
|
|
156
157
|
return "signed in";
|
|
@@ -214,6 +215,22 @@ const taskCommands = {
|
|
|
214
215
|
const permissionCommands = {
|
|
215
216
|
summary: "List and answer a session's permission requests: tool calls waiting to run",
|
|
216
217
|
commands: {
|
|
218
|
+
mode: {
|
|
219
|
+
summary: `Show the session's permission mode, or switch it: "ask" before each tool call, or "auto" to allow them all (the waiting ones too)`,
|
|
220
|
+
args: ["AGENT/SESSION", "[MODE]"],
|
|
221
|
+
async run([name, mode], _flags, { agents }) {
|
|
222
|
+
const ref = sessionRef(name);
|
|
223
|
+
if (mode === undefined) {
|
|
224
|
+
const session = (await agents.listSessions()).find((candidate) => candidate.agentName === ref.agentName && candidate.name === ref.sessionName);
|
|
225
|
+
return console.log(session?.permissionMode ?? "ask");
|
|
226
|
+
}
|
|
227
|
+
const known = AGENT_PERMISSION_MODES.find((candidate) => candidate === mode);
|
|
228
|
+
if (!known)
|
|
229
|
+
throw new UsageError(`unknown permission mode ${mode}: use one of ${AGENT_PERMISSION_MODES.join(", ")}`);
|
|
230
|
+
await agents.setPermissionMode(ref, known);
|
|
231
|
+
console.log(known);
|
|
232
|
+
},
|
|
233
|
+
},
|
|
217
234
|
ls: {
|
|
218
235
|
summary: "List a session's tool calls waiting for permission",
|
|
219
236
|
args: ["AGENT/SESSION"],
|
|
@@ -293,7 +310,7 @@ export const sessionCommands = {
|
|
|
293
310
|
.map((session) => [
|
|
294
311
|
`${session.agentName}/${session.name}`,
|
|
295
312
|
session.backend,
|
|
296
|
-
session.status,
|
|
313
|
+
describeStatus(session.status),
|
|
297
314
|
session.model ?? "(default)",
|
|
298
315
|
session.nativeId ?? "",
|
|
299
316
|
])
|
|
@@ -367,7 +384,6 @@ export const sessionCommands = {
|
|
|
367
384
|
const ref = sessionRef(name);
|
|
368
385
|
const stopWatching = watchPending(agents, ref);
|
|
369
386
|
const printer = createTerminalPrinter({ paced: true });
|
|
370
|
-
// Ctrl-C: out with what's still being typed, and the terminal back to normal text.
|
|
371
387
|
process.once("SIGINT", () => {
|
|
372
388
|
printer.close();
|
|
373
389
|
process.exit(130);
|
|
@@ -403,8 +419,8 @@ export const sessionCommands = {
|
|
|
403
419
|
before: typeof flags.before === "string" ? timeFlag(flags.before) : undefined,
|
|
404
420
|
});
|
|
405
421
|
const printer = createTerminalPrinter({ paced: false });
|
|
406
|
-
for (const
|
|
407
|
-
printer.printTranscript(
|
|
422
|
+
for (const message of page.messages)
|
|
423
|
+
printer.printTranscript(message);
|
|
408
424
|
printer.close();
|
|
409
425
|
if (page.nextBefore)
|
|
410
426
|
process.stderr.write(`(older: hyperbrane session logs ${name} --before ${page.nextBefore})\n`);
|
|
@@ -416,7 +432,7 @@ export const sessionCommands = {
|
|
|
416
432
|
async run([name], _flags, { agents }) {
|
|
417
433
|
const ref = sessionRef(name);
|
|
418
434
|
const [state, messages] = await Promise.all([agents.getSessionStatus(ref), agents.getLastUserMessages(ref)]);
|
|
419
|
-
console.log(state);
|
|
435
|
+
console.log(describeStatus(state));
|
|
420
436
|
for (const { message, queued } of messages) {
|
|
421
437
|
const content = message.message.content;
|
|
422
438
|
const text = typeof content === "string" ? content : content.map((block) => (block.type === "text" ? block.text : "")).join("");
|
|
@@ -439,7 +455,6 @@ export const sessionCommands = {
|
|
|
439
455
|
},
|
|
440
456
|
};
|
|
441
457
|
const AGO_UNITS = { s: 1_000, m: 60_000, h: 3_600_000, d: 86_400_000 };
|
|
442
|
-
/** --before's TIME as an ISO 8601 time: a date or time, or how long ago ("30m"). */
|
|
443
458
|
function timeFlag(value) {
|
|
444
459
|
const ago = /^(\d+)([smhd])$/.exec(value);
|
|
445
460
|
const time = ago ? Date.now() - Number(ago[1]) * AGO_UNITS[ago[2]] : Date.parse(value);
|
package/dist/cli/command.d.ts
CHANGED
|
@@ -1,34 +1,35 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { AgentClient, AgentProvision, AgentSessionCapabilities } from "../agent/api.ts";
|
|
2
|
+
import type { DimensionClient } from "../dimension/api.ts";
|
|
3
|
+
import type { GatewayClient, PortalClient } from "../portal-gateway/api.ts";
|
|
2
4
|
export type Flag = {
|
|
3
5
|
type: "string" | "boolean";
|
|
4
6
|
short?: string;
|
|
5
|
-
/** Shown in help, e.g. "BYTES". */
|
|
6
7
|
value?: string;
|
|
7
8
|
description: string;
|
|
8
|
-
/** May be given more than once; its value is then a string[]. */
|
|
9
9
|
multiple?: boolean;
|
|
10
10
|
};
|
|
11
11
|
export type Flags = Record<string, string | boolean | string[] | undefined>;
|
|
12
|
+
export type Clients = {
|
|
13
|
+
readonly dimensions: DimensionClient;
|
|
14
|
+
readonly gateways: GatewayClient;
|
|
15
|
+
readonly portals: PortalClient;
|
|
16
|
+
readonly agents: AgentClient & AgentProvision & AgentSessionCapabilities;
|
|
17
|
+
};
|
|
12
18
|
export type Command = {
|
|
13
19
|
summary: string;
|
|
14
|
-
/** Positional arguments: "NAME" is required, "[NAME]" optional, a trailing "NAME..." takes one or more. */
|
|
15
20
|
args?: string[];
|
|
16
21
|
flags?: Record<string, Flag>;
|
|
17
|
-
run(args: string[], flags: Flags,
|
|
22
|
+
run(args: string[], flags: Flags, clients: Clients): Promise<void>;
|
|
18
23
|
};
|
|
19
24
|
export type CommandGroup = {
|
|
20
25
|
summary: string;
|
|
21
|
-
/** A group may hold groups of its own: `hyperbrane session permission allow`. */
|
|
22
26
|
commands: Record<string, Command | CommandGroup>;
|
|
23
|
-
/** Runs when the next word isn't one of `commands`: `hyperbrane session model A/S` next to `... model set`. */
|
|
24
27
|
default?: Command;
|
|
25
28
|
};
|
|
26
29
|
export declare function isGroup(entry: Command | CommandGroup): entry is CommandGroup;
|
|
27
|
-
/** Bad invocation: printed with a pointer to --help. */
|
|
28
30
|
export declare class UsageError extends Error {
|
|
29
31
|
name: string;
|
|
30
32
|
}
|
|
31
|
-
/** Some items of a multi-item command failed; each error was already printed. */
|
|
32
33
|
export declare class PartialFailure extends Error {
|
|
33
34
|
name: string;
|
|
34
35
|
}
|
|
@@ -37,9 +38,7 @@ export declare function parseCommand(command: Command, argv: string[]): {
|
|
|
37
38
|
flags: Flags;
|
|
38
39
|
};
|
|
39
40
|
export declare function requireFlag(flags: Flags, name: string): string;
|
|
40
|
-
/** docker rm style: every item is attempted, each success prints its name, failures print and fail the command. */
|
|
41
41
|
export declare function forEach(names: string[], action: (name: string) => Promise<void>): Promise<void>;
|
|
42
|
-
/** `ls` output: the table, or with -q only the first column. */
|
|
43
42
|
export declare function printList(flags: Flags, headers: string[], rows: string[][]): void;
|
|
44
43
|
export declare const QUIET_FLAG: Record<string, Flag>;
|
|
45
44
|
export declare function commandUsage(path: string, command: Command): string;
|
package/dist/cli/command.js
CHANGED
|
@@ -3,11 +3,9 @@ import { formatTable } from "./table.js";
|
|
|
3
3
|
export function isGroup(entry) {
|
|
4
4
|
return "commands" in entry;
|
|
5
5
|
}
|
|
6
|
-
/** Bad invocation: printed with a pointer to --help. */
|
|
7
6
|
export class UsageError extends Error {
|
|
8
7
|
name = "UsageError";
|
|
9
8
|
}
|
|
10
|
-
/** Some items of a multi-item command failed; each error was already printed. */
|
|
11
9
|
export class PartialFailure extends Error {
|
|
12
10
|
name = "PartialFailure";
|
|
13
11
|
}
|
|
@@ -39,7 +37,6 @@ export function requireFlag(flags, name) {
|
|
|
39
37
|
throw new UsageError(`--${name} is required`);
|
|
40
38
|
return value;
|
|
41
39
|
}
|
|
42
|
-
/** docker rm style: every item is attempted, each success prints its name, failures print and fail the command. */
|
|
43
40
|
export async function forEach(names, action) {
|
|
44
41
|
let failed = false;
|
|
45
42
|
for (const name of names) {
|
|
@@ -55,7 +52,6 @@ export async function forEach(names, action) {
|
|
|
55
52
|
if (failed)
|
|
56
53
|
throw new PartialFailure();
|
|
57
54
|
}
|
|
58
|
-
/** `ls` output: the table, or with -q only the first column. */
|
|
59
55
|
export function printList(flags, headers, rows) {
|
|
60
56
|
if (flags.quiet) {
|
|
61
57
|
for (const row of rows)
|
package/dist/cli/dimension.js
CHANGED
|
@@ -8,13 +8,12 @@ function statusColumn(dimension) {
|
|
|
8
8
|
}
|
|
9
9
|
return dimension.status[0].toUpperCase() + dimension.status.slice(1);
|
|
10
10
|
}
|
|
11
|
-
function dimensionRow(dimension) {
|
|
12
|
-
const usage = dimension.memoryUsage === null ? "--" : formatBytes(dimension.memoryUsage);
|
|
11
|
+
function dimensionRow(dimension, usage) {
|
|
13
12
|
return [
|
|
14
13
|
dimension.name,
|
|
15
14
|
statusColumn(dimension),
|
|
16
|
-
|
|
17
|
-
`${usage} / ${formatBytes(dimension.memoryLimit)}`,
|
|
15
|
+
usage ? formatCpuPercent(usage.cpuUsage) : "--",
|
|
16
|
+
`${usage ? formatBytes(usage.memoryUsage) : "--"} / ${formatBytes(dimension.memoryLimit)}`,
|
|
18
17
|
String(dimension.cpuLimit),
|
|
19
18
|
dimension.directory,
|
|
20
19
|
];
|
|
@@ -26,9 +25,10 @@ export const dimensionCommands = {
|
|
|
26
25
|
summary: "List dimensions",
|
|
27
26
|
flags: QUIET_FLAG,
|
|
28
27
|
async run(_args, flags, { dimensions }) {
|
|
29
|
-
const
|
|
28
|
+
const [list, usage] = await Promise.all([dimensions.listDimensions(), dimensions.getDimensionUsage()]);
|
|
29
|
+
const rows = list
|
|
30
30
|
.sort((a, b) => a.name.localeCompare(b.name))
|
|
31
|
-
.map(dimensionRow);
|
|
31
|
+
.map((dimension) => dimensionRow(dimension, usage.find((used) => used.name === dimension.name)));
|
|
32
32
|
printList(flags, ["NAME", "STATUS", "CPU %", "MEM USAGE / LIMIT", "CPUS", "DIRECTORY"], rows);
|
|
33
33
|
},
|
|
34
34
|
},
|
package/dist/cli/gateway.js
CHANGED
|
@@ -7,10 +7,9 @@ var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExte
|
|
|
7
7
|
return path;
|
|
8
8
|
};
|
|
9
9
|
import { resolve } from "node:path";
|
|
10
|
-
import
|
|
11
|
-
import openai from "../upstreams/openai.js";
|
|
10
|
+
import { BUILTIN_UPSTREAMS as BUILTINS } from "../upstreams/index.js";
|
|
12
11
|
import { QUIET_FLAG, UsageError, forEach, printList, requireFlag } from "./command.js";
|
|
13
|
-
const BUILTIN_UPSTREAMS =
|
|
12
|
+
const BUILTIN_UPSTREAMS = Object.fromEntries(BUILTINS.map((upstream) => [upstream.name, upstream]));
|
|
14
13
|
const TRAFFIC_ACTIONS = ["BLOCK", "DELAY", "ASK", "INTERCEPT"];
|
|
15
14
|
export const gatewayCommands = {
|
|
16
15
|
summary: "Manage portal gateways: proxies that hold credentials for the dimensions behind them",
|
|
@@ -37,10 +36,8 @@ export const gatewayCommands = {
|
|
|
37
36
|
create: {
|
|
38
37
|
summary: "Create a gateway, finish creating one that was interrupted, or upgrade one to the current image",
|
|
39
38
|
args: ["NAME"],
|
|
40
|
-
async run([name], _flags, { gateways
|
|
39
|
+
async run([name], _flags, { gateways }) {
|
|
41
40
|
await gateways.createGateway({ name: name });
|
|
42
|
-
// An upgrade replaces the container, and its portals' links with it.
|
|
43
|
-
await portals.restorePortals({ gatewayName: name });
|
|
44
41
|
console.log(name);
|
|
45
42
|
},
|
|
46
43
|
},
|
package/dist/cli/main.js
CHANGED
|
@@ -1,24 +1,14 @@
|
|
|
1
1
|
#!/usr/bin/env bun
|
|
2
|
-
import { createPortalWatcher } from "../portal-gateway/portalService.js";
|
|
3
2
|
import { PartialFailure, UsageError, commandUsage, groupUsage, parseCommand, isGroup, } from "./command.js";
|
|
4
3
|
import { agentCommands, sessionCommands } from "./agent.js";
|
|
5
4
|
import { dimensionCommands } from "./dimension.js";
|
|
6
5
|
import { credentialCommands, gatewayCommands, keyCommands, ruleCommands, upstreamCommands } from "./gateway.js";
|
|
7
6
|
import { portalCommands } from "./portal.js";
|
|
8
|
-
import {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
watcher.start();
|
|
14
|
-
console.error("hyperbrane daemon running; Ctrl-C to stop");
|
|
15
|
-
await new Promise((done) => {
|
|
16
|
-
process.once("SIGINT", done);
|
|
17
|
-
process.once("SIGTERM", done);
|
|
18
|
-
});
|
|
19
|
-
await watcher.stop();
|
|
20
|
-
},
|
|
21
|
-
};
|
|
7
|
+
import { createAgentClient } from "../agent/agentClient.js";
|
|
8
|
+
import { createDimensionClient } from "../dimension/client.js";
|
|
9
|
+
import { createGatewayClient } from "../portal-gateway/gatewayClient.js";
|
|
10
|
+
import { createPortalClient } from "../portal-gateway/portalClient.js";
|
|
11
|
+
import { createSandboxClient } from "../sandbox/client.js";
|
|
22
12
|
const GROUPS = {
|
|
23
13
|
dimension: dimensionCommands,
|
|
24
14
|
gateway: gatewayCommands,
|
|
@@ -30,9 +20,8 @@ const GROUPS = {
|
|
|
30
20
|
agent: agentCommands,
|
|
31
21
|
session: sessionCommands,
|
|
32
22
|
};
|
|
33
|
-
const COMMANDS = { daemon };
|
|
34
23
|
function usage() {
|
|
35
|
-
const names =
|
|
24
|
+
const names = Object.keys(GROUPS);
|
|
36
25
|
const width = Math.max(...names.map((name) => name.length)) + 3;
|
|
37
26
|
return [
|
|
38
27
|
"Usage: hyperbrane COMMAND",
|
|
@@ -42,21 +31,14 @@ function usage() {
|
|
|
42
31
|
"Management Commands:",
|
|
43
32
|
...Object.entries(GROUPS).map(([name, group]) => ` ${name.padEnd(width)}${group.summary}`),
|
|
44
33
|
"",
|
|
45
|
-
"Commands:",
|
|
46
|
-
...Object.entries(COMMANDS).map(([name, command]) => ` ${name.padEnd(width)}${command.summary}`),
|
|
47
|
-
"",
|
|
48
34
|
"Run 'hyperbrane COMMAND --help' for more information on a command.",
|
|
49
35
|
].join("\n");
|
|
50
36
|
}
|
|
51
37
|
const isHelp = (arg) => arg === "--help" || arg === "-h";
|
|
52
|
-
/** Resolves the command to run, or returns help text to print. Groups nest: each word picks an entry. */
|
|
53
38
|
function resolveCommand(argv) {
|
|
54
39
|
const [first] = argv;
|
|
55
40
|
if (first === undefined || isHelp(first) || first === "help")
|
|
56
41
|
return { help: usage() };
|
|
57
|
-
const standalone = COMMANDS[first];
|
|
58
|
-
if (standalone)
|
|
59
|
-
return { path: first, command: standalone, rest: argv.slice(1) };
|
|
60
42
|
let group = GROUPS[first];
|
|
61
43
|
if (!group)
|
|
62
44
|
return new UsageError(`unknown command ${first}`);
|
|
@@ -99,14 +81,15 @@ async function main(argv) {
|
|
|
99
81
|
console.error(`Error: ${error.message}\nRun 'hyperbrane ${path} --help' for usage.`);
|
|
100
82
|
return 2;
|
|
101
83
|
}
|
|
102
|
-
const
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
84
|
+
const machine = createSandboxClient({ kind: "local" });
|
|
85
|
+
const clients = {
|
|
86
|
+
dimensions: createDimensionClient(machine),
|
|
87
|
+
gateways: createGatewayClient(machine),
|
|
88
|
+
portals: createPortalClient(machine),
|
|
89
|
+
agents: createAgentClient(machine),
|
|
90
|
+
};
|
|
108
91
|
try {
|
|
109
|
-
await command.run(parsed.args, parsed.flags,
|
|
92
|
+
await command.run(parsed.args, parsed.flags, clients);
|
|
110
93
|
return 0;
|
|
111
94
|
}
|
|
112
95
|
catch (error) {
|
|
@@ -1,22 +1,14 @@
|
|
|
1
|
-
import type { AgentStreamingMessage } from "../agent/api.ts";
|
|
1
|
+
import type { AgentStreamingMessage, AgentTranscriptMessage } from "../agent/api.ts";
|
|
2
2
|
export declare function preview(value: unknown): string;
|
|
3
|
-
/** The part of stdout the printer uses. */
|
|
4
3
|
export type TerminalStream = {
|
|
5
4
|
isTTY?: boolean;
|
|
6
5
|
write(chunk: string): unknown;
|
|
7
6
|
};
|
|
8
7
|
export interface TerminalPrinter {
|
|
9
|
-
/** A stream message: partial text and thinking as they arrive, tool calls and results, and how each turn ended. */
|
|
10
8
|
print(message: AgentStreamingMessage): void;
|
|
11
|
-
|
|
12
|
-
printTranscript(role: "user" | "assistant", content: unknown): void;
|
|
9
|
+
printTranscript(message: AgentTranscriptMessage): void;
|
|
13
10
|
close(): void;
|
|
14
11
|
}
|
|
15
|
-
/**
|
|
16
|
-
* Prints to `stream` (stdout); `paced` text is typed out steadily (see createPacedOutput) when it's
|
|
17
|
-
* a terminal. A complete assistant message's text is printed only if none of it streamed: claude
|
|
18
|
-
* reports failures it hits before reaching the API (a TLS error, say) as a synthetic message.
|
|
19
|
-
*/
|
|
20
12
|
export declare function createTerminalPrinter({ paced, stream }: {
|
|
21
13
|
paced: boolean;
|
|
22
14
|
stream?: TerminalStream;
|
|
@@ -1,18 +1,10 @@
|
|
|
1
|
-
/** Longest a tool input or result is shown, in characters. */
|
|
2
1
|
const PREVIEW_LENGTH = 400;
|
|
3
|
-
/** The pacer's clock: about a frame. */
|
|
4
2
|
const TICK_MS = 16;
|
|
5
|
-
/** Deltas arriving this close together are one burst. */
|
|
6
3
|
const BURST_GAP_MS = 20;
|
|
7
|
-
/** How far back the arrival rate is measured. */
|
|
8
4
|
const RATE_WINDOW_MS = 2_000;
|
|
9
|
-
/** The time a lone first burst is spread over, before there's a rate to go by. */
|
|
10
5
|
const FIRST_BURST_MS = 300;
|
|
11
|
-
/** Typing runs this much faster than text arrives, so the buffer drains rather than grows. */
|
|
12
6
|
const CATCH_UP = 1.1;
|
|
13
|
-
/** The slowest the pacer types, in characters per ms. */
|
|
14
7
|
const MIN_RATE = 0.06;
|
|
15
|
-
/** No character waits longer than this to be typed, whatever the pace. */
|
|
16
8
|
const MAX_LAG_MS = 1_000;
|
|
17
9
|
const DIM = "\x1b[2m";
|
|
18
10
|
const NORMAL = "\x1b[22m";
|
|
@@ -20,10 +12,6 @@ export function preview(value) {
|
|
|
20
12
|
const text = typeof value === "string" ? value : JSON.stringify(value);
|
|
21
13
|
return text.length > PREVIEW_LENGTH ? `${text.slice(0, PREVIEW_LENGTH)}…` : text;
|
|
22
14
|
}
|
|
23
|
-
/**
|
|
24
|
-
* Writes to `stream`, switching styles as text changes between answer and thinking: dimmed on a
|
|
25
|
-
* terminal, marked with [thinking] otherwise. Thinking always ends on a line of its own.
|
|
26
|
-
*/
|
|
27
15
|
function createStyledWriter(stream) {
|
|
28
16
|
const tty = stream.isTTY === true;
|
|
29
17
|
let style = "text";
|
|
@@ -47,25 +35,15 @@ function createStyledWriter(stream) {
|
|
|
47
35
|
},
|
|
48
36
|
};
|
|
49
37
|
}
|
|
50
|
-
/** Writes everything at once, as it comes. */
|
|
51
38
|
function createDirectOutput(stream) {
|
|
52
39
|
const writer = createStyledWriter(stream);
|
|
53
40
|
return { text: writer.text, line: writer.line, close: () => writer.line("") };
|
|
54
41
|
}
|
|
55
|
-
/**
|
|
56
|
-
* Types text out at a steady pace instead of in the bursts it arrives in (model APIs send several
|
|
57
|
-
* words at once, then pause for a while): at the rate text has been arriving, a little faster, so
|
|
58
|
-
* each burst lasts until about when the next one comes, and never more than MAX_LAG_MS behind. A
|
|
59
|
-
* pause shows only when the model pauses for longer than that. Lines wait for the text before
|
|
60
|
-
* them, then go out whole.
|
|
61
|
-
*/
|
|
62
42
|
function createPacedOutput(stream) {
|
|
63
43
|
const writer = createStyledWriter(stream);
|
|
64
44
|
const queue = [];
|
|
65
|
-
/** Recent bursts: when each came, and how many characters. */
|
|
66
45
|
const bursts = [];
|
|
67
46
|
let waitingChars = 0;
|
|
68
|
-
/** Characters the pace has allowed but not yet typed (fractions carry over between ticks). */
|
|
69
47
|
let credit = 0;
|
|
70
48
|
let lastTick = 0;
|
|
71
49
|
let timer;
|
|
@@ -79,22 +57,12 @@ function createPacedOutput(stream) {
|
|
|
79
57
|
while (bursts.length > 1 && now - bursts[0].at > RATE_WINDOW_MS)
|
|
80
58
|
bursts.shift();
|
|
81
59
|
}
|
|
82
|
-
/**
|
|
83
|
-
* Characters per ms the text has been arriving at: the bursts before the newest over the time they
|
|
84
|
-
* span up to it, since the newest is what covers the time ahead. A lone burst is spread over
|
|
85
|
-
* FIRST_BURST_MS.
|
|
86
|
-
*/
|
|
87
60
|
function arrivalRate() {
|
|
88
61
|
if (bursts.length < 2)
|
|
89
62
|
return (bursts[0]?.chars ?? 0) / FIRST_BURST_MS;
|
|
90
63
|
const earlier = bursts.slice(0, -1).reduce((sum, burst) => sum + burst.chars, 0);
|
|
91
64
|
return earlier / (bursts.at(-1).at - bursts[0].at);
|
|
92
65
|
}
|
|
93
|
-
/**
|
|
94
|
-
* The least that keeps every waiting chunk within MAX_LAG_MS, spread evenly over the ticks left
|
|
95
|
-
* rather than all at once when it's due: for each chunk, the characters up to its end over the
|
|
96
|
-
* ticks until its deadline. Only matters when text arrives faster than the rate predicted.
|
|
97
|
-
*/
|
|
98
66
|
function deadlinePace() {
|
|
99
67
|
const now = performance.now();
|
|
100
68
|
let before = 0;
|
|
@@ -110,7 +78,6 @@ function createPacedOutput(stream) {
|
|
|
110
78
|
}
|
|
111
79
|
function tick() {
|
|
112
80
|
const now = performance.now();
|
|
113
|
-
// A late tick (a busy event loop) catches up, but not by more than a few frames at once.
|
|
114
81
|
credit += Math.max(MIN_RATE, arrivalRate() * CATCH_UP) * Math.min(now - lastTick, TICK_MS * 4);
|
|
115
82
|
lastTick = now;
|
|
116
83
|
let budget = Math.max(Math.floor(credit), deadlinePace());
|
|
@@ -141,14 +108,12 @@ function createPacedOutput(stream) {
|
|
|
141
108
|
lastTick = performance.now();
|
|
142
109
|
timer = setInterval(tick, TICK_MS);
|
|
143
110
|
}
|
|
144
|
-
// Nothing is banked while idle: the next burst paces from zero instead of coming out at once.
|
|
145
111
|
function stop() {
|
|
146
112
|
clearInterval(timer);
|
|
147
113
|
timer = undefined;
|
|
148
114
|
credit = 0;
|
|
149
115
|
}
|
|
150
116
|
function text(chunk, style) {
|
|
151
|
-
// Code points, so a character outside the BMP is never split across ticks.
|
|
152
117
|
const chars = [...chunk];
|
|
153
118
|
queue.push({ kind: "text", style, chars, arrivedAt: performance.now() });
|
|
154
119
|
waitingChars += chars.length;
|
|
@@ -173,11 +138,19 @@ function createPacedOutput(stream) {
|
|
|
173
138
|
}
|
|
174
139
|
return { text, line, close };
|
|
175
140
|
}
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
141
|
+
function printSystem(output, message) {
|
|
142
|
+
output.line(`\n[${describeSystem(message)}]\n`);
|
|
143
|
+
}
|
|
144
|
+
function describeSystem(message) {
|
|
145
|
+
if (message.subtype === "compact_boundary") {
|
|
146
|
+
const meta = message.compact_metadata;
|
|
147
|
+
return meta ? `compacted, ${meta.trigger}, from ${meta.pre_tokens} tokens` : "compacted";
|
|
148
|
+
}
|
|
149
|
+
const { event } = message;
|
|
150
|
+
if (event.kind === "review")
|
|
151
|
+
return `review ${event.state}: ${event.review}`;
|
|
152
|
+
return `subagent ${event.agent} (${event.path}) ${event.activity}`;
|
|
153
|
+
}
|
|
181
154
|
function printContent(output, role, content, withText) {
|
|
182
155
|
if (typeof content === "string") {
|
|
183
156
|
if (role === "user")
|
|
@@ -201,11 +174,6 @@ function printContent(output, role, content, withText) {
|
|
|
201
174
|
output.line(`[result${block.is_error ? ", error" : ""}] ${preview(block.content ?? "")}\n`);
|
|
202
175
|
}
|
|
203
176
|
}
|
|
204
|
-
/**
|
|
205
|
-
* Prints to `stream` (stdout); `paced` text is typed out steadily (see createPacedOutput) when it's
|
|
206
|
-
* a terminal. A complete assistant message's text is printed only if none of it streamed: claude
|
|
207
|
-
* reports failures it hits before reaching the API (a TLS error, say) as a synthetic message.
|
|
208
|
-
*/
|
|
209
177
|
export function createTerminalPrinter({ paced, stream = process.stdout }) {
|
|
210
178
|
const output = paced && stream.isTTY ? createPacedOutput(stream) : createDirectOutput(stream);
|
|
211
179
|
let streamed = false;
|
|
@@ -239,13 +207,15 @@ export function createTerminalPrinter({ paced, stream = process.stdout }) {
|
|
|
239
207
|
output.line("\n[done]\n");
|
|
240
208
|
return;
|
|
241
209
|
case "system":
|
|
210
|
+
if (message.subtype === "compact_boundary" || message.subtype === "session_event")
|
|
211
|
+
return printSystem(output, message);
|
|
242
212
|
output.line(`[session ${message.session_id}, model ${message.model}]\n`);
|
|
243
213
|
return;
|
|
244
214
|
}
|
|
245
215
|
}
|
|
246
216
|
return {
|
|
247
217
|
print,
|
|
248
|
-
printTranscript: (
|
|
218
|
+
printTranscript: (message) => (message.type === "system" ? printSystem(output, message) : printContent(output, message.type, message.message.content, true)),
|
|
249
219
|
close: output.close,
|
|
250
220
|
};
|
|
251
221
|
}
|
package/dist/cli/table.d.ts
CHANGED
|
@@ -1,7 +1,4 @@
|
|
|
1
1
|
export declare function formatTable(headers: string[], rows: string[][]): string;
|
|
2
|
-
/** 268435456 -> "256MiB", 1597440 -> "1.523MiB" (docker's units.BytesSize). */
|
|
3
2
|
export declare function formatBytes(bytes: number): string;
|
|
4
|
-
/** 0.0512 cores -> "5.12%" (docker stats' CPU %: 100% is one full core). */
|
|
5
3
|
export declare function formatCpuPercent(cores: number): string;
|
|
6
|
-
/** Seconds -> "3 minutes", "About an hour", ... (docker's units.HumanDuration). */
|
|
7
4
|
export declare function formatDuration(seconds: number): string;
|
package/dist/cli/table.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
// Output in the style of the docker CLI (its tabwriter: min width 10, padding 3).
|
|
2
1
|
const MIN_WIDTH = 10;
|
|
3
2
|
const PADDING = 3;
|
|
4
3
|
export function formatTable(headers, rows) {
|
|
@@ -11,7 +10,6 @@ export function formatTable(headers, rows) {
|
|
|
11
10
|
.join("\n");
|
|
12
11
|
}
|
|
13
12
|
const BYTE_UNITS = ["B", "KiB", "MiB", "GiB", "TiB", "PiB"];
|
|
14
|
-
/** 268435456 -> "256MiB", 1597440 -> "1.523MiB" (docker's units.BytesSize). */
|
|
15
13
|
export function formatBytes(bytes) {
|
|
16
14
|
let value = bytes;
|
|
17
15
|
let unit = 0;
|
|
@@ -21,11 +19,9 @@ export function formatBytes(bytes) {
|
|
|
21
19
|
}
|
|
22
20
|
return `${Number(value.toPrecision(4))}${BYTE_UNITS[unit]}`;
|
|
23
21
|
}
|
|
24
|
-
/** 0.0512 cores -> "5.12%" (docker stats' CPU %: 100% is one full core). */
|
|
25
22
|
export function formatCpuPercent(cores) {
|
|
26
23
|
return `${(cores * 100).toFixed(2)}%`;
|
|
27
24
|
}
|
|
28
|
-
/** Seconds -> "3 minutes", "About an hour", ... (docker's units.HumanDuration). */
|
|
29
25
|
export function formatDuration(seconds) {
|
|
30
26
|
const minutes = seconds / 60;
|
|
31
27
|
const hours = minutes / 60;
|