@agent-compose/sdk 0.2.2 → 0.2.4

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 (88) hide show
  1. package/README.md +145 -33
  2. package/dist/agent/agent-loop.d.ts +83 -5
  3. package/dist/agent/run-agent.d.ts +34 -9
  4. package/dist/client.d.ts +247 -99
  5. package/dist/index.d.ts +26 -11
  6. package/dist/index.js +1968 -746
  7. package/dist/processors/builtins.d.ts +35 -0
  8. package/dist/processors/index.d.ts +4 -0
  9. package/dist/processors/processor.d.ts +91 -0
  10. package/dist/processors/processor.test.d.ts +1 -0
  11. package/dist/processors/runner.d.ts +19 -0
  12. package/dist/request-context/index.d.ts +2 -0
  13. package/dist/request-context/request-context.d.ts +159 -0
  14. package/dist/request-context/request-context.test.d.ts +1 -0
  15. package/dist/runtimes/claude.d.ts +27 -50
  16. package/dist/runtimes/openai-desktop.js +1919 -742
  17. package/dist/runtimes/vercel.d.ts +34 -0
  18. package/dist/runtimes/vercel.js +474 -0
  19. package/dist/sandbox.d.ts +29 -25
  20. package/dist/step-invocation/__tests__/invoker.test.d.ts +1 -0
  21. package/dist/step-invocation/__tests__/protocol.test.d.ts +1 -0
  22. package/dist/step-invocation/__tests__/server.test.d.ts +1 -0
  23. package/dist/step-invocation/index.d.ts +25 -0
  24. package/dist/step-invocation/invoker.d.ts +65 -0
  25. package/dist/step-invocation/protocol.d.ts +44 -0
  26. package/dist/step-invocation/server.d.ts +63 -0
  27. package/dist/step-invocation/types.d.ts +72 -0
  28. package/dist/tools/coding.d.ts +49 -0
  29. package/dist/tools/coding.test.d.ts +1 -0
  30. package/dist/tools/index.d.ts +2 -0
  31. package/dist/types/events.d.ts +36 -0
  32. package/dist/types/execution-context.d.ts +22 -0
  33. package/dist/types/runtime.d.ts +32 -0
  34. package/dist/types/sandbox-environment.d.ts +5 -2
  35. package/dist/types/sandbox.d.ts +14 -12
  36. package/dist/types/workflow-metadata.d.ts +51 -0
  37. package/dist/types/workflow-plan.d.ts +19 -0
  38. package/dist/types/workflow.d.ts +57 -17
  39. package/dist/utils/bundler.d.ts +62 -3
  40. package/dist/workflow-steps/__tests__/observability.test.d.ts +1 -0
  41. package/dist/workflow-steps/index.d.ts +10 -0
  42. package/dist/workflow-steps/observability.d.ts +58 -0
  43. package/dist/workflow-steps/runner.d.ts +96 -0
  44. package/dist/workflow-steps/step.d.ts +25 -0
  45. package/dist/workflow-steps/types.d.ts +135 -0
  46. package/dist/workflow-steps/workflow-steps.test.d.ts +1 -0
  47. package/dist/workflow-steps/workflow.d.ts +50 -0
  48. package/dist/workflows/engine.d.ts +27 -13
  49. package/dist/workflows/invoke-child.d.ts +10 -0
  50. package/package.json +25 -15
  51. package/src/agent/agent-loop.ts +197 -26
  52. package/src/agent/run-agent.ts +40 -15
  53. package/src/client.ts +326 -76
  54. package/src/index.ts +124 -10
  55. package/src/processors/builtins.ts +72 -0
  56. package/src/processors/index.ts +15 -0
  57. package/src/processors/processor.ts +103 -0
  58. package/src/processors/runner.ts +42 -0
  59. package/src/request-context/index.ts +17 -0
  60. package/src/request-context/request-context.ts +302 -0
  61. package/src/runtimes/claude.ts +123 -254
  62. package/src/runtimes/vercel.ts +180 -0
  63. package/src/sandbox.ts +53 -21
  64. package/src/step-invocation/index.ts +33 -0
  65. package/src/step-invocation/invoker.ts +204 -0
  66. package/src/step-invocation/protocol.ts +57 -0
  67. package/src/step-invocation/server.ts +184 -0
  68. package/src/step-invocation/types.ts +70 -0
  69. package/src/tools/coding.ts +126 -0
  70. package/src/tools/index.ts +8 -0
  71. package/src/types/events.ts +40 -0
  72. package/src/types/execution-context.ts +30 -0
  73. package/src/types/runtime.ts +24 -0
  74. package/src/types/sandbox-environment.ts +7 -5
  75. package/src/types/sandbox.ts +16 -12
  76. package/src/types/workflow-metadata.ts +84 -0
  77. package/src/types/workflow-plan.ts +24 -0
  78. package/src/types/workflow.ts +139 -25
  79. package/src/utils/bundler.ts +213 -19
  80. package/src/utils/source-loader.ts +2 -2
  81. package/src/workflow-steps/index.ts +30 -0
  82. package/src/workflow-steps/observability.ts +103 -0
  83. package/src/workflow-steps/runner.ts +244 -0
  84. package/src/workflow-steps/step.ts +38 -0
  85. package/src/workflow-steps/types.ts +134 -0
  86. package/src/workflow-steps/workflow.ts +95 -0
  87. package/src/workflows/engine.ts +69 -40
  88. package/src/workflows/invoke-child.ts +29 -0
@@ -0,0 +1,65 @@
1
+ /**
2
+ * Server-side half of StepInvocation. The Temporal `executeStep` activity
3
+ * (and any future durable engine's equivalent) calls `invokeStep(...)` to
4
+ * run one step inside an existing runner sandbox.
5
+ *
6
+ * Owns:
7
+ * - per-invocation result token (protocol hygiene — keeps user-side
8
+ * stdout from accidentally contaminating the result channel)
9
+ * - input + request-context file writes
10
+ * - env stamping
11
+ * - sandbox.commands.run with the runner command
12
+ * - tokenised stdout sentinel parse
13
+ * - failure-mode classification (protocol / user-step / runner-exit)
14
+ *
15
+ * Caller owns:
16
+ * - reconnecting to the runner sandbox (per-team, per-run)
17
+ * - turning a kinded error into the activity's exception shape
18
+ *
19
+ * No timeout: Temporal's startToCloseTimeout already bounds the activity.
20
+ * `sandbox.commands.run({ timeoutMs: 0 })` lets the runner consume that
21
+ * full window before the activity times out and Temporal kills the call.
22
+ */
23
+ import type { SandboxProvider } from "../types/sandbox.js";
24
+ import type { StepRequest, StepResult } from "./types.js";
25
+ export { RUNNER_COMMAND } from "./protocol.js";
26
+ /** Build the env map for one step invocation. Pure function; tests use it
27
+ * to assert the env shape (and to assert that no server-held credentials
28
+ * leak in) without spawning a sandbox. */
29
+ export declare function buildStepEnvs(args: {
30
+ runId: string;
31
+ stepIndex: number;
32
+ resultToken: string;
33
+ }): Record<string, string>;
34
+ /** Scan the runner's stdout for the tokenised sentinel line and return a
35
+ * classified result. Returns `null` when no sentinel is present — the
36
+ * caller distinguishes that case from a parsed `{ ok: false }` payload
37
+ * using exit code (see `invokeStep`). Pure function for testability.
38
+ *
39
+ * Failure classification is taken from the runner's `kind` field on the
40
+ * payload (the runner separates setup/protocol failures from handler
41
+ * throws). If `kind` is missing or unknown, treat as `protocol` —
42
+ * that's a malformed payload, which by definition is a wire violation. */
43
+ export declare function parseStepResult<TOutput = unknown>(stdout: string, resultToken: string): StepResult<TOutput> | null;
44
+ /**
45
+ * Run one step inside the given sandbox. The full ceremony is here so the
46
+ * caller body is "reconnect sandbox → invokeStep → narrow result". A
47
+ * stdout line that happens to start with the sentinel prefix but carries
48
+ * a different token is ignored — the per-invocation token guarantees the
49
+ * result channel can't be contaminated by user `console.log` output or
50
+ * by any dep that logs a JSON-shaped line.
51
+ */
52
+ export interface InvokeStepOptions {
53
+ envs?: Record<string, string>;
54
+ /** Live stdout / stderr from the runner subprocess, line-by-line. Called
55
+ * from inside `sandbox.commands.run` as chunks arrive. The sentinel line
56
+ * carrying the protocol result token is filtered out before delivery so
57
+ * callers only see user-visible runtime output.
58
+ *
59
+ * Callbacks are invoked synchronously from the sandbox stream loop — keep
60
+ * them cheap (e.g. push to an in-memory array). Persisting / shipping is
61
+ * the caller's job; the activity batches and inserts at step completion. */
62
+ onStdout?: (line: string) => void;
63
+ onStderr?: (line: string) => void;
64
+ }
65
+ export declare function invokeStep<TOutput = unknown>(sandbox: SandboxProvider, request: StepRequest, opts?: InvokeStepOptions): Promise<StepResult<TOutput>>;
@@ -0,0 +1,44 @@
1
+ /**
2
+ * StepInvocation — wire protocol between server-side activity (the
3
+ * invoker) and runner-side step server. Both halves consume these
4
+ * constants so the format is single-sourced; changing it is one diff.
5
+ *
6
+ * The protocol carries one workflow step's input/output across an OS
7
+ * process boundary (server's Temporal worker process → runner sandbox
8
+ * subprocess). It deliberately does not depend on Temporal — a future
9
+ * Inngest provider can reuse the same wire.
10
+ */
11
+ /** Sentinel that prefixes the step result on the runner's stdout. The
12
+ * invoker scans for `<prefix><token>:<json>` so any user `console.log`
13
+ * with the same prefix but a wrong token is rejected. */
14
+ export declare const STEP_RESULT_PREFIX = "__AC_STEP_RESULT__";
15
+ /** Build the line prefix the runner emits and the invoker scans for. The
16
+ * runner-side serveStep writes `<prefix><token>:<json>\n`; the invoker's
17
+ * result parser AND the stdout line splitter both match on this exact
18
+ * prefix so a future change can't make them drift (review found a
19
+ * separator mismatch that leaked the sentinel into captured logs). */
20
+ export declare function stepResultLinePrefix(token: string): string;
21
+ /** Sandbox-side path where dispatch writes the compiled runner bundle.
22
+ * Both modes (full-mode `dispatch.ts` and step-mode `invokeStep`) spawn
23
+ * the runner from this path; single source of truth. */
24
+ export declare const RUNNER_BUNDLE_PATH = "/tmp/runner.bundle.js";
25
+ /** Command the invoker (and dispatch) spawns inside the sandbox. */
26
+ export declare const RUNNER_COMMAND = "node /tmp/runner.bundle.js";
27
+ /** Names of the env vars the invoker stamps onto the runner subprocess.
28
+ * The runner's serveStep reads from these. Centralising the names lets
29
+ * tests assert the env shape without duplicating string literals. */
30
+ export declare const STEP_ENV: {
31
+ readonly RUN_ID: "RUN_ID";
32
+ readonly STEP_MODE: "AC_STEP_MODE";
33
+ readonly STEP_INDEX: "AC_STEP_INDEX";
34
+ readonly STEP_INPUT_PATH: "AC_STEP_INPUT_PATH";
35
+ readonly REQUEST_CONTEXT_PATH: "AC_REQUEST_CONTEXT_PATH";
36
+ readonly STEP_RESULT_TOKEN: "AC_STEP_RESULT_TOKEN";
37
+ };
38
+ /** Sandbox-side path where the invoker writes the JSON-encoded step input.
39
+ * The serveStep reads from this exact path; both halves use this helper. */
40
+ export declare function stepInputPath(stepIndex: number): string;
41
+ /** Sandbox-side path where the invoker writes the JSON-encoded request
42
+ * context. The serveStep reads from this exact path; both halves use
43
+ * this helper. */
44
+ export declare function requestContextPath(stepIndex: number): string;
@@ -0,0 +1,63 @@
1
+ /**
2
+ * Runner-side half of StepInvocation. The worker's runner.ts in step
3
+ * mode calls `serveStep(handler)` — read the input + request context
4
+ * from env-pointed files, run the user handler, emit the tokenised
5
+ * sentinel result line on stdout, exit with the right code.
6
+ *
7
+ * Owns:
8
+ * - reading inputs from the env-pointed JSON files
9
+ * - parse-error handling (protocol-violating env or malformed file)
10
+ * - tokenised sentinel emission (matched by the invoker's parser)
11
+ * - awaited stdout flush before process.exit (Linux pipes can drop
12
+ * unflushed bytes when the writer exits)
13
+ * - exit codes (0 on success, 1 on any failure)
14
+ *
15
+ * Handler owns:
16
+ * - what to do with the input (load the compiled workflow, run the
17
+ * step, return the output)
18
+ *
19
+ * `serveStep` never returns — it always exits the process. The return
20
+ * type is `Promise<never>` so callers can `await serveStep(...)` and
21
+ * trust nothing runs after.
22
+ */
23
+ import type { RequestContextWire } from "../request-context/request-context.js";
24
+ import type { StepObservability } from "../workflow-steps/observability.js";
25
+ /** What the handler receives. The serveStep already parsed the input
26
+ * and request context from their JSON files. */
27
+ export interface ServeStepRequest<TInput = unknown> {
28
+ runId: string;
29
+ stepIndex: number;
30
+ input: TInput;
31
+ requestContext: RequestContextWire;
32
+ }
33
+ /** What the handler returns. `observability` is the buffered snapshot
34
+ * of `ctx.setMetadata` / `ctx.step` / `ctx.agentEvents` recorded during
35
+ * the step; serveStep forwards it on the wire and the activity persists
36
+ * it. Undefined for handlers that don't use the hooks. */
37
+ export interface StepHandlerResult<TOutput = unknown> {
38
+ output: TOutput;
39
+ observability?: StepObservability;
40
+ }
41
+ /** User handler signature: take parsed step request, return the step
42
+ * output (and optional observability bundle). Throwing turns into
43
+ * `{ ok: false, kind: "user-step", error: <message> }` on the wire. */
44
+ export type StepHandler<TInput = unknown, TOutput = unknown> = (request: ServeStepRequest<TInput>) => Promise<StepHandlerResult<TOutput>>;
45
+ /**
46
+ * Read step input + request context, invoke `handler`, emit the result,
47
+ * exit. `Promise<never>` because every code path ends in `process.exit`.
48
+ *
49
+ * Two distinct phases under separate try/catch:
50
+ * 1. Setup — read envs, parse the input + context files. Failures
51
+ * here mean the wire is broken (server bug); they emit
52
+ * `{ok:false, kind:"protocol"}`.
53
+ * 2. Handler — call the user-supplied step body. Failures here are
54
+ * user code throwing; they emit `{ok:false, kind:"user-step"}`.
55
+ *
56
+ * Between the two phases, step-invocation transport envs are scrubbed
57
+ * from process.env so user code (including any workflow module imported
58
+ * inside the handler) cannot read AC_STEP_RESULT_TOKEN — that keeps the
59
+ * result channel uncorruptible by stdout output from anywhere in the
60
+ * workflow's dep tree. RUN_ID remains available to match full-mode
61
+ * runner behaviour.
62
+ */
63
+ export declare function serveStep<TInput, TOutput>(handler: StepHandler<TInput, TOutput>): Promise<never>;
@@ -0,0 +1,72 @@
1
+ /**
2
+ * StepInvocation public types — what callers (the activity) get back, and
3
+ * the discriminated error union that classifies failure modes.
4
+ */
5
+ import type { RequestContextWire } from "../request-context/request-context.js";
6
+ import type { StepObservability } from "../workflow-steps/observability.js";
7
+ /** What the invoker needs to drive one step invocation. The step's
8
+ * human-readable name is *not* on here — `invokeStep` doesn't need it
9
+ * (the result token isolates the result channel from stdout traffic;
10
+ * run id is enough for message attribution). Callers attach step name
11
+ * to thrown errors at their layer (see `StepExecutionError`). */
12
+ export interface StepRequest<TInput = unknown> {
13
+ runId: string;
14
+ stepIndex: number;
15
+ input: TInput;
16
+ requestContext: RequestContextWire;
17
+ }
18
+ /**
19
+ * Outcome of one step invocation. Successful runs carry the step's output;
20
+ * failed runs carry a kinded error so the caller can distinguish "user
21
+ * code threw" from "runner crashed before emitting" from "wire protocol
22
+ * violation". The dashboard surfaces the kind to operators; the activity
23
+ * uses the kind to pick a useful failRun reason.
24
+ */
25
+ export type StepResult<TOutput = unknown> = {
26
+ ok: true;
27
+ output: TOutput;
28
+ observability?: StepObservability;
29
+ } | {
30
+ ok: false;
31
+ error: StepInvocationError;
32
+ };
33
+ /**
34
+ * Discriminated error union.
35
+ *
36
+ * - `protocol` — the runner did not emit a tokenised sentinel line, OR the
37
+ * sentinel JSON was malformed. This is a runner-side bug or a sandbox
38
+ * provider that swallowed stdout. Surface it loudly; do not blame user
39
+ * code.
40
+ *
41
+ * - `user-step` — the step body threw. The runner caught it and emitted
42
+ * `{ ok: false, error: <user message> }`. The message is the user's
43
+ * to read.
44
+ *
45
+ * - `runner-exit` — the runner subprocess exited non-zero before emitting
46
+ * any sentinel. Out-of-memory, SIGKILL from sandbox lifetime cap,
47
+ * bundler crash, etc. Distinct from `protocol` because exit code is
48
+ * meaningful evidence.
49
+ */
50
+ export type StepInvocationError = {
51
+ kind: "protocol";
52
+ message: string;
53
+ } | {
54
+ kind: "user-step";
55
+ message: string;
56
+ } | {
57
+ kind: "runner-exit";
58
+ message: string;
59
+ exitCode: number;
60
+ };
61
+ /**
62
+ * Error thrown by the activity (or any caller) to surface a step failure
63
+ * with its kind preserved. The Temporal activity boundary serialises
64
+ * `message` to `failRun`, so the message is prefixed with `[<kind>]` —
65
+ * dashboard / log consumers can parse the prefix without losing the
66
+ * structured shape carried on the instance itself.
67
+ */
68
+ export declare class StepExecutionError extends Error {
69
+ readonly kind: StepInvocationError["kind"];
70
+ readonly exitCode: number | undefined;
71
+ constructor(error: StepInvocationError, stepLabel: string);
72
+ }
@@ -0,0 +1,49 @@
1
+ import { z } from "zod";
2
+ import type { SandboxProvider } from "../types/sandbox.js";
3
+ export interface CodingTool<TInput extends Record<string, unknown> = Record<string, unknown>> {
4
+ name: string;
5
+ description: string;
6
+ inputSchema: z.ZodType<TInput>;
7
+ execute(input: TInput, ctx: {
8
+ sandbox: SandboxProvider;
9
+ cwd?: string;
10
+ abortSignal?: AbortSignal;
11
+ }): Promise<string>;
12
+ }
13
+ export declare const readTool: CodingTool<{
14
+ path: string;
15
+ offset?: number;
16
+ limit?: number;
17
+ }>;
18
+ export declare const writeTool: CodingTool<{
19
+ path: string;
20
+ content: string;
21
+ }>;
22
+ export declare const editTool: CodingTool<{
23
+ path: string;
24
+ oldString: string;
25
+ newString: string;
26
+ replaceAll?: boolean;
27
+ }>;
28
+ export declare const bashTool: CodingTool<{
29
+ command: string;
30
+ timeoutMs?: number;
31
+ cwd?: string;
32
+ }>;
33
+ export declare const codingTools: readonly [CodingTool<{
34
+ path: string;
35
+ offset?: number;
36
+ limit?: number;
37
+ }>, CodingTool<{
38
+ path: string;
39
+ content: string;
40
+ }>, CodingTool<{
41
+ path: string;
42
+ oldString: string;
43
+ newString: string;
44
+ replaceAll?: boolean;
45
+ }>, CodingTool<{
46
+ command: string;
47
+ timeoutMs?: number;
48
+ cwd?: string;
49
+ }>];
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,2 @@
1
+ export { bashTool, codingTools, editTool, readTool, writeTool, } from "./coding.js";
2
+ export type { CodingTool } from "./coding.js";
@@ -8,6 +8,42 @@
8
8
  * The `event` field doubles as the SSE `event:` name.
9
9
  */
10
10
  export type RunEvent = {
11
+ event: "agent.spawned";
12
+ runId: string;
13
+ at: number;
14
+ seq?: number;
15
+ agentId: string;
16
+ label: string;
17
+ } | {
18
+ event: "agent.message";
19
+ runId: string;
20
+ at: number;
21
+ seq?: number;
22
+ agentId: string;
23
+ label: string;
24
+ iteration: number;
25
+ message: unknown;
26
+ } | {
27
+ event: "agent.iteration";
28
+ runId: string;
29
+ at: number;
30
+ seq?: number;
31
+ agentId: string;
32
+ label: string;
33
+ iteration: number;
34
+ status: unknown;
35
+ } | {
36
+ event: "agent.settled";
37
+ runId: string;
38
+ at: number;
39
+ seq?: number;
40
+ agentId: string;
41
+ label: string;
42
+ outcome: "success" | "failed";
43
+ iterations: number;
44
+ durationMs: number;
45
+ failureReason?: string;
46
+ } | {
11
47
  event: "agent_event";
12
48
  runId: string;
13
49
  at: number;
@@ -0,0 +1,22 @@
1
+ /** Shared execution context capabilities for workflow functions and steps. */
2
+ import type { InvokeAndWaitOptions, RunStatus } from "../client.js";
3
+ import type { RequestContext } from "../request-context/request-context.js";
4
+ import type { SandboxProvider } from "./sandbox.js";
5
+ /** The identity of this workflow run. */
6
+ export interface WorkflowRun {
7
+ id: string;
8
+ }
9
+ export interface InvokeChild {
10
+ <TOutput = unknown>(name: string, input?: Record<string, unknown>, opts?: Omit<InvokeAndWaitOptions, "parentRunId">): Promise<RunStatus<TOutput>>;
11
+ }
12
+ /** Capabilities shared by legacy workflow ctx and step ctx. */
13
+ export interface BaseExecutionContext {
14
+ run: WorkflowRun;
15
+ requestContext: RequestContext;
16
+ /** Present when the engine executes inside a sandbox-backed workspace. */
17
+ sandbox?: SandboxProvider;
18
+ /** Persist key-value metadata on the run record when the engine supports it. */
19
+ setMetadata?: (data: Record<string, unknown>) => Promise<void>;
20
+ /** Invoke another registered workflow and wait for it to settle. */
21
+ invokeChild: InvokeChild;
22
+ }
@@ -3,6 +3,8 @@
3
3
  */
4
4
  import type { SandboxProvider } from "./sandbox.js";
5
5
  import type { AgentMessage } from "./protocol.js";
6
+ import type { Processor, ProcessorContext, ToolCall } from "../processors/processor.js";
7
+ import type { RequestContext } from "../request-context/request-context.js";
6
8
  /** Configuration for a single MCP server. */
7
9
  export interface McpServerConfig {
8
10
  command: string;
@@ -18,15 +20,45 @@ export interface RuntimeOptions {
18
20
  label?: string;
19
21
  /** Working directory — the claude CLI process starts here so relative paths work correctly. */
20
22
  cwd?: string;
23
+ /** Processor chain registered by workflow/agent code. Runtime adapters that
24
+ * own tool execution should call `processToolCall` before the tool runs. */
25
+ processors?: readonly Processor[];
26
+ /** Per-run typed bag threaded into processor contexts. */
27
+ requestContext?: RequestContext;
28
+ /** Agent id and label for processor context / adapter logs. */
29
+ agentId?: string;
30
+ iteration?: number;
31
+ /** Optional JSON schema for runtimes with native structured-output support. */
32
+ outputFormat?: {
33
+ type: "json_schema";
34
+ schema: Record<string, unknown>;
35
+ };
21
36
  }
37
+ /** Runtime-normalized result of running pre-tool processors. */
38
+ export type ToolCallGateResult = {
39
+ kind: "allow";
40
+ call: ToolCall;
41
+ } | {
42
+ kind: "deny";
43
+ reason: string;
44
+ } | {
45
+ kind: "abort";
46
+ reason: string;
47
+ };
22
48
  /**
23
49
  * The execution contract every runtime must satisfy.
24
50
  * Given a prompt, yield a stream of agent events.
25
51
  */
26
52
  export interface ModelExecutionContract {
53
+ /** True when this runtime can run `processToolCall` before tool execution. */
54
+ supportsToolCallProcessor?: boolean;
55
+ /** Runtime-owned pre-tool gate. Adapters call the shared processor chain
56
+ * through this seam; the agent loop stays SDK-agnostic. */
57
+ gateToolCall?(call: ToolCall, ctx: ProcessorContext): Promise<ToolCallGateResult>;
27
58
  sendMessage(opts: {
28
59
  prompt: string;
29
60
  sessionId?: string;
61
+ iteration?: number;
30
62
  signal?: AbortSignal;
31
63
  }): AsyncGenerator<AgentMessage>;
32
64
  }
@@ -36,7 +36,7 @@
36
36
  * ```
37
37
  */
38
38
  import type { SandboxProvider } from "./sandbox.js";
39
- import type { WorkflowFn } from "./workflow.js";
39
+ import type { Workflow } from "../workflow-steps/types.js";
40
40
  export interface SandboxEnvironmentDefinition {
41
41
  name: string;
42
42
  description?: string;
@@ -46,4 +46,7 @@ export interface SandboxEnvironmentDefinition {
46
46
  * be referenced as the `snapshot` field on another workflow). */
47
47
  saveSnapshot?: boolean;
48
48
  }
49
- export declare function defineSandboxEnvironment(env: SandboxEnvironmentDefinition): WorkflowFn<void>;
49
+ /** Sugar over `defineWorkflow` for setup-only workflows that exist to
50
+ * capture a snapshot. The workflow takes no meaningful input and returns
51
+ * nothing — its value is the side effect on the sandbox VM. */
52
+ export declare function defineSandboxEnvironment(env: SandboxEnvironmentDefinition): Workflow<Record<string, unknown>, void>;
@@ -3,25 +3,27 @@
3
3
  * Provider-agnostic: E2B, Vercel, Docker, or any other backend implements this.
4
4
  */
5
5
  /** Base compute interface — pure I/O, no filesystem path or git concerns. */
6
+ export interface SandboxCommandRunOptions {
7
+ cwd?: string;
8
+ timeoutMs?: number;
9
+ envs?: Record<string, string>;
10
+ onStdout?: (data: string) => void;
11
+ onStderr?: (data: string) => void;
12
+ background?: boolean;
13
+ }
14
+ export interface SandboxCommandResult {
15
+ exitCode: number;
16
+ stdout: string;
17
+ }
6
18
  export interface SandboxProvider {
7
19
  sandboxId: string;
8
20
  /** Working directory for the agent process. Set by onStart after environment setup. */
9
21
  cwd?: string;
10
22
  commands: {
11
- run(cmd: string, opts?: {
12
- cwd?: string;
13
- timeoutMs?: number;
14
- envs?: Record<string, string>;
15
- onStdout?: (data: string) => void;
16
- onStderr?: (data: string) => void;
17
- background?: boolean;
18
- }): Promise<{
19
- exitCode: number;
20
- stdout: string;
21
- }>;
23
+ run(cmd: string, opts?: SandboxCommandRunOptions): Promise<SandboxCommandResult>;
22
24
  };
23
25
  files: {
24
- write(path: string, content: string): Promise<unknown>;
26
+ write(path: string, content: string): Promise<void>;
25
27
  };
26
28
  kill(): Promise<void>;
27
29
  /** Capture the running sandbox's state as a reusable snapshot. Vercel
@@ -0,0 +1,51 @@
1
+ /**
2
+ * `WorkflowMetadata` — server-readable declarations that ride on every
3
+ * `Workflow` as `workflow.metadata`. Owned here (not in `types/workflow.ts`)
4
+ * because both that file and `workflow-steps/workflow.ts` need the type +
5
+ * helper; co-locating them in `types/workflow.ts` introduced a runtime
6
+ * import cycle.
7
+ *
8
+ * Keep this module free of value imports from `types/workflow.ts` or
9
+ * `workflow-steps/workflow.ts` — it is the cycle-break point.
10
+ */
11
+ import type { SandboxNetworkPolicy } from "../sandbox.js";
12
+ import type { Processor } from "../processors/processor.js";
13
+ /**
14
+ * Workflow-level metadata read by the server at registration. Lives on
15
+ * every `Workflow` as `workflow.metadata`, regardless of which form of
16
+ * `defineWorkflow` produced it.
17
+ *
18
+ * The bundler reads these from the default export at registration time
19
+ * and forwards them to the server's POST /api/v1/templates payload.
20
+ */
21
+ /** Server-side knob for whether/how a Workflow Memory agent should run
22
+ * after this workflow completes. `"default"` runs the built-in extractor;
23
+ * `false` disables; an object names a custom memory workflow to dispatch. */
24
+ export type WorkflowMemoryConfig = "default" | false | {
25
+ workflow: string;
26
+ };
27
+ export interface WorkflowMetadata {
28
+ networkPolicy?: SandboxNetworkPolicy;
29
+ placeholders?: Record<string, string>;
30
+ snapshot?: string;
31
+ saveSnapshot?: boolean;
32
+ processors?: readonly Processor[];
33
+ memory?: WorkflowMemoryConfig;
34
+ }
35
+ /**
36
+ * Pull the server-readable declarations off a source object (run-form
37
+ * `WorkflowDefinition` or step-form `StepWorkflowDefinition`) into a
38
+ * single `WorkflowMetadata` bag. Undefined fields are omitted so the
39
+ * canonical metadata hash (server-side) is stable across re-registers
40
+ * that left a field unspecified.
41
+ *
42
+ * Returns a frozen bag — see `freezeMetadataValue` for the depth. The
43
+ * workflow object is meant to be immutable after `defineWorkflow` returns;
44
+ * the bundler reads `metadata` directly and any mutation between
45
+ * construction and bundling would diverge the canonical metadata hash
46
+ * from what the author declared.
47
+ *
48
+ * Accepts any source that overlaps `WorkflowMetadata` in field shape —
49
+ * both definition types are supersets of it.
50
+ */
51
+ export declare function extractMetadata(source: Partial<WorkflowMetadata>): WorkflowMetadata;
@@ -0,0 +1,19 @@
1
+ /**
2
+ * WorkflowPlan — provider-neutral execution shape extracted at registration.
3
+ *
4
+ * The server must not execute user workflow source to discover shape at
5
+ * dispatch time. The CLI/bundler inspects the bundled module in the user's
6
+ * environment and sends this compact plan as metadata.
7
+ *
8
+ * Every workflow has a step plan. Legacy `defineWorkflow({ run })`
9
+ * workflows are wrapped at the SDK boundary as a single-step compiled
10
+ * workflow (step name = "run"); the bundler sees the same shape regardless.
11
+ */
12
+ export interface WorkflowStepPlan {
13
+ index: number;
14
+ name: string;
15
+ }
16
+ export interface WorkflowPlan {
17
+ steps: WorkflowStepPlan[];
18
+ }
19
+ export declare function workflowPlan(steps: WorkflowStepPlan[]): WorkflowPlan;