@agent-compose/sdk 0.4.0 → 0.5.1
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/dist/client.d.ts +4 -0
- package/dist/index.js +12 -7
- package/dist/runtimes/openai-desktop.js +12 -7
- package/dist/types/sandbox.d.ts +5 -0
- package/dist/types/workflow.d.ts +12 -0
- package/dist/utils/bundler.d.ts +4 -0
- package/package.json +1 -1
- package/src/client.ts +4 -0
- package/src/sandbox.ts +12 -3
- package/src/types/sandbox.ts +5 -0
- package/src/types/workflow.ts +25 -4
- package/src/utils/bundler.ts +5 -0
package/dist/client.d.ts
CHANGED
|
@@ -50,6 +50,10 @@ export interface RegisterWorkflowInput {
|
|
|
50
50
|
version?: string;
|
|
51
51
|
schedule?: string;
|
|
52
52
|
runtimes?: RuntimeSourceInput[];
|
|
53
|
+
/** Human-readable description declared via
|
|
54
|
+
* `defineWorkflow({ description })`. Stored in template metadata and
|
|
55
|
+
* surfaced on the dashboard template card. */
|
|
56
|
+
description?: string;
|
|
53
57
|
networkPolicy?: unknown;
|
|
54
58
|
placeholders?: Record<string, string>;
|
|
55
59
|
/** All snapshot config — `bootFrom` (where to restore at run start),
|
package/dist/index.js
CHANGED
|
@@ -547,10 +547,12 @@ function isWorkflow(value) {
|
|
|
547
547
|
// src/types/workflow.ts
|
|
548
548
|
function compileRunForm(def, metadata) {
|
|
549
549
|
const unknownSchema = z2.unknown();
|
|
550
|
+
const inputSchema = def.input ?? unknownSchema;
|
|
551
|
+
const outputSchema = def.output ?? unknownSchema;
|
|
550
552
|
const step = {
|
|
551
553
|
name: "run",
|
|
552
|
-
input:
|
|
553
|
-
output:
|
|
554
|
+
input: inputSchema,
|
|
555
|
+
output: outputSchema,
|
|
554
556
|
run: async (stepCtx) => {
|
|
555
557
|
const workflowCtx = {
|
|
556
558
|
input: stepCtx.input,
|
|
@@ -570,8 +572,8 @@ function compileRunForm(def, metadata) {
|
|
|
570
572
|
};
|
|
571
573
|
const workflow = {
|
|
572
574
|
id: "@run-form",
|
|
573
|
-
input:
|
|
574
|
-
output:
|
|
575
|
+
input: inputSchema,
|
|
576
|
+
output: outputSchema,
|
|
575
577
|
steps: Object.freeze([step]),
|
|
576
578
|
metadata
|
|
577
579
|
};
|
|
@@ -1067,6 +1069,7 @@ async function bundleWorkflow(workflowPath, overrides) {
|
|
|
1067
1069
|
workflowPlan: plan,
|
|
1068
1070
|
networkPolicy: overrides?.networkPolicy ?? metadata.networkPolicy,
|
|
1069
1071
|
placeholders: overrides?.placeholders ?? metadata.placeholders,
|
|
1072
|
+
...metadata.description !== undefined ? { description: metadata.description } : {},
|
|
1070
1073
|
...inputSchema !== undefined ? { inputSchema } : {},
|
|
1071
1074
|
...outputSchema !== undefined ? { outputSchema } : {},
|
|
1072
1075
|
...metadata.snapshots !== undefined ? { snapshots: metadata.snapshots } : {},
|
|
@@ -1596,13 +1599,14 @@ function makeVercelSandboxProvider(sb, globalEnvs) {
|
|
|
1596
1599
|
sandboxId: sb.sandboxId,
|
|
1597
1600
|
commands: {
|
|
1598
1601
|
async run(cmd, opts) {
|
|
1602
|
+
const sudo = opts?.sudo === true;
|
|
1599
1603
|
if (opts?.background) {
|
|
1600
|
-
sb.runCommand({ cmd: "sh", args: ["-c", cmd], cwd: opts.cwd, env: mergeEnvs(opts.envs), detached: true }).catch((err) => console.error(`[sandbox] background command failed: ${err instanceof Error ? err.message : String(err)}`));
|
|
1604
|
+
sb.runCommand({ cmd: "sh", args: ["-c", cmd], cwd: opts.cwd, env: mergeEnvs(opts.envs), detached: true, ...sudo ? { sudo: true } : {} }).catch((err) => console.error(`[sandbox] background command failed: ${err instanceof Error ? err.message : String(err)}`));
|
|
1601
1605
|
return { exitCode: 0, stdout: "" };
|
|
1602
1606
|
}
|
|
1603
1607
|
const signal = opts?.timeoutMs ? AbortSignal.timeout(opts.timeoutMs) : undefined;
|
|
1604
1608
|
let stdout = "";
|
|
1605
|
-
const handle = await sb.runCommand({ cmd: "sh", args: ["-c", cmd], cwd: opts?.cwd, env: mergeEnvs(opts?.envs), detached: true, signal });
|
|
1609
|
+
const handle = await sb.runCommand({ cmd: "sh", args: ["-c", cmd], cwd: opts?.cwd, env: mergeEnvs(opts?.envs), detached: true, signal, ...sudo ? { sudo: true } : {} });
|
|
1606
1610
|
await pRetry(async (attempt) => {
|
|
1607
1611
|
const h = attempt === 1 ? handle : await sb.getCommand(handle.cmdId);
|
|
1608
1612
|
for await (const log of h.logs()) {
|
|
@@ -1641,8 +1645,9 @@ function makeLocalSandboxProvider() {
|
|
|
1641
1645
|
sandboxId: "local",
|
|
1642
1646
|
commands: {
|
|
1643
1647
|
run(cmd, opts) {
|
|
1648
|
+
const finalCmd = opts?.sudo ? `sudo ${cmd}` : cmd;
|
|
1644
1649
|
return new Promise((resolve, reject) => {
|
|
1645
|
-
const proc = spawn("sh", ["-c",
|
|
1650
|
+
const proc = spawn("sh", ["-c", finalCmd], {
|
|
1646
1651
|
...opts?.cwd ? { cwd: opts.cwd } : {},
|
|
1647
1652
|
env: { ...process.env, ...opts?.envs ?? {} },
|
|
1648
1653
|
stdio: ["ignore", "pipe", "pipe"]
|
|
@@ -547,10 +547,12 @@ function isWorkflow(value) {
|
|
|
547
547
|
// src/types/workflow.ts
|
|
548
548
|
function compileRunForm(def, metadata) {
|
|
549
549
|
const unknownSchema = z2.unknown();
|
|
550
|
+
const inputSchema = def.input ?? unknownSchema;
|
|
551
|
+
const outputSchema = def.output ?? unknownSchema;
|
|
550
552
|
const step = {
|
|
551
553
|
name: "run",
|
|
552
|
-
input:
|
|
553
|
-
output:
|
|
554
|
+
input: inputSchema,
|
|
555
|
+
output: outputSchema,
|
|
554
556
|
run: async (stepCtx) => {
|
|
555
557
|
const workflowCtx = {
|
|
556
558
|
input: stepCtx.input,
|
|
@@ -570,8 +572,8 @@ function compileRunForm(def, metadata) {
|
|
|
570
572
|
};
|
|
571
573
|
const workflow = {
|
|
572
574
|
id: "@run-form",
|
|
573
|
-
input:
|
|
574
|
-
output:
|
|
575
|
+
input: inputSchema,
|
|
576
|
+
output: outputSchema,
|
|
575
577
|
steps: Object.freeze([step]),
|
|
576
578
|
metadata
|
|
577
579
|
};
|
|
@@ -1067,6 +1069,7 @@ async function bundleWorkflow(workflowPath, overrides) {
|
|
|
1067
1069
|
workflowPlan: plan,
|
|
1068
1070
|
networkPolicy: overrides?.networkPolicy ?? metadata.networkPolicy,
|
|
1069
1071
|
placeholders: overrides?.placeholders ?? metadata.placeholders,
|
|
1072
|
+
...metadata.description !== undefined ? { description: metadata.description } : {},
|
|
1070
1073
|
...inputSchema !== undefined ? { inputSchema } : {},
|
|
1071
1074
|
...outputSchema !== undefined ? { outputSchema } : {},
|
|
1072
1075
|
...metadata.snapshots !== undefined ? { snapshots: metadata.snapshots } : {},
|
|
@@ -1596,13 +1599,14 @@ function makeVercelSandboxProvider(sb, globalEnvs) {
|
|
|
1596
1599
|
sandboxId: sb.sandboxId,
|
|
1597
1600
|
commands: {
|
|
1598
1601
|
async run(cmd, opts) {
|
|
1602
|
+
const sudo = opts?.sudo === true;
|
|
1599
1603
|
if (opts?.background) {
|
|
1600
|
-
sb.runCommand({ cmd: "sh", args: ["-c", cmd], cwd: opts.cwd, env: mergeEnvs(opts.envs), detached: true }).catch((err) => console.error(`[sandbox] background command failed: ${err instanceof Error ? err.message : String(err)}`));
|
|
1604
|
+
sb.runCommand({ cmd: "sh", args: ["-c", cmd], cwd: opts.cwd, env: mergeEnvs(opts.envs), detached: true, ...sudo ? { sudo: true } : {} }).catch((err) => console.error(`[sandbox] background command failed: ${err instanceof Error ? err.message : String(err)}`));
|
|
1601
1605
|
return { exitCode: 0, stdout: "" };
|
|
1602
1606
|
}
|
|
1603
1607
|
const signal = opts?.timeoutMs ? AbortSignal.timeout(opts.timeoutMs) : undefined;
|
|
1604
1608
|
let stdout = "";
|
|
1605
|
-
const handle = await sb.runCommand({ cmd: "sh", args: ["-c", cmd], cwd: opts?.cwd, env: mergeEnvs(opts?.envs), detached: true, signal });
|
|
1609
|
+
const handle = await sb.runCommand({ cmd: "sh", args: ["-c", cmd], cwd: opts?.cwd, env: mergeEnvs(opts?.envs), detached: true, signal, ...sudo ? { sudo: true } : {} });
|
|
1606
1610
|
await pRetry(async (attempt) => {
|
|
1607
1611
|
const h = attempt === 1 ? handle : await sb.getCommand(handle.cmdId);
|
|
1608
1612
|
for await (const log of h.logs()) {
|
|
@@ -1641,8 +1645,9 @@ function makeLocalSandboxProvider() {
|
|
|
1641
1645
|
sandboxId: "local",
|
|
1642
1646
|
commands: {
|
|
1643
1647
|
run(cmd, opts) {
|
|
1648
|
+
const finalCmd = opts?.sudo ? `sudo ${cmd}` : cmd;
|
|
1644
1649
|
return new Promise((resolve, reject) => {
|
|
1645
|
-
const proc = spawn("sh", ["-c",
|
|
1650
|
+
const proc = spawn("sh", ["-c", finalCmd], {
|
|
1646
1651
|
...opts?.cwd ? { cwd: opts.cwd } : {},
|
|
1647
1652
|
env: { ...process.env, ...opts?.envs ?? {} },
|
|
1648
1653
|
stdio: ["ignore", "pipe", "pipe"]
|
package/dist/types/sandbox.d.ts
CHANGED
|
@@ -10,6 +10,11 @@ export interface SandboxCommandRunOptions {
|
|
|
10
10
|
onStdout?: (data: string) => void;
|
|
11
11
|
onStderr?: (data: string) => void;
|
|
12
12
|
background?: boolean;
|
|
13
|
+
/** Run the command with root privileges. Vercel maps this to its native
|
|
14
|
+
* `sudo` flag; E2B runs the command as `user: "root"`; the local provider
|
|
15
|
+
* prepends `sudo`. Defaults to false. Requires the sandbox image to grant
|
|
16
|
+
* the command root (Vercel's runtimes do — passwordless). */
|
|
17
|
+
sudo?: boolean;
|
|
13
18
|
}
|
|
14
19
|
export interface SandboxCommandResult {
|
|
15
20
|
exitCode: number;
|
package/dist/types/workflow.d.ts
CHANGED
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
* LLM agent loops live in `agent(opts)` (sdk/src/agent/run-agent.ts).
|
|
14
14
|
* Invoking other workflows uses `AgentComposeClient.invoke[AndWait](...)`.
|
|
15
15
|
*/
|
|
16
|
+
import { z } from "zod";
|
|
16
17
|
import type { SandboxNetworkPolicy } from "../sandbox.js";
|
|
17
18
|
import type { SandboxProvider } from "./sandbox.js";
|
|
18
19
|
import type { AgentLifecycleEvent } from "../agent/agent-loop.js";
|
|
@@ -70,6 +71,17 @@ export interface WorkflowDefinition<TOutput = unknown, TInput extends Record<str
|
|
|
70
71
|
/** One-line, human-readable description of what this workflow does.
|
|
71
72
|
* Surfaced on the dashboard template tile + run page header. */
|
|
72
73
|
description?: string;
|
|
74
|
+
/** Zod schema for the workflow's `input`. When declared, the SDK
|
|
75
|
+
* bundler captures it as JSON-Schema-shaped `inputSchema` in
|
|
76
|
+
* template metadata, the dashboard playground renders a typed
|
|
77
|
+
* form, and the engine validates dispatched payloads against it
|
|
78
|
+
* at the step boundary. Omit to leave inputs as `unknown` (the
|
|
79
|
+
* legacy default — playground falls back to a freeform JSON
|
|
80
|
+
* textarea). */
|
|
81
|
+
input?: z.ZodType<TInput>;
|
|
82
|
+
/** Same as `input`, for the workflow's return value. Captured into
|
|
83
|
+
* `outputSchema` metadata and rendered in the IO panel. */
|
|
84
|
+
output?: z.ZodType<TOutput>;
|
|
73
85
|
run: WorkflowFn<TOutput, TInput>;
|
|
74
86
|
/**
|
|
75
87
|
* All snapshot config — boot source plus capture mode.
|
package/dist/utils/bundler.d.ts
CHANGED
|
@@ -49,6 +49,10 @@ export declare class WorkflowSourceValidationError extends Error {
|
|
|
49
49
|
export interface BundledWorkflow {
|
|
50
50
|
source: string;
|
|
51
51
|
manifest: WorkflowManifest;
|
|
52
|
+
/** One-line, human-readable description declared via
|
|
53
|
+
* `defineWorkflow({ description })`. Surfaced on the dashboard
|
|
54
|
+
* template card + run header. */
|
|
55
|
+
description?: string;
|
|
52
56
|
networkPolicy?: SandboxNetworkPolicy;
|
|
53
57
|
placeholders?: Record<string, string>;
|
|
54
58
|
/** Snapshot config from the workflow definition — `bootFrom` (where to
|
package/package.json
CHANGED
package/src/client.ts
CHANGED
|
@@ -85,6 +85,10 @@ export interface RegisterWorkflowInput {
|
|
|
85
85
|
version?: string;
|
|
86
86
|
schedule?: string;
|
|
87
87
|
runtimes?: RuntimeSourceInput[];
|
|
88
|
+
/** Human-readable description declared via
|
|
89
|
+
* `defineWorkflow({ description })`. Stored in template metadata and
|
|
90
|
+
* surfaced on the dashboard template card. */
|
|
91
|
+
description?: string;
|
|
88
92
|
networkPolicy?: unknown;
|
|
89
93
|
placeholders?: Record<string, string>;
|
|
90
94
|
/** All snapshot config — `bootFrom` (where to restore at run start),
|
package/src/sandbox.ts
CHANGED
|
@@ -200,16 +200,20 @@ function makeVercelSandboxProvider(sb: any, globalEnvs?: Record<string, string>)
|
|
|
200
200
|
sandboxId: sb.sandboxId,
|
|
201
201
|
commands: {
|
|
202
202
|
async run(cmd, opts) {
|
|
203
|
+
// Vercel's runCommand takes a native `sudo` flag — pass it on the `sh`
|
|
204
|
+
// invocation so the whole shell (and every command it spawns) runs as
|
|
205
|
+
// root, matching `sb.runCommand({ cmd, args, sudo: true })` semantics.
|
|
206
|
+
const sudo = opts?.sudo === true;
|
|
203
207
|
if (opts?.background) {
|
|
204
208
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
205
|
-
void (sb.runCommand({ cmd: "sh", args: ["-c", cmd], cwd: opts.cwd, env: mergeEnvs(opts.envs), detached: true }) as Promise<any>)
|
|
209
|
+
void (sb.runCommand({ cmd: "sh", args: ["-c", cmd], cwd: opts.cwd, env: mergeEnvs(opts.envs), detached: true, ...(sudo ? { sudo: true } : {}) }) as Promise<any>)
|
|
206
210
|
.catch((err: unknown) => console.error(`[sandbox] background command failed: ${err instanceof Error ? err.message : String(err)}`));
|
|
207
211
|
return { exitCode: 0, stdout: "" };
|
|
208
212
|
}
|
|
209
213
|
const signal = opts?.timeoutMs ? AbortSignal.timeout(opts.timeoutMs) : undefined;
|
|
210
214
|
let stdout = "";
|
|
211
215
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
212
|
-
const handle: any = await sb.runCommand({ cmd: "sh", args: ["-c", cmd], cwd: opts?.cwd, env: mergeEnvs(opts?.envs), detached: true, signal });
|
|
216
|
+
const handle: any = await sb.runCommand({ cmd: "sh", args: ["-c", cmd], cwd: opts?.cwd, env: mergeEnvs(opts?.envs), detached: true, signal, ...(sudo ? { sudo: true } : {}) });
|
|
213
217
|
// Reconnect to the already-running command on transient stream failures (e.g. BrotliDecompressionError).
|
|
214
218
|
await pRetry(async (attempt) => {
|
|
215
219
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
@@ -261,8 +265,13 @@ export function makeLocalSandboxProvider(): SandboxProvider {
|
|
|
261
265
|
sandboxId: "local",
|
|
262
266
|
commands: {
|
|
263
267
|
run(cmd, opts) {
|
|
268
|
+
// Prepend `sudo` so the command runs as root. The local provider
|
|
269
|
+
// targets the runner's own host VM (used by defineSandboxEnvironment
|
|
270
|
+
// recipes); harmless when the host is already root or has passwordless
|
|
271
|
+
// sudo, which is the only context it runs in.
|
|
272
|
+
const finalCmd = opts?.sudo ? `sudo ${cmd}` : cmd;
|
|
264
273
|
return new Promise((resolve, reject) => {
|
|
265
|
-
const proc = spawn("sh", ["-c",
|
|
274
|
+
const proc = spawn("sh", ["-c", finalCmd], {
|
|
266
275
|
...(opts?.cwd ? { cwd: opts.cwd } : {}),
|
|
267
276
|
env: { ...process.env, ...(opts?.envs ?? {}) },
|
|
268
277
|
stdio: ["ignore", "pipe", "pipe"],
|
package/src/types/sandbox.ts
CHANGED
|
@@ -11,6 +11,11 @@ export interface SandboxCommandRunOptions {
|
|
|
11
11
|
onStdout?: (data: string) => void;
|
|
12
12
|
onStderr?: (data: string) => void;
|
|
13
13
|
background?: boolean;
|
|
14
|
+
/** Run the command with root privileges. Vercel maps this to its native
|
|
15
|
+
* `sudo` flag; E2B runs the command as `user: "root"`; the local provider
|
|
16
|
+
* prepends `sudo`. Defaults to false. Requires the sandbox image to grant
|
|
17
|
+
* the command root (Vercel's runtimes do — passwordless). */
|
|
18
|
+
sudo?: boolean;
|
|
14
19
|
}
|
|
15
20
|
|
|
16
21
|
export interface SandboxCommandResult {
|
package/src/types/workflow.ts
CHANGED
|
@@ -92,6 +92,17 @@ export interface WorkflowDefinition<
|
|
|
92
92
|
/** One-line, human-readable description of what this workflow does.
|
|
93
93
|
* Surfaced on the dashboard template tile + run page header. */
|
|
94
94
|
description?: string;
|
|
95
|
+
/** Zod schema for the workflow's `input`. When declared, the SDK
|
|
96
|
+
* bundler captures it as JSON-Schema-shaped `inputSchema` in
|
|
97
|
+
* template metadata, the dashboard playground renders a typed
|
|
98
|
+
* form, and the engine validates dispatched payloads against it
|
|
99
|
+
* at the step boundary. Omit to leave inputs as `unknown` (the
|
|
100
|
+
* legacy default — playground falls back to a freeform JSON
|
|
101
|
+
* textarea). */
|
|
102
|
+
input?: z.ZodType<TInput>;
|
|
103
|
+
/** Same as `input`, for the workflow's return value. Captured into
|
|
104
|
+
* `outputSchema` metadata and rendered in the IO panel. */
|
|
105
|
+
output?: z.ZodType<TOutput>;
|
|
95
106
|
run: WorkflowFn<TOutput, TInput>;
|
|
96
107
|
/**
|
|
97
108
|
* All snapshot config — boot source plus capture mode.
|
|
@@ -168,15 +179,25 @@ export interface WorkflowDefinition<
|
|
|
168
179
|
* under that one step. Authors keep the same source; the dashboard sees
|
|
169
180
|
* the same timeline shape.
|
|
170
181
|
*/
|
|
182
|
+
// TODO: collapse run-form into pure sugar over step-form. Run-form
|
|
183
|
+
// already compiles to step-form-with-one-step here, so maintaining two
|
|
184
|
+
// authoring surfaces is API duplication that periodically drifts (see
|
|
185
|
+
// the input/output thread-through bug fixed on 2026-05-20: step-form
|
|
186
|
+
// preserved schemas, run-form silently stamped z.unknown()). Cleaner:
|
|
187
|
+
// turn `defineWorkflow({ run })` into a thin wrapper that calls the
|
|
188
|
+
// step builder with a synthesised `{name:"run", input, output, run}`
|
|
189
|
+
// step, then delete this function. Runtime stays identical.
|
|
171
190
|
function compileRunForm<TOutput, TInput extends Record<string, unknown>>(
|
|
172
191
|
def: WorkflowDefinition<TOutput, TInput>,
|
|
173
192
|
metadata: WorkflowMetadata,
|
|
174
193
|
): Workflow<TInput, TOutput> {
|
|
175
194
|
const unknownSchema = z.unknown() as z.ZodType<unknown>;
|
|
195
|
+
const inputSchema: z.ZodType<TInput> = def.input ?? (unknownSchema as z.ZodType<TInput>);
|
|
196
|
+
const outputSchema: z.ZodType<TOutput> = def.output ?? (unknownSchema as z.ZodType<TOutput>);
|
|
176
197
|
const step: Step<TInput, TOutput> = {
|
|
177
198
|
name: "run",
|
|
178
|
-
input:
|
|
179
|
-
output:
|
|
199
|
+
input: inputSchema,
|
|
200
|
+
output: outputSchema,
|
|
180
201
|
run: async (stepCtx) => {
|
|
181
202
|
// Proxy the legacy WorkflowCtx hooks to the step's collector-backed
|
|
182
203
|
// implementations. The engine harvests the snapshot after execute
|
|
@@ -198,8 +219,8 @@ function compileRunForm<TOutput, TInput extends Record<string, unknown>>(
|
|
|
198
219
|
};
|
|
199
220
|
const workflow: Workflow<TInput, TOutput> = {
|
|
200
221
|
id: "@run-form",
|
|
201
|
-
input:
|
|
202
|
-
output:
|
|
222
|
+
input: inputSchema,
|
|
223
|
+
output: outputSchema,
|
|
203
224
|
steps: Object.freeze([step]),
|
|
204
225
|
metadata,
|
|
205
226
|
};
|
package/src/utils/bundler.ts
CHANGED
|
@@ -63,6 +63,10 @@ export class WorkflowSourceValidationError extends Error {
|
|
|
63
63
|
export interface BundledWorkflow {
|
|
64
64
|
source: string;
|
|
65
65
|
manifest: WorkflowManifest;
|
|
66
|
+
/** One-line, human-readable description declared via
|
|
67
|
+
* `defineWorkflow({ description })`. Surfaced on the dashboard
|
|
68
|
+
* template card + run header. */
|
|
69
|
+
description?: string;
|
|
66
70
|
networkPolicy?: SandboxNetworkPolicy;
|
|
67
71
|
placeholders?: Record<string, string>;
|
|
68
72
|
/** Snapshot config from the workflow definition — `bootFrom` (where to
|
|
@@ -292,6 +296,7 @@ export async function bundleWorkflow(
|
|
|
292
296
|
workflowPlan: plan,
|
|
293
297
|
networkPolicy: overrides?.networkPolicy ?? metadata.networkPolicy,
|
|
294
298
|
placeholders: overrides?.placeholders ?? metadata.placeholders,
|
|
299
|
+
...(metadata.description !== undefined ? { description: metadata.description } : {}),
|
|
295
300
|
...(inputSchema !== undefined ? { inputSchema } : {}),
|
|
296
301
|
...(outputSchema !== undefined ? { outputSchema } : {}),
|
|
297
302
|
...(metadata.snapshots !== undefined ? { snapshots: metadata.snapshots } : {}),
|