@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.
- package/README.md +145 -33
- package/dist/agent/agent-loop.d.ts +83 -5
- package/dist/agent/run-agent.d.ts +34 -9
- package/dist/client.d.ts +247 -99
- package/dist/index.d.ts +26 -11
- package/dist/index.js +1968 -746
- package/dist/processors/builtins.d.ts +35 -0
- package/dist/processors/index.d.ts +4 -0
- package/dist/processors/processor.d.ts +91 -0
- package/dist/processors/processor.test.d.ts +1 -0
- package/dist/processors/runner.d.ts +19 -0
- package/dist/request-context/index.d.ts +2 -0
- package/dist/request-context/request-context.d.ts +159 -0
- package/dist/request-context/request-context.test.d.ts +1 -0
- package/dist/runtimes/claude.d.ts +27 -50
- package/dist/runtimes/openai-desktop.js +1919 -742
- package/dist/runtimes/vercel.d.ts +34 -0
- package/dist/runtimes/vercel.js +474 -0
- package/dist/sandbox.d.ts +29 -25
- package/dist/step-invocation/__tests__/invoker.test.d.ts +1 -0
- package/dist/step-invocation/__tests__/protocol.test.d.ts +1 -0
- package/dist/step-invocation/__tests__/server.test.d.ts +1 -0
- package/dist/step-invocation/index.d.ts +25 -0
- package/dist/step-invocation/invoker.d.ts +65 -0
- package/dist/step-invocation/protocol.d.ts +44 -0
- package/dist/step-invocation/server.d.ts +63 -0
- package/dist/step-invocation/types.d.ts +72 -0
- package/dist/tools/coding.d.ts +49 -0
- package/dist/tools/coding.test.d.ts +1 -0
- package/dist/tools/index.d.ts +2 -0
- package/dist/types/events.d.ts +36 -0
- package/dist/types/execution-context.d.ts +22 -0
- package/dist/types/runtime.d.ts +32 -0
- package/dist/types/sandbox-environment.d.ts +5 -2
- package/dist/types/sandbox.d.ts +14 -12
- package/dist/types/workflow-metadata.d.ts +51 -0
- package/dist/types/workflow-plan.d.ts +19 -0
- package/dist/types/workflow.d.ts +57 -17
- package/dist/utils/bundler.d.ts +62 -3
- package/dist/workflow-steps/__tests__/observability.test.d.ts +1 -0
- package/dist/workflow-steps/index.d.ts +10 -0
- package/dist/workflow-steps/observability.d.ts +58 -0
- package/dist/workflow-steps/runner.d.ts +96 -0
- package/dist/workflow-steps/step.d.ts +25 -0
- package/dist/workflow-steps/types.d.ts +135 -0
- package/dist/workflow-steps/workflow-steps.test.d.ts +1 -0
- package/dist/workflow-steps/workflow.d.ts +50 -0
- package/dist/workflows/engine.d.ts +27 -13
- package/dist/workflows/invoke-child.d.ts +10 -0
- package/package.json +25 -15
- package/src/agent/agent-loop.ts +197 -26
- package/src/agent/run-agent.ts +40 -15
- package/src/client.ts +326 -76
- package/src/index.ts +124 -10
- package/src/processors/builtins.ts +72 -0
- package/src/processors/index.ts +15 -0
- package/src/processors/processor.ts +103 -0
- package/src/processors/runner.ts +42 -0
- package/src/request-context/index.ts +17 -0
- package/src/request-context/request-context.ts +302 -0
- package/src/runtimes/claude.ts +123 -254
- package/src/runtimes/vercel.ts +180 -0
- package/src/sandbox.ts +53 -21
- package/src/step-invocation/index.ts +33 -0
- package/src/step-invocation/invoker.ts +204 -0
- package/src/step-invocation/protocol.ts +57 -0
- package/src/step-invocation/server.ts +184 -0
- package/src/step-invocation/types.ts +70 -0
- package/src/tools/coding.ts +126 -0
- package/src/tools/index.ts +8 -0
- package/src/types/events.ts +40 -0
- package/src/types/execution-context.ts +30 -0
- package/src/types/runtime.ts +24 -0
- package/src/types/sandbox-environment.ts +7 -5
- package/src/types/sandbox.ts +16 -12
- package/src/types/workflow-metadata.ts +84 -0
- package/src/types/workflow-plan.ts +24 -0
- package/src/types/workflow.ts +139 -25
- package/src/utils/bundler.ts +213 -19
- package/src/utils/source-loader.ts +2 -2
- package/src/workflow-steps/index.ts +30 -0
- package/src/workflow-steps/observability.ts +103 -0
- package/src/workflow-steps/runner.ts +244 -0
- package/src/workflow-steps/step.ts +38 -0
- package/src/workflow-steps/types.ts +134 -0
- package/src/workflow-steps/workflow.ts +95 -0
- package/src/workflows/engine.ts +69 -40
- 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 {};
|
package/dist/types/events.d.ts
CHANGED
|
@@ -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
|
+
}
|
package/dist/types/runtime.d.ts
CHANGED
|
@@ -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 {
|
|
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
|
-
|
|
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>;
|
package/dist/types/sandbox.d.ts
CHANGED
|
@@ -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<
|
|
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;
|