@agent-compose/sdk 0.3.1 → 0.5.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/dist/client.d.ts +40 -0
- package/dist/index.js +21 -4
- package/dist/runtimes/openai-desktop.js +21 -4
- 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 +61 -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),
|
|
@@ -132,6 +136,27 @@ export interface UpdateFactoryInput {
|
|
|
132
136
|
name?: string;
|
|
133
137
|
description?: string;
|
|
134
138
|
}
|
|
139
|
+
export interface ScheduleRow {
|
|
140
|
+
id: string;
|
|
141
|
+
name: string;
|
|
142
|
+
workflowName: string;
|
|
143
|
+
cron: string;
|
|
144
|
+
createdAt: string;
|
|
145
|
+
updatedAt: string;
|
|
146
|
+
nextFireAt: string | null;
|
|
147
|
+
lastFireAt: string | null;
|
|
148
|
+
}
|
|
149
|
+
export interface CreateScheduleInput {
|
|
150
|
+
/** Human-friendly schedule name. Unique within the factory. */
|
|
151
|
+
name: string;
|
|
152
|
+
/** The workflow this schedule should fire. Must already be registered
|
|
153
|
+
* in the same factory. */
|
|
154
|
+
workflow: string;
|
|
155
|
+
/** Cron expression (UTC). */
|
|
156
|
+
cron: string;
|
|
157
|
+
/** Factory to attach the schedule to. Defaults to `"default"`. */
|
|
158
|
+
factorySlug?: string;
|
|
159
|
+
}
|
|
135
160
|
export interface SecretOptions {
|
|
136
161
|
factorySlug?: string;
|
|
137
162
|
}
|
|
@@ -424,6 +449,21 @@ export declare class AgentComposeClient {
|
|
|
424
449
|
/** Delete a factory. Refuses `default` and any factory still
|
|
425
450
|
* containing workflows. */
|
|
426
451
|
deleteFactory(slug: string): Promise<void>;
|
|
452
|
+
/** List every schedule in a factory, with the engine-reported next/last
|
|
453
|
+
* fire times merged in. */
|
|
454
|
+
listSchedules(factorySlug?: string): Promise<ScheduleRow[]>;
|
|
455
|
+
/** Create a new schedule. `name` is per-factory unique; the server
|
|
456
|
+
* returns 409 on collision. */
|
|
457
|
+
createSchedule(payload: CreateScheduleInput): Promise<{
|
|
458
|
+
id: string;
|
|
459
|
+
name: string;
|
|
460
|
+
workflow: string;
|
|
461
|
+
cron: string;
|
|
462
|
+
}>;
|
|
463
|
+
/** Delete a schedule by id. Best-effort: a transient engine error is
|
|
464
|
+
* logged server-side but the DB row is removed regardless — the boot
|
|
465
|
+
* reconciler reconverges on next start. */
|
|
466
|
+
deleteSchedule(id: string, factorySlug?: string): Promise<void>;
|
|
427
467
|
/** Create or update a workflow secret. Value is stored in GCP Secret Manager. */
|
|
428
468
|
setSecret(workflowName: string, key: string, value: string, opts?: SecretOptions): Promise<SetSecretResult>;
|
|
429
469
|
/** List secret keys registered for a workflow (metadata only — values are never returned). */
|
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
|
};
|
|
@@ -861,6 +863,20 @@ class AgentComposeClient {
|
|
|
861
863
|
deleteFactory(slug) {
|
|
862
864
|
return this.fetch(`/api/v1/factories/${encodeURIComponent(slug)}`, { method: "DELETE" });
|
|
863
865
|
}
|
|
866
|
+
async listSchedules(factorySlug = "default") {
|
|
867
|
+
const body = await this.fetch(`/api/v1/factories/${encodeURIComponent(factorySlug)}/schedules`);
|
|
868
|
+
return body.schedules;
|
|
869
|
+
}
|
|
870
|
+
createSchedule(payload) {
|
|
871
|
+
const factorySlug = payload.factorySlug ?? "default";
|
|
872
|
+
return this.fetch(`/api/v1/factories/${encodeURIComponent(factorySlug)}/schedules`, {
|
|
873
|
+
method: "POST",
|
|
874
|
+
body: { name: payload.name, workflow: payload.workflow, cron: payload.cron }
|
|
875
|
+
});
|
|
876
|
+
}
|
|
877
|
+
deleteSchedule(id, factorySlug = "default") {
|
|
878
|
+
return this.fetch(`/api/v1/factories/${encodeURIComponent(factorySlug)}/schedules/${encodeURIComponent(id)}`, { method: "DELETE" });
|
|
879
|
+
}
|
|
864
880
|
setSecret(workflowName, key, value, opts) {
|
|
865
881
|
const factorySlug = opts?.factorySlug ?? DEFAULT_FACTORY;
|
|
866
882
|
return this.fetch(templatePath(factorySlug, workflowName, "secrets"), {
|
|
@@ -1053,6 +1069,7 @@ async function bundleWorkflow(workflowPath, overrides) {
|
|
|
1053
1069
|
workflowPlan: plan,
|
|
1054
1070
|
networkPolicy: overrides?.networkPolicy ?? metadata.networkPolicy,
|
|
1055
1071
|
placeholders: overrides?.placeholders ?? metadata.placeholders,
|
|
1072
|
+
...metadata.description !== undefined ? { description: metadata.description } : {},
|
|
1056
1073
|
...inputSchema !== undefined ? { inputSchema } : {},
|
|
1057
1074
|
...outputSchema !== undefined ? { outputSchema } : {},
|
|
1058
1075
|
...metadata.snapshots !== undefined ? { snapshots: metadata.snapshots } : {},
|
|
@@ -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
|
};
|
|
@@ -861,6 +863,20 @@ class AgentComposeClient {
|
|
|
861
863
|
deleteFactory(slug) {
|
|
862
864
|
return this.fetch(`/api/v1/factories/${encodeURIComponent(slug)}`, { method: "DELETE" });
|
|
863
865
|
}
|
|
866
|
+
async listSchedules(factorySlug = "default") {
|
|
867
|
+
const body = await this.fetch(`/api/v1/factories/${encodeURIComponent(factorySlug)}/schedules`);
|
|
868
|
+
return body.schedules;
|
|
869
|
+
}
|
|
870
|
+
createSchedule(payload) {
|
|
871
|
+
const factorySlug = payload.factorySlug ?? "default";
|
|
872
|
+
return this.fetch(`/api/v1/factories/${encodeURIComponent(factorySlug)}/schedules`, {
|
|
873
|
+
method: "POST",
|
|
874
|
+
body: { name: payload.name, workflow: payload.workflow, cron: payload.cron }
|
|
875
|
+
});
|
|
876
|
+
}
|
|
877
|
+
deleteSchedule(id, factorySlug = "default") {
|
|
878
|
+
return this.fetch(`/api/v1/factories/${encodeURIComponent(factorySlug)}/schedules/${encodeURIComponent(id)}`, { method: "DELETE" });
|
|
879
|
+
}
|
|
864
880
|
setSecret(workflowName, key, value, opts) {
|
|
865
881
|
const factorySlug = opts?.factorySlug ?? DEFAULT_FACTORY;
|
|
866
882
|
return this.fetch(templatePath(factorySlug, workflowName, "secrets"), {
|
|
@@ -1053,6 +1069,7 @@ async function bundleWorkflow(workflowPath, overrides) {
|
|
|
1053
1069
|
workflowPlan: plan,
|
|
1054
1070
|
networkPolicy: overrides?.networkPolicy ?? metadata.networkPolicy,
|
|
1055
1071
|
placeholders: overrides?.placeholders ?? metadata.placeholders,
|
|
1072
|
+
...metadata.description !== undefined ? { description: metadata.description } : {},
|
|
1056
1073
|
...inputSchema !== undefined ? { inputSchema } : {},
|
|
1057
1074
|
...outputSchema !== undefined ? { outputSchema } : {},
|
|
1058
1075
|
...metadata.snapshots !== undefined ? { snapshots: metadata.snapshots } : {},
|
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),
|
|
@@ -177,6 +181,29 @@ export interface UpdateFactoryInput {
|
|
|
177
181
|
description?: string;
|
|
178
182
|
}
|
|
179
183
|
|
|
184
|
+
export interface ScheduleRow {
|
|
185
|
+
id: string;
|
|
186
|
+
name: string;
|
|
187
|
+
workflowName: string;
|
|
188
|
+
cron: string;
|
|
189
|
+
createdAt: string;
|
|
190
|
+
updatedAt: string;
|
|
191
|
+
nextFireAt: string | null;
|
|
192
|
+
lastFireAt: string | null;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
export interface CreateScheduleInput {
|
|
196
|
+
/** Human-friendly schedule name. Unique within the factory. */
|
|
197
|
+
name: string;
|
|
198
|
+
/** The workflow this schedule should fire. Must already be registered
|
|
199
|
+
* in the same factory. */
|
|
200
|
+
workflow: string;
|
|
201
|
+
/** Cron expression (UTC). */
|
|
202
|
+
cron: string;
|
|
203
|
+
/** Factory to attach the schedule to. Defaults to `"default"`. */
|
|
204
|
+
factorySlug?: string;
|
|
205
|
+
}
|
|
206
|
+
|
|
180
207
|
export interface SecretOptions {
|
|
181
208
|
factorySlug?: string;
|
|
182
209
|
}
|
|
@@ -668,6 +695,40 @@ export class AgentComposeClient {
|
|
|
668
695
|
return this.fetch(`/api/v1/factories/${encodeURIComponent(slug)}`, { method: "DELETE" });
|
|
669
696
|
}
|
|
670
697
|
|
|
698
|
+
// ── Schedules ─────────────────────────────────────────────────────────────
|
|
699
|
+
// Cron schedules attached to a registered workflow. One workflow can have
|
|
700
|
+
// N schedules with distinct names + cadences; runs the schedule triggers
|
|
701
|
+
// are tagged with the schedule's id and name in their metadata.
|
|
702
|
+
|
|
703
|
+
/** List every schedule in a factory, with the engine-reported next/last
|
|
704
|
+
* fire times merged in. */
|
|
705
|
+
async listSchedules(factorySlug = "default"): Promise<ScheduleRow[]> {
|
|
706
|
+
const body = await this.fetch<{ schedules: ScheduleRow[] }>(
|
|
707
|
+
`/api/v1/factories/${encodeURIComponent(factorySlug)}/schedules`,
|
|
708
|
+
);
|
|
709
|
+
return body.schedules;
|
|
710
|
+
}
|
|
711
|
+
|
|
712
|
+
/** Create a new schedule. `name` is per-factory unique; the server
|
|
713
|
+
* returns 409 on collision. */
|
|
714
|
+
createSchedule(payload: CreateScheduleInput): Promise<{ id: string; name: string; workflow: string; cron: string }> {
|
|
715
|
+
const factorySlug = payload.factorySlug ?? "default";
|
|
716
|
+
return this.fetch(`/api/v1/factories/${encodeURIComponent(factorySlug)}/schedules`, {
|
|
717
|
+
method: "POST",
|
|
718
|
+
body: { name: payload.name, workflow: payload.workflow, cron: payload.cron },
|
|
719
|
+
});
|
|
720
|
+
}
|
|
721
|
+
|
|
722
|
+
/** Delete a schedule by id. Best-effort: a transient engine error is
|
|
723
|
+
* logged server-side but the DB row is removed regardless — the boot
|
|
724
|
+
* reconciler reconverges on next start. */
|
|
725
|
+
deleteSchedule(id: string, factorySlug = "default"): Promise<void> {
|
|
726
|
+
return this.fetch(
|
|
727
|
+
`/api/v1/factories/${encodeURIComponent(factorySlug)}/schedules/${encodeURIComponent(id)}`,
|
|
728
|
+
{ method: "DELETE" },
|
|
729
|
+
);
|
|
730
|
+
}
|
|
731
|
+
|
|
671
732
|
// ── Secrets ────────────────────────────────────────────────────────────────
|
|
672
733
|
// Scoped to (factory, workflow, key). Stored in GCP Secret Manager;
|
|
673
734
|
// `factorySlug` defaults to `"default"`.
|
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 } : {}),
|