@agent-compose/sdk 0.8.4 → 0.8.6
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 +213 -189
- package/dist/agent/agent-context.d.ts +9 -1
- package/dist/agent/agent-loop.d.ts +14 -6
- package/dist/agent/perf-sampler.d.ts +27 -2
- package/dist/agent/run-agent.d.ts +1 -1
- package/dist/client.d.ts +250 -59
- package/dist/directives.d.ts +14 -0
- package/dist/display.d.ts +7 -0
- package/dist/errors.d.ts +1 -1
- package/dist/generated/agentc-commands.d.ts +34 -0
- package/dist/index.d.ts +13 -11
- package/dist/index.js +1692 -194
- package/dist/request-context/request-context.d.ts +1 -1
- package/dist/runtimes/_cli-agent.d.ts +278 -58
- package/dist/runtimes/claude-code.d.ts +90 -1
- package/dist/runtimes/claude.d.ts +1 -1
- package/dist/runtimes/codex.d.ts +94 -6
- package/dist/runtimes/codex.mid-turn-hook.test.d.ts +10 -0
- package/dist/runtimes/openai-desktop.d.ts +50 -0
- package/dist/runtimes/openai-desktop.js +1689 -211
- package/dist/runtimes/openai-desktop.test.d.ts +20 -0
- package/dist/runtimes/opencode.d.ts +48 -11
- package/dist/runtimes/opencode.test.d.ts +14 -0
- package/dist/runtimes/tool-pulse.test.d.ts +17 -0
- package/dist/sandbox/baked-clis.d.ts +75 -0
- package/dist/sandbox/devbox.d.ts +5 -5
- package/dist/sandbox/exec-stream.d.ts +1 -2
- package/dist/sandbox/network-policy.d.ts +23 -5
- package/dist/sandbox/registry.d.ts +12 -0
- package/dist/sandbox/sizes.d.ts +11 -5
- package/dist/sandbox.d.ts +5 -3
- package/dist/step-invocation/protocol.d.ts +3 -4
- package/dist/step-invocation/server.d.ts +2 -2
- package/dist/step-invocation/types.d.ts +2 -2
- package/dist/types/api-conversations.d.ts +513 -27
- package/dist/types/api-factory.d.ts +183 -3
- package/dist/types/api-projects.d.ts +480 -0
- package/dist/types/api-runs.d.ts +8 -0
- package/dist/types/api-scopes.d.ts +32 -3
- package/dist/types/conversation-stream.d.ts +27 -1
- package/dist/types/execution-context.d.ts +1 -1
- package/dist/types/protocol.d.ts +182 -2
- package/dist/types/runtime.d.ts +80 -2
- package/dist/types/workflow-metadata.d.ts +2 -4
- package/dist/types/workflow-plan.d.ts +1 -3
- package/dist/utils/bundler.d.ts +23 -0
- package/dist/workflow-steps/observability.d.ts +2 -3
- package/dist/workflow-steps/runner.d.ts +5 -8
- package/dist/workflow-steps/types.d.ts +8 -10
- package/dist/workflow-steps/workflow.d.ts +2 -1
- package/dist/workflows/engine.d.ts +3 -5
- package/dist/workflows/invoke-child.d.ts +2 -2
- package/package.json +2 -2
- package/src/agent/agent-context.ts +193 -116
- package/src/agent/agent-loop.ts +16 -9
- package/src/agent/desktop-open.ts +13 -1
- package/src/agent/perf-sampler.ts +54 -3
- package/src/agent/run-agent.ts +1 -1
- package/src/client.ts +418 -80
- package/src/directives.ts +21 -1
- package/src/display.ts +12 -0
- package/src/errors.ts +1 -0
- package/src/generated/agentc-commands.ts +571 -0
- package/src/index.ts +65 -18
- package/src/pause/pause-core.ts +2 -1
- package/src/request-context/request-context.ts +1 -1
- package/src/runtimes/_cli-agent.ts +607 -132
- package/src/runtimes/claude-code.ts +427 -20
- package/src/runtimes/claude.ts +1 -1
- package/src/runtimes/codex.ts +188 -19
- package/src/runtimes/openai-desktop.ts +82 -19
- package/src/runtimes/opencode.ts +195 -26
- package/src/sandbox/baked-clis.ts +86 -0
- package/src/sandbox/devbox.ts +5 -5
- package/src/sandbox/exec-stream.ts +1 -2
- package/src/sandbox/network-policy.ts +51 -7
- package/src/sandbox/providers/e2b.ts +63 -19
- package/src/sandbox/providers/vercel.ts +6 -6
- package/src/sandbox/registry.ts +19 -1
- package/src/sandbox/sizes.ts +11 -5
- package/src/sandbox.ts +9 -2
- package/src/step-invocation/invoker.ts +2 -6
- package/src/step-invocation/protocol.ts +3 -4
- package/src/step-invocation/server.ts +2 -2
- package/src/types/api-conversations.ts +424 -29
- package/src/types/api-factory.ts +189 -3
- package/src/types/api-projects.ts +443 -0
- package/src/types/api-runs.ts +5 -0
- package/src/types/api-scopes.ts +32 -3
- package/src/types/conversation-stream.ts +29 -1
- package/src/types/execution-context.ts +1 -1
- package/src/types/protocol.ts +180 -2
- package/src/types/runtime.ts +71 -2
- package/src/types/sandbox-environment.ts +1 -2
- package/src/types/workflow-metadata.ts +2 -4
- package/src/types/workflow-plan.ts +1 -3
- package/src/utils/bundler.ts +88 -19
- package/src/workflow-steps/observability.ts +2 -3
- package/src/workflow-steps/runner.ts +5 -8
- package/src/workflow-steps/types.ts +8 -10
- package/src/workflow-steps/workflow.ts +2 -1
- package/src/workflows/engine.ts +3 -5
- package/src/workflows/invoke-child.ts +2 -2
- package/dist/pause/__tests__/errors.test.d.ts +0 -1
- package/dist/pause/__tests__/wrappers.test.d.ts +0 -1
- package/dist/step-invocation/__tests__/protocol.test.d.ts +0 -1
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* openai-desktop runner spec — coordinate spaces (the incident pin).
|
|
3
|
+
*
|
|
4
|
+
* The model sees every screenshot downscaled to DISPLAY (1024×720) and emits
|
|
5
|
+
* coordinates in THAT space; the runner must map them back through EACH
|
|
6
|
+
* capture's REAL geometry — read from the screenshot buffer itself — before
|
|
7
|
+
* touching the provider. Pinned here:
|
|
8
|
+
*
|
|
9
|
+
* - captureScaledScreenshot derives scaleX/scaleY from the frame's own
|
|
10
|
+
* pixel dimensions, and two frames of differing geometry yield differing
|
|
11
|
+
* scales (the fixed-constants regression);
|
|
12
|
+
* - the legacy 1280×800 constants apply ONLY as a fallback when a frame's
|
|
13
|
+
* metadata carries no dimensions;
|
|
14
|
+
* - click/double/right/middle/move and BOTH drag endpoints scale; typed
|
|
15
|
+
* text, key chords, and scroll tick counts pass through untouched;
|
|
16
|
+
* - the sendMessage loop applies the CURRENT capture's scale to the calls
|
|
17
|
+
* the model made against that capture, and refreshes the scale with
|
|
18
|
+
* every new frame it sends back.
|
|
19
|
+
*/
|
|
20
|
+
export {};
|
|
@@ -1,20 +1,57 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* OpenCode CLI runtime — drives sst's `opencode` agentic CLI inside the sandbox.
|
|
3
|
-
* OpenCode speaks ACP natively (`opencode acp`, protocolVersion 1 — verified
|
|
4
|
-
* live on E2B), so the runner drives it over ACP; the JSONL members below are
|
|
5
|
-
* only the version-mismatch fallback (vestigial for a v1 agent).
|
|
6
3
|
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
4
|
+
* Two transports share this spec:
|
|
5
|
+
* - the SDK runner (createCliAgentRuntime) speaks ACP: `opencode acp` is a
|
|
6
|
+
* protocolVersion-1 ACP server (verified live on E2B, 2026-06-30) on a
|
|
7
|
+
* provider with a duplex-stdin command primitive, and the JSONL members
|
|
8
|
+
* below are its version-mismatch fallback;
|
|
9
|
+
* - the platform's cloud lane (server turn-workflow/tailer.ts) never speaks
|
|
10
|
+
* ACP: it launches `buildCommand` detached, tails the CLI's stdout file
|
|
11
|
+
* line by line, JSON-parses every line and maps it through `mapEvent`.
|
|
12
|
+
* The dispatch constitution's `fast` lane (google/gemini-3.7-flash on
|
|
13
|
+
* opencode) runs there, so the JSONL members are the LIVE path for it.
|
|
11
14
|
*
|
|
12
|
-
*
|
|
13
|
-
* `
|
|
14
|
-
*
|
|
15
|
-
*
|
|
15
|
+
* The 2026-10-02 fast-lane failure (prod: 5 of 5 opencode turns settled
|
|
16
|
+
* `harness_no_output` over ten days) — `opencode run` without `--format json`
|
|
17
|
+
* prints the reply as human-formatted prose and its tool narration on stderr,
|
|
18
|
+
* so the tailer parsed zero JSON lines and the turn settled empty while the
|
|
19
|
+
* work itself had completed (reproduced locally, 2026-10-03). `--format json`
|
|
20
|
+
* makes `run` print one JSON event per line — `{type, timestamp, sessionID,
|
|
21
|
+
* part}` for step_start / step_finish / text / reasoning / tool_use, and
|
|
22
|
+
* `{type: "error", timestamp, sessionID, error}` for a session error
|
|
23
|
+
* (packages/opencode/src/cli/cmd/run.ts, v1.18.34: text and reasoning parts
|
|
24
|
+
* fire once, when the part's `time.end` lands; a tool part fires once, at
|
|
25
|
+
* `state.status` completed or error). Captured real streams:
|
|
26
|
+
* `__fixtures__/jsonl/opencode`.
|
|
27
|
+
*
|
|
28
|
+
* Auth + model: the platform routes opencode through its gateway as the
|
|
29
|
+
* custom provider `gw` — server session-runtime-config.ts writes
|
|
30
|
+
* ~/.config/opencode/opencode.json with the gateway base URL and
|
|
31
|
+
* `{env:OPENROUTER_API_KEY}`, and the model flag is `gw/openrouter/<provider>/
|
|
32
|
+
* <model>`. Stand-alone SDK use sets OPENROUTER_API_KEY (a factory/workflow
|
|
33
|
+
* secret) and an `openrouter/<provider>/<model>` id.
|
|
34
|
+
*
|
|
35
|
+
* Resume (owner, 2026-10-03: "resume like other workers"): every event
|
|
36
|
+
* carries the CLI's `sessionID`; `extractSessionId` reads it, the tailer
|
|
37
|
+
* records it, and a follow-up turn on the same machine launches `run
|
|
38
|
+
* --session <id>` with only the new messages (renderCloudPrompt). The store
|
|
39
|
+
* is SQLite under the guest's ~/.local/share/opencode, so a resume target
|
|
40
|
+
* can be gone (a stale binding, a wiped store): `run --session` then exits 1
|
|
41
|
+
* with `Error: Session not found` on stderr and nothing on stdout — the
|
|
42
|
+
* classifier's `resume_target_missing` (turn-failure-class.ts), which the
|
|
43
|
+
* cloud turn workflow heals by dropping the binding and relaunching the turn
|
|
44
|
+
* fresh. Verified live on 1.18.34 (fixtures `resume-turn-1/2.jsonl`,
|
|
45
|
+
* `session-not-found.stderr`).
|
|
16
46
|
*/
|
|
17
47
|
import { type CliAgentSpec } from "./_cli-agent.js";
|
|
48
|
+
/** The text of an opencode session error — `{name, data: {message, statusCode?}}`
|
|
49
|
+
* (ProviderAuthError / APIError / UnknownError / … in the opencode SDK
|
|
50
|
+
* types): name and HTTP status first so the settle's classifier reads the
|
|
51
|
+
* cause, then the provider's own words. Captured shapes: a 401 from the
|
|
52
|
+
* gateway is `APIError` with statusCode 401; an unknown model id is
|
|
53
|
+
* `UnknownError` with the gateway's "Unexpected server error". */
|
|
54
|
+
export declare function opencodeErrorText(error: unknown): string;
|
|
18
55
|
export declare const opencodeSpec: CliAgentSpec;
|
|
19
56
|
export interface OpencodeRuntimeConfig {
|
|
20
57
|
/** OpenRouter-prefixed model id (default `openrouter/z-ai/glm-5.2`). */
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* opencodeSpec — the cloud lane's launch and its parse of `opencode run
|
|
3
|
+
* --format json`, against REAL captured streams (opencode 1.18.34 through the
|
|
4
|
+
* dev gateway on google/gemini-3.7-flash, 2026-10-03; paths rewritten to
|
|
5
|
+
* /workspace, a 401's key fragment redacted).
|
|
6
|
+
*
|
|
7
|
+
* The 2026-10-02 fast-lane failure: prod's 5 of 5 opencode turns settled
|
|
8
|
+
* `harness_no_output` because the launch printed prose, which the tailer's
|
|
9
|
+
* JSON parse skipped line by line. These pins hold the two halves of the
|
|
10
|
+
* fix — the launch asks for JSON, and the mapper reads every event shape the
|
|
11
|
+
* CLI emits — so the lane can never again run to a clean exit with nothing
|
|
12
|
+
* the transcript can show.
|
|
13
|
+
*/
|
|
14
|
+
export {};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tool-run pulse (child-telemetry contract, 2026-08-29) — the guest
|
|
3
|
+
* heartbeat's sample of the runner's own session, carried as the durable
|
|
4
|
+
* probe's trailing field. Pins:
|
|
5
|
+
*
|
|
6
|
+
* 1. the pulse token round-trips through the probe line (7th field),
|
|
7
|
+
* and its absence (`-`, old guests) parses evidence-absent;
|
|
8
|
+
* 2. parseToolPulseToken rejects everything malformed — never a guess;
|
|
9
|
+
* 3. the probe command with a pulsePath reads it with the char
|
|
10
|
+
* whitelist; without one it emits the `-` placeholder (the shape
|
|
11
|
+
* stays 7 fields either way);
|
|
12
|
+
* 4. the heartbeat fragment writes the pulse file and never breaks the
|
|
13
|
+
* beat on a guest without procps (`ps` failing degrades quiet);
|
|
14
|
+
* 5. a 5-field (pre-perf) and 6-field (pre-pulse) probe line still
|
|
15
|
+
* parse — old guests are evidence-absent, never errors.
|
|
16
|
+
*/
|
|
17
|
+
export {};
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Harness CLIs the E2B session image bakes, pinned: the SINGLE SOURCE for
|
|
3
|
+
* each version. `infra/e2b-template/parts.ts` installs exactly this version
|
|
4
|
+
* into every `agent-env-<size>`, and the runtime spec's on-demand install
|
|
5
|
+
* fetches the same one on a machine whose image predates the bake. It lives
|
|
6
|
+
* under `sdk/src/sandbox/` so a bump rebuilds the images: sandbox-images.yml
|
|
7
|
+
* watches this directory.
|
|
8
|
+
*
|
|
9
|
+
* The ruling (owner, 2026-10-02): workers run the NEWEST CLIs, baked and
|
|
10
|
+
* pinned so every machine runs the same tested version, with no per-machine
|
|
11
|
+
* self-update — prod workers were running claude 2.1.287 on an image that
|
|
12
|
+
* baked 2.1.283, because the CLI updated itself inside the machines. Each
|
|
13
|
+
* release bumps the pins here; the two constants below turn the CLIs' own
|
|
14
|
+
* updaters off wherever the platform runs them.
|
|
15
|
+
*/
|
|
16
|
+
/** Anthropic's claude CLI (the native installer's versioned binary, copied
|
|
17
|
+
* to /usr/local/bin/claude). The floor is the worker model: Opus 5.5 needs
|
|
18
|
+
* 2.1.280 or newer. 2.1.287 is current on npm (2026-10-02) and is the build
|
|
19
|
+
* the rtk `--settings` hook, the `[1m]` window behind a gateway base URL and
|
|
20
|
+
* the prompt-cache TTL env were verified against. */
|
|
21
|
+
export declare const CLAUDE_CODE_VERSION = "2.1.287";
|
|
22
|
+
/** OpenAI's codex CLI (`@openai/codex`). 0.160.0 is current on npm
|
|
23
|
+
* (2026-10-02); codex.ts's event mapping (command_execution / agent_message
|
|
24
|
+
* / turn.completed usage) and the hook trust-hash recipe were re-verified
|
|
25
|
+
* live against it, and its plan-tool and hook sources are byte-identical to
|
|
26
|
+
* rust-v0.159.2, where the `todo_list` shape was captured. Unbaked, every
|
|
27
|
+
* session's first codex turn waited ~13 s in prod for the npm install
|
|
28
|
+
* before its launch (2026-09-30), and each machine got whichever version
|
|
29
|
+
* npm served that minute. Bump deliberately. */
|
|
30
|
+
export declare const CODEX_CLI_VERSION = "0.160.0";
|
|
31
|
+
/** sst's opencode CLI (`opencode-ai`) — the harness behind the dispatch
|
|
32
|
+
* constitution's `fast` lane. 1.18.34 is current on npm (2026-09-30) and
|
|
33
|
+
* is the build the cloud lane (runtimes/opencode.ts) was verified against,
|
|
34
|
+
* live through the gateway on google/gemini-3.7-flash (2026-10-03): the
|
|
35
|
+
* `run --format json` event shapes (runtimes/__fixtures__/jsonl/opencode),
|
|
36
|
+
* the prompt on stdin, and the `--auto` permission flag — which 1.15.13
|
|
37
|
+
* still spelled `--dangerously-skip-permissions`, the kind of flag drift
|
|
38
|
+
* an unpinned install ships straight into prod. Until this pin the spec
|
|
39
|
+
* installed whatever npm served that minute, on each machine's first
|
|
40
|
+
* opencode turn. Bump deliberately. */
|
|
41
|
+
export declare const OPENCODE_CLI_VERSION = "1.18.34";
|
|
42
|
+
/** rtk (rtk-ai/rtk), the shell-output compressor behind the Bash PreToolUse
|
|
43
|
+
* hook every claude and codex session carries (runtimes/claude-code.ts
|
|
44
|
+
* RTK_BASH_HOOK_COMMAND, runtimes/codex.ts RTK_CODEX_HOOK_COMMAND). The
|
|
45
|
+
* floor is `rtk hook codex`, added in 0.50.0 (2026-09-24); 0.51.0 is the
|
|
46
|
+
* current release (2026-10-02) and the build both hooks' exact smoke
|
|
47
|
+
* payloads were run against (2026-10-04). Until this pin the image ran
|
|
48
|
+
* rtk's installer unpinned, so it baked whatever release the installer
|
|
49
|
+
* served on the day its layer was last built — and E2B served that layer
|
|
50
|
+
* from cache for six weeks: every 2026-10 image carried rtk 0.45.0, whose
|
|
51
|
+
* `rtk hook` had no `codex`, so the codex hook exited 2 with clap's usage
|
|
52
|
+
* on stderr and Codex blocked every shell command of every codex session
|
|
53
|
+
* from the hook's 2026-10-03 deploy on. The image recipe downloads exactly
|
|
54
|
+
* this release (infra parts.ts RTK_INSTALL, sha256-verified); its verify
|
|
55
|
+
* layer and the smoke gate assert the baked version. Bump deliberately,
|
|
56
|
+
* re-running both hooks' payloads against the new build. */
|
|
57
|
+
export declare const RTK_VERSION = "0.51.0";
|
|
58
|
+
/** Env that turns the claude CLI's updater off — the admin-grade switch
|
|
59
|
+
* (verified in the 2.1.287 binary): it disables the background self-update
|
|
60
|
+
* AND `claude update`, so a machine runs the baked version until the image
|
|
61
|
+
* is rebuilt; `DISABLE_AUTOUPDATER` would stop only the background updater.
|
|
62
|
+
* The `autoUpdates: false` config does nothing for the native installer.
|
|
63
|
+
* Sessions get it from the session env file, runs from the runner env. */
|
|
64
|
+
export declare const CLAUDE_CODE_NO_SELF_UPDATE_ENV: Readonly<Record<string, string>>;
|
|
65
|
+
/** The config.toml line that turns codex's startup update check off
|
|
66
|
+
* (`check_for_update_on_startup`, codex-rs config: "set to false only if
|
|
67
|
+
* your Codex updates are centrally managed" — they are: the image). A
|
|
68
|
+
* top-level key, so it must come before any `[table]` in the file.
|
|
69
|
+
* Accepted by 0.160.0 under `--strict-config` (live, 2026-10-02). */
|
|
70
|
+
export declare const CODEX_NO_SELF_UPDATE_CONFIG_LINE = "check_for_update_on_startup = false\n";
|
|
71
|
+
/** The opencode.json keys that turn opencode's updater off (`autoupdate`
|
|
72
|
+
* takes true | false | "notify" in 1.18.34's config schema). Spread into
|
|
73
|
+
* the session config the server writes (session-runtime-config.ts), so a
|
|
74
|
+
* machine runs the baked version until the image is rebuilt. */
|
|
75
|
+
export declare const OPENCODE_NO_SELF_UPDATE_CONFIG: Readonly<Record<string, boolean>>;
|
package/dist/sandbox/devbox.d.ts
CHANGED
|
@@ -5,13 +5,13 @@
|
|
|
5
5
|
* This module is the SINGLE SOURCE for the machine's template identity: the
|
|
6
6
|
* recipe lives in `infra/e2b-template/devbox.ts`, `infra/e2b-template/build.ts`
|
|
7
7
|
* bakes it under the alias below, and the server imports the alias from here to
|
|
8
|
-
* provision a machine (exactly how `
|
|
9
|
-
* a stable ALIAS, never a snapshot id, so the same string resolves
|
|
10
|
-
* E2B account a deployment uses).
|
|
8
|
+
* provision a machine (exactly how `e2bAgentEnvTemplate` reaches the E2B
|
|
9
|
+
* provider — a stable ALIAS, never a snapshot id, so the same string resolves
|
|
10
|
+
* in whichever E2B account a deployment uses).
|
|
11
11
|
*
|
|
12
12
|
* Interactive only. Workflow RUNS never execute on a devbox (ADR-0038 §2.6):
|
|
13
|
-
* runs boot the clean per-size `agent-
|
|
14
|
-
*
|
|
13
|
+
* runs boot the clean per-size `agent-env-<size>` template (the same image
|
|
14
|
+
* sessions boot) so reproducibility never inherits hand-configured drift.
|
|
15
15
|
*/
|
|
16
16
|
/** Stable E2B template ALIAS for the per-member desktop machine. Baked by
|
|
17
17
|
* `infra/e2b-template/build.ts` from `infra/e2b-template/devbox.ts`; CI rebakes
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* SSE exec-stream parser —
|
|
3
|
-
* runner.ts to consume a streamed command execution.
|
|
2
|
+
* SSE exec-stream parser — consumes a streamed command execution.
|
|
4
3
|
*/
|
|
5
4
|
import type { SandboxCommandResult } from "../types/sandbox.js";
|
|
6
5
|
export interface ParseSseExecStreamOptions {
|
|
@@ -37,6 +37,15 @@ export type SandboxNetworkPolicy = "allow-all" | "deny-all" | {
|
|
|
37
37
|
allow?: string[] | Record<string, SandboxNetworkAllowRule[]>;
|
|
38
38
|
subnets?: SandboxNetworkSubnetPolicy;
|
|
39
39
|
};
|
|
40
|
+
/**
|
|
41
|
+
* OPEN egress save the given CIDRs: every domain and every IPv4 destination,
|
|
42
|
+
* with `deny` applied ahead of both — "allow-all" spelled out so it can carry
|
|
43
|
+
* a deny (the server stamps its metadata-endpoint deny on every open policy).
|
|
44
|
+
* Vercel enforces this shape natively (its subnet denies take precedence
|
|
45
|
+
* over allowed domains and CIDRs). E2B lets an allow entry win over a deny,
|
|
46
|
+
* so `toE2bNetwork` recognizes the shape and emits a bare deny list instead.
|
|
47
|
+
*/
|
|
48
|
+
export declare function openEgressExcept(deny: readonly string[]): SandboxNetworkPolicy;
|
|
40
49
|
/** Matches a path containing a dot-dot segment — literal (`/../`) or
|
|
41
50
|
* percent-encoded (`%2e%2e`, `%2f` boundaries). `DOT_SEGMENT_PATH_RE2` is
|
|
42
51
|
* the RE2 form handed to Vercel's matcher: wrapped in `.*` so it behaves
|
|
@@ -74,17 +83,26 @@ export declare function toVercelNetworkPolicy(policy: SandboxNetworkPolicy): Ver
|
|
|
74
83
|
* (`SandboxNetworkOpts`) — the E2B analogue of `toVercelNetworkPolicy`.
|
|
75
84
|
*
|
|
76
85
|
* - `allowOut`: the set of allowed egress targets — every host named in
|
|
77
|
-
* `allow` PLUS every CIDR in `subnets.allow`.
|
|
78
|
-
* data-plane CIDRs ride here as FIRST-CLASS allow entries (E2B has no
|
|
79
|
-
* root-exemption to lean on, unlike the old in-VM iptables model).
|
|
86
|
+
* `allow` PLUS every CIDR in `subnets.allow`.
|
|
80
87
|
* - `denyOut`: the all-traffic sentinel (`0.0.0.0/0`) so the policy is
|
|
81
|
-
* DEFAULT-DENY — only `allowOut` targets pass
|
|
82
|
-
* deny, so a host in both lists
|
|
88
|
+
* DEFAULT-DENY — only `allowOut` targets pass — plus every CIDR in
|
|
89
|
+
* `subnets.deny`. E2B applies allow before deny, so a host in both lists
|
|
90
|
+
* is allowed: a `subnets.deny` CIDR bites on E2B only where no allow
|
|
91
|
+
* entry covers the destination (E2B's documented precedence; Vercel
|
|
92
|
+
* applies its `subnets.deny` ahead of every allow). Whether E2B's `"*"`
|
|
93
|
+
* domain wildcard also covers a request addressed to a bare IP is E2B's
|
|
94
|
+
* call, so a deny under a `"*"`-plus-rules policy is not relied on here.
|
|
83
95
|
* - `rules`: per-host header injection. For each host carrying transform(s),
|
|
84
96
|
* emit one rule per transform with `{ transform: { headers } }`. A host
|
|
85
97
|
* with a rule MUST also be in `allowOut` (registering a rule does not
|
|
86
98
|
* grant egress on its own — E2B's API requires the host in `allowOut`).
|
|
87
99
|
*
|
|
100
|
+
* OPEN egress save some CIDRs (`openEgressExcept`) is the one shape E2B's
|
|
101
|
+
* allow precedence cannot express as allow + deny lists — its "every IPv4
|
|
102
|
+
* destination" allow would win over the deny. It becomes a bare `denyOut`
|
|
103
|
+
* of those CIDRs: no allow list and no domain filtering (so raw TCP keeps
|
|
104
|
+
* flowing, as under "allow-all"), only the denied destinations refused.
|
|
105
|
+
*
|
|
88
106
|
* BEHAVIOURAL DIVERGENCE FROM iron-proxy / Vercel — path/method gating is NOT
|
|
89
107
|
* available on E2B native rules. An `SandboxNetworkRule` carries only a
|
|
90
108
|
* `transform` (header injection); there is no method/path matcher. So our
|
|
@@ -9,6 +9,18 @@ import type { SandboxProvider } from "../types/sandbox.js";
|
|
|
9
9
|
import type { SandboxCreateOpts, SandboxProviderDef, OwnedSandbox } from "./provider-def.js";
|
|
10
10
|
export type SandboxProviderName = "vercel" | "e2b" | "e2b-desktop";
|
|
11
11
|
export declare const SANDBOX_PROVIDERS: Record<string, SandboxProviderDef>;
|
|
12
|
+
/** Did a CREATE fail because its create SOURCE (template alias / snapshot id)
|
|
13
|
+
* does not resolve on the provider — vs any other create fault? The server's
|
|
14
|
+
* recovery-boot fall-through keys on this: a ring snapshot licensed on an
|
|
15
|
+
* INDETERMINATE existence probe that turns out to be gone must fall through
|
|
16
|
+
* the ring toward the base image, while every other create fault (quota,
|
|
17
|
+
* auth, 5xx, network) must propagate — falling through on those would trade
|
|
18
|
+
* a still-recoverable machine state for a base boot. E2B maps the create-
|
|
19
|
+
* time 404 ("template not found") to its typed `NotFoundError`; the message
|
|
20
|
+
* match is the fallback for untyped transports (Vercel). Lives in the SDK
|
|
21
|
+
* because the server holds its OWN `e2b` module instance — an `instanceof`
|
|
22
|
+
* against the class from the wrong copy is always false. */
|
|
23
|
+
export declare function isSandboxSourceNotFoundError(error: unknown): boolean;
|
|
12
24
|
/** Provision a sandbox for the named provider. */
|
|
13
25
|
export declare function createSandbox(provider: SandboxProviderName, opts: SandboxCreateOpts): Promise<SandboxProvider>;
|
|
14
26
|
/** Reconnect to an existing sandbox by provider + provider-native sandbox ID. */
|
package/dist/sandbox/sizes.d.ts
CHANGED
|
@@ -138,12 +138,18 @@ export declare function sandboxSizeLabel(size: SandboxSize): string;
|
|
|
138
138
|
/** Stable E2B template ALIAS for the platform base at a given size
|
|
139
139
|
* (`agent-compose-base-<size>`). Aliases — not snapshot ids — so the refs are
|
|
140
140
|
* multi-account-clean: the same string resolves in any E2B account that built
|
|
141
|
-
* the templates. Built by `infra/e2b-template/build.ts
|
|
142
|
-
*
|
|
141
|
+
* the templates. Built by `infra/e2b-template/build.ts`. An EXPLICIT
|
|
142
|
+
* `bootFrom`/template target only — nothing boots it by default: template-less
|
|
143
|
+
* E2B creates resolve `e2bAgentEnvTemplate` (the session-identical image)
|
|
144
|
+
* instead, so the run and session lanes can never diverge on baked tooling. */
|
|
143
145
|
export declare function e2bBaseTemplate(size: SandboxSize): string;
|
|
144
|
-
/** Stable E2B template ALIAS for the agent runtime (base + claude binary
|
|
145
|
-
* given size (`agent-env-<size>`).
|
|
146
|
-
*
|
|
146
|
+
/** Stable E2B template ALIAS for the agent runtime (base + claude binary +
|
|
147
|
+
* dev toolbelt + session desktop) at a given size (`agent-env-<size>`).
|
|
148
|
+
* THE default E2B boot image, both lanes: every cloud SESSION boots it
|
|
149
|
+
* (server/src/sandbox/persistent.ts), and every template-less E2B workflow
|
|
150
|
+
* RUN boots it too (the e2b provider's size-matched default). The agent
|
|
151
|
+
* default templates boot from this via
|
|
152
|
+
* `bootFrom: { snapshotId: e2bAgentEnvTemplate(size) }`. Multi-account-clean
|
|
147
153
|
* for the same reason as `e2bBaseTemplate`. */
|
|
148
154
|
export declare function e2bAgentEnvTemplate(size: SandboxSize): string;
|
|
149
155
|
/** Is `id` one of the platform-managed E2B template aliases — a
|
package/dist/sandbox.d.ts
CHANGED
|
@@ -5,17 +5,19 @@
|
|
|
5
5
|
* - `sandbox/network-policy.ts` — egress policy shape + per-provider translators
|
|
6
6
|
* - `sandbox/sizes.ts` — machine sizes + E2B template aliases
|
|
7
7
|
* - `sandbox/devbox.ts` — the ADR-0038 per-member desktop machine alias
|
|
8
|
+
* - `sandbox/baked-clis.ts` — harness CLI versions the session image bakes
|
|
8
9
|
* - `sandbox/provider-def.ts` — provider contract, create opts, fleet tag
|
|
9
|
-
* - `sandbox/exec-stream.ts` — SSE exec-stream parser
|
|
10
|
+
* - `sandbox/exec-stream.ts` — SSE exec-stream parser
|
|
10
11
|
* - `sandbox/providers/*` — vercel / e2b / e2b-desktop / local providers
|
|
11
12
|
* - `sandbox/registry.ts` — provider registry + fleet management
|
|
12
13
|
*/
|
|
13
14
|
export type { SandboxProvider, DesktopSandboxProvider, SandboxCommandRunOptions, SandboxCommandResult, SandboxDuplexProcess, SandboxSpawnDuplexOptions } from "./types/sandbox.js";
|
|
14
15
|
export type { SandboxNetworkHeaderTransform, SandboxNetworkAllowRule, SandboxNetworkSubnetPolicy, SandboxNetworkPolicy, } from "./sandbox/network-policy.js";
|
|
15
|
-
export { DOT_SEGMENT_PATH_RE2, toVercelNetworkPolicy, toE2bNetwork } from "./sandbox/network-policy.js";
|
|
16
|
+
export { DOT_SEGMENT_PATH_RE2, openEgressExcept, toVercelNetworkPolicy, toE2bNetwork } from "./sandbox/network-policy.js";
|
|
16
17
|
export type { SandboxSize } from "./sandbox/sizes.js";
|
|
17
18
|
export { SANDBOX_SIZES, SANDBOX_MACHINES, SANDBOX_VCPUS, DEFAULT_SANDBOX_SIZE, SESSION_DEFAULT_SANDBOX_SIZE, E2B_TEMPLATE_SIZES, E2B_MAX_VCPUS, E2B_MAX_MEMORY_MB, VERCEL_MEMORY_MB_PER_VCPU, isE2bSupportedSize, isVercelSupportedSize, sandboxSizeLabel, e2bMachineSpec, e2bBaseTemplate, e2bAgentEnvTemplate, isPlatformE2bTemplateAlias, } from "./sandbox/sizes.js";
|
|
18
19
|
export { E2B_DEVBOX_TEMPLATE, E2B_DEVBOX_SPEC, E2B_DEVBOX_RECIPE_VERSION, e2bDevboxTemplateRef, } from "./sandbox/devbox.js";
|
|
20
|
+
export { CLAUDE_CODE_VERSION, CODEX_CLI_VERSION, OPENCODE_CLI_VERSION, RTK_VERSION, CLAUDE_CODE_NO_SELF_UPDATE_ENV, CODEX_NO_SELF_UPDATE_CONFIG_LINE, OPENCODE_NO_SELF_UPDATE_CONFIG, } from "./sandbox/baked-clis.js";
|
|
19
21
|
export { AGENT_COMPOSE_TAG } from "./sandbox/provider-def.js";
|
|
20
22
|
export type { SandboxCreateOpts, OwnedSandbox } from "./sandbox/provider-def.js";
|
|
21
23
|
export { parseSseExecStream } from "./sandbox/exec-stream.js";
|
|
@@ -24,5 +26,5 @@ export { makeSandboxProvider, e2bMaxSandboxMs } from "./sandbox/providers/e2b.js
|
|
|
24
26
|
export { makeDesktopSandboxProvider } from "./sandbox/providers/desktop.js";
|
|
25
27
|
export { VERCEL_MAX_TAGS, buildVercelTags } from "./sandbox/providers/vercel.js";
|
|
26
28
|
export { makeLocalSandboxProvider } from "./sandbox/providers/local.js";
|
|
27
|
-
export { SANDBOX_PROVIDERS, createSandbox, reconnectSandbox, deleteSandboxSnapshot, snapshotResolves, getSandboxQuotas, listOwnedSandboxes, killSandboxById, killAllSandboxes, } from "./sandbox/registry.js";
|
|
29
|
+
export { SANDBOX_PROVIDERS, createSandbox, reconnectSandbox, deleteSandboxSnapshot, snapshotResolves, isSandboxSourceNotFoundError, getSandboxQuotas, listOwnedSandboxes, killSandboxById, killAllSandboxes, } from "./sandbox/registry.js";
|
|
28
30
|
export type { SandboxProviderName, SandboxQuotaResult, OwnedSandboxResult } from "./sandbox/registry.js";
|
|
@@ -29,11 +29,10 @@ export declare function stepResultLinePrefix(token: string): string;
|
|
|
29
29
|
* `console.log` can't forge either without knowing the token, and the
|
|
30
30
|
* invoker can filter both prefixes from captured stdout with one token. */
|
|
31
31
|
export declare function stepPauseLinePrefix(token: string): string;
|
|
32
|
-
/** Sandbox-side path where
|
|
33
|
-
*
|
|
34
|
-
* the runner from this path; single source of truth. */
|
|
32
|
+
/** Sandbox-side path where the sandbox bootstrap writes the compiled runner
|
|
33
|
+
* bundle; `invokeStep` spawns the runner from this path. */
|
|
35
34
|
export declare const RUNNER_BUNDLE_PATH = "/tmp/runner.bundle.js";
|
|
36
|
-
/** Command the invoker
|
|
35
|
+
/** Command the invoker spawns inside the sandbox. */
|
|
37
36
|
export declare const RUNNER_COMMAND = "node /tmp/runner.bundle.js";
|
|
38
37
|
/** Names of the env vars the invoker stamps onto the runner subprocess.
|
|
39
38
|
* The runner's serveStep reads from these. Centralising the names lets
|
|
@@ -58,7 +58,7 @@ export type StepHandler<TInput = unknown, TOutput = unknown> = (request: ServeSt
|
|
|
58
58
|
* from process.env so user code (including any workflow module imported
|
|
59
59
|
* inside the handler) cannot read AC_STEP_RESULT_TOKEN — that keeps the
|
|
60
60
|
* result channel uncorruptible by stdout output from anywhere in the
|
|
61
|
-
* workflow's dep tree. RUN_ID remains available
|
|
62
|
-
*
|
|
61
|
+
* workflow's dep tree. RUN_ID remains available: SDK code inside the step
|
|
62
|
+
* (`agent()`, the client's parent-run link) reads it.
|
|
63
63
|
*/
|
|
64
64
|
export declare function serveStep<TInput, TOutput>(handler: StepHandler<TInput, TOutput>): Promise<never>;
|
|
@@ -54,10 +54,10 @@ export type StepResult<TOutput = unknown> = {
|
|
|
54
54
|
export declare const StepPauseRequestSchema: z.ZodObject<{
|
|
55
55
|
reason: z.ZodString;
|
|
56
56
|
kind: z.ZodEnum<{
|
|
57
|
-
|
|
57
|
+
event: "event";
|
|
58
58
|
decision: "decision";
|
|
59
|
+
custom: "custom";
|
|
59
60
|
sleep: "sleep";
|
|
60
|
-
event: "event";
|
|
61
61
|
}>;
|
|
62
62
|
payload: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
63
63
|
ttlMs: z.ZodOptional<z.ZodNumber>;
|