@agent-compose/sdk 0.1.0

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Layr Labs
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,152 @@
1
+ # @agent-compose/sdk
2
+
3
+ Client library for building against agent-compose. Provides TypeScript types for defining agents, runtimes, and workflows, plus an HTTP client that auto-discovers dependencies and registers everything with a single call.
4
+
5
+ ---
6
+
7
+ ## Installation
8
+
9
+ ```bash
10
+ npm install @agent-compose/sdk
11
+ # peer dep:
12
+ npm install zod
13
+ ```
14
+
15
+ ---
16
+
17
+ ## Defining an Agent
18
+
19
+ ```typescript
20
+ // my-agents/planner.ts
21
+ import { defineAgent } from "@agent-compose/sdk";
22
+
23
+ export default defineAgent({
24
+ name: "planner",
25
+ runtime: "claude", // registered runtime name
26
+ prompt: "Explore the codebase and write a plan...",
27
+ budget: { turnsPerIteration: 70, maxIterations: 1 },
28
+ });
29
+ ```
30
+
31
+ ---
32
+
33
+ ## Defining a Runtime
34
+
35
+ ```typescript
36
+ // my-runtimes/claude.ts
37
+ import { defineRuntime } from "@agent-compose/sdk";
38
+ // ClaudeRunner is provided by the server — import from your server package
39
+ import { ClaudeRunner } from "@agent-compose/server/runtimes/claude.js";
40
+
41
+ export default defineRuntime({
42
+ provider: "claude-code", // must match what createAgentSandbox knows about
43
+ create: (sandbox, opts) => new ClaudeRunner(sandbox, opts),
44
+ });
45
+ ```
46
+
47
+ ---
48
+
49
+ ## Writing a Workflow
50
+
51
+ ```typescript
52
+ // my-workflow.ts
53
+ import type { WorkflowFn } from "@agent-compose/sdk";
54
+
55
+ const myWorkflow: WorkflowFn = async (ctx) => {
56
+ const planner = await ctx.spawnAgent("planner", {
57
+ data: { task: ctx.input.task },
58
+ });
59
+
60
+ await ctx.spawnAgent("implementer", {
61
+ input: planner, // chains branch + response
62
+ data: { task: ctx.input.task },
63
+ });
64
+
65
+ await ctx.setMetadata({ done: true });
66
+ };
67
+
68
+ export default myWorkflow;
69
+ ```
70
+
71
+ ---
72
+
73
+ ## Registration
74
+
75
+ `AgentComposeClient.register()` reads the workflow file, scans for `ctx.spawnAgent("name")` calls, resolves each agent's source file, reads `runtime: "name"` from each agent, resolves runtime sources — then bundles and POSTs everything in one call.
76
+
77
+ ```typescript
78
+ import { AgentComposeClient } from "@agent-compose/sdk";
79
+
80
+ const client = new AgentComposeClient(
81
+ "http://localhost:8080",
82
+ process.env.API_KEY!,
83
+ );
84
+
85
+ // Auto-discovers agents and runtimes from the workflow file
86
+ await client.register({
87
+ name: "my-workflow",
88
+ workflowPath: "./my-workflow.ts",
89
+ // agentPaths and runtimePaths are optional overrides if auto-discovery fails
90
+ });
91
+ ```
92
+
93
+ **Auto-discovery convention** — for agent `"planner"`, the client looks for:
94
+ - `./planner.ts`
95
+ - `./planner/index.ts`
96
+ - `./agents/planner.ts`
97
+ - `./agents/planner/index.ts`
98
+
99
+ For runtime `"claude"`, it looks for:
100
+ - `./claude.ts`
101
+ - `./runtimes/claude.ts`
102
+
103
+ ---
104
+
105
+ ## Invocation
106
+
107
+ ```typescript
108
+ // Invoke a registered workflow (returns immediately with a run ID)
109
+ const { id } = await client.invoke("my-workflow", {
110
+ task: "Add rate limiting to the /projects endpoint",
111
+ });
112
+
113
+ // Poll until done
114
+ let status;
115
+ do {
116
+ await new Promise(r => setTimeout(r, 5000));
117
+ status = await client.getStatus(id);
118
+ } while (status.status === "running");
119
+
120
+ console.log(status.output); // workflow's setMetadata() payload
121
+ ```
122
+
123
+ ---
124
+
125
+ ## Exported Types
126
+
127
+ ```typescript
128
+ // Factory functions
129
+ defineAgent(pkg: AgentDefinition): AgentDefinition
130
+ defineRuntime(pkg: AgentRuntime): AgentRuntime
131
+
132
+ // Workflow authoring
133
+ type WorkflowFn = (ctx: WorkflowCtx) => Promise<void>
134
+ interface WorkflowCtx { spawnAgent, setMetadata, sendMessage, input, run, cost }
135
+
136
+ // Agent types
137
+ interface AgentDefinition { name, runtime, prompt, budget?, tools?, onStart?, onFinish? }
138
+ interface AgentOpts { budget?, data?, input?, branch?, onStart?, onFinish? }
139
+ interface AgentResult<T> { response: T; session: AgentSession }
140
+
141
+ // Runtime types
142
+ interface AgentRuntime<S> { provider: string; create(sandbox: S, opts): ModelExecutionContract }
143
+ interface ModelExecutionContract { sendMessage(opts): AsyncGenerator<AgentMessage> }
144
+
145
+ // Protocol
146
+ interface AgentStatus { summary, completed, blockers, exit_signal }
147
+ type AgentMessage = AgentMessageInit | AgentMessageText | AgentMessageToolUse | ...
148
+
149
+ // Sandbox
150
+ interface SandboxProvider { sandboxId, cwd?, commands, files, kill() }
151
+ interface DesktopSandboxProvider extends SandboxProvider { screenshot(), leftClick(), ... }
152
+ ```
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Agent loop — runner-agnostic iteration driver operating through ModelExecutionContract.
3
+ * Each iteration: build prompt → sendMessage() → parse <status> → done / continue / circuit-break.
4
+ */
5
+ import type { RuntimeOptions, ModelExecutionContract } from "../index.js";
6
+ import { z } from "zod";
7
+ import type { AgentStatus, AgentMessage } from "./protocol.js";
8
+ export declare const DEFAULT_CLAUDE_MODEL = "claude-opus-4-7";
9
+ export declare function parseAgentStatus(text: string): AgentStatus | null;
10
+ export interface AgentLoopResult {
11
+ sessionId: string;
12
+ lastStatus: AgentStatus | null;
13
+ iterations: number;
14
+ response?: unknown;
15
+ }
16
+ export declare function agentLoop(opts: {
17
+ label?: string;
18
+ onIteration?: (iteration: number, status: AgentStatus | null) => void;
19
+ turnsPerIteration?: number;
20
+ maxIterations?: number;
21
+ buildPrompt: (lastStatus: AgentStatus | null, iteration: number) => string;
22
+ onAgentEvent?: (iteration: number, msg: AgentMessage) => void;
23
+ allowedTools?: string[];
24
+ responseSchema?: z.ZodType<unknown>;
25
+ runtime?: (opts: RuntimeOptions) => ModelExecutionContract;
26
+ cwd?: string;
27
+ }): Promise<AgentLoopResult>;
@@ -0,0 +1,7 @@
1
+ import { z } from "zod";
2
+ import { AgentStatusSchema } from "../utils/schemas.js";
3
+ import type { AgentMessage } from "../types/protocol.js";
4
+ export type { AgentMessage, AgentMessageInit, AgentMessageText, AgentMessageThinking, AgentMessageToolUse, AgentMessageToolResult, AgentMessageDone, AgentMessageError, AgentMessageUsage, AgentStatus, } from "../types/protocol.js";
5
+ export { AgentStatusSchema };
6
+ export declare const AgentMessageSchema: z.ZodType<AgentMessage>;
7
+ export declare function parseAgentResponse(text: string): unknown;
@@ -0,0 +1,58 @@
1
+ /**
2
+ * runAgent — canonical entry point for embedding an LLM agent inside a
3
+ * workflow. The workflow's `run()` body calls it; the loop executes
4
+ * against the runner's own VM.
5
+ *
6
+ * Glue packaged so workflows don't duplicate it:
7
+ * - Inject `{{VAR}}` placeholders into the prompt template.
8
+ * - Strip the `--- frontmatter ---` header authors use for IDE hints.
9
+ * - Append PROTOCOL_SUFFIX (status/response format instructions).
10
+ * - Append a response-format appendix when `responseSchema` is set.
11
+ * - Delegate to `agentLoop`.
12
+ */
13
+ import { z } from "zod";
14
+ import type { AgentLoopResult } from "./agent-loop.js";
15
+ import type { AgentMessage, AgentStatus } from "../types/protocol.js";
16
+ import type { AgentRuntime } from "../types/runtime.js";
17
+ import type { SandboxProvider } from "../types/sandbox.js";
18
+ import type { AgentBudget } from "../types/workflow.js";
19
+ export interface RunAgentOpts<T = unknown> {
20
+ /** Sandbox the runtime executes commands against. Inside a workflow,
21
+ * always pass `ctx.sandbox` — a pre-constructed local provider for
22
+ * the runner's own VM. Exposed as a parameter so tests and non-workflow
23
+ * callers can substitute their own. */
24
+ sandbox: SandboxProvider;
25
+ /** Runtime definition from `createClaudeRuntime({...})` (or custom). */
26
+ runtime: AgentRuntime;
27
+ /** Prompt template. Authors can include YAML-style `--- frontmatter ---`
28
+ * at the top for IDE hints; it's stripped before the model sees it. */
29
+ prompt: string;
30
+ /** Substitution map for `{{VAR}}` placeholders in the prompt. `WORKING_DIR`
31
+ * and `DIFF_BASE` auto-populate from `opts.workingDir` unless overridden. */
32
+ promptVars?: Record<string, string>;
33
+ /** `cwd` forwarded to the runtime — every shell command runs here. */
34
+ workingDir?: string;
35
+ /** Tools the model may use. Defaults to a safe kitchen-sink set inside
36
+ * `agentLoop`. Pass [] to disable tool use entirely. */
37
+ tools?: string[];
38
+ /** Turn/iteration caps. Defaults: 40 turns/iteration, 8 iterations. */
39
+ budget?: AgentBudget;
40
+ /** If set, the loop demands a `<response>` block when `exit_signal=true`
41
+ * and validates it against this schema. The response format appendix is
42
+ * appended to the prompt on first iteration. */
43
+ responseSchema?: z.ZodType<T>;
44
+ /** Label prefix for runtime stderr ("[sbid][agent]" by default). */
45
+ label?: string;
46
+ /** Per-message event callback — wire this to your workflow's event
47
+ * telemetry if you want per-tool-call observability. */
48
+ onAgentEvent?: (iteration: number, msg: AgentMessage) => void;
49
+ /** Per-iteration status callback — fires after each model turn with the
50
+ * parsed `<status>` block (or null if the model didn't emit one). */
51
+ onIteration?: (iteration: number, status: AgentStatus | null) => void;
52
+ }
53
+ /**
54
+ * Run an agent loop inside a workflow. Returns the loop's final
55
+ * `AgentLoopResult`, including `response` when a `responseSchema` was
56
+ * supplied and the model validated against it.
57
+ */
58
+ export declare function runAgent<T = unknown>(opts: RunAgentOpts<T>): Promise<AgentLoopResult>;
@@ -0,0 +1,110 @@
1
+ /**
2
+ * AgentComposeClient — HTTP client for the agent-compose server API.
3
+ *
4
+ * register() accepts pre-built sources — use the CLI (agent-compose register)
5
+ * or build sources yourself and pass them directly.
6
+ */
7
+ export interface RegisterResult {
8
+ id: string;
9
+ name: string;
10
+ version: string;
11
+ runtimes?: Array<{
12
+ name: string;
13
+ version: string;
14
+ id: string;
15
+ }>;
16
+ }
17
+ export interface RunStatus {
18
+ id: string;
19
+ status: "running" | "success" | "failed" | "abandoned";
20
+ output?: Record<string, unknown>;
21
+ }
22
+ export interface SnapshotListEntry {
23
+ runId: string;
24
+ workflow: string | null;
25
+ version: string | null;
26
+ vercelSnapshotId: string;
27
+ endedAt: string | null;
28
+ }
29
+ export declare class AgentComposeClient {
30
+ private readonly fetch;
31
+ constructor(baseUrl: string, apiKey: string);
32
+ /** Register a workflow with pre-built sources. */
33
+ register(payload: {
34
+ name: string;
35
+ source: string;
36
+ version?: string;
37
+ schedule?: string;
38
+ runtimes?: Array<{
39
+ name: string;
40
+ source: string;
41
+ }>;
42
+ networkPolicy?: unknown;
43
+ placeholders?: Record<string, string>;
44
+ /** Name (or `name@version`) of another workflow whose snapshot this
45
+ * workflow's runner boots from. Must reference a workflow previously
46
+ * registered with `--build`. */
47
+ sandboxEnvironment?: string;
48
+ /** If true, runs default to capturing a long-lived sandbox snapshot on
49
+ * success. Individual invocations can override via `invoke(..., { snapshot })`. */
50
+ snapshot?: boolean;
51
+ }): Promise<RegisterResult>;
52
+ /** Invoke a workflow. Returns run ID immediately — workflow runs asynchronously.
53
+ *
54
+ * `snapshot`: `true` overrides the workflow default; `false` opts out. When
55
+ * the run captures a snapshot, its id is stamped on the row and can be
56
+ * referenced as `sandboxEnvironment` by other workflows.
57
+ *
58
+ * `parentRunId`: links the new run to another of the same account's
59
+ * currently-running runs. When omitted, the client auto-detects from
60
+ * `process.env.RUN_ID` — set by the runner sandbox on every dispatch,
61
+ * so workflows invoking other workflows get the parent/child tree for
62
+ * free. Pass `null` to suppress auto-detection (e.g. invoking a top-level
63
+ * sibling workflow from inside a runner for a reason unrelated to the
64
+ * current run). Explicit non-null wins over auto-detection. */
65
+ invoke(name: string, input?: Record<string, unknown>, opts?: {
66
+ snapshot?: boolean;
67
+ parentRunId?: string | null;
68
+ }): Promise<{
69
+ id: string;
70
+ }>;
71
+ /** Invoke a workflow and wait for it to settle (success / failed / abandoned).
72
+ * Polls `getStatus` on a fixed interval. Rejects with `AgentComposeError`
73
+ * if the run settles non-success, or a plain `Error` on timeout.
74
+ *
75
+ * Defaults: `timeoutMs = 30min`, `pollIntervalMs = 1000ms`. Tune down for
76
+ * tests, tune up for long-running workflows. The parent-child auto-
77
+ * detection from `invoke()` applies here too. */
78
+ invokeAndWait(name: string, input?: Record<string, unknown>, opts?: {
79
+ snapshot?: boolean;
80
+ parentRunId?: string | null;
81
+ timeoutMs?: number;
82
+ pollIntervalMs?: number;
83
+ }): Promise<RunStatus>;
84
+ /** List runs this account has captured snapshots for. */
85
+ listSnapshots(opts?: {
86
+ workflow?: string;
87
+ limit?: number;
88
+ }): Promise<SnapshotListEntry[]>;
89
+ /** Delete the snapshot captured by a specific run. Frees Vercel storage. */
90
+ deleteSnapshot(runId: string): Promise<void>;
91
+ /** Poll run status. */
92
+ getStatus(runId: string): Promise<RunStatus>;
93
+ /** List registered workflow templates. */
94
+ listTemplates(): Promise<Array<{
95
+ name: string;
96
+ version: string;
97
+ }>>;
98
+ /** Create or update a workflow secret. Value is stored in GCP Secret Manager. */
99
+ setSecret(workflowName: string, key: string, value: string): Promise<{
100
+ key: string;
101
+ }>;
102
+ /** List secret keys registered for a workflow (metadata only — values are never returned). */
103
+ listSecrets(workflowName: string): Promise<Array<{
104
+ key: string;
105
+ createdAt: string;
106
+ updatedAt: string;
107
+ }>>;
108
+ /** Delete a workflow secret. */
109
+ deleteSecret(workflowName: string, key: string): Promise<void>;
110
+ }
@@ -0,0 +1,5 @@
1
+ /** Thrown by AgentComposeClient when the server returns a non-2xx response. */
2
+ export declare class AgentComposeError extends Error {
3
+ readonly status: number;
4
+ constructor(status: number, message: string);
5
+ }
@@ -0,0 +1,43 @@
1
+ /**
2
+ * @agent-compose/sdk
3
+ *
4
+ * Tools for defining runtimes and workflows, registering/invoking them
5
+ * against an agent-compose server, and running LLM agent loops inside a
6
+ * workflow via `runAgent(opts)`.
7
+ *
8
+ * @example
9
+ * ```typescript
10
+ * import { defineWorkflow, runAgent, AgentComposeClient } from "@agent-compose/sdk";
11
+ * ```
12
+ */
13
+ export { defineRuntime } from "./types/runtime.js";
14
+ export { defineWorkflow } from "./types/workflow.js";
15
+ export type { WorkflowDefinition } from "./types/workflow.js";
16
+ export { defineSandboxEnvironment } from "./types/sandbox-environment.js";
17
+ export type { SandboxEnvironmentDefinition } from "./types/sandbox-environment.js";
18
+ export type { AgentRuntime, McpServerConfig, ModelExecutionContract, RuntimeOptions, } from "./types/runtime.js";
19
+ export type { WorkflowFn, WorkflowCtx, WorkflowRun, AgentBudget, WorkflowHooks, } from "./types/workflow.js";
20
+ export type { AgentMessage, AgentMessageInit, AgentMessageText, AgentMessageThinking, AgentMessageToolUse, AgentMessageToolResult, AgentMessageDone, AgentMessageError, AgentMessageUsage, AgentStatus, } from "./types/protocol.js";
21
+ export type { SandboxProvider, DesktopSandboxProvider, } from "./types/sandbox.js";
22
+ export { AgentComposeClient } from "./client.js";
23
+ export type { RegisterResult, RunStatus } from "./client.js";
24
+ export { AgentComposeError } from "./errors.js";
25
+ export { formatError } from "./utils/errors.js";
26
+ export { discoverRuntimeName } from "./utils/discovery.js";
27
+ export { bundleWorkflow } from "./utils/bundler.js";
28
+ export type { BundledWorkflow } from "./utils/bundler.js";
29
+ export { AgentStatusSchema } from "./utils/schemas.js";
30
+ export { createClaudeRuntime, ClaudeRunner } from "./runtimes/claude.js";
31
+ export type { ClaudeRuntimeConfig } from "./runtimes/claude.js";
32
+ export { default as claudeRuntime } from "./runtimes/claude.js";
33
+ export type { RunEvent } from "./types/events.js";
34
+ export { createSandbox, reconnectSandbox, killAllSandboxes, killSandboxById, getSandboxQuotas, listOwnedSandboxes, deleteSandboxSnapshot, makeSandboxProvider, makeDesktopSandboxProvider, parseSseExecStream, AGENT_COMPOSE_TAG } from "./sandbox.js";
35
+ export type { SandboxCreateOpts, SandboxNetworkPolicy, OwnedSandbox } from "./sandbox.js";
36
+ export { runWorkflow, WorkflowError, EngineError, classifyError, parseNameVersion } from "./workflows/engine.js";
37
+ export type { WorkflowResult, EngineSubsystem } from "./workflows/engine.js";
38
+ export { agentLoop, parseAgentStatus, DEFAULT_CLAUDE_MODEL } from "./agent/agent-loop.js";
39
+ export type { AgentLoopResult } from "./agent/agent-loop.js";
40
+ export { runAgent } from "./agent/run-agent.js";
41
+ export type { RunAgentOpts } from "./agent/run-agent.js";
42
+ export { AgentMessageSchema, parseAgentResponse } from "./agent/protocol.js";
43
+ export { importSourceModule, TMP_DIR, LATEST_VERSION } from "./utils/source-loader.js";