@agent-compose/sdk 0.2.5 → 0.3.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/README.md +31 -19
- package/dist/client.d.ts +83 -26
- package/dist/index.d.ts +3 -2
- package/dist/index.js +88 -17
- package/dist/runtimes/openai-desktop.js +88 -17
- package/dist/types/sandbox-environment.d.ts +23 -14
- package/dist/types/sandbox.d.ts +6 -1
- package/dist/types/workflow-metadata.d.ts +72 -8
- package/dist/types/workflow.d.ts +23 -19
- package/dist/utils/bundler.d.ts +12 -7
- package/dist/workflow-steps/workflow.d.ts +4 -2
- package/package.json +1 -1
- package/src/client.ts +124 -30
- package/src/index.ts +9 -1
- package/src/sandbox.ts +5 -1
- package/src/types/sandbox-environment.ts +25 -15
- package/src/types/sandbox.ts +6 -2
- package/src/types/workflow-metadata.ts +77 -12
- package/src/types/workflow.ts +23 -19
- package/src/utils/bundler.ts +77 -10
- package/src/workflow-steps/workflow.ts +4 -2
- package/src/workflows/invoke-child.ts +1 -1
|
@@ -1,16 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* A sandbox environment is a workflow whose job is to leave its VM in a
|
|
3
3
|
* configured state, then snapshot it so other workflows can boot from that
|
|
4
|
-
* state. Capture is **opt-in**: the wrapper below sets
|
|
5
|
-
* by default (opt out with
|
|
6
|
-
* effects).
|
|
4
|
+
* state. Capture is **opt-in**: the wrapper below sets
|
|
5
|
+
* `snapshots: { saveLatest: true }` by default (opt out with
|
|
6
|
+
* `saveLatest: false` if you only want side effects).
|
|
7
7
|
*
|
|
8
|
-
* Once captured, reference the snapshot from another workflow's
|
|
9
|
-
* field by
|
|
8
|
+
* Once captured, reference the snapshot from another workflow's
|
|
9
|
+
* `snapshots.bootFrom` field by provider snapshot id:
|
|
10
10
|
*
|
|
11
|
-
*
|
|
12
|
-
* snapshot: "my-setup@v1" // version-scoped recency
|
|
13
|
-
* snapshot: "<run-uuid>" // pinned to an exact run
|
|
11
|
+
* snapshots: { bootFrom: { snapshotId: "snap_..." } }
|
|
14
12
|
*
|
|
15
13
|
* `defineSandboxEnvironment` is sugar over `defineWorkflow` — it makes the
|
|
16
14
|
* setup recipe read like an imperative script by supplying the local
|
|
@@ -20,7 +18,7 @@
|
|
|
20
18
|
* 1. Author a setup file with `defineSandboxEnvironment`.
|
|
21
19
|
* 2. `agentc register setup.ts --build` — registers and invokes once to
|
|
22
20
|
* capture the snapshot.
|
|
23
|
-
* 3. Other workflows declare `
|
|
21
|
+
* 3. Other workflows declare `snapshots: { bootFrom: { snapshotId } }`.
|
|
24
22
|
* 4. `agentc snapshot list` / `delete` to manage the Vercel storage bill.
|
|
25
23
|
*
|
|
26
24
|
* @example
|
|
@@ -37,16 +35,27 @@
|
|
|
37
35
|
*/
|
|
38
36
|
import type { SandboxProvider } from "./sandbox.js";
|
|
39
37
|
import type { Workflow } from "../workflow-steps/types.js";
|
|
38
|
+
import type { SnapshotConfig } from "./workflow-metadata.js";
|
|
40
39
|
export interface SandboxEnvironmentDefinition {
|
|
41
40
|
name: string;
|
|
42
41
|
description?: string;
|
|
43
42
|
setup: (sb: SandboxProvider) => Promise<void>;
|
|
44
|
-
/** Override the sugar's `
|
|
45
|
-
* out of snapshot capture (rarely
|
|
46
|
-
*
|
|
47
|
-
|
|
43
|
+
/** Override the sugar's `{ saveLatest: true }` default. Set
|
|
44
|
+
* `{ saveLatest: false }` to opt out of snapshot capture (rarely
|
|
45
|
+
* useful — an env with no snapshot can't be referenced as a
|
|
46
|
+
* `bootFrom` on another workflow). */
|
|
47
|
+
snapshots?: SnapshotConfig;
|
|
48
|
+
/** Override the sugar's `memory: false` default. Setup workflows
|
|
49
|
+
* don't typically benefit from memory extraction; opt in explicitly
|
|
50
|
+
* when they do. */
|
|
51
|
+
memory?: boolean;
|
|
48
52
|
}
|
|
49
53
|
/** Sugar over `defineWorkflow` for setup-only workflows that exist to
|
|
50
54
|
* capture a snapshot. The workflow takes no meaningful input and returns
|
|
51
|
-
* nothing — its value is the side effect on the sandbox VM.
|
|
55
|
+
* nothing — its value is the side effect on the sandbox VM.
|
|
56
|
+
*
|
|
57
|
+
* Defaults `memory: false` because sandbox environments emit setup
|
|
58
|
+
* output (npm installs, command exit codes) rather than agent traces
|
|
59
|
+
* worth memorising. Authors can opt in explicitly via `env.memory:
|
|
60
|
+
* true` if their environment somehow does want extraction. */
|
|
52
61
|
export declare function defineSandboxEnvironment(env: SandboxEnvironmentDefinition): Workflow<Record<string, unknown>, void>;
|
package/dist/types/sandbox.d.ts
CHANGED
|
@@ -29,9 +29,14 @@ export interface SandboxProvider {
|
|
|
29
29
|
/** Capture the running sandbox's state as a reusable snapshot. Vercel
|
|
30
30
|
* supports it natively; E2B's model is Dockerfile-based and doesn't map
|
|
31
31
|
* cleanly — `undefined` on providers that don't. Used by the server's
|
|
32
|
-
* `--build` flow to stamp the snapshot id on the workflow row.
|
|
32
|
+
* `--build` flow to stamp the snapshot id on the workflow row.
|
|
33
|
+
*
|
|
34
|
+
* `sizeBytes` is the on-disk footprint reported by the provider. May
|
|
35
|
+
* be omitted when the provider doesn't expose it; the server stores
|
|
36
|
+
* `null` for missing values rather than estimating. */
|
|
33
37
|
snapshot?(): Promise<{
|
|
34
38
|
snapshotId: string;
|
|
39
|
+
sizeBytes?: number;
|
|
35
40
|
}>;
|
|
36
41
|
}
|
|
37
42
|
/** Stateless provider-level snapshot deletion — no live sandbox needed,
|
|
@@ -18,19 +18,83 @@ import type { Processor } from "../processors/processor.js";
|
|
|
18
18
|
* The bundler reads these from the default export at registration time
|
|
19
19
|
* and forwards them to the server's POST /api/v1/templates payload.
|
|
20
20
|
*/
|
|
21
|
-
/**
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
export type WorkflowMemoryConfig =
|
|
25
|
-
|
|
21
|
+
/** Whether the built-in Workflow Memory extractor should run after this
|
|
22
|
+
* workflow completes. Boolean toggle — custom post-run workflows live
|
|
23
|
+
* in the separate `postRunHooks` array on `WorkflowMetadata`. */
|
|
24
|
+
export type WorkflowMemoryConfig = boolean;
|
|
25
|
+
/** Where a run boots from. The snapshot id is the unit of identity —
|
|
26
|
+
* each captured snapshot already records the workflow + version it
|
|
27
|
+
* came from on the snapshot row, so there's no separate "latest of
|
|
28
|
+
* workflow X" resolution at dispatch time. Operators pick a snapshot
|
|
29
|
+
* from the dashboard snapshot list (or `agentc snapshot list`) and
|
|
30
|
+
* paste the id here.
|
|
31
|
+
*
|
|
32
|
+
* Omit `bootFrom` entirely to boot a fresh base sandbox. */
|
|
33
|
+
export type BootSnapshot = {
|
|
34
|
+
snapshotId: string;
|
|
26
35
|
};
|
|
36
|
+
/** Snapshot configuration — boot source plus capture knobs. One object
|
|
37
|
+
* per workflow / per invocation; collapsing boot + capture under a
|
|
38
|
+
* single key reads as "all snapshot config lives here." */
|
|
39
|
+
export interface SnapshotConfig {
|
|
40
|
+
/** Where the runner restores from at run start. Structured (workflow
|
|
41
|
+
* ref or snapshot id) so the intent is explicit at the call site. */
|
|
42
|
+
bootFrom?: BootSnapshot;
|
|
43
|
+
/** Capture the sandbox state on terminal success. The latest pointer
|
|
44
|
+
* on `workflow_runs.vercel_snapshot_id` always tracks the most
|
|
45
|
+
* recent capture; without `retainSteps`, prior captures are deleted
|
|
46
|
+
* as new ones land — constant storage cost. */
|
|
47
|
+
saveLatest?: boolean;
|
|
48
|
+
/** Only meaningful with `saveLatest: true`. Retain every step's
|
|
49
|
+
* snapshot in `run_step_snapshots` so a future dispatch can boot
|
|
50
|
+
* from a specific step's checkpoint via its `snapshotId`. Cost
|
|
51
|
+
* scales linearly with step count. */
|
|
52
|
+
retainSteps?: boolean;
|
|
53
|
+
}
|
|
54
|
+
/** JSON-Schema-shaped description captured by the bundler from a
|
|
55
|
+
* workflow's `input` or `output` zod schema. Carried in template
|
|
56
|
+
* metadata so the dashboard can render typed input forms + output
|
|
57
|
+
* type tables. */
|
|
58
|
+
export interface IOSchema {
|
|
59
|
+
/** JSON Schema `type` keyword, when single-valued. Omitted for unions / unknowns. */
|
|
60
|
+
type?: string | string[];
|
|
61
|
+
/** Free-form description pulled from `.describe(...)` on the root. */
|
|
62
|
+
description?: string;
|
|
63
|
+
/** Object-shape: one entry per property. */
|
|
64
|
+
properties?: Record<string, {
|
|
65
|
+
type?: string | string[];
|
|
66
|
+
description?: string;
|
|
67
|
+
}>;
|
|
68
|
+
/** Required property names — relevant only when `type === "object"`. */
|
|
69
|
+
required?: string[];
|
|
70
|
+
}
|
|
71
|
+
/** Alias kept for backwards source-compatibility with the original
|
|
72
|
+
* output-only release. New code should prefer `IOSchema`. */
|
|
73
|
+
export type OutputSchema = IOSchema;
|
|
27
74
|
export interface WorkflowMetadata {
|
|
28
75
|
networkPolicy?: SandboxNetworkPolicy;
|
|
29
76
|
placeholders?: Record<string, string>;
|
|
30
|
-
|
|
31
|
-
|
|
77
|
+
/** Input schema captured at bundle time from the workflow's
|
|
78
|
+
* declared `input` zod schema. Step-form workflows populate this
|
|
79
|
+
* automatically; run-form workflows (no explicit input schema —
|
|
80
|
+
* defaults to `z.unknown()`) leave it undefined. */
|
|
81
|
+
inputSchema?: IOSchema;
|
|
82
|
+
/** Output schema captured at bundle time from the workflow's
|
|
83
|
+
* declared `output` zod schema. Step-form workflows populate this
|
|
84
|
+
* automatically; run-form workflows whose `run()` returns
|
|
85
|
+
* arbitrarily-typed values leave it undefined. */
|
|
86
|
+
outputSchema?: IOSchema;
|
|
87
|
+
/** All snapshot config — boot source + capture mode. */
|
|
88
|
+
snapshots?: SnapshotConfig;
|
|
32
89
|
processors?: readonly Processor[];
|
|
33
|
-
memory
|
|
90
|
+
/** Run the built-in memory extractor after this workflow completes.
|
|
91
|
+
* Opt-in; defaults to false when omitted. */
|
|
92
|
+
memory?: boolean;
|
|
93
|
+
/** Ordered list of workflow names that run after this workflow
|
|
94
|
+
* completes. The runtime dispatches them in declaration order; the
|
|
95
|
+
* built-in memory extractor (when `memory: true`) runs as a separate
|
|
96
|
+
* hook alongside whatever's declared here. */
|
|
97
|
+
postRunHooks?: readonly string[];
|
|
34
98
|
}
|
|
35
99
|
/**
|
|
36
100
|
* Pull the server-readable declarations off a source object (run-form
|
package/dist/types/workflow.d.ts
CHANGED
|
@@ -25,8 +25,8 @@ export type { WorkflowMetadata } from "./workflow-metadata.js";
|
|
|
25
25
|
export interface AgentEventSink {
|
|
26
26
|
emit(event: AgentLifecycleEvent): void | Promise<void>;
|
|
27
27
|
}
|
|
28
|
-
import type { WorkflowMemoryConfig } from "./workflow-metadata.js";
|
|
29
|
-
export type { WorkflowMemoryConfig };
|
|
28
|
+
import type { WorkflowMemoryConfig, SnapshotConfig, BootSnapshot, IOSchema, OutputSchema } from "./workflow-metadata.js";
|
|
29
|
+
export type { WorkflowMemoryConfig, SnapshotConfig, BootSnapshot, IOSchema, OutputSchema };
|
|
30
30
|
/** Turn/iteration budget for `agent(opts)`. Re-exported here so authors
|
|
31
31
|
* can type per-invoke budget overrides they pass as workflow input. */
|
|
32
32
|
export interface AgentBudget {
|
|
@@ -69,21 +69,21 @@ export type WorkflowFn<TOutput = unknown, TInput extends Record<string, unknown>
|
|
|
69
69
|
export interface WorkflowDefinition<TOutput = unknown, TInput extends Record<string, unknown> = Record<string, unknown>> {
|
|
70
70
|
run: WorkflowFn<TOutput, TInput>;
|
|
71
71
|
/**
|
|
72
|
-
*
|
|
73
|
-
*
|
|
74
|
-
*
|
|
75
|
-
*
|
|
76
|
-
*
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
*
|
|
81
|
-
*
|
|
82
|
-
*
|
|
83
|
-
* `
|
|
84
|
-
* `
|
|
72
|
+
* All snapshot config — boot source plus capture mode.
|
|
73
|
+
*
|
|
74
|
+
* `snapshots.bootFrom`: the runner restores from this exact provider
|
|
75
|
+
* snapshot id at run start. Omit to boot a fresh sandbox.
|
|
76
|
+
*
|
|
77
|
+
* `snapshots.saveLatest`: `true` captures one snapshot after each
|
|
78
|
+
* successful step (latest-only — prior is freed).
|
|
79
|
+
* `{ saveLatest: true, retainSteps: true }` keeps every step's
|
|
80
|
+
* snapshot for fork / replay / time-travel.
|
|
81
|
+
*
|
|
82
|
+
* Snapshots are long-lived (never auto-expire). List + delete via
|
|
83
|
+
* `agentc snapshot list/delete`. Per-invocation
|
|
84
|
+
* `invoke({ snapshots })` overrides this default.
|
|
85
85
|
*/
|
|
86
|
-
|
|
86
|
+
snapshots?: SnapshotConfig;
|
|
87
87
|
/**
|
|
88
88
|
* Outbound network policy for the runner sandbox.
|
|
89
89
|
* Use "*": [] to allow all traffic while still injecting headers for specific domains.
|
|
@@ -120,10 +120,14 @@ export interface WorkflowDefinition<TOutput = unknown, TInput extends Record<str
|
|
|
120
120
|
* }
|
|
121
121
|
*/
|
|
122
122
|
placeholders?: Record<string, string>;
|
|
123
|
-
/**
|
|
124
|
-
*
|
|
125
|
-
* custom memory workflow once custom extractors are supported. */
|
|
123
|
+
/** Run the built-in memory extractor after this workflow completes.
|
|
124
|
+
* Opt-in; defaults to false when omitted. */
|
|
126
125
|
memory?: WorkflowMemoryConfig;
|
|
126
|
+
/** Ordered list of workflow names to dispatch as post-hooks after
|
|
127
|
+
* this workflow completes. Each hook receives the source run's
|
|
128
|
+
* context. The memory extractor (when `memory: true`) runs as an
|
|
129
|
+
* additional hook alongside these. */
|
|
130
|
+
postRunHooks?: readonly string[];
|
|
127
131
|
}
|
|
128
132
|
/**
|
|
129
133
|
* Declare a workflow. Two forms; both return a `Workflow` whose
|
package/dist/utils/bundler.d.ts
CHANGED
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
* this function returns alongside the bundled bytes, and cross-checks the
|
|
20
20
|
* manifest's `sourceHash` against the source it received.
|
|
21
21
|
*/
|
|
22
|
-
import type { WorkflowMemoryConfig } from "../types/workflow.js";
|
|
22
|
+
import type { WorkflowMemoryConfig, SnapshotConfig } from "../types/workflow.js";
|
|
23
23
|
import type { SandboxNetworkPolicy } from "../sandbox.js";
|
|
24
24
|
import { type WorkflowPlan } from "../types/workflow-plan.js";
|
|
25
25
|
/** Bumped when the manifest contract changes in a way the server should
|
|
@@ -51,15 +51,20 @@ export interface BundledWorkflow {
|
|
|
51
51
|
manifest: WorkflowManifest;
|
|
52
52
|
networkPolicy?: SandboxNetworkPolicy;
|
|
53
53
|
placeholders?: Record<string, string>;
|
|
54
|
-
/**
|
|
55
|
-
*
|
|
56
|
-
|
|
57
|
-
snapshot?: string;
|
|
58
|
-
/** Default capture-on-success flag from the workflow definition. */
|
|
59
|
-
saveSnapshot?: boolean;
|
|
54
|
+
/** Snapshot config from the workflow definition — `bootFrom` (where to
|
|
55
|
+
* restore at run start), `save`, `retain`. */
|
|
56
|
+
snapshots?: SnapshotConfig;
|
|
60
57
|
workflowPlan: WorkflowPlan;
|
|
61
58
|
/** Workflow Memory extractor config. */
|
|
62
59
|
memory?: WorkflowMemoryConfig;
|
|
60
|
+
/** Ordered post-hook workflow names declared on the workflow. */
|
|
61
|
+
postRunHooks?: readonly string[];
|
|
62
|
+
/** Compact JSON-Schema-shaped description of the workflow's input
|
|
63
|
+
* type. Extracted from the workflow's declared `input` zod schema
|
|
64
|
+
* at bundle time; undefined when the schema is `z.unknown()`. */
|
|
65
|
+
inputSchema?: import("../types/workflow-metadata.js").IOSchema;
|
|
66
|
+
/** Same for the workflow's output zod schema. */
|
|
67
|
+
outputSchema?: import("../types/workflow-metadata.js").IOSchema;
|
|
63
68
|
}
|
|
64
69
|
/**
|
|
65
70
|
* Parse the bundled source and assert the default export is a CallExpression
|
|
@@ -20,6 +20,7 @@
|
|
|
20
20
|
*/
|
|
21
21
|
import type { z } from "zod";
|
|
22
22
|
import type { Step, Workflow } from "./types.js";
|
|
23
|
+
import type { SnapshotConfig, WorkflowMemoryConfig } from "../types/workflow-metadata.js";
|
|
23
24
|
import type { SandboxNetworkPolicy } from "../sandbox.js";
|
|
24
25
|
import type { Processor } from "../processors/processor.js";
|
|
25
26
|
export interface WorkflowBuilder<TInput, TCurrent> {
|
|
@@ -41,8 +42,9 @@ export interface StepWorkflowDefinition<TInput, TOutput> {
|
|
|
41
42
|
output: z.ZodType<TOutput>;
|
|
42
43
|
networkPolicy?: SandboxNetworkPolicy;
|
|
43
44
|
placeholders?: Record<string, string>;
|
|
44
|
-
|
|
45
|
-
|
|
45
|
+
snapshots?: SnapshotConfig;
|
|
46
|
+
memory?: WorkflowMemoryConfig;
|
|
47
|
+
postRunHooks?: readonly string[];
|
|
46
48
|
processors?: readonly Processor[];
|
|
47
49
|
}
|
|
48
50
|
export declare function createStepWorkflow<TInput, TOutput>(opts: StepWorkflowDefinition<TInput, TOutput>): WorkflowBuilder<TInput, TInput>;
|
package/package.json
CHANGED
package/src/client.ts
CHANGED
|
@@ -17,6 +17,7 @@ import { parseSseStream } from "./sse.js";
|
|
|
17
17
|
import type { SandboxNetworkPolicy } from "./sandbox.js";
|
|
18
18
|
import type { RunEvent } from "./types/events.js";
|
|
19
19
|
import type { WorkflowPlan } from "./types/workflow-plan.js";
|
|
20
|
+
import type { SnapshotConfig, IOSchema } from "./types/workflow-metadata.js";
|
|
20
21
|
import type { WorkflowManifest } from "./utils/bundler.js";
|
|
21
22
|
|
|
22
23
|
/** UUID-v4-ish — matches the server-side predicate. Used to auto-detect
|
|
@@ -51,6 +52,13 @@ export interface RegisterResult {
|
|
|
51
52
|
name: string;
|
|
52
53
|
version: string;
|
|
53
54
|
runtimes?: RegisteredRuntime[];
|
|
55
|
+
/** Non-fatal advisories from the server. Surfaced at register time so the
|
|
56
|
+
* operator sees them while still in front of the terminal — currently
|
|
57
|
+
* covers "memory extraction is configured but its workflow is not
|
|
58
|
+
* registered in this factory". Empty/undefined when registration was
|
|
59
|
+
* cleanly resolved against everything the workflow declares it
|
|
60
|
+
* depends on. */
|
|
61
|
+
warnings?: string[];
|
|
54
62
|
}
|
|
55
63
|
|
|
56
64
|
export interface RegisteredRuntime {
|
|
@@ -79,14 +87,22 @@ export interface RegisterWorkflowInput {
|
|
|
79
87
|
runtimes?: RuntimeSourceInput[];
|
|
80
88
|
networkPolicy?: unknown;
|
|
81
89
|
placeholders?: Record<string, string>;
|
|
82
|
-
/**
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
saveSnapshot?: boolean;
|
|
90
|
+
/** All snapshot config — `bootFrom` (where to restore at run start),
|
|
91
|
+
* `save`, `retain`. See `WorkflowMetadata.snapshots`. */
|
|
92
|
+
snapshots?: SnapshotConfig;
|
|
86
93
|
/** Provider-neutral execution plan detected by the CLI bundler. */
|
|
87
94
|
workflowPlan?: WorkflowPlan;
|
|
88
|
-
/**
|
|
89
|
-
|
|
95
|
+
/** Run the built-in memory extractor after this workflow completes.
|
|
96
|
+
* Opt-in; defaults to false when omitted. */
|
|
97
|
+
memory?: boolean;
|
|
98
|
+
/** Ordered list of workflow names that run as post-hooks after this
|
|
99
|
+
* workflow completes. The memory extractor (when `memory: true`)
|
|
100
|
+
* runs as an additional hook alongside these. */
|
|
101
|
+
postRunHooks?: readonly string[];
|
|
102
|
+
/** Input schema extracted from the workflow's `input` zod schema. */
|
|
103
|
+
inputSchema?: IOSchema;
|
|
104
|
+
/** Output schema extracted from the workflow's `output` zod schema. */
|
|
105
|
+
outputSchema?: IOSchema;
|
|
90
106
|
/** Factory slug. Defaults to `"default"`. */
|
|
91
107
|
factorySlug?: string;
|
|
92
108
|
}
|
|
@@ -94,10 +110,11 @@ export interface RegisterWorkflowInput {
|
|
|
94
110
|
export type RunState = "running" | "success" | "failed" | "abandoned" | "canceled";
|
|
95
111
|
|
|
96
112
|
export interface InvokeWorkflowOptions {
|
|
97
|
-
/** Per-invocation snapshot override
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
113
|
+
/** Per-invocation snapshot config override. `snapshots.bootFrom`
|
|
114
|
+
* replaces the template's boot source; `snapshots.saveLatest` and
|
|
115
|
+
* `snapshots.retainSteps` override capture mode. Anything omitted
|
|
116
|
+
* falls back to the template's registered default. */
|
|
117
|
+
snapshots?: SnapshotConfig;
|
|
101
118
|
/** Per-invocation network policy override. Replaces the template-level
|
|
102
119
|
* policy for this run only — registered metadata is not mutated. */
|
|
103
120
|
networkPolicy?: SandboxNetworkPolicy;
|
|
@@ -106,6 +123,13 @@ export interface InvokeWorkflowOptions {
|
|
|
106
123
|
* vars after brokering. Replaces the template-level placeholders for
|
|
107
124
|
* this run only — registered metadata is not mutated. */
|
|
108
125
|
placeholders?: Record<string, string>;
|
|
126
|
+
/** Per-invocation memory-extractor override — `false` skips the
|
|
127
|
+
* built-in memory hook for this run; omitting leaves the registered
|
|
128
|
+
* default in place. */
|
|
129
|
+
memory?: boolean;
|
|
130
|
+
/** Per-invocation post-hook override — replaces the registered
|
|
131
|
+
* `postRunHooks` array for this run only. */
|
|
132
|
+
postRunHooks?: readonly string[];
|
|
109
133
|
/** Explicit parent run id. Pass `null` to suppress ambient RUN_ID auto-detection. */
|
|
110
134
|
parentRunId?: string | null;
|
|
111
135
|
/** Agent loop inside the parent run that caused this invoke, when applicable. */
|
|
@@ -124,8 +148,12 @@ export interface InvokeResult {
|
|
|
124
148
|
}
|
|
125
149
|
|
|
126
150
|
export interface ListSnapshotsOptions {
|
|
151
|
+
/** Factory slug. Defaults to `"default"`. */
|
|
152
|
+
factorySlug?: string;
|
|
127
153
|
workflow?: string;
|
|
128
154
|
limit?: number;
|
|
155
|
+
/** Cursor returned as `next_cursor` from `listSnapshotsPage`. */
|
|
156
|
+
before?: string;
|
|
129
157
|
}
|
|
130
158
|
|
|
131
159
|
export interface TemplateRow {
|
|
@@ -332,19 +360,66 @@ export interface CancelRunResponse {
|
|
|
332
360
|
}
|
|
333
361
|
|
|
334
362
|
export interface SnapshotListEntry {
|
|
363
|
+
snapshotId: string;
|
|
364
|
+
kind: "latest" | "step";
|
|
365
|
+
stepIndex: number | null;
|
|
335
366
|
runId: string;
|
|
336
367
|
workflow: string | null;
|
|
337
368
|
version: string | null;
|
|
338
|
-
|
|
339
|
-
|
|
369
|
+
createdAt: string | null;
|
|
370
|
+
/** Provider-reported on-disk size, or null when unavailable. */
|
|
371
|
+
sizeBytes: number | null;
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
export interface SnapshotListResponse {
|
|
375
|
+
object: "list";
|
|
376
|
+
data: SnapshotListEntry[];
|
|
377
|
+
has_more: boolean;
|
|
378
|
+
next_cursor: string | null;
|
|
340
379
|
}
|
|
341
380
|
|
|
381
|
+
export interface RunSnapshotEntry {
|
|
382
|
+
snapshotId: string;
|
|
383
|
+
/** `"latest"` = current/last pointer on the run.
|
|
384
|
+
* `"step"` = retained per-step snapshot. */
|
|
385
|
+
kind: "latest" | "step";
|
|
386
|
+
stepIndex: number | null;
|
|
387
|
+
createdAt: string | null;
|
|
388
|
+
/** Provider-reported on-disk size, or null when unavailable. */
|
|
389
|
+
sizeBytes: number | null;
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
export interface AgentComposeClientOptions {
|
|
393
|
+
/** Your team's API key — minted from the dashboard or `agentc keys create`.
|
|
394
|
+
* Required. Resolved from `process.env.AGENT_COMPOSE_API_KEY` when omitted. */
|
|
395
|
+
apiKey?: string;
|
|
396
|
+
/** Override the API host. Defaults to `process.env.AGENT_COMPOSE_URL` if
|
|
397
|
+
* set, otherwise the public host (`https://api.agentcompose.ai`). Most
|
|
398
|
+
* callers should leave this unset — the only consumers that need it are
|
|
399
|
+
* the CLI's local-dev path and tests that point at a fake server. */
|
|
400
|
+
baseUrl?: string;
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
const PUBLIC_API_HOST = "https://api.agentcompose.ai";
|
|
404
|
+
|
|
342
405
|
export class AgentComposeClient {
|
|
343
406
|
private readonly fetch: typeof ofetch;
|
|
344
407
|
private readonly baseUrl: string;
|
|
345
408
|
private readonly apiKey: string;
|
|
346
409
|
|
|
347
|
-
constructor(
|
|
410
|
+
constructor(options: AgentComposeClientOptions = {}) {
|
|
411
|
+
const apiKey = options.apiKey
|
|
412
|
+
?? (typeof process !== "undefined" ? process.env?.AGENT_COMPOSE_API_KEY : undefined)
|
|
413
|
+
?? "";
|
|
414
|
+
if (!apiKey) {
|
|
415
|
+
throw new Error(
|
|
416
|
+
"AgentComposeClient: `apiKey` is required. Pass it as `{ apiKey }` " +
|
|
417
|
+
"or set the AGENT_COMPOSE_API_KEY env var.",
|
|
418
|
+
);
|
|
419
|
+
}
|
|
420
|
+
const baseUrl = options.baseUrl
|
|
421
|
+
?? (typeof process !== "undefined" ? process.env?.AGENT_COMPOSE_URL : undefined)
|
|
422
|
+
?? PUBLIC_API_HOST;
|
|
348
423
|
this.baseUrl = baseUrl.replace(/\/$/, "");
|
|
349
424
|
this.apiKey = apiKey;
|
|
350
425
|
this.fetch = ofetch.create({
|
|
@@ -366,16 +441,9 @@ export class AgentComposeClient {
|
|
|
366
441
|
|
|
367
442
|
/** Invoke a workflow. Returns run ID immediately — workflow runs asynchronously.
|
|
368
443
|
*
|
|
369
|
-
* `
|
|
370
|
-
*
|
|
371
|
-
*
|
|
372
|
-
* snapshots (e.g. a benchmark workflow running against a different
|
|
373
|
-
* starting state per invocation). Does not change the template's
|
|
374
|
-
* registered default; only affects this run.
|
|
375
|
-
*
|
|
376
|
-
* `saveSnapshot`: `true` overrides the workflow default; `false` opts
|
|
377
|
-
* out. When the run captures a snapshot, its id is stamped on the row
|
|
378
|
-
* and can be referenced as the `snapshot` field on other workflows.
|
|
444
|
+
* `snapshots`: per-invocation snapshot config override. `bootFrom`
|
|
445
|
+
* accepts `{ snapshotId }`; `saveLatest` / `retainSteps` control
|
|
446
|
+
* capture. Merged field-by-field with the registered default.
|
|
379
447
|
*
|
|
380
448
|
* `parentRunId`: links the new run to another of the same account's
|
|
381
449
|
* currently-running runs. When omitted, the client auto-detects from
|
|
@@ -399,10 +467,11 @@ export class AgentComposeClient {
|
|
|
399
467
|
method: "POST",
|
|
400
468
|
body: {
|
|
401
469
|
input,
|
|
402
|
-
...(opts?.
|
|
403
|
-
...(opts?.saveSnapshot !== undefined ? { saveSnapshot: opts.saveSnapshot } : {}),
|
|
470
|
+
...(opts?.snapshots !== undefined ? { snapshots: opts.snapshots } : {}),
|
|
404
471
|
...(opts?.networkPolicy !== undefined ? { networkPolicy: opts.networkPolicy } : {}),
|
|
405
472
|
...(opts?.placeholders !== undefined ? { placeholders: opts.placeholders } : {}),
|
|
473
|
+
...(opts?.memory !== undefined ? { memory: opts.memory } : {}),
|
|
474
|
+
...(opts?.postRunHooks !== undefined ? { postRunHooks: opts.postRunHooks } : {}),
|
|
406
475
|
...(parentRunId ? { parentRunId } : {}),
|
|
407
476
|
...(opts?.agentId ? { agentId: opts.agentId } : {}),
|
|
408
477
|
},
|
|
@@ -441,20 +510,45 @@ export class AgentComposeClient {
|
|
|
441
510
|
throw new AgentComposeError(504, `invokeAndWait: run ${runId} did not settle within ${timeoutMs}ms`);
|
|
442
511
|
}
|
|
443
512
|
|
|
444
|
-
/** List
|
|
513
|
+
/** List captured snapshots in a factory. */
|
|
445
514
|
async listSnapshots(opts?: ListSnapshotsOptions): Promise<SnapshotListEntry[]> {
|
|
515
|
+
const body = await this.listSnapshotsPage(opts);
|
|
516
|
+
return body.data;
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
/** List one page of captured snapshots in a factory. */
|
|
520
|
+
async listSnapshotsPage(opts?: ListSnapshotsOptions): Promise<SnapshotListResponse> {
|
|
521
|
+
const factorySlug = opts?.factorySlug ?? DEFAULT_FACTORY;
|
|
446
522
|
const q = new URLSearchParams();
|
|
447
523
|
if (opts?.workflow) q.set("workflow", opts.workflow);
|
|
448
524
|
if (opts?.limit != null) q.set("limit", String(opts.limit));
|
|
449
|
-
|
|
450
|
-
|
|
525
|
+
if (opts?.before) q.set("before", opts.before);
|
|
526
|
+
return this.fetch<SnapshotListResponse>(
|
|
527
|
+
`/api/v1/factories/${encodeURIComponent(factorySlug)}/snapshots${q.toString() ? `?${q}` : ""}`,
|
|
451
528
|
);
|
|
452
|
-
return body.data;
|
|
453
529
|
}
|
|
454
530
|
|
|
455
531
|
/** Delete the snapshot captured by a specific run. Frees Vercel storage. */
|
|
456
532
|
deleteSnapshot(runId: string): Promise<void> {
|
|
457
|
-
return this.fetch(`/api/v1/workflows/${runId}/snapshot`, { method: "DELETE" });
|
|
533
|
+
return this.fetch(`/api/v1/workflows/${encodeURIComponent(runId)}/snapshot`, { method: "DELETE" });
|
|
534
|
+
}
|
|
535
|
+
|
|
536
|
+
/** List all snapshots captured for a single run — the latest pointer
|
|
537
|
+
* plus any retained per-step rows (`snapshots: { retainSteps: true }`). */
|
|
538
|
+
async listRunSnapshots(runId: string): Promise<RunSnapshotEntry[]> {
|
|
539
|
+
const body = await this.fetch<{ object: "list"; data: RunSnapshotEntry[]; has_more: boolean }>(
|
|
540
|
+
`/api/v1/workflows/${encodeURIComponent(runId)}/snapshots`,
|
|
541
|
+
);
|
|
542
|
+
return body.data;
|
|
543
|
+
}
|
|
544
|
+
|
|
545
|
+
/** Delete one snapshot from a run by id. Walks both the latest pointer
|
|
546
|
+
* and the retention rows; provider-side delete is best-effort. */
|
|
547
|
+
deleteRunSnapshot(runId: string, snapshotId: string): Promise<void> {
|
|
548
|
+
return this.fetch(
|
|
549
|
+
`/api/v1/workflows/${encodeURIComponent(runId)}/snapshots/${encodeURIComponent(snapshotId)}`,
|
|
550
|
+
{ method: "DELETE" },
|
|
551
|
+
);
|
|
458
552
|
}
|
|
459
553
|
|
|
460
554
|
/** Poll run status. */
|
package/src/index.ts
CHANGED
|
@@ -36,7 +36,15 @@ export type {
|
|
|
36
36
|
WorkflowRun,
|
|
37
37
|
AgentBudget,
|
|
38
38
|
WorkflowHooks,
|
|
39
|
+
SnapshotConfig,
|
|
40
|
+
BootSnapshot,
|
|
41
|
+
IOSchema,
|
|
42
|
+
OutputSchema,
|
|
43
|
+
WorkflowMemoryConfig,
|
|
39
44
|
} from "./types/workflow.js";
|
|
45
|
+
|
|
46
|
+
// Snapshot entry type re-exported for consumers (dashboard, CLI).
|
|
47
|
+
export type { RunSnapshotEntry } from "./client.js";
|
|
40
48
|
export type { WorkflowPlan, WorkflowStepPlan } from "./types/workflow-plan.js";
|
|
41
49
|
export type { BaseExecutionContext, InvokeChild } from "./types/execution-context.js";
|
|
42
50
|
|
|
@@ -105,7 +113,7 @@ export type {
|
|
|
105
113
|
CreateApiKeyInput, StreamRunLogsOptions,
|
|
106
114
|
EventSubjectType, EventRow, ReportEventInput, ListEventsOptions, ListEventsResult,
|
|
107
115
|
RunLogLine, ListRunLogsOptions,
|
|
108
|
-
RegisteredRuntime, RunState, RunStatus, FactoryRow, SnapshotListEntry,
|
|
116
|
+
RegisteredRuntime, RunState, RunStatus, FactoryRow, SnapshotListEntry, SnapshotListResponse,
|
|
109
117
|
ApiKey, ApiKeyCreated,
|
|
110
118
|
UsageRollupRow, UsageResponse,
|
|
111
119
|
CancelRunResponse,
|
package/src/sandbox.ts
CHANGED
|
@@ -239,7 +239,11 @@ function makeVercelSandboxProvider(sb: any, globalEnvs?: Record<string, string>)
|
|
|
239
239
|
async snapshot() {
|
|
240
240
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
241
241
|
const res: any = await sb.snapshot({ expiration: 0 });
|
|
242
|
-
|
|
242
|
+
const sizeBytes = typeof res.sizeBytes === "number" ? res.sizeBytes : undefined;
|
|
243
|
+
return {
|
|
244
|
+
snapshotId: res.snapshotId as string,
|
|
245
|
+
...(sizeBytes !== undefined ? { sizeBytes } : {}),
|
|
246
|
+
};
|
|
243
247
|
},
|
|
244
248
|
};
|
|
245
249
|
}
|