@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
|
|
@@ -39,20 +37,31 @@
|
|
|
39
37
|
import type { SandboxProvider } from "./sandbox.js";
|
|
40
38
|
import { defineWorkflow } from "./workflow.js";
|
|
41
39
|
import type { Workflow } from "../workflow-steps/types.js";
|
|
40
|
+
import type { SnapshotConfig } from "./workflow-metadata.js";
|
|
42
41
|
|
|
43
42
|
export interface SandboxEnvironmentDefinition {
|
|
44
43
|
name: string;
|
|
45
44
|
description?: string;
|
|
46
45
|
setup: (sb: SandboxProvider) => Promise<void>;
|
|
47
|
-
/** Override the sugar's `
|
|
48
|
-
* out of snapshot capture (rarely
|
|
49
|
-
*
|
|
50
|
-
|
|
46
|
+
/** Override the sugar's `{ saveLatest: true }` default. Set
|
|
47
|
+
* `{ saveLatest: false }` to opt out of snapshot capture (rarely
|
|
48
|
+
* useful — an env with no snapshot can't be referenced as a
|
|
49
|
+
* `bootFrom` on another workflow). */
|
|
50
|
+
snapshots?: SnapshotConfig;
|
|
51
|
+
/** Override the sugar's `memory: false` default. Setup workflows
|
|
52
|
+
* don't typically benefit from memory extraction; opt in explicitly
|
|
53
|
+
* when they do. */
|
|
54
|
+
memory?: boolean;
|
|
51
55
|
}
|
|
52
56
|
|
|
53
57
|
/** Sugar over `defineWorkflow` for setup-only workflows that exist to
|
|
54
58
|
* capture a snapshot. The workflow takes no meaningful input and returns
|
|
55
|
-
* nothing — its value is the side effect on the sandbox VM.
|
|
59
|
+
* nothing — its value is the side effect on the sandbox VM.
|
|
60
|
+
*
|
|
61
|
+
* Defaults `memory: false` because sandbox environments emit setup
|
|
62
|
+
* output (npm installs, command exit codes) rather than agent traces
|
|
63
|
+
* worth memorising. Authors can opt in explicitly via `env.memory:
|
|
64
|
+
* true` if their environment somehow does want extraction. */
|
|
56
65
|
export function defineSandboxEnvironment(
|
|
57
66
|
env: SandboxEnvironmentDefinition,
|
|
58
67
|
): Workflow<Record<string, unknown>, void> {
|
|
@@ -60,7 +69,8 @@ export function defineSandboxEnvironment(
|
|
|
60
69
|
throw new Error(`defineSandboxEnvironment(${env.name}): 'setup' must be a function`);
|
|
61
70
|
}
|
|
62
71
|
return defineWorkflow<void, Record<string, unknown>>({
|
|
63
|
-
|
|
72
|
+
snapshots: env.snapshots ?? { saveLatest: true },
|
|
73
|
+
memory: env.memory ?? false,
|
|
64
74
|
run: async (_ctx, sandbox) => env.setup(sandbox),
|
|
65
75
|
});
|
|
66
76
|
}
|
package/src/types/sandbox.ts
CHANGED
|
@@ -32,8 +32,12 @@ export interface SandboxProvider {
|
|
|
32
32
|
/** Capture the running sandbox's state as a reusable snapshot. Vercel
|
|
33
33
|
* supports it natively; E2B's model is Dockerfile-based and doesn't map
|
|
34
34
|
* cleanly — `undefined` on providers that don't. Used by the server's
|
|
35
|
-
* `--build` flow to stamp the snapshot id on the workflow row.
|
|
36
|
-
|
|
35
|
+
* `--build` flow to stamp the snapshot id on the workflow row.
|
|
36
|
+
*
|
|
37
|
+
* `sizeBytes` is the on-disk footprint reported by the provider. May
|
|
38
|
+
* be omitted when the provider doesn't expose it; the server stores
|
|
39
|
+
* `null` for missing values rather than estimating. */
|
|
40
|
+
snapshot?(): Promise<{ snapshotId: string; sizeBytes?: number }>;
|
|
37
41
|
}
|
|
38
42
|
|
|
39
43
|
/** Stateless provider-level snapshot deletion — no live sandbox needed,
|
|
@@ -20,18 +20,83 @@ import type { Processor } from "../processors/processor.js";
|
|
|
20
20
|
* The bundler reads these from the default export at registration time
|
|
21
21
|
* and forwards them to the server's POST /api/v1/templates payload.
|
|
22
22
|
*/
|
|
23
|
-
/**
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
export type WorkflowMemoryConfig =
|
|
23
|
+
/** Whether the built-in Workflow Memory extractor should run after this
|
|
24
|
+
* workflow completes. Boolean toggle — custom post-run workflows live
|
|
25
|
+
* in the separate `postRunHooks` array on `WorkflowMetadata`. */
|
|
26
|
+
export type WorkflowMemoryConfig = boolean;
|
|
27
|
+
|
|
28
|
+
/** Where a run boots from. The snapshot id is the unit of identity —
|
|
29
|
+
* each captured snapshot already records the workflow + version it
|
|
30
|
+
* came from on the snapshot row, so there's no separate "latest of
|
|
31
|
+
* workflow X" resolution at dispatch time. Operators pick a snapshot
|
|
32
|
+
* from the dashboard snapshot list (or `agentc snapshot list`) and
|
|
33
|
+
* paste the id here.
|
|
34
|
+
*
|
|
35
|
+
* Omit `bootFrom` entirely to boot a fresh base sandbox. */
|
|
36
|
+
export type BootSnapshot = { snapshotId: string };
|
|
37
|
+
|
|
38
|
+
/** Snapshot configuration — boot source plus capture knobs. One object
|
|
39
|
+
* per workflow / per invocation; collapsing boot + capture under a
|
|
40
|
+
* single key reads as "all snapshot config lives here." */
|
|
41
|
+
export interface SnapshotConfig {
|
|
42
|
+
/** Where the runner restores from at run start. Structured (workflow
|
|
43
|
+
* ref or snapshot id) so the intent is explicit at the call site. */
|
|
44
|
+
bootFrom?: BootSnapshot;
|
|
45
|
+
/** Capture the sandbox state on terminal success. The latest pointer
|
|
46
|
+
* on `workflow_runs.vercel_snapshot_id` always tracks the most
|
|
47
|
+
* recent capture; without `retainSteps`, prior captures are deleted
|
|
48
|
+
* as new ones land — constant storage cost. */
|
|
49
|
+
saveLatest?: boolean;
|
|
50
|
+
/** Only meaningful with `saveLatest: true`. Retain every step's
|
|
51
|
+
* snapshot in `run_step_snapshots` so a future dispatch can boot
|
|
52
|
+
* from a specific step's checkpoint via its `snapshotId`. Cost
|
|
53
|
+
* scales linearly with step count. */
|
|
54
|
+
retainSteps?: boolean;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/** JSON-Schema-shaped description captured by the bundler from a
|
|
58
|
+
* workflow's `input` or `output` zod schema. Carried in template
|
|
59
|
+
* metadata so the dashboard can render typed input forms + output
|
|
60
|
+
* type tables. */
|
|
61
|
+
export interface IOSchema {
|
|
62
|
+
/** JSON Schema `type` keyword, when single-valued. Omitted for unions / unknowns. */
|
|
63
|
+
type?: string | string[];
|
|
64
|
+
/** Free-form description pulled from `.describe(...)` on the root. */
|
|
65
|
+
description?: string;
|
|
66
|
+
/** Object-shape: one entry per property. */
|
|
67
|
+
properties?: Record<string, { type?: string | string[]; description?: string }>;
|
|
68
|
+
/** Required property names — relevant only when `type === "object"`. */
|
|
69
|
+
required?: string[];
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/** Alias kept for backwards source-compatibility with the original
|
|
73
|
+
* output-only release. New code should prefer `IOSchema`. */
|
|
74
|
+
export type OutputSchema = IOSchema;
|
|
27
75
|
|
|
28
76
|
export interface WorkflowMetadata {
|
|
29
77
|
networkPolicy?: SandboxNetworkPolicy;
|
|
30
78
|
placeholders?: Record<string, string>;
|
|
31
|
-
|
|
32
|
-
|
|
79
|
+
/** Input schema captured at bundle time from the workflow's
|
|
80
|
+
* declared `input` zod schema. Step-form workflows populate this
|
|
81
|
+
* automatically; run-form workflows (no explicit input schema —
|
|
82
|
+
* defaults to `z.unknown()`) leave it undefined. */
|
|
83
|
+
inputSchema?: IOSchema;
|
|
84
|
+
/** Output schema captured at bundle time from the workflow's
|
|
85
|
+
* declared `output` zod schema. Step-form workflows populate this
|
|
86
|
+
* automatically; run-form workflows whose `run()` returns
|
|
87
|
+
* arbitrarily-typed values leave it undefined. */
|
|
88
|
+
outputSchema?: IOSchema;
|
|
89
|
+
/** All snapshot config — boot source + capture mode. */
|
|
90
|
+
snapshots?: SnapshotConfig;
|
|
33
91
|
processors?: readonly Processor[];
|
|
34
|
-
memory
|
|
92
|
+
/** Run the built-in memory extractor after this workflow completes.
|
|
93
|
+
* Opt-in; defaults to false when omitted. */
|
|
94
|
+
memory?: boolean;
|
|
95
|
+
/** Ordered list of workflow names that run after this workflow
|
|
96
|
+
* completes. The runtime dispatches them in declaration order; the
|
|
97
|
+
* built-in memory extractor (when `memory: true`) runs as a separate
|
|
98
|
+
* hook alongside whatever's declared here. */
|
|
99
|
+
postRunHooks?: readonly string[];
|
|
35
100
|
}
|
|
36
101
|
|
|
37
102
|
/**
|
|
@@ -54,12 +119,12 @@ export function extractMetadata(source: Partial<WorkflowMetadata>): WorkflowMeta
|
|
|
54
119
|
const out: WorkflowMetadata = {};
|
|
55
120
|
if (source.networkPolicy !== undefined) out.networkPolicy = freezeMetadataValue(source.networkPolicy);
|
|
56
121
|
if (source.placeholders !== undefined) out.placeholders = Object.freeze({ ...source.placeholders });
|
|
57
|
-
if (source.
|
|
58
|
-
if (source.
|
|
122
|
+
if (source.inputSchema !== undefined) out.inputSchema = freezeMetadataValue(source.inputSchema);
|
|
123
|
+
if (source.outputSchema !== undefined) out.outputSchema = freezeMetadataValue(source.outputSchema);
|
|
124
|
+
if (source.snapshots !== undefined) out.snapshots = Object.freeze({ ...source.snapshots });
|
|
59
125
|
if (source.processors !== undefined) out.processors = Object.freeze([...source.processors]);
|
|
60
|
-
if (source.memory !== undefined) out.memory =
|
|
61
|
-
|
|
62
|
-
: source.memory;
|
|
126
|
+
if (source.memory !== undefined) out.memory = source.memory;
|
|
127
|
+
if (source.postRunHooks !== undefined) out.postRunHooks = Object.freeze([...source.postRunHooks]);
|
|
63
128
|
return Object.freeze(out);
|
|
64
129
|
}
|
|
65
130
|
|
package/src/types/workflow.ts
CHANGED
|
@@ -37,8 +37,8 @@ export interface AgentEventSink {
|
|
|
37
37
|
emit(event: AgentLifecycleEvent): void | Promise<void>;
|
|
38
38
|
}
|
|
39
39
|
|
|
40
|
-
import type { WorkflowMemoryConfig } from "./workflow-metadata.js";
|
|
41
|
-
export type { WorkflowMemoryConfig };
|
|
40
|
+
import type { WorkflowMemoryConfig, SnapshotConfig, BootSnapshot, IOSchema, OutputSchema } from "./workflow-metadata.js";
|
|
41
|
+
export type { WorkflowMemoryConfig, SnapshotConfig, BootSnapshot, IOSchema, OutputSchema };
|
|
42
42
|
|
|
43
43
|
/** Turn/iteration budget for `agent(opts)`. Re-exported here so authors
|
|
44
44
|
* can type per-invoke budget overrides they pass as workflow input. */
|
|
@@ -91,21 +91,21 @@ export interface WorkflowDefinition<
|
|
|
91
91
|
> {
|
|
92
92
|
run: WorkflowFn<TOutput, TInput>;
|
|
93
93
|
/**
|
|
94
|
-
*
|
|
95
|
-
*
|
|
96
|
-
*
|
|
97
|
-
*
|
|
98
|
-
*
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
*
|
|
103
|
-
*
|
|
104
|
-
*
|
|
105
|
-
* `
|
|
106
|
-
* `
|
|
94
|
+
* All snapshot config — boot source plus capture mode.
|
|
95
|
+
*
|
|
96
|
+
* `snapshots.bootFrom`: the runner restores from this exact provider
|
|
97
|
+
* snapshot id at run start. Omit to boot a fresh sandbox.
|
|
98
|
+
*
|
|
99
|
+
* `snapshots.saveLatest`: `true` captures one snapshot after each
|
|
100
|
+
* successful step (latest-only — prior is freed).
|
|
101
|
+
* `{ saveLatest: true, retainSteps: true }` keeps every step's
|
|
102
|
+
* snapshot for fork / replay / time-travel.
|
|
103
|
+
*
|
|
104
|
+
* Snapshots are long-lived (never auto-expire). List + delete via
|
|
105
|
+
* `agentc snapshot list/delete`. Per-invocation
|
|
106
|
+
* `invoke({ snapshots })` overrides this default.
|
|
107
107
|
*/
|
|
108
|
-
|
|
108
|
+
snapshots?: SnapshotConfig;
|
|
109
109
|
/**
|
|
110
110
|
* Outbound network policy for the runner sandbox.
|
|
111
111
|
* Use "*": [] to allow all traffic while still injecting headers for specific domains.
|
|
@@ -142,10 +142,14 @@ export interface WorkflowDefinition<
|
|
|
142
142
|
* }
|
|
143
143
|
*/
|
|
144
144
|
placeholders?: Record<string, string>;
|
|
145
|
-
/**
|
|
146
|
-
*
|
|
147
|
-
* custom memory workflow once custom extractors are supported. */
|
|
145
|
+
/** Run the built-in memory extractor after this workflow completes.
|
|
146
|
+
* Opt-in; defaults to false when omitted. */
|
|
148
147
|
memory?: WorkflowMemoryConfig;
|
|
148
|
+
/** Ordered list of workflow names to dispatch as post-hooks after
|
|
149
|
+
* this workflow completes. Each hook receives the source run's
|
|
150
|
+
* context. The memory extractor (when `memory: true`) runs as an
|
|
151
|
+
* additional hook alongside these. */
|
|
152
|
+
postRunHooks?: readonly string[];
|
|
149
153
|
}
|
|
150
154
|
|
|
151
155
|
/**
|
package/src/utils/bundler.ts
CHANGED
|
@@ -24,7 +24,7 @@ import { createHash } from "node:crypto";
|
|
|
24
24
|
import { parse as babelParse } from "@babel/parser";
|
|
25
25
|
import type { File, ExportDefaultDeclaration, CallExpression, Expression, Statement } from "@babel/types";
|
|
26
26
|
import { importSourceModule } from "./source-loader.js";
|
|
27
|
-
import type { WorkflowMemoryConfig } from "../types/workflow.js";
|
|
27
|
+
import type { WorkflowMemoryConfig, SnapshotConfig } from "../types/workflow.js";
|
|
28
28
|
import type { SandboxNetworkPolicy } from "../sandbox.js";
|
|
29
29
|
import { isWorkflow } from "../workflow-steps/workflow.js";
|
|
30
30
|
import type { Workflow } from "../workflow-steps/types.js";
|
|
@@ -65,15 +65,20 @@ export interface BundledWorkflow {
|
|
|
65
65
|
manifest: WorkflowManifest;
|
|
66
66
|
networkPolicy?: SandboxNetworkPolicy;
|
|
67
67
|
placeholders?: Record<string, string>;
|
|
68
|
-
/**
|
|
69
|
-
*
|
|
70
|
-
|
|
71
|
-
snapshot?: string;
|
|
72
|
-
/** Default capture-on-success flag from the workflow definition. */
|
|
73
|
-
saveSnapshot?: boolean;
|
|
68
|
+
/** Snapshot config from the workflow definition — `bootFrom` (where to
|
|
69
|
+
* restore at run start), `save`, `retain`. */
|
|
70
|
+
snapshots?: SnapshotConfig;
|
|
74
71
|
workflowPlan: WorkflowPlan;
|
|
75
72
|
/** Workflow Memory extractor config. */
|
|
76
73
|
memory?: WorkflowMemoryConfig;
|
|
74
|
+
/** Ordered post-hook workflow names declared on the workflow. */
|
|
75
|
+
postRunHooks?: readonly string[];
|
|
76
|
+
/** Compact JSON-Schema-shaped description of the workflow's input
|
|
77
|
+
* type. Extracted from the workflow's declared `input` zod schema
|
|
78
|
+
* at bundle time; undefined when the schema is `z.unknown()`. */
|
|
79
|
+
inputSchema?: import("../types/workflow-metadata.js").IOSchema;
|
|
80
|
+
/** Same for the workflow's output zod schema. */
|
|
81
|
+
outputSchema?: import("../types/workflow-metadata.js").IOSchema;
|
|
77
82
|
}
|
|
78
83
|
|
|
79
84
|
async function bundle(path: string, label: string): Promise<string> {
|
|
@@ -270,14 +275,76 @@ export async function bundleWorkflow(
|
|
|
270
275
|
bundlerVersion: BUNDLER_VERSION,
|
|
271
276
|
};
|
|
272
277
|
|
|
278
|
+
// Input + output schemas: the workflow's `input` / `output` zod
|
|
279
|
+
// schemas → compact JSON-Schema-shaped descriptions carried in
|
|
280
|
+
// template metadata. Used by the dashboard's "Registered" panel to
|
|
281
|
+
// render schema tables and (eventually) client-side validation in
|
|
282
|
+
// the playground. Run-form workflows stamp `z.unknown()` for both
|
|
283
|
+
// — `extractIOSchema` filters those down to undefined so the
|
|
284
|
+
// dashboard renders the "no declared schema" empty state instead
|
|
285
|
+
// of a meaningless empty table.
|
|
286
|
+
const inputSchema = extractIOSchema(workflow.input);
|
|
287
|
+
const outputSchema = extractIOSchema(workflow.output);
|
|
288
|
+
|
|
273
289
|
return {
|
|
274
290
|
source,
|
|
275
291
|
manifest,
|
|
276
292
|
workflowPlan: plan,
|
|
277
293
|
networkPolicy: overrides?.networkPolicy ?? metadata.networkPolicy,
|
|
278
294
|
placeholders: overrides?.placeholders ?? metadata.placeholders,
|
|
279
|
-
...(
|
|
280
|
-
...(
|
|
281
|
-
...(metadata.
|
|
295
|
+
...(inputSchema !== undefined ? { inputSchema } : {}),
|
|
296
|
+
...(outputSchema !== undefined ? { outputSchema } : {}),
|
|
297
|
+
...(metadata.snapshots !== undefined ? { snapshots: metadata.snapshots } : {}),
|
|
298
|
+
...(metadata.memory !== undefined ? { memory: metadata.memory } : {}),
|
|
299
|
+
...(metadata.postRunHooks !== undefined ? { postRunHooks: metadata.postRunHooks } : {}),
|
|
282
300
|
};
|
|
283
301
|
}
|
|
302
|
+
|
|
303
|
+
/** Convert a workflow's `input` or `output` zod schema into a compact,
|
|
304
|
+
* serialisable description for template metadata. Uses Zod 4's
|
|
305
|
+
* `toJSONSchema` and trims the result to fields the dashboard
|
|
306
|
+
* renders — full draft 2020-12 schemas have refs / unions / nested
|
|
307
|
+
* allOf chains that are noisier than the dashboard needs.
|
|
308
|
+
*
|
|
309
|
+
* Returns undefined when:
|
|
310
|
+
* - The schema can't be serialised (corrupt / unknown variant)
|
|
311
|
+
* - The schema is effectively `unknown` (the run-form sugar default —
|
|
312
|
+
* no meaningful contract to render). */
|
|
313
|
+
function extractIOSchema(
|
|
314
|
+
zodSchema: { _zod?: unknown } | unknown,
|
|
315
|
+
): import("../types/workflow-metadata.js").IOSchema | undefined {
|
|
316
|
+
// Late require to keep this module tree-shakeable for callers that
|
|
317
|
+
// don't bundle. `toJSONSchema` lives on the top-level Zod export in v4.
|
|
318
|
+
let json: Record<string, unknown> | undefined;
|
|
319
|
+
try {
|
|
320
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports, @typescript-eslint/no-var-requires
|
|
321
|
+
const z = require("zod") as { toJSONSchema?: (s: unknown) => Record<string, unknown> };
|
|
322
|
+
if (!z.toJSONSchema) return undefined;
|
|
323
|
+
json = z.toJSONSchema(zodSchema);
|
|
324
|
+
} catch {
|
|
325
|
+
return undefined;
|
|
326
|
+
}
|
|
327
|
+
if (!json || typeof json !== "object") return undefined;
|
|
328
|
+
|
|
329
|
+
// `z.unknown()` serialises to `{}` (no type, no properties). Skip that
|
|
330
|
+
// — there's nothing useful to show.
|
|
331
|
+
if (Object.keys(json).filter((k) => k !== "$schema").length === 0) return undefined;
|
|
332
|
+
|
|
333
|
+
const out: import("../types/workflow-metadata.js").OutputSchema = {};
|
|
334
|
+
if (json.type !== undefined) out.type = json.type as string | string[];
|
|
335
|
+
if (json.description !== undefined) out.description = String(json.description);
|
|
336
|
+
if (json.properties && typeof json.properties === "object") {
|
|
337
|
+
const props: Record<string, { type?: string | string[]; description?: string }> = {};
|
|
338
|
+
for (const [key, raw] of Object.entries(json.properties as Record<string, unknown>)) {
|
|
339
|
+
if (raw && typeof raw === "object") {
|
|
340
|
+
const r = raw as Record<string, unknown>;
|
|
341
|
+
props[key] = {};
|
|
342
|
+
if (r.type !== undefined) props[key].type = r.type as string | string[];
|
|
343
|
+
if (r.description !== undefined) props[key].description = String(r.description);
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
if (Object.keys(props).length > 0) out.properties = props;
|
|
347
|
+
}
|
|
348
|
+
if (Array.isArray(json.required)) out.required = json.required.map(String);
|
|
349
|
+
return out;
|
|
350
|
+
}
|
|
@@ -23,6 +23,7 @@ import type { z } from "zod";
|
|
|
23
23
|
import type { Step, Workflow } from "./types.js";
|
|
24
24
|
import { WORKFLOW_BRAND } from "./types.js";
|
|
25
25
|
import { extractMetadata } from "../types/workflow-metadata.js";
|
|
26
|
+
import type { SnapshotConfig, WorkflowMemoryConfig } from "../types/workflow-metadata.js";
|
|
26
27
|
import type { SandboxNetworkPolicy } from "../sandbox.js";
|
|
27
28
|
import type { Processor } from "../processors/processor.js";
|
|
28
29
|
|
|
@@ -46,8 +47,9 @@ export interface StepWorkflowDefinition<TInput, TOutput> {
|
|
|
46
47
|
output: z.ZodType<TOutput>;
|
|
47
48
|
networkPolicy?: SandboxNetworkPolicy;
|
|
48
49
|
placeholders?: Record<string, string>;
|
|
49
|
-
|
|
50
|
-
|
|
50
|
+
snapshots?: SnapshotConfig;
|
|
51
|
+
memory?: WorkflowMemoryConfig;
|
|
52
|
+
postRunHooks?: readonly string[];
|
|
51
53
|
processors?: readonly Processor[];
|
|
52
54
|
}
|
|
53
55
|
|
|
@@ -18,7 +18,7 @@ export function buildInvokeChild(
|
|
|
18
18
|
if (!baseUrl || !apiKey) {
|
|
19
19
|
throw new Error("ctx.invokeChild requires AGENT_COMPOSE_URL and AGENT_COMPOSE_API_KEY");
|
|
20
20
|
}
|
|
21
|
-
childClient = new AgentComposeClient(
|
|
21
|
+
childClient = new AgentComposeClient({ apiKey, baseUrl });
|
|
22
22
|
return childClient;
|
|
23
23
|
};
|
|
24
24
|
return (name, input, childOpts) => getChildClient().invokeAndWait(name, input, {
|