@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.
Files changed (106) hide show
  1. package/README.md +213 -189
  2. package/dist/agent/agent-context.d.ts +9 -1
  3. package/dist/agent/agent-loop.d.ts +14 -6
  4. package/dist/agent/perf-sampler.d.ts +27 -2
  5. package/dist/agent/run-agent.d.ts +1 -1
  6. package/dist/client.d.ts +250 -59
  7. package/dist/directives.d.ts +14 -0
  8. package/dist/display.d.ts +7 -0
  9. package/dist/errors.d.ts +1 -1
  10. package/dist/generated/agentc-commands.d.ts +34 -0
  11. package/dist/index.d.ts +13 -11
  12. package/dist/index.js +1692 -194
  13. package/dist/request-context/request-context.d.ts +1 -1
  14. package/dist/runtimes/_cli-agent.d.ts +278 -58
  15. package/dist/runtimes/claude-code.d.ts +90 -1
  16. package/dist/runtimes/claude.d.ts +1 -1
  17. package/dist/runtimes/codex.d.ts +94 -6
  18. package/dist/runtimes/codex.mid-turn-hook.test.d.ts +10 -0
  19. package/dist/runtimes/openai-desktop.d.ts +50 -0
  20. package/dist/runtimes/openai-desktop.js +1689 -211
  21. package/dist/runtimes/openai-desktop.test.d.ts +20 -0
  22. package/dist/runtimes/opencode.d.ts +48 -11
  23. package/dist/runtimes/opencode.test.d.ts +14 -0
  24. package/dist/runtimes/tool-pulse.test.d.ts +17 -0
  25. package/dist/sandbox/baked-clis.d.ts +75 -0
  26. package/dist/sandbox/devbox.d.ts +5 -5
  27. package/dist/sandbox/exec-stream.d.ts +1 -2
  28. package/dist/sandbox/network-policy.d.ts +23 -5
  29. package/dist/sandbox/registry.d.ts +12 -0
  30. package/dist/sandbox/sizes.d.ts +11 -5
  31. package/dist/sandbox.d.ts +5 -3
  32. package/dist/step-invocation/protocol.d.ts +3 -4
  33. package/dist/step-invocation/server.d.ts +2 -2
  34. package/dist/step-invocation/types.d.ts +2 -2
  35. package/dist/types/api-conversations.d.ts +513 -27
  36. package/dist/types/api-factory.d.ts +183 -3
  37. package/dist/types/api-projects.d.ts +480 -0
  38. package/dist/types/api-runs.d.ts +8 -0
  39. package/dist/types/api-scopes.d.ts +32 -3
  40. package/dist/types/conversation-stream.d.ts +27 -1
  41. package/dist/types/execution-context.d.ts +1 -1
  42. package/dist/types/protocol.d.ts +182 -2
  43. package/dist/types/runtime.d.ts +80 -2
  44. package/dist/types/workflow-metadata.d.ts +2 -4
  45. package/dist/types/workflow-plan.d.ts +1 -3
  46. package/dist/utils/bundler.d.ts +23 -0
  47. package/dist/workflow-steps/observability.d.ts +2 -3
  48. package/dist/workflow-steps/runner.d.ts +5 -8
  49. package/dist/workflow-steps/types.d.ts +8 -10
  50. package/dist/workflow-steps/workflow.d.ts +2 -1
  51. package/dist/workflows/engine.d.ts +3 -5
  52. package/dist/workflows/invoke-child.d.ts +2 -2
  53. package/package.json +2 -2
  54. package/src/agent/agent-context.ts +193 -116
  55. package/src/agent/agent-loop.ts +16 -9
  56. package/src/agent/desktop-open.ts +13 -1
  57. package/src/agent/perf-sampler.ts +54 -3
  58. package/src/agent/run-agent.ts +1 -1
  59. package/src/client.ts +418 -80
  60. package/src/directives.ts +21 -1
  61. package/src/display.ts +12 -0
  62. package/src/errors.ts +1 -0
  63. package/src/generated/agentc-commands.ts +571 -0
  64. package/src/index.ts +65 -18
  65. package/src/pause/pause-core.ts +2 -1
  66. package/src/request-context/request-context.ts +1 -1
  67. package/src/runtimes/_cli-agent.ts +607 -132
  68. package/src/runtimes/claude-code.ts +427 -20
  69. package/src/runtimes/claude.ts +1 -1
  70. package/src/runtimes/codex.ts +188 -19
  71. package/src/runtimes/openai-desktop.ts +82 -19
  72. package/src/runtimes/opencode.ts +195 -26
  73. package/src/sandbox/baked-clis.ts +86 -0
  74. package/src/sandbox/devbox.ts +5 -5
  75. package/src/sandbox/exec-stream.ts +1 -2
  76. package/src/sandbox/network-policy.ts +51 -7
  77. package/src/sandbox/providers/e2b.ts +63 -19
  78. package/src/sandbox/providers/vercel.ts +6 -6
  79. package/src/sandbox/registry.ts +19 -1
  80. package/src/sandbox/sizes.ts +11 -5
  81. package/src/sandbox.ts +9 -2
  82. package/src/step-invocation/invoker.ts +2 -6
  83. package/src/step-invocation/protocol.ts +3 -4
  84. package/src/step-invocation/server.ts +2 -2
  85. package/src/types/api-conversations.ts +424 -29
  86. package/src/types/api-factory.ts +189 -3
  87. package/src/types/api-projects.ts +443 -0
  88. package/src/types/api-runs.ts +5 -0
  89. package/src/types/api-scopes.ts +32 -3
  90. package/src/types/conversation-stream.ts +29 -1
  91. package/src/types/execution-context.ts +1 -1
  92. package/src/types/protocol.ts +180 -2
  93. package/src/types/runtime.ts +71 -2
  94. package/src/types/sandbox-environment.ts +1 -2
  95. package/src/types/workflow-metadata.ts +2 -4
  96. package/src/types/workflow-plan.ts +1 -3
  97. package/src/utils/bundler.ts +88 -19
  98. package/src/workflow-steps/observability.ts +2 -3
  99. package/src/workflow-steps/runner.ts +5 -8
  100. package/src/workflow-steps/types.ts +8 -10
  101. package/src/workflow-steps/workflow.ts +2 -1
  102. package/src/workflows/engine.ts +3 -5
  103. package/src/workflows/invoke-child.ts +2 -2
  104. package/dist/pause/__tests__/errors.test.d.ts +0 -1
  105. package/dist/pause/__tests__/wrappers.test.d.ts +0 -1
  106. package/dist/step-invocation/__tests__/protocol.test.d.ts +0 -1
@@ -5,14 +5,102 @@
5
5
  * only stream-parse what it prints.
6
6
  *
7
7
  * Auth: set `OPENAI_API_KEY` (or `CODEX_API_KEY`) in the sandbox env via a
8
- * workflow secret. The runtime installs the `codex` CLI (`@openai/codex`) on
9
- * demand — no image baking needed; pair with `snapshots: { bootFrom: "reuse" }`
10
- * to install once and boot from the captured snapshot on every run after.
8
+ * workflow secret. The E2B session image bakes the pinned `codex` CLI
9
+ * (`@openai/codex@CODEX_CLI_VERSION`); on any other machine the runtime
10
+ * installs that same version on demand (pair with
11
+ * `snapshots: { bootFrom: "reuse" }` to install once and boot from the
12
+ * captured snapshot on every run after).
11
13
  *
12
14
  * Verified against codex-cli 0.124.0: `codex exec --json` + resume-by-thread,
13
- * with the command_execution / reasoning / agent_message item shapes below.
15
+ * with the command_execution / reasoning / agent_message item shapes below;
16
+ * the plan's `todo_list` item against codex-rs rust-v0.153.4 and
17
+ * rust-v0.159.2 (see codexPlanMessages); the command_execution /
18
+ * agent_message / turn.completed shapes re-verified live against 0.160.0
19
+ * (the pin), whose plan-tool sources are byte-identical to rust-v0.159.2.
14
20
  */
15
21
  import { type CliAgentSpec, type CliReasoningEffort } from "./_cli-agent.js";
22
+ /** The Bash PreToolUse hook rtk installs for Codex (`rtk init -g --codex`
23
+ * writes exactly this entry — matcher `Bash`, command `rtk hook codex` —
24
+ * into $CODEX_HOME/hooks.json). `rtk hook codex` exists since rtk 0.50.0;
25
+ * the image bakes RTK_VERSION (sandbox/baked-clis.ts), which this payload
26
+ * was run against. Codex's shell tool matches the `Bash` matcher (codex-rs
27
+ * rust-v0.160.0, the pinned CODEX_CLI_VERSION; identical at
28
+ * rust-v0.159.2), and the hook runs under `$SHELL -lc` with the PreToolUse
29
+ * JSON on stdin. `rtk hook codex` answers `permissionDecision: "allow"` +
30
+ * `updatedInput` rewriting `git status` to `rtk git status` when it has a
31
+ * filter for the command; Codex applies the replacement before its own
32
+ * approval and sandbox checks. For a command it cannot compress (an
33
+ * unknown tool, a pipe into one, substitutions, heredocs, redirects, a
34
+ * `RTK_DISABLED=1` prefix, an unknown permission mode) it prints nothing
35
+ * and exits 0, and Codex runs the original unchanged.
36
+ *
37
+ * The wrapper fails OPEN both ways, like RTK_BASH_HOOK_COMMAND
38
+ * (claude-code.ts). `command -v` covers an image without rtk (the devbox,
39
+ * a bare Vercel VM): silent, exit 0, so Codex runs the command instead of
40
+ * failing every shell call's hook with 127. The trailing `exit 0` covers
41
+ * an rtk that cannot answer: Codex treats a PreToolUse hook's exit 2 with
42
+ * stderr as a BLOCK of the tool call (codex-rs hooks/src/events/
43
+ * pre_tool_use.rs at rust-v0.160.0 — the model reads "Command blocked by
44
+ * PreToolUse hook: <stderr>"), and clap exits 2 with its usage on stderr
45
+ * for a subcommand it does not know. That was 2026-10-03: the image's rtk
46
+ * was a cache-served 0.45.0 with no `hook codex`, and this hook — `exec`
47
+ * handing rtk's exit code to Codex — blocked every shell command of every
48
+ * codex session. rtk's hooks never exit non-zero on purpose (they fail
49
+ * open with no stdout), so a non-zero exit is always a broken rtk, and the
50
+ * compressor must never cost the worker its shell: the exit code is
51
+ * dropped, and the smoke gate's codex-rtk-hook-rewrite check is what
52
+ * proves the rewrite itself. */
53
+ export declare const RTK_CODEX_HOOK_COMMAND = "command -v rtk >/dev/null 2>&1 && rtk hook codex; exit 0";
54
+ /** The PostToolUse command hook that carries a mid-turn message into a
55
+ * RUNNING codex turn (the 2026-10-02 relayed-steer incident: three of the
56
+ * owner's instructions waited 48-51 minutes for a codex build to end).
57
+ * Codex runs it, under `$SHELL -lc` with the event JSON on stdin and the
58
+ * codex process's own environment, after every tool call it completes
59
+ * (codex-rs core/src/tools/registry.rs → hook_runtime.rs at rust-v0.160.0,
60
+ * the pin). The launch wrapper exported the turn's inbox and delivered-
61
+ * counter paths into that environment (sdk _cli-agent.ts
62
+ * toolHookInboxFragment); the hook forwards the inbox lines past the
63
+ * counter as the hook's `additionalContext`, which codex records as
64
+ * developer context in the live turn's history before the model's next
65
+ * request (hook_runtime.rs record_additional_contexts), then advances the
66
+ * counter — the same ack the server's inject lane trusts for the stdin
67
+ * lane. Not a platform turn (no inbox in the environment): silent, exit 0.
68
+ * Codex's default spill threshold for a hook's additional context is 2,500
69
+ * tokens (hooks/src/output_spill.rs); a longer message reaches the model
70
+ * as a preview plus a file pointer, which a steer never is. */
71
+ export declare const CODEX_MID_TURN_HOOK_COMMAND: string;
72
+ /** $CODEX_HOME/hooks.json for every platform Codex session (the server
73
+ * writes it at boot, session-runtime-config.ts). Codex only RUNS a
74
+ * user-level hook it has persisted trust for — the TUI's review prompt
75
+ * has no headless counterpart, and `--dangerously-bypass-hook-trust` would
76
+ * run a cloned repository's `.codex/hooks.json` unreviewed too — so the
77
+ * server also writes the trust record for each of these exact hooks into
78
+ * the config.toml it generates (sandbox/codex-hooks.ts). Verified live
79
+ * against codex 0.159.2 and 0.160.0 for the rtk hook: with the record,
80
+ * `codex exec` rewrote `git status` through rtk with no bypass flag;
81
+ * without it, the hook was skipped.
82
+ *
83
+ * The PostToolUse group carries NO matcher: codex runs a matcher-less hook
84
+ * after every tool it completes (hooks/src/events/common.rs
85
+ * matches_matcher: an absent matcher is a match), so a mid-turn message
86
+ * lands at the next tool step whatever the tool was. */
87
+ export declare const CODEX_PLATFORM_HOOKS: {
88
+ readonly hooks: {
89
+ readonly PreToolUse: readonly [{
90
+ readonly matcher: "Bash";
91
+ readonly hooks: readonly [{
92
+ readonly type: "command";
93
+ readonly command: "command -v rtk >/dev/null 2>&1 && rtk hook codex; exit 0";
94
+ }];
95
+ }];
96
+ readonly PostToolUse: readonly [{
97
+ readonly hooks: readonly [{
98
+ readonly type: "command";
99
+ readonly command: string;
100
+ }];
101
+ }];
102
+ };
103
+ };
16
104
  /** True when an error-item message is a known codex advisory (log-level
17
105
  * noise), not a real error. Exported for tests. */
18
106
  export declare function isCodexAdvisoryNoise(text: string): boolean;
@@ -28,8 +116,8 @@ export declare function codexWriterLockPreflight(threadId: string, waitAttempts?
28
116
  * `mapEvent` is the golden the ACP normaliser is asserted equal to. Not part
29
117
  * of the public runtime surface — `createCodexRuntime` stays the entry point. */
30
118
  export declare const codexSpec: CliAgentSpec;
31
- /** The effort levels codex actually has (`model_reasoning_effort`):
32
- * low|medium|high|xhigh — no "max" (that level is Claude Code's alone). */
119
+ /** The effort levels this runtime passes to codex (`model_reasoning_effort`):
120
+ * low|medium|high|xhigh, the levels every codex model takes. */
33
121
  export type CodexReasoningEffort = Exclude<CliReasoningEffort, "max">;
34
122
  export interface CodexRuntimeConfig {
35
123
  /** Codex model id (`-m`). Omit to use the codex CLI's configured default. */
@@ -0,0 +1,10 @@
1
+ /**
2
+ * codex's mid-turn hook, run for real: the PostToolUse command hook
3
+ * (CODEX_MID_TURN_HOOK_COMMAND) executed under `sh` the way codex runs a
4
+ * command hook — the event JSON on stdin, the codex process's environment —
5
+ * against a constructed inbox, and the launch fragment that gives the codex
6
+ * process that environment (toolHookInboxFragment). These pin what the
7
+ * guest DOES: the JSON codex parses, the delivered counter the server's ack
8
+ * trusts, and silence everywhere else.
9
+ */
10
+ export {};
@@ -3,11 +3,35 @@
3
3
  *
4
4
  * Works against DesktopSandboxProvider — no E2B SDK dependency here.
5
5
  * The action→screenshot loop runs until the model emits text, then yields it.
6
+ *
7
+ * COORDINATE SPACES (incident note). Every screenshot is downscaled to the
8
+ * model's DISPLAY geometry (1024×720) before it is sent, so the model emits
9
+ * coordinates in the SCALED screenshot's space — never the real desktop's.
10
+ * An earlier revision executed those coordinates against the real desktop
11
+ * using hardcoded real-geometry constants, so on any sandbox whose actual
12
+ * geometry differed, every click landed in the wrong place. The provider has
13
+ * no geometry call, so the real geometry is read from each screenshot buffer
14
+ * itself (sharp metadata), and the resulting per-capture `CaptureScale` maps
15
+ * the model's coordinates back onto the exact frame it saw. The old constants
16
+ * survive ONLY as a fallback for the metadata-missing case.
6
17
  */
7
18
  import type { DesktopSandboxProvider, AgentMessage, ModelExecutionContract, RuntimeOptions } from "../index.js";
8
19
  export interface OpenAIDesktopRunnerOptions extends RuntimeOptions {
9
20
  openaiKey: string;
10
21
  }
22
+ /** One model-emitted desktop action. Coordinates arrive in DISPLAY (model)
23
+ * space and are rescaled through the CURRENT capture's `CaptureScale`
24
+ * before dispatch. Exported so tests can type their fixtures. */
25
+ export interface ComputerAction {
26
+ type: string;
27
+ coordinate?: [number, number];
28
+ startCoordinate?: [number, number];
29
+ endCoordinate?: [number, number];
30
+ text?: string;
31
+ key?: string;
32
+ direction?: string;
33
+ ticks?: number;
34
+ }
11
35
  export declare class OpenAIDesktopRunner implements ModelExecutionContract {
12
36
  private sandbox;
13
37
  readonly kind = "openai-desktop";
@@ -20,5 +44,31 @@ export declare class OpenAIDesktopRunner implements ModelExecutionContract {
20
44
  sessionId?: string;
21
45
  }): AsyncGenerator<AgentMessage>;
22
46
  }
47
+ /** Real-desktop pixels per model-DISPLAY pixel, derived from ONE capture.
48
+ * Coordinates the model emits against that capture are multiplied by these
49
+ * factors (and rounded) before touching the provider. */
50
+ export interface CaptureScale {
51
+ scaleX: number;
52
+ scaleY: number;
53
+ }
54
+ /** One captured frame: the model-facing image plus the scale that maps the
55
+ * model's coordinates back onto this frame's real desktop. */
56
+ export interface ScaledCapture {
57
+ /** Base64 PNG resized to DISPLAY_WIDTH×DISPLAY_HEIGHT (fit "fill"). */
58
+ b64: string;
59
+ scale: CaptureScale;
60
+ }
61
+ /** Derive a capture's scale from its real pixel dimensions. The constants
62
+ * are a FALLBACK only — used when sharp cannot read the frame's metadata;
63
+ * a real dimension always wins. */
64
+ export declare function scaleFromDimensions(width: number | undefined, height: number | undefined): CaptureScale;
65
+ /** Capture one frame: read the REAL geometry from the raw screenshot's own
66
+ * metadata, downscale to the model's DISPLAY geometry, and return both the
67
+ * image and the scale that maps model coordinates back onto this frame. */
68
+ export declare function captureScaledScreenshot(sandbox: DesktopSandboxProvider): Promise<ScaledCapture>;
69
+ /** Dispatch one model action against the provider, mapping every coordinate
70
+ * through the CURRENT capture's scale. Non-coordinate payloads — scroll
71
+ * deltas (ticks), typed text, key chords — pass through untouched. */
72
+ export declare function executeAction(sandbox: DesktopSandboxProvider, action: ComputerAction, scale: CaptureScale): Promise<void>;
23
73
  declare const _default: import("../index.js").AgentRuntime<DesktopSandboxProvider>;
24
74
  export default _default;