@agent-compose/cli 0.2.1 → 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 +4 -1
- package/dist/index.js +124 -23
- package/package.json +11 -11
- package/skills/ac:generate-workflow.md +353 -122
- package/skills/ac:invoke.md +31 -9
- package/skills/ac:register-invoke.md +44 -7
- package/skills/ac:register.md +4 -1
- package/skills/ac:schedule.md +132 -0
- package/skills/ac:setup.md +4 -1
- package/skills/ac:snapshots.md +10 -2
- package/skills/ac:tutorial.md +375 -0
- package/skills/ac:demo.md +0 -134
|
@@ -7,131 +7,362 @@ effort: high
|
|
|
7
7
|
|
|
8
8
|
# Generate Workflow
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
10
|
+
Walk the user through building a new workflow, **in their own words**.
|
|
11
|
+
This skill is used by operators and product folks as well as engineers
|
|
12
|
+
— ask questions in plain language and decide the shape internally.
|
|
13
|
+
|
|
14
|
+
## What to ask the user
|
|
15
|
+
|
|
16
|
+
Ask these one at a time. Keep the language non-technical. Don't ask
|
|
17
|
+
about "step-form vs run-form" — that's an internal call.
|
|
18
|
+
|
|
19
|
+
1. **What should this workflow do?**
|
|
20
|
+
One paragraph in plain English. This becomes the workflow's
|
|
21
|
+
`description` (shown on the dashboard tile and run page header).
|
|
22
|
+
Example: "Pulls open pull requests from a GitHub repo, scores each
|
|
23
|
+
one by review urgency, and posts the top five to Slack."
|
|
24
|
+
|
|
25
|
+
2. **What information does it take in?**
|
|
26
|
+
Walk through each input field: a short name, a type (text, number,
|
|
27
|
+
yes/no, list, object), and a one-line description of what it's for.
|
|
28
|
+
Each field's description becomes a `.describe(...)` on the zod
|
|
29
|
+
schema so it shows up in the dashboard's Input panel.
|
|
30
|
+
|
|
31
|
+
3. **What does it produce?**
|
|
32
|
+
Same pattern for the output. Fields + types + per-field
|
|
33
|
+
descriptions. The dashboard's Output panel renders these straight
|
|
34
|
+
from the schema.
|
|
35
|
+
|
|
36
|
+
4. **Where should it live?**
|
|
37
|
+
Project-relative path, e.g. `src/workflows/`. Also ask for a
|
|
38
|
+
kebab-case name if one isn't obvious from the description.
|
|
39
|
+
|
|
40
|
+
5. **Does it need to call external services?**
|
|
41
|
+
If yes, ask which (GitHub, Slack, OpenAI, an internal API, etc.).
|
|
42
|
+
You'll generate a network policy + brokered-secret stubs.
|
|
43
|
+
|
|
44
|
+
6. **Should it run on a schedule?**
|
|
45
|
+
If yes, ask for the cadence in plain English ("every weekday at 9am
|
|
46
|
+
ET", "every hour", "the 1st of every month"). Convert to cron
|
|
47
|
+
yourself (UTC). Schedules are *separate from workflow source*: you
|
|
48
|
+
don't put cron in `defineWorkflow(...)`. After register, run
|
|
49
|
+
`agentc schedule create <name> --workflow <wf> --cron '<expr>'`
|
|
50
|
+
(or, for the simple "one cron per workflow" case, pass
|
|
51
|
+
`--schedule '<expr>'` to `agentc register` and the CLI auto-creates
|
|
52
|
+
a same-named schedule). Read the cron expression back to the user
|
|
53
|
+
to confirm.
|
|
54
|
+
|
|
55
|
+
7. **Anything else worth recording?**
|
|
56
|
+
Optional. Most workflows are fine without this.
|
|
57
|
+
|
|
58
|
+
**Do NOT ask** the user about:
|
|
59
|
+
|
|
60
|
+
- step-form vs run-form
|
|
61
|
+
- sandbox environments / dependency installation
|
|
62
|
+
- snapshots: `saveLatest`, `retainSteps`, `bootFrom`
|
|
63
|
+
- `memory` / `postRunHooks` / `processors`
|
|
64
|
+
|
|
65
|
+
Decide those internally based on what they described (see the
|
|
66
|
+
"Internal decisions" section below).
|
|
67
|
+
|
|
68
|
+
## Internal decisions
|
|
69
|
+
|
|
70
|
+
After answering the questions above, decide the shape WITHOUT asking:
|
|
71
|
+
|
|
72
|
+
### Pick the workflow shape
|
|
73
|
+
|
|
74
|
+
- **Step-form** (`defineWorkflow({...}).step(s1).step(s2).build()` with
|
|
75
|
+
`defineStep(...)` objects) — pick this when the body decomposes
|
|
76
|
+
cleanly into named phases with typed handoffs. Each step's output
|
|
77
|
+
threads into the next step's input. The dashboard renders each step
|
|
78
|
+
as a typed phase with its own duration. Examples: ETL pipelines,
|
|
79
|
+
classification → enrichment → publish, fetch → score → rank.
|
|
80
|
+
|
|
81
|
+
- **Run-form** (one `async (ctx, sandbox)` body with `agent({...})`
|
|
82
|
+
calls inside) — pick this when the body is dominated by one or more
|
|
83
|
+
agent loops. Decomposing an LLM iteration into typed engine steps is
|
|
84
|
+
the wrong shape. Use `ctx.step("phase-name", () => …)` inside the
|
|
85
|
+
body for observability sub-events when there's pre-agent setup
|
|
86
|
+
worth tracing on the run timeline.
|
|
87
|
+
|
|
88
|
+
When the user's description says "agent", "LLM", "the model decides",
|
|
89
|
+
"reasons through", "writes a summary based on", "navigates the
|
|
90
|
+
website" — that's run-form. When they describe deterministic phases
|
|
91
|
+
that each transform structured data — that's step-form. If genuinely
|
|
92
|
+
mixed, default to run-form and use `ctx.step` for the deterministic
|
|
93
|
+
phases.
|
|
94
|
+
|
|
95
|
+
### Should it have a sandbox environment?
|
|
96
|
+
|
|
97
|
+
If the workflow needs specific tools, CLIs, or installed packages in
|
|
98
|
+
its runner VM (Playwright + Chromium, a specific Node version, an SDK
|
|
99
|
+
that needs `npm install`-ing first), it needs a **sandbox
|
|
100
|
+
environment** to capture that pre-installed state. The user doesn't
|
|
101
|
+
need to know about this — you decide.
|
|
102
|
+
|
|
103
|
+
When you decide a sandbox env is needed:
|
|
104
|
+
|
|
105
|
+
1. Generate a small `defineSandboxEnvironment` workflow alongside the
|
|
106
|
+
user's workflow. Name it after the deps it captures (e.g.
|
|
107
|
+
`playwright-env`).
|
|
108
|
+
2. Register that first with `agentc register --build` so the snapshot
|
|
109
|
+
is captured.
|
|
110
|
+
3. Reference the captured snapshot from the user's workflow via
|
|
111
|
+
`snapshots: { bootFrom: { snapshotId: "<id from the env's first
|
|
112
|
+
run>" } }`.
|
|
113
|
+
4. Tell the user about it in user terms: "I'll also create a one-time
|
|
114
|
+
setup workflow `playwright-env` that installs Playwright. We
|
|
115
|
+
register that first to capture a baseline image, then your workflow
|
|
116
|
+
boots from that image so it doesn't reinstall on every run."
|
|
117
|
+
|
|
118
|
+
Most workflows DO NOT need this. Default to no sandbox env.
|
|
119
|
+
|
|
120
|
+
### Always include in the generated file
|
|
121
|
+
|
|
122
|
+
- `description: "..."` on the `defineWorkflow` / `defineSandboxEnvironment`
|
|
123
|
+
call — straight from the user's question 1 answer.
|
|
124
|
+
- `.describe("...")` on **every** zod schema field — from the user's
|
|
125
|
+
question 2 + 3 answers. Schema descriptions appear in the dashboard
|
|
126
|
+
IO panels; without them, fields show only their type.
|
|
127
|
+
- `.describe("...")` on the root schema too where helpful — surfaces
|
|
128
|
+
at the panel header.
|
|
129
|
+
|
|
130
|
+
## Templates
|
|
131
|
+
|
|
132
|
+
Generate the appropriate template based on your internal shape
|
|
133
|
+
decision.
|
|
134
|
+
|
|
135
|
+
### Template A — step-form (typed pipeline)
|
|
136
|
+
|
|
137
|
+
```ts
|
|
138
|
+
import { defineWorkflow, defineStep } from "@agent-compose/sdk";
|
|
139
|
+
import { z } from "zod";
|
|
140
|
+
|
|
141
|
+
const InputSchema = z.object({
|
|
142
|
+
repo: z.string().describe("GitHub repository as `owner/name`"),
|
|
143
|
+
limit: z.number().int().positive().describe("Maximum number of PRs to score"),
|
|
144
|
+
}).describe("Inputs for the PR triage workflow");
|
|
145
|
+
|
|
146
|
+
const FetchOutput = z.object({
|
|
147
|
+
prs: z.array(z.object({
|
|
148
|
+
number: z.number().describe("PR number"),
|
|
149
|
+
title: z.string().describe("PR title"),
|
|
150
|
+
author: z.string().describe("PR author's GitHub login"),
|
|
151
|
+
})).describe("Open PRs pulled from GitHub"),
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
const ScoreOutput = z.object({
|
|
155
|
+
scored: z.array(z.object({
|
|
156
|
+
number: z.number().describe("PR number"),
|
|
157
|
+
score: z.number().describe("Review-urgency score, 0..1"),
|
|
158
|
+
})).describe("PRs scored by review urgency"),
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
const OutputSchema = z.object({
|
|
162
|
+
top: z.array(z.object({
|
|
163
|
+
number: z.number().describe("PR number"),
|
|
164
|
+
score: z.number().describe("Review-urgency score, 0..1"),
|
|
165
|
+
})).describe("The top-scoring PRs, descending by score"),
|
|
166
|
+
}).describe("Top PRs surfaced by the triage workflow");
|
|
167
|
+
|
|
168
|
+
const fetchStep = defineStep({
|
|
169
|
+
name: "fetch-prs",
|
|
170
|
+
input: InputSchema,
|
|
171
|
+
output: FetchOutput,
|
|
172
|
+
run: async ({ input }) => {
|
|
173
|
+
// Pure server-side work: fetch, parse, transform.
|
|
174
|
+
return { prs: [/* ... */] };
|
|
175
|
+
},
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
const scoreStep = defineStep({
|
|
179
|
+
name: "score-prs",
|
|
180
|
+
input: FetchOutput,
|
|
181
|
+
output: ScoreOutput,
|
|
182
|
+
run: ({ input }) => ({
|
|
183
|
+
scored: input.prs.map(p => ({ number: p.number, score: 0 })),
|
|
184
|
+
}),
|
|
185
|
+
});
|
|
186
|
+
|
|
187
|
+
const pickTopStep = defineStep({
|
|
188
|
+
name: "pick-top",
|
|
189
|
+
input: ScoreOutput,
|
|
190
|
+
output: OutputSchema,
|
|
191
|
+
run: ({ input }) => ({ top: input.scored.slice(0, 5) }),
|
|
192
|
+
});
|
|
193
|
+
|
|
194
|
+
export default defineWorkflow({
|
|
195
|
+
id: "pr-triage",
|
|
196
|
+
description: "Pulls open PRs from a GitHub repo, scores each one by review urgency, surfaces the top five.",
|
|
197
|
+
input: InputSchema,
|
|
198
|
+
output: OutputSchema,
|
|
199
|
+
})
|
|
200
|
+
.step(fetchStep)
|
|
201
|
+
.step(scoreStep)
|
|
202
|
+
.step(pickTopStep)
|
|
203
|
+
.build();
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
Notes:
|
|
207
|
+
- Each step's `output` schema must satisfy the next step's `input`
|
|
208
|
+
schema (the SDK enforces this at `defineWorkflow().step(...)` time
|
|
209
|
+
via TS inference). Reshape inside the upstream step's `run` body,
|
|
210
|
+
not at the boundary.
|
|
211
|
+
- Step bodies don't receive a `sandbox`. If a step needs to run code
|
|
212
|
+
inside the runner VM, that's the agent-driven shape — use run-form.
|
|
213
|
+
|
|
214
|
+
### Template B — run-form (agent-driven body)
|
|
215
|
+
|
|
216
|
+
```ts
|
|
217
|
+
import { defineWorkflow, agent, claudeRuntime } from "@agent-compose/sdk";
|
|
218
|
+
import { z } from "zod";
|
|
219
|
+
import PROMPT from "./prompt.md" with { type: "text" };
|
|
220
|
+
|
|
221
|
+
const InputSchema = z.object({
|
|
222
|
+
repo: z.string().describe("GitHub repository as `owner/name`"),
|
|
223
|
+
}).describe("Inputs for the code review agent");
|
|
224
|
+
|
|
225
|
+
const OutputSchema = z.object({
|
|
226
|
+
ok: z.boolean().describe("True when the agent finished its review"),
|
|
227
|
+
summary: z.string().optional().describe("One-paragraph summary of the agent's findings"),
|
|
228
|
+
}).describe("Result of the code review agent");
|
|
229
|
+
|
|
230
|
+
export default defineWorkflow({
|
|
231
|
+
description: "Runs an LLM agent that reviews recent changes in a repo and writes a summary.",
|
|
232
|
+
input: InputSchema,
|
|
233
|
+
output: OutputSchema,
|
|
234
|
+
|
|
235
|
+
async run(ctx, sandbox) {
|
|
236
|
+
// Pre-agent setup. `ctx.step("phase", () => ...)` is for the run
|
|
237
|
+
// timeline — emits step_started / step_completed events. It's
|
|
238
|
+
// observability sugar, not an engine step.
|
|
239
|
+
const data = await ctx.step("fetch-input", async () => {
|
|
240
|
+
// pure-server fetch / preparation
|
|
241
|
+
return { /* ... */ };
|
|
242
|
+
});
|
|
243
|
+
|
|
244
|
+
// Agent loop — the LLM iterates against the sandbox until it
|
|
245
|
+
// emits `exit_signal: true` or hits the budget.
|
|
246
|
+
const result = await agent({
|
|
247
|
+
sandbox,
|
|
248
|
+
runtime: claudeRuntime,
|
|
249
|
+
prompt: `${PROMPT}\n\nContext: ${JSON.stringify(data)}`,
|
|
250
|
+
tools: ["Read", "Write", "Edit", "Bash", "Grep", "Glob"],
|
|
251
|
+
budget: { turnsPerIteration: 40, maxIterations: 6 },
|
|
252
|
+
// responseSchema: MyZodSchema, // for typed handoffs
|
|
253
|
+
});
|
|
254
|
+
|
|
255
|
+
await ctx.setMetadata({ summary: result.status?.summary });
|
|
256
|
+
return {
|
|
257
|
+
ok: !!result.status?.completed,
|
|
258
|
+
summary: result.status?.summary,
|
|
259
|
+
};
|
|
260
|
+
},
|
|
261
|
+
|
|
262
|
+
// ── Optional metadata, attached by the bundler at registration ──
|
|
263
|
+
//
|
|
264
|
+
// networkPolicy: outbound traffic + brokered secret substitution.
|
|
265
|
+
// networkPolicy: {
|
|
266
|
+
// allow: {
|
|
267
|
+
// "api.github.com": [{ transform: [{ headers: {
|
|
268
|
+
// Authorization: "basic:$GITHUB_TOKEN",
|
|
269
|
+
// } }] }],
|
|
270
|
+
// },
|
|
271
|
+
// },
|
|
272
|
+
// // Placeholder values the runner sees in env vars AFTER brokering.
|
|
273
|
+
// // Only needed when a tool / SDK validates the env var format on
|
|
274
|
+
// // startup. The real secret never enters the VM — Vercel's
|
|
275
|
+
// // firewall substitutes it on the way out.
|
|
276
|
+
// placeholders: { GITHUB_TOKEN: "ghp_" + "x".repeat(36) },
|
|
277
|
+
//
|
|
278
|
+
// snapshots — boot source + capture mode:
|
|
279
|
+
// snapshots: {
|
|
280
|
+
// bootFrom: { snapshotId: "snap_abc…" },
|
|
281
|
+
// saveLatest: true,
|
|
282
|
+
// retainSteps: false,
|
|
283
|
+
// },
|
|
284
|
+
//
|
|
285
|
+
// memory — opt-in. Requires `workflow-memory` to be registered in
|
|
286
|
+
// this factory.
|
|
287
|
+
// memory: true,
|
|
288
|
+
//
|
|
289
|
+
// postRunHooks — workflows that run after this one completes:
|
|
290
|
+
// postRunHooks: ["audit-trail", "notify-slack"],
|
|
291
|
+
});
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
Notes:
|
|
295
|
+
- Always declare the return type (or let TS infer + show it on hover).
|
|
296
|
+
- `Promise.all` to fan out independent `agent` calls.
|
|
297
|
+
- `ctx.step("phase-name", () => …)` for any named non-agent phase
|
|
298
|
+
worth showing on the dashboard timeline.
|
|
299
|
+
|
|
300
|
+
### Sandbox environment companion (only when you decided one is needed)
|
|
301
|
+
|
|
302
|
+
```ts
|
|
303
|
+
// playwright-env.ts — captures a baseline VM with Playwright pre-installed.
|
|
304
|
+
// Register this first with `agentc register playwright-env.ts --build`
|
|
305
|
+
// so the snapshot exists before user workflows reference it.
|
|
306
|
+
import { defineSandboxEnvironment } from "@agent-compose/sdk";
|
|
307
|
+
|
|
308
|
+
export default defineSandboxEnvironment({
|
|
309
|
+
name: "playwright-env",
|
|
310
|
+
description: "Sandbox with Playwright + Chromium installed for browser-using agents.",
|
|
311
|
+
setup: async (sb) => {
|
|
312
|
+
await sb.commands.run("sudo npm install -g playwright");
|
|
313
|
+
await sb.commands.run("sudo npx playwright install --with-deps chromium");
|
|
314
|
+
},
|
|
315
|
+
});
|
|
316
|
+
```
|
|
317
|
+
|
|
318
|
+
After `agentc register --build` succeeds, the CLI prints a snapshot
|
|
319
|
+
id; reference it on the user workflow:
|
|
320
|
+
|
|
321
|
+
```ts
|
|
322
|
+
export default defineWorkflow({
|
|
323
|
+
description: "...",
|
|
324
|
+
input: InputSchema,
|
|
325
|
+
output: OutputSchema,
|
|
326
|
+
snapshots: { bootFrom: { snapshotId: "<id from --build>" } },
|
|
327
|
+
// ...
|
|
328
|
+
});
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
## Final steps
|
|
332
|
+
|
|
333
|
+
1. Show the user the file(s) you plan to write and confirm before
|
|
334
|
+
writing. In plain language: "I'll create `pr-triage.ts` in
|
|
335
|
+
`src/workflows/`. It takes `{ repo, limit }` and returns
|
|
336
|
+
`{ top: [...] }`. Sound right?"
|
|
337
|
+
2. Write the files.
|
|
338
|
+
3. Suggest `bun run typecheck` (or the project's equivalent) to
|
|
339
|
+
validate.
|
|
340
|
+
4. Tell the user the next commands in plain English:
|
|
341
|
+
- "To register: `agentc register src/workflows/pr-triage.ts`."
|
|
342
|
+
- "To test it: `agentc invoke pr-triage --follow`."
|
|
343
|
+
- (If you added a sandbox env companion: "First register the
|
|
344
|
+
`playwright-env` workflow with `--build` so the snapshot is
|
|
345
|
+
captured, then register and invoke `pr-triage`.")
|
|
346
|
+
- (If the user asked for a schedule at step 6:
|
|
347
|
+
"To run it on the schedule: `agentc schedule create pr-triage-daily
|
|
348
|
+
--workflow pr-triage --cron '<expr>'` — the cron pattern we
|
|
349
|
+
worked out earlier.")
|
|
123
350
|
|
|
124
351
|
## When the user asks for memory extraction
|
|
125
352
|
|
|
126
|
-
The built-in memory extractor (`workflow-memory`) is a separate
|
|
127
|
-
that must be registered in the same factory. Walk them
|
|
353
|
+
The built-in memory extractor (`workflow-memory`) is a separate
|
|
354
|
+
workflow that must be registered in the same factory. Walk them
|
|
355
|
+
through it in user terms:
|
|
128
356
|
|
|
129
|
-
1.
|
|
357
|
+
1. "I'll add the `workflow-memory` recipe to your project."
|
|
358
|
+
Copy from `templates/workflow-memory.ts` (or
|
|
130
359
|
`.agentc/smoketest/workflows/workflow-memory.ts` for the smoke
|
|
131
|
-
variant)
|
|
132
|
-
2. `agentc register ./workflow-memory.ts` to install it.
|
|
133
|
-
3.
|
|
360
|
+
variant).
|
|
361
|
+
2. "Run `agentc register ./workflow-memory.ts` once to install it."
|
|
362
|
+
3. "Now any workflow with `memory: true` will trigger it after each
|
|
363
|
+
successful run."
|
|
134
364
|
|
|
135
|
-
|
|
136
|
-
use `postRunHooks: [...]` instead.
|
|
137
|
-
with the source run's full
|
|
365
|
+
For custom post-run workflows (analytics, audit, notifications)
|
|
366
|
+
without the built-in extractor, use `postRunHooks: [...]` instead.
|
|
367
|
+
Each post-hook runs in declaration order with the source run's full
|
|
368
|
+
context.
|
package/skills/ac:invoke.md
CHANGED
|
@@ -7,6 +7,13 @@ allowed-tools: Bash(agentc *)
|
|
|
7
7
|
|
|
8
8
|
# Invoke Workflow
|
|
9
9
|
|
|
10
|
+
A one-shot dispatch — the CLI POSTs to `/api/v1/factories/<slug>/templates/<name>/invoke`,
|
|
11
|
+
the server creates a run row, the worker boots a sandbox, and the
|
|
12
|
+
workflow runs. Scheduled runs go through the same dispatch path but
|
|
13
|
+
are triggered by a cron tick instead; they're tagged with
|
|
14
|
+
`_scheduleId` + `_scheduleName` on metadata so the dashboard shows
|
|
15
|
+
"schedule by <name>" on the row. This skill is the manual path.
|
|
16
|
+
|
|
10
17
|
## Context
|
|
11
18
|
|
|
12
19
|
Registered workflows:
|
|
@@ -18,7 +25,8 @@ Registered workflows:
|
|
|
18
25
|
|
|
19
26
|
The user wants to invoke: **$ARGUMENTS**
|
|
20
27
|
|
|
21
|
-
If
|
|
28
|
+
If `$ARGUMENTS` is empty, ask which workflow to invoke. Use the
|
|
29
|
+
registered workflows list above as suggestions.
|
|
22
30
|
|
|
23
31
|
Once you have the workflow name, dispatch it:
|
|
24
32
|
|
|
@@ -26,17 +34,31 @@ Once you have the workflow name, dispatch it:
|
|
|
26
34
|
agentc invoke <name> --follow
|
|
27
35
|
```
|
|
28
36
|
|
|
37
|
+
Common extra flags:
|
|
38
|
+
- `--input '{"k":"v"}'` — JSON input matching the workflow's `inputSchema`.
|
|
39
|
+
- `--factory <slug>` — invoke into a non-default factory.
|
|
40
|
+
- `--snapshot <snap_…>` — per-invocation `bootFrom` override (per `/ac:snapshots`).
|
|
41
|
+
|
|
29
42
|
## Output
|
|
30
43
|
|
|
31
44
|
Stream events as they arrive. When complete, report:
|
|
32
|
-
- Final outcome (success / failed)
|
|
33
|
-
-
|
|
34
|
-
- Any PR URL, plan URL, or artifact
|
|
35
|
-
or via `agentc logs <run-id>` after the fact)
|
|
45
|
+
- Final outcome (success / failed / cancelled / abandoned)
|
|
46
|
+
- Wall time (`run_complete` includes elapsed seconds)
|
|
47
|
+
- Any PR URL, plan URL, or artifact emitted (visible in the streamed
|
|
48
|
+
events or via `agentc logs <run-id>` after the fact)
|
|
36
49
|
|
|
37
50
|
## Next Steps
|
|
38
51
|
|
|
39
|
-
- **Success** → Report
|
|
40
|
-
- **Failed** → Show the failure reason. Offer
|
|
41
|
-
|
|
42
|
-
- **
|
|
52
|
+
- **Success** → Report outcome + any output emitted.
|
|
53
|
+
- **Failed** → Show the failure reason. Offer `/ac:logs <run-id>` for
|
|
54
|
+
the full event stream.
|
|
55
|
+
- **Secrets missing** → "Run `/ac:secrets set <workflow> <KEY> <value>`
|
|
56
|
+
to configure the required secret."
|
|
57
|
+
- **Template not found** → "Run `/ac:register <workflow.ts>` to
|
|
58
|
+
register it first."
|
|
59
|
+
- **Snapshot missing (`bootFrom` 503)** → The snapshot id this
|
|
60
|
+
workflow boots from was deleted. List captured snapshots
|
|
61
|
+
(`/ac:snapshots`) and update the workflow's `snapshots: { bootFrom }`
|
|
62
|
+
with a current id, then re-register.
|
|
63
|
+
- **Want it to run on a schedule?** → `/ac:schedule create <name>
|
|
64
|
+
--workflow <wf> --cron '<expr>'`.
|
|
@@ -7,22 +7,59 @@ allowed-tools: Bash(agentc *)
|
|
|
7
7
|
|
|
8
8
|
# Register and Invoke
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
Bundle + register a workflow, then dispatch it once and stream the run.
|
|
11
|
+
Tight inner-loop for verifying source-level changes against the server.
|
|
12
|
+
|
|
13
|
+
## Instructions
|
|
14
|
+
|
|
15
|
+
The user passed: **$ARGUMENTS**
|
|
16
|
+
|
|
17
|
+
If `$ARGUMENTS` is empty, ask for the workflow file path before
|
|
18
|
+
proceeding.
|
|
19
|
+
|
|
20
|
+
Parse out the workflow file (first positional arg, ends in `.ts`).
|
|
21
|
+
Anything after it (`--input`, `--factory`, etc.) is passed through to
|
|
22
|
+
`agentc invoke`.
|
|
11
23
|
|
|
12
24
|
## Plan
|
|
13
25
|
|
|
14
26
|
```bash
|
|
15
|
-
|
|
16
|
-
agentc
|
|
27
|
+
# Register the file:
|
|
28
|
+
agentc register <workflow.ts>
|
|
29
|
+
|
|
30
|
+
# Then invoke it by name (basename minus .ts) and stream:
|
|
31
|
+
agentc invoke <workflow-name> --follow [...invoke flags]
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
If the user wants the workflow to run on a schedule instead of (or in
|
|
35
|
+
addition to) the one-shot test, suggest `/ac:schedule create` AFTER the
|
|
36
|
+
register completes — schedules live independently of register/invoke
|
|
37
|
+
and shouldn't be mixed into this iteration loop.
|
|
38
|
+
|
|
39
|
+
For the shorthand path (one schedule per workflow, named after the
|
|
40
|
+
workflow), pass `--schedule '<cron>'` to `agentc register`:
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
agentc register <workflow.ts> --schedule '0 9 * * *'
|
|
17
44
|
```
|
|
18
45
|
|
|
19
|
-
|
|
46
|
+
That creates + reconciles the schedule at register time; you still
|
|
47
|
+
need a manual `agentc invoke` to test it without waiting for the next
|
|
48
|
+
tick.
|
|
20
49
|
|
|
21
50
|
## Output
|
|
22
51
|
|
|
23
|
-
Show register output, then stream the run. When complete, report
|
|
52
|
+
Show register output, then stream the run live. When complete, report:
|
|
53
|
+
- Final outcome (success / failed / abandoned)
|
|
54
|
+
- Wall time (from `run_complete`)
|
|
55
|
+
- Any PR URL, plan URL, or artifact emitted along the way
|
|
24
56
|
|
|
25
57
|
## Next Steps
|
|
26
58
|
|
|
27
|
-
- **Registration failed** →
|
|
28
|
-
|
|
59
|
+
- **Registration failed** → Re-read the bundler / validator error.
|
|
60
|
+
Usually a missing import path, malformed `defineWorkflow(...)`, or a
|
|
61
|
+
manifest mismatch. Fix and re-run.
|
|
62
|
+
- **Run failed** → Show failure reason from the final event. Offer
|
|
63
|
+
`/ac:logs <run-id>` for the full event stream.
|
|
64
|
+
- **Need a schedule** → `/ac:schedule create <name> --workflow <wf>
|
|
65
|
+
--cron '<expr>'` after this completes.
|
package/skills/ac:register.md
CHANGED
|
@@ -36,7 +36,10 @@ Confirm:
|
|
|
36
36
|
|
|
37
37
|
## Next Steps
|
|
38
38
|
|
|
39
|
-
- **Success** → "Registered. Run `/ac:invoke <name>` to test it.
|
|
39
|
+
- **Success** → "Registered. Run `/ac:invoke <name>` to test it.
|
|
40
|
+
Want it on a schedule? `/ac:schedule create <name> --workflow <wf>
|
|
41
|
+
--cron '<expr>'` (or pass `--schedule '<expr>'` next time you
|
|
42
|
+
register for the auto-shorthand)."
|
|
40
43
|
- **Bundle failed** → Re-read the bundler error; usually a missing import path
|
|
41
44
|
or a runtime that couldn't be resolved.
|
|
42
45
|
- **Validation error** → Fix the reported issue in the source file and re-run.
|