@agent-compose/sdk 0.5.0 → 0.5.2

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 (90) hide show
  1. package/dist/active-step.d.ts +60 -0
  2. package/dist/agent/agent-loop-steer.test.d.ts +1 -0
  3. package/dist/agent/agent-loop.d.ts +46 -0
  4. package/dist/agent/async-queue.d.ts +29 -0
  5. package/dist/agent/protocol.d.ts +9 -1
  6. package/dist/agent/resolve-agent-id.test.d.ts +1 -0
  7. package/dist/agent/run-agent.d.ts +16 -3
  8. package/dist/agent/steer-control.d.ts +57 -0
  9. package/dist/agent/steer-control.test.d.ts +1 -0
  10. package/dist/client.d.ts +161 -0
  11. package/dist/index.d.ts +7 -4
  12. package/dist/index.js +1341 -157
  13. package/dist/pause/__tests__/agent-loop-checkpoint.test.d.ts +1 -0
  14. package/dist/pause/__tests__/checkpoint.test.d.ts +1 -0
  15. package/dist/pause/__tests__/errors.test.d.ts +1 -0
  16. package/dist/pause/__tests__/manager.test.d.ts +1 -0
  17. package/dist/pause/__tests__/pause-core.test.d.ts +1 -0
  18. package/dist/pause/__tests__/state-dir.test.d.ts +1 -0
  19. package/dist/pause/__tests__/wrappers.test.d.ts +1 -0
  20. package/dist/pause/checkpoint.d.ts +28 -0
  21. package/dist/pause/errors.d.ts +52 -0
  22. package/dist/pause/manager.d.ts +63 -0
  23. package/dist/pause/pause-core.d.ts +101 -0
  24. package/dist/pause/state-dir.d.ts +80 -0
  25. package/dist/pause/wrappers.d.ts +41 -0
  26. package/dist/request-context/request-context.d.ts +12 -0
  27. package/dist/runtimes/claude.d.ts +6 -0
  28. package/dist/runtimes/openai-desktop.d.ts +2 -0
  29. package/dist/runtimes/openai-desktop.js +1338 -156
  30. package/dist/runtimes/vercel.d.ts +12 -0
  31. package/dist/runtimes/vercel.js +50 -7
  32. package/dist/runtimes/vercel.test.d.ts +1 -0
  33. package/dist/sse.d.ts +2 -3
  34. package/dist/step-invocation/index.d.ts +2 -2
  35. package/dist/step-invocation/invoker.d.ts +3 -0
  36. package/dist/step-invocation/protocol.d.ts +12 -0
  37. package/dist/step-invocation/server.d.ts +1 -0
  38. package/dist/step-invocation/types.d.ts +40 -5
  39. package/dist/types/events.d.ts +9 -0
  40. package/dist/types/execution-context.d.ts +25 -0
  41. package/dist/types/protocol.d.ts +8 -0
  42. package/dist/types/runtime.d.ts +55 -0
  43. package/dist/types/sandbox.d.ts +6 -1
  44. package/dist/utils/schemas.d.ts +2 -0
  45. package/dist/workflow-steps/__tests__/pause-wiring.test.d.ts +1 -0
  46. package/dist/workflow-steps/index.d.ts +2 -0
  47. package/dist/workflow-steps/observability.d.ts +43 -11
  48. package/dist/workflow-steps/run-callback.d.ts +39 -0
  49. package/dist/workflow-steps/runner.d.ts +8 -0
  50. package/package.json +1 -1
  51. package/src/active-step.ts +124 -0
  52. package/src/agent/agent-loop.ts +253 -19
  53. package/src/agent/async-queue.ts +61 -0
  54. package/src/agent/protocol.ts +12 -2
  55. package/src/agent/run-agent.ts +184 -8
  56. package/src/agent/steer-control.ts +125 -0
  57. package/src/client.ts +277 -0
  58. package/src/index.ts +18 -2
  59. package/src/pause/checkpoint.ts +44 -0
  60. package/src/pause/errors.ts +70 -0
  61. package/src/pause/manager.ts +177 -0
  62. package/src/pause/pause-core.ts +267 -0
  63. package/src/pause/state-dir.ts +262 -0
  64. package/src/pause/wrappers.ts +79 -0
  65. package/src/request-context/request-context.ts +17 -2
  66. package/src/runtimes/claude.ts +101 -6
  67. package/src/runtimes/openai-desktop.ts +11 -0
  68. package/src/runtimes/vercel.ts +26 -0
  69. package/src/sandbox.ts +45 -17
  70. package/src/sse.ts +8 -6
  71. package/src/step-invocation/index.ts +2 -1
  72. package/src/step-invocation/invoker.ts +107 -29
  73. package/src/step-invocation/protocol.ts +16 -0
  74. package/src/step-invocation/server.ts +45 -12
  75. package/src/step-invocation/types.ts +43 -7
  76. package/src/tools/coding.ts +16 -5
  77. package/src/types/events.ts +9 -0
  78. package/src/types/execution-context.ts +25 -0
  79. package/src/types/protocol.ts +8 -0
  80. package/src/types/runtime.ts +52 -0
  81. package/src/types/sandbox.ts +10 -1
  82. package/src/types/workflow.ts +6 -1
  83. package/src/utils/bundler.ts +8 -3
  84. package/src/utils/schemas.ts +2 -0
  85. package/src/workflow-steps/index.ts +3 -0
  86. package/src/workflow-steps/observability.ts +84 -13
  87. package/src/workflow-steps/run-callback.ts +72 -0
  88. package/src/workflow-steps/runner.ts +70 -8
  89. package/dist/utils/discovery.d.ts +0 -2
  90. package/src/utils/discovery.ts +0 -4
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,28 @@
1
+ /**
2
+ * `ctx.checkpoint(name, fn)` — disk-backed memoise across pause-resume.
3
+ *
4
+ * First call: `fn()` runs, the result is atomically written to
5
+ * `/tmp/wf/state/checkpoints/<name>.json`. On any subsequent invocation
6
+ * of the same step body (e.g. after pause-resume re-enters the
7
+ * subprocess), the file exists in the restored sandbox; `fn` is NOT
8
+ * called, the recorded value is returned.
9
+ *
10
+ * Use for: large context loads, expensive deterministic transforms,
11
+ * idempotent-but-slow computations that you want to skip on resume.
12
+ *
13
+ * Do NOT use for: side effects with external systems (DB writes, HTTP
14
+ * POSTs, sending email). Those need `ctx.invokeChild(...)` — Temporal's
15
+ * exactly-once guarantee covers cross-process side effects; disk-backed
16
+ * memoisation is in-sandbox only and would silently retry on a sandbox
17
+ * recreation that lost the checkpoint file.
18
+ *
19
+ * See ADR-0006 §"`ctx.checkpoint(name, fn)` — disk-backed memoisation".
20
+ */
21
+ /** Read-or-run-and-write helper. `name` is validated by the state-dir
22
+ * layer (rejects path-escape attempts); `fn` is awaited if it returns
23
+ * a Promise so sync and async callers compose identically. */
24
+ export declare function checkpoint<T>(name: string, fn: () => Promise<T> | T): Promise<T>;
25
+ /** Bind user checkpoint names to a runner-owned namespace. The user's
26
+ * `name` is still validated independently so a scope prefix cannot turn
27
+ * an empty or path-escaping name into a valid filename. */
28
+ export declare function scopedCheckpoint(scope: string): typeof checkpoint;
@@ -0,0 +1,52 @@
1
+ /**
2
+ * User-facing pause errors (ADR-0006 / ADR-0011).
3
+ *
4
+ * These are thrown into USER step/agent code when a pause cannot return a
5
+ * value — the caller can catch them. They are distinct from `PauseSignal`
6
+ * (the internal control-flow signal in `pause-core.ts` that unwinds the
7
+ * stack to `serveStep`): `PauseSignal` never reaches user code, these do.
8
+ *
9
+ * Each carries a stable `code` so the activity boundary and the dashboard
10
+ * can classify the failure without string-matching the message — the same
11
+ * pattern as `StepExecutionError` (`step-invocation/types.ts`).
12
+ *
13
+ * `target: ESNext` (sdk/tsconfig.json) makes `extends Error` + `instanceof`
14
+ * work without a manual prototype fix; `this.name = new.target.name` gives
15
+ * each subclass its own class name on the instance.
16
+ */
17
+ /** Stable, machine-readable discriminator for each pause error. */
18
+ export type PauseErrorCode = "pause_expired" | "pause_schema" | "pause_request";
19
+ /** Base for every user-facing pause error. Not thrown directly. */
20
+ export declare abstract class PauseError extends Error {
21
+ abstract readonly code: PauseErrorCode;
22
+ constructor(message: string);
23
+ }
24
+ /**
25
+ * The pause's TTL elapsed before it was resolved, and `onExpiry` was
26
+ * `{ mode: "throw" }` (the default). When `onExpiry` is
27
+ * `{ mode: "resolve", value }`, `ctx.pause` returns `value` instead of
28
+ * throwing this.
29
+ */
30
+ export declare class PauseExpiredError extends PauseError {
31
+ readonly code = "pause_expired";
32
+ constructor(message?: string);
33
+ }
34
+ /**
35
+ * The resume payload failed the caller's `schema`. `issues` carries the
36
+ * validation detail for an in-sandbox `catch`; note only `message` survives
37
+ * the serveStep wire boundary, so do not rely on `issues` outside the
38
+ * throwing process.
39
+ */
40
+ export declare class PauseSchemaError extends PauseError {
41
+ readonly code = "pause_schema";
42
+ readonly issues: unknown;
43
+ constructor(message: string, issues?: unknown);
44
+ }
45
+ /**
46
+ * The pause request itself is invalid before it can be emitted to the engine:
47
+ * empty reason, non-positive ttl, invalid kind, or a non-JSON payload.
48
+ */
49
+ export declare class PauseRequestError extends PauseError {
50
+ readonly code = "pause_request";
51
+ constructor(message?: string);
52
+ }
@@ -0,0 +1,63 @@
1
+ /**
2
+ * Local pause/resume manager.
3
+ *
4
+ * This module owns the SDK-local state machine that makes a re-entered
5
+ * runner subprocess pick up agent work correctly. It deliberately does not
6
+ * know about Temporal, Postgres, HTTP resume routes, or dashboard feeds.
7
+ * Those layers own durable wait/audit state; this layer owns only the
8
+ * `/tmp/wf/state` files captured by sandbox snapshots.
9
+ */
10
+ import type { AgentStatus } from "../types/protocol.js";
11
+ import type { ModelExecutionContract } from "../types/runtime.js";
12
+ export interface AgentLoopProgressState {
13
+ iteration: number;
14
+ completedIterations: number;
15
+ lastSessionId: string;
16
+ lastStatus: AgentStatus | null;
17
+ lastResponseText: string;
18
+ lastResponseValidationError: string;
19
+ iterationsWithoutStatus: number;
20
+ blockerStreak: {
21
+ key: string;
22
+ count: number;
23
+ } | null;
24
+ /** PR 7 steer-pause intent — see RunningAgentLoopStateSchema. Optional so the
25
+ * loop can omit it until it wires steer (the schema defaults it to null). */
26
+ pendingSteerPause?: {
27
+ reason: string;
28
+ correlationKey: string | null;
29
+ at: number;
30
+ } | null;
31
+ }
32
+ export interface SettledAgentLoopResult<TResponse = unknown> {
33
+ sessionId: string;
34
+ lastStatus: AgentStatus | null;
35
+ iterations: number;
36
+ response?: TResponse;
37
+ }
38
+ export type AgentLoopRestore<TResponse = unknown> = {
39
+ kind: "fresh";
40
+ } | {
41
+ kind: "invalid";
42
+ error: string;
43
+ } | {
44
+ kind: "running";
45
+ state: AgentLoopProgressState;
46
+ } | {
47
+ kind: "settled";
48
+ result: SettledAgentLoopResult<TResponse>;
49
+ };
50
+ /**
51
+ * Coordinates the agent-loop files in `/tmp/wf/state`.
52
+ *
53
+ * Raw filesystem safety lives in `state-dir.ts`; runtime blob shape lives in
54
+ * each runtime adapter. `PauseManager` is the seam that binds those two to
55
+ * the agent-loop state machine.
56
+ */
57
+ export declare class PauseManager {
58
+ private readonly agentId;
59
+ constructor(agentId: string);
60
+ restoreAgentLoop<TResponse = unknown>(runtime: ModelExecutionContract): Promise<AgentLoopRestore<TResponse>>;
61
+ saveRunningAgentLoop(state: AgentLoopProgressState, runtime: ModelExecutionContract): Promise<void>;
62
+ saveSettledAgentLoop<TResponse = unknown>(result: SettledAgentLoopResult<TResponse>): Promise<void>;
63
+ }
@@ -0,0 +1,101 @@
1
+ /**
2
+ * `pause-core` — the engine behind `ctx.pause` (ADR-0006 / ADR-0011 PR 6).
3
+ *
4
+ * How a pause works (and why this shape):
5
+ *
6
+ * First reach (fresh): read `pauses/<pauseId>.json` → absent/unresolved →
7
+ * write the placeholder record and `throw new PauseSignal(...)`. The
8
+ * exception unwinds the step body to `serveStep`, which emits the
9
+ * `__AC_STEP_PAUSE__` sentinel and exits 0. The engine snapshots, inserts
10
+ * a `run_pauses` row keyed by `pauseId`, and waits durably.
11
+ *
12
+ * Re-entry (resolved): the engine has written the resolution onto the same
13
+ * file. The runner re-runs the step body from the top in a fresh
14
+ * subprocess; the SAME `ctx.pause` call recomputes the SAME `pauseId`,
15
+ * reads the file, and returns the resume payload (or applies `onExpiry`).
16
+ *
17
+ * The whole thing hinges on `pauseId` being recomputed identically across the
18
+ * exit/re-enter boundary, with NO surviving in-process state. So `pauseId` is
19
+ * a **deterministic UUIDv5** of a stable coordinate — never random. UUIDv5
20
+ * (not a free-form string) because `run_pauses.id` is a `uuid` PRIMARY KEY.
21
+ *
22
+ * `PauseSignal` is internal control flow, NOT a user-facing error — `serveStep`
23
+ * and the agent loop must let it propagate (the user-facing `Pause*Error` classes in
24
+ * `errors.ts` are the ones user code catches). It deliberately does not extend
25
+ * `Error`, so a stray `catch (e) { if (e instanceof Error) … }` cannot quietly
26
+ * absorb it; callers add explicit `instanceof PauseSignal` re-throw guards.
27
+ *
28
+ * Runs in the runner subprocess (may use `node:crypto`), never in the Temporal
29
+ * workflow VM.
30
+ */
31
+ import type { z } from "zod";
32
+ import { type StepPauseRequest } from "../step-invocation/types.js";
33
+ import type { StepObservability } from "../workflow-steps/observability.js";
34
+ /** Public `ctx.pause` argument shape (ADR-0006 §"SDK surface"). `schema` and
35
+ * `onExpiry` are SDK-local — consumed here, never sent on the wire. The wire
36
+ * `kind` is NOT a public field: a raw `ctx.pause` is always `kind: "custom"`;
37
+ * `decision`/`sleep`/`event` come only from the wrappers. */
38
+ export interface PauseRequest<T = unknown> {
39
+ reason: string;
40
+ payload?: Record<string, unknown>;
41
+ schema?: z.ZodType<T>;
42
+ ttlMs?: number;
43
+ onExpiry?: {
44
+ mode: "throw";
45
+ } | {
46
+ mode: "resolve";
47
+ value: T;
48
+ };
49
+ correlationKey?: string;
50
+ snapshot?: boolean;
51
+ }
52
+ /** The coordinate that makes `pauseId` deterministic + re-entry-stable. */
53
+ export interface PauseCoordinate {
54
+ runId: string;
55
+ stepIndex: number;
56
+ /** Present when the pause fires inside an agent loop (PR 7 steer-pause).
57
+ * Pins the id to the loop boundary (agentId + iteration) so it stays stable
58
+ * across the loop's iteration-skipping on resume — a bare per-step ordinal
59
+ * desyncs because completed iterations don't re-run, landing the ordinal at
60
+ * a different value. Step-body pauses leave it absent (the `:bare` form). */
61
+ agentScope?: {
62
+ agentId: string;
63
+ iteration: number;
64
+ };
65
+ }
66
+ /** Realm-global brand so `isPauseSignal` recognises a PauseSignal thrown by a
67
+ * DIFFERENT SDK instance. A bundled workflow inlines its own SDK copy (its
68
+ * `agent()` steer-pause throws the bundle's `PauseSignal`), but the runner
69
+ * catches with its own class — a plain `instanceof` is false across that
70
+ * boundary, so the pause was mis-classified as a step failure and no
71
+ * `run_pauses` row was written. `ctx.pause` avoided this only because its
72
+ * signal is runner-thrown. `Symbol.for` is shared across the realm, so the
73
+ * brand survives the instance split. */
74
+ declare const PAUSE_SIGNAL_BRAND: unique symbol;
75
+ /**
76
+ * Internal control-flow signal thrown by `corePause` on a fresh pause.
77
+ * Caught by `serveStep` (emits the sentinel + exits) and re-thrown past every
78
+ * intermediate catch. NOT an `Error` and NOT user-facing.
79
+ */
80
+ export declare class PauseSignal {
81
+ readonly pauseId: string;
82
+ readonly pauseRequest: StepPauseRequest;
83
+ readonly observability?: StepObservability | undefined;
84
+ readonly [PAUSE_SIGNAL_BRAND]: true;
85
+ constructor(pauseId: string, pauseRequest: StepPauseRequest, observability?: StepObservability | undefined);
86
+ }
87
+ /** Cross-instance-safe `PauseSignal` check. Use this instead of
88
+ * `err instanceof PauseSignal` anywhere a signal may have been thrown by a
89
+ * different SDK instance (the runner catching a bundled workflow's signal). */
90
+ export declare function isPauseSignal(err: unknown): err is PauseSignal;
91
+ /** Wipe the ordinal counters. Called by the runner at first-boot alongside
92
+ * `resetStateDir()`; a fresh module load already starts empty, so this is
93
+ * belt-and-braces for any in-process reuse. */
94
+ export declare function resetPauseOrdinals(): void;
95
+ /**
96
+ * The body of `ctx.pause`. On a fresh pause it throws `PauseSignal`; on
97
+ * re-entry it returns the resume payload (or applies `onExpiry` / throws
98
+ * `PauseSchemaError`). See the module header.
99
+ */
100
+ export declare function corePause<T = unknown>(req: PauseRequest<T>, coord: PauseCoordinate, kind?: StepPauseRequest["kind"]): Promise<T>;
101
+ export {};
@@ -0,0 +1,80 @@
1
+ /**
2
+ * Pause state directory — durable per-agent / per-checkpoint / per-pause
3
+ * blobs the sandbox snapshot carries across pause-resume.
4
+ *
5
+ * Layout under `/tmp/wf/state/`:
6
+ *
7
+ * agent-<agentInstanceId>.json ← agent loop state (iteration, messages, processor cursor)
8
+ * runtime-<agentInstanceId>.json ← runtime-private blob (opaque to the loop)
9
+ * checkpoints/<name>.json ← user `ctx.checkpoint(name, fn)` memoised values
10
+ * pauses/<pauseId>.json ← pause records (request + resume payload once available)
11
+ *
12
+ * Atomic writes (write-tmp → fsync → rename) so a mid-write `sandbox.snapshot()`
13
+ * cannot capture partial state. Most read helpers return `null` on missing-file
14
+ * rather than throwing — callers branch on presence to distinguish "first
15
+ * run" from "post-resume restore". User checkpoints use an explicit
16
+ * found/value result because `null` is a valid memoised value.
17
+ *
18
+ * The state-dir layout is treated as wire protocol between the SDK
19
+ * runner (writer) and the SDK on the next subprocess invocation (reader).
20
+ * Changing a filename or shape is a breaking change to pause resumption
21
+ * for any in-flight paused workflow. See ADR-0006.
22
+ */
23
+ /** Root of the pause state-dir. Defaults to `/tmp/wf/state` — the
24
+ * canonical location inside the sandbox. Tests and non-`/tmp`-writable
25
+ * environments can override via `AGENT_COMPOSE_STATE_DIR`.
26
+ *
27
+ * Read at CALL TIME, not module load. An earlier draft cached it on
28
+ * first import, but that turned out to be test-ordering-fragile: once
29
+ * any test imported state-dir (directly or transitively via
30
+ * agent-loop) the path got locked to whatever env was set at that
31
+ * instant, and a later test setting `AGENT_COMPOSE_STATE_DIR` would
32
+ * silently write to the cached path instead. Reading the env each
33
+ * call costs nothing measurable next to the fsync. */
34
+ export declare function getStateDir(): string;
35
+ export declare function assertSafeCheckpointName(name: string): void;
36
+ export type CheckpointRead<T> = {
37
+ found: true;
38
+ value: T;
39
+ } | {
40
+ found: false;
41
+ };
42
+ export declare function readAgentState<T = unknown>(agentInstanceId: string): Promise<T | null>;
43
+ export declare function writeAgentState(agentInstanceId: string, state: unknown): Promise<void>;
44
+ export declare function readRuntimeCheckpoint<T = unknown>(agentInstanceId: string): Promise<T | null>;
45
+ export declare function writeRuntimeCheckpoint(agentInstanceId: string, blob: unknown): Promise<void>;
46
+ export declare function readCheckpoint<T = unknown>(name: string): Promise<CheckpointRead<T>>;
47
+ export declare function writeCheckpoint(name: string, value: unknown): Promise<void>;
48
+ /** The `pauses/<pauseId>.json` file — the only durable handoff between the
49
+ * paused subprocess and the resumed one.
50
+ *
51
+ * Written twice in two execution contexts:
52
+ * - At pause time the runner writes the placeholder `{ pauseId, request }`
53
+ * (no `resolved`). The snapshot captures it.
54
+ * - At resume time the engine activity writes the resolution — usually
55
+ * merged on top of the placeholder, but snapshotless pauses may only have
56
+ * `{ resolved: true, resumePayload, expired }` in a fresh sandbox. Those
57
+ * three resolution fields are always present together so the byte shape
58
+ * distinguishes a real resume (`expired:false`) from a TTL expiry
59
+ * (`expired:true`) from an unresolved placeholder (`resolved` absent).
60
+ *
61
+ * `corePause` reads it on re-entry: `resolved !== true` ⇒ still my own
62
+ * placeholder, pause again; `expired` ⇒ apply `onExpiry`; else return
63
+ * `resumePayload`. */
64
+ export interface PauseRecord {
65
+ pauseId: string;
66
+ request: unknown;
67
+ /** Set true once the engine has written the resolution (resume or expiry). */
68
+ resolved?: boolean;
69
+ /** Value to return from `ctx.pause` on a real resume; null for expiry. */
70
+ resumePayload?: unknown;
71
+ /** True when the resolution is a TTL expiry, not a caller-driven resume. */
72
+ expired?: boolean;
73
+ }
74
+ export declare function readPauseRecord(pauseId: string): Promise<PauseRecord | null>;
75
+ export declare function writePauseRecord(record: PauseRecord): Promise<void>;
76
+ /** Wipe the entire state directory. Used by the runner at first-boot
77
+ * (no pauseId in env) so a freshly-dispatched run never inherits state
78
+ * from a prior dispatch that shared the sandbox snapshot template.
79
+ * No-op when the directory doesn't exist. */
80
+ export declare function resetStateDir(): Promise<void>;
@@ -0,0 +1,41 @@
1
+ /**
2
+ * The three opinionated pause wrappers (ADR-0006 §"SDK surface"), each a thin
3
+ * closure over `ctx.pause`:
4
+ *
5
+ * - `requestDecision` — pause for a typed human/agent decision (schema required).
6
+ * - `sleep` — a lightweight timed pause; resolves on its own TTL,
7
+ * skips the snapshot, returns void.
8
+ * - `waitForEvent` — pause until an event resumes by correlation key.
9
+ *
10
+ * Built from a `PauseFn` so the wrapper logic lives in one place and the step
11
+ * runner just spreads them onto the context next to `pause`.
12
+ */
13
+ import type { z } from "zod";
14
+ import type { StepPauseRequest } from "../step-invocation/types.js";
15
+ import type { PauseRequest } from "./pause-core.js";
16
+ /** The public `ctx.pause` callable (always `kind: "custom"`). */
17
+ export type PauseFn = <T = unknown>(req: PauseRequest<T>) => Promise<T>;
18
+ /** Internal: pause with an explicit wire `kind`. The wrappers stamp
19
+ * `decision`/`sleep`/`event` through this; the public `ctx.pause` is always
20
+ * `custom` and never exposes it. */
21
+ export type KindedPauseFn = <T = unknown>(req: PauseRequest<T>, kind: StepPauseRequest["kind"]) => Promise<T>;
22
+ export interface RequestDecisionRequest<T> {
23
+ reason: string;
24
+ payload?: Record<string, unknown>;
25
+ /** Required — a decision is always validated against a shape. */
26
+ schema: z.ZodType<T>;
27
+ ttlMs?: number;
28
+ }
29
+ export interface WaitForEventRequest<T> {
30
+ reason: string;
31
+ /** Required — the by-key resume route targets this. */
32
+ correlationKey: string;
33
+ schema?: z.ZodType<T>;
34
+ ttlMs?: number;
35
+ }
36
+ export interface PauseWrappers {
37
+ requestDecision<T>(req: RequestDecisionRequest<T>): Promise<T>;
38
+ sleep(durationMs: number): Promise<void>;
39
+ waitForEvent<T = unknown>(req: WaitForEventRequest<T>): Promise<T>;
40
+ }
41
+ export declare function buildPauseWrappers(pause: KindedPauseFn): PauseWrappers;
@@ -38,6 +38,7 @@
38
38
  * `invokeChild` propagation: only reserved keys flow to the child; freeform
39
39
  * is per-run by design (cross-run state must be explicit via `input`).
40
40
  */
41
+ import { z } from "zod";
41
42
  /** Reserved key namespace prefix — anything starting with this is platform-owned. */
42
43
  export declare const AC_RESERVED_PREFIX = "ac__";
43
44
  export declare const AC_TEAM_ID: "ac__teamId";
@@ -77,6 +78,17 @@ export interface RequestContextWire {
77
78
  };
78
79
  user: Record<string, unknown>;
79
80
  }
81
+ export declare const RequestContextWireSchema: z.ZodObject<{
82
+ reserved: z.ZodObject<{
83
+ teamId: z.ZodString;
84
+ runId: z.ZodString;
85
+ workflowId: z.ZodString;
86
+ factoryId: z.ZodNullable<z.ZodString>;
87
+ apiKeyScopes: z.ZodReadonly<z.ZodArray<z.ZodString>>;
88
+ parentRunId: z.ZodNullable<z.ZodString>;
89
+ }, z.core.$strip>;
90
+ user: z.ZodRecord<z.ZodString, z.ZodUnknown>;
91
+ }, z.core.$strip>;
80
92
  /** Thrown when a caller tries to `set` or `delete` a reserved key downstream. */
81
93
  export declare class ReservedKeyError extends Error {
82
94
  readonly key: string;
@@ -26,13 +26,19 @@ export declare class ClaudeRunner implements ModelExecutionContract {
26
26
  private readonly options;
27
27
  private readonly config;
28
28
  supportsToolCallProcessor: boolean;
29
+ readonly kind = "claude";
29
30
  constructor(_sandbox: SandboxProvider, options?: RuntimeOptions, config?: ClaudeRuntimeConfig);
31
+ get model(): string;
30
32
  gateToolCall(call: ToolCall, ctx: ProcessorContext): Promise<ToolCallGateResult>;
31
33
  sendMessage(opts: {
32
34
  prompt: string;
33
35
  sessionId?: string;
34
36
  iteration?: number;
35
37
  signal?: AbortSignal;
38
+ inboxStream?: AsyncIterable<{
39
+ text: string;
40
+ senderName?: string | null;
41
+ }>;
36
42
  }): AsyncGenerator<AgentMessage>;
37
43
  }
38
44
  export declare function createClaudeRuntime(config?: ClaudeRuntimeConfig): import("../index.js").AgentRuntime<SandboxProvider>;
@@ -10,6 +10,8 @@ export interface OpenAIDesktopRunnerOptions extends RuntimeOptions {
10
10
  }
11
11
  export declare class OpenAIDesktopRunner implements ModelExecutionContract {
12
12
  private sandbox;
13
+ readonly kind = "openai-desktop";
14
+ readonly model = "computer-use-preview";
13
15
  private openai;
14
16
  private label;
15
17
  constructor(sandbox: DesktopSandboxProvider, opts: OpenAIDesktopRunnerOptions);