@automatalabs/workflows 0.23.1 → 0.23.2
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 +69 -37
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -6,17 +6,19 @@ The programmatic **SDK** for AgentPrism — run dynamic, multi-agent **workflow
|
|
|
6
6
|
|
|
7
7
|
You author a small JavaScript **script** (a string), the engine runs it in a deterministic,
|
|
8
8
|
journaled, resumable realm, and every `agent()` call inside it is fanned out to a pooled ACP
|
|
9
|
-
backend — **Claude** (`claude-agent-acp`)
|
|
10
|
-
subprocess to completion.
|
|
9
|
+
backend — **Claude** (`claude-agent-acp`), **Codex** (`codex-acp`), **OpenCode** (`opencode acp`),
|
|
10
|
+
or a registered custom ACP agent — driving the actual subprocess to completion.
|
|
11
11
|
|
|
12
12
|
This package is the **canonical SDK** that the stdio MCP server
|
|
13
13
|
[`@automatalabs/mcp-server`](https://www.npmjs.com/package/@automatalabs/mcp-server) is built on.
|
|
14
14
|
If you want to expose a `workflow` tool to an MCP host (Claude Code, Zed, …), use that package; if
|
|
15
15
|
you want to embed the runner in your own program, use this one.
|
|
16
16
|
|
|
17
|
-
It is a **
|
|
18
|
-
|
|
19
|
-
|
|
17
|
+
It is a **programmatic library**, not an MCP stdio server. It is a thin facade over the engine +
|
|
18
|
+
ACP packages and adds one convenience helper, `runDynamicWorkflow`, which defaults the agent
|
|
19
|
+
backend to ACP. The ACP layer does use `@modelcontextprotocol/sdk` internally when it hosts the
|
|
20
|
+
optional StructuredOutput tool for eligible agents; consumers still interact through this SDK's
|
|
21
|
+
workflow/runner APIs rather than MCP server schemas.
|
|
20
22
|
|
|
21
23
|
---
|
|
22
24
|
|
|
@@ -26,8 +28,9 @@ convenience helper, `runDynamicWorkflow`, which defaults the agent backend to AC
|
|
|
26
28
|
pnpm add @automatalabs/workflows
|
|
27
29
|
```
|
|
28
30
|
|
|
29
|
-
> The
|
|
30
|
-
>
|
|
31
|
+
> The Claude and Codex ACP servers ship as transitive dependencies and are spawned on demand.
|
|
32
|
+
> OpenCode is host-resolved: install `opencode-ai` or make `opencode` available on `PATH` before
|
|
33
|
+
> routing a call to it.
|
|
31
34
|
|
|
32
35
|
---
|
|
33
36
|
|
|
@@ -39,6 +42,7 @@ pnpm add @automatalabs/workflows
|
|
|
39
42
|
- **Claude** — a logged-in Claude Code install (`~/.claude`) **or** `ANTHROPIC_API_KEY` in the
|
|
40
43
|
environment.
|
|
41
44
|
- **Codex** — a logged-in Codex install (`~/.codex`).
|
|
45
|
+
- **OpenCode** — credentials configured for the provider OpenCode will use.
|
|
42
46
|
|
|
43
47
|
You only need auth for the backend(s) your scripts actually route to. The default backend is
|
|
44
48
|
Claude (override with `AGENTPRISM_DEFAULT_BACKEND`; see [Backend selection](#backend-selection)).
|
|
@@ -94,6 +98,8 @@ Options (`RunDynamicWorkflowOptions`):
|
|
|
94
98
|
| `cwd` | `string` | Base working directory for the run (e.g. the project root): every subagent session runs here (a per-agent `agent({ cwd })` or worktree isolation overrides it), worktrees branch from it, and `agentType` definitions are scanned from it. Omitted ⇒ `process.cwd()`. |
|
|
95
99
|
| `runner` | `AgentRunner` | Swap the backend (or stub it in tests). Omitted ⇒ `createAcpRunner()`. |
|
|
96
100
|
| `exec` | `ExecOptions` | Per-run controls forwarded to the manager: `tokenBudget`, `agentTimeoutMs`, `concurrency`, `agentRetries`, `signal`, `onProgress`, `confirm`, … |
|
|
101
|
+
| `allowScriptBackends` | `boolean \| callback` | Approve the commands declared in `meta.backends`; declarations are inert without host approval. |
|
|
102
|
+
| `workflows` | `string \| string[] \| WorkflowDir` | Resolve the first argument and nested `workflow("name")` calls from one or more directories. |
|
|
97
103
|
|
|
98
104
|
```ts
|
|
99
105
|
const run = await runDynamicWorkflow(script, {
|
|
@@ -126,7 +132,7 @@ try {
|
|
|
126
132
|
type: "object", additionalProperties: false,
|
|
127
133
|
required: ["summary"], properties: { summary: { type: "string" } },
|
|
128
134
|
},
|
|
129
|
-
model: "opus", // routes to Claude; e.g. "gpt-5
|
|
135
|
+
model: "opus", // routes to Claude; e.g. "gpt-5.5" routes to Codex
|
|
130
136
|
cwd: process.cwd(), // absolute working dir for the agent's session
|
|
131
137
|
});
|
|
132
138
|
// data is the schema-validated object (not text)
|
|
@@ -137,13 +143,13 @@ try {
|
|
|
137
143
|
}
|
|
138
144
|
```
|
|
139
145
|
|
|
140
|
-
`run(prompt, options?)` accepts the seam's `RunOptions`: `schema`, `model`, `tier`, `cwd`,
|
|
141
|
-
`instructions`, `label`, `toolNames` / `disallowedToolNames`, `signal`, `mcpServers`,
|
|
142
|
-
`meta` / `promptMeta` (generic ACP `_meta` passthroughs merged into `session/new` /
|
|
143
|
-
`session/prompt`), `baseInstructions` / `developerInstructions` (Codex-only), and
|
|
144
|
-
|
|
145
|
-
usage is delivered via `onUsage` (it may never fire — ACP usage is
|
|
146
|
-
return value.
|
|
146
|
+
`run(prompt, options?)` accepts the seam's `RunOptions`: `schema`, `maxSchemaRetries`, `model`, `mode`, `tier`, `cwd`,
|
|
147
|
+
`instructions`, `label`, `toolNames` / `disallowedToolNames`, `signal`, `mcpServers`, `images`,
|
|
148
|
+
`backends`, `meta` / `promptMeta` (generic ACP `_meta` passthroughs merged into `session/new` /
|
|
149
|
+
`session/prompt`), `baseInstructions` / `developerInstructions` (Codex-only), `keepSession`, and
|
|
150
|
+
the out-of-band callbacks `onUsage` / `onModelResolved` / `onModelFallback` / `onHistory` /
|
|
151
|
+
`onSessionOpen`. Token/cost usage is delivered via `onUsage` (it may never fire — ACP usage is
|
|
152
|
+
experimental), never via the return value.
|
|
147
153
|
|
|
148
154
|
> **Codex session instructions.** When the run routes to the Codex backend, `baseInstructions`
|
|
149
155
|
> **replaces** Codex's built-in base system prompt and `developerInstructions` adds developer-role
|
|
@@ -153,7 +159,7 @@ return value.
|
|
|
153
159
|
>
|
|
154
160
|
> ```ts
|
|
155
161
|
> await runner.run("Cut the release.", {
|
|
156
|
-
> model: "gpt-5
|
|
162
|
+
> model: "gpt-5.5",
|
|
157
163
|
> baseInstructions: "You are a release bot. Only touch CHANGELOG.md.",
|
|
158
164
|
> developerInstructions: "Prefer conventional-commit summaries.",
|
|
159
165
|
> });
|
|
@@ -175,9 +181,10 @@ return value.
|
|
|
175
181
|
>
|
|
176
182
|
> `model: "browser/vision-large"` additionally selects `vision-large` from the agent's config-option
|
|
177
183
|
> catalog. The same registry can be declared via `AGENTPRISM_BACKENDS` (JSON env var; the
|
|
178
|
-
> programmatic option wins per name). A `schema` is forwarded
|
|
179
|
-
>
|
|
180
|
-
>
|
|
184
|
+
> programmatic option wins per name). A `schema` is forwarded as turn-level `_meta.outputSchema`
|
|
185
|
+
> and embedded in the prompt. Eligible HTTP-MCP agents also receive the client-hosted
|
|
186
|
+
> `StructuredOutput` capture tool; otherwise the result is JSON-parsed from the final message.
|
|
187
|
+
> Every path still goes through the validate/re-prompt ladder.
|
|
181
188
|
>
|
|
182
189
|
> A workflow **script** can also declare backends itself via `meta.backends` (same config shape,
|
|
183
190
|
> keyed by name). Because script-declared backends spawn commands on your machine, they are inert
|
|
@@ -187,6 +194,20 @@ return value.
|
|
|
187
194
|
> its `agent()` calls to the default backend). Host-registered names always win over script
|
|
188
195
|
> declarations. Lower-level callers can thread a pre-approved registry via `exec.scriptBackends`.
|
|
189
196
|
|
|
197
|
+
#### Authentication lifecycle
|
|
198
|
+
|
|
199
|
+
`createAcpRunner()` is auth-capable. It exposes `describeAuthMethods()` / `completeAuth()` and the
|
|
200
|
+
`runner.auth` controller (`status`, `authenticate`, `logout`) while preserving the minimal
|
|
201
|
+
`AgentRunner.run()` seam. Existing environment variables and backend-native credential stores are
|
|
202
|
+
used normally. A direct `runner.run()` throws `WorkflowError { code: "AUTH_REQUIRED" }` when no
|
|
203
|
+
resolver can satisfy the backend; a `WorkflowManager` catches that code and returns a resumable
|
|
204
|
+
`paused` result with redacted `authContext`.
|
|
205
|
+
|
|
206
|
+
Pass `onAuth` and `authCapabilities` to `createAcpRunner()` when the embedding host can collect
|
|
207
|
+
credentials inline. Secret env/meta resolutions live in the runner's in-memory auth store, are
|
|
208
|
+
redacted from events/errors, and are cleared on logout. Browser/TTY methods still require a host
|
|
209
|
+
that can actually complete them.
|
|
210
|
+
|
|
190
211
|
### c) `WorkflowManager` — stateful / resumable runs
|
|
191
212
|
|
|
192
213
|
`runDynamicWorkflow` is a thin wrapper over a fresh `WorkflowManager`. Construct one yourself to
|
|
@@ -200,18 +221,18 @@ const manager = new WorkflowManager({ agent: createAcpRunner() });
|
|
|
200
221
|
const run = await manager.runSync(script, { repo: "agentprism" }, { tokenBudget: 200_000 });
|
|
201
222
|
|
|
202
223
|
if (run.status === "paused") {
|
|
203
|
-
//
|
|
204
|
-
//
|
|
205
|
-
const
|
|
206
|
-
|
|
207
|
-
const finished = await manager.runSync(script, { repo: "agentprism" }, { resumeJournal });
|
|
208
|
-
console.log(finished.status); // "completed", typically
|
|
224
|
+
// resume() reloads the original script, args, cwd, and journal under the SAME runId,
|
|
225
|
+
// then continues in the background. Observe manager events or getRun(runId) for status.
|
|
226
|
+
const accepted = await manager.resume(run.runId);
|
|
227
|
+
console.log(accepted); // true when the paused run was accepted for resume
|
|
209
228
|
}
|
|
210
229
|
```
|
|
211
230
|
|
|
212
231
|
`runSync(script, args?, exec?)` always resolves to a terminal `WorkflowRunResult`. A run **pauses**
|
|
213
|
-
(rather than fails) on a provider usage limit or
|
|
214
|
-
above. `
|
|
232
|
+
(rather than fails) on a provider usage limit or ACP authentication requirement; both are
|
|
233
|
+
resumable as above. A headless `checkpoint()` applies its configured default or abort behavior.
|
|
234
|
+
An auth pause carries `reason: "auth_required"` plus a non-secret `authContext`; complete auth on
|
|
235
|
+
an auth-capable runner before resuming. `WorkflowManagerOptions` lets you set a default `agent`, `concurrency`, `cwd`, a
|
|
215
236
|
`loadSavedWorkflow` resolver (enables nested `workflow('name')`), a custom `persistence`
|
|
216
237
|
implementation, and per-agent timeout/retry defaults.
|
|
217
238
|
|
|
@@ -229,6 +250,12 @@ names.
|
|
|
229
250
|
manager.on("agentEvent", ({ runId, label, name }) => console.error(runId, label, name));
|
|
230
251
|
```
|
|
231
252
|
|
|
253
|
+
Every live ACP-backed `agent()` call records a non-secret re-attach handle in
|
|
254
|
+
`run.agentSessions`. Set `agent(..., { keepSession: true })` to skip release-time `session/close`,
|
|
255
|
+
then use the runner's `loadSession()` or `resumeSession()` host API with that record. Session
|
|
256
|
+
handles are additive and are also preserved in journals; they do not change the deterministic
|
|
257
|
+
resume identity.
|
|
258
|
+
|
|
232
259
|
### d) Bring your own backend — implement the `AgentRunner` seam
|
|
233
260
|
|
|
234
261
|
`AgentRunner` is the single, frozen coupling point between the engine and any backend. Implement
|
|
@@ -434,8 +461,8 @@ report.warnings; // approval reminders, phase mismatches, headless-abo
|
|
|
434
461
|
|
|
435
462
|
Pass a JSON Schema to `agent({ schema })` (in a script) or `runner.run(prompt, { schema })` (direct)
|
|
436
463
|
and the result is a **validated object** instead of text. The backend constrains output natively
|
|
437
|
-
(Claude `outputFormat`; Codex strict `outputSchema
|
|
438
|
-
client-side (typebox `Convert` → `Check`); on a miss the runner re-prompts a bounded number of
|
|
464
|
+
(Claude `outputFormat`; Codex strict `outputSchema`; prompt/tool-assisted JSON for OpenCode and
|
|
465
|
+
custom agents), then the value is coerced and validated client-side (typebox `Convert` → `Check`); on a miss the runner re-prompts a bounded number of
|
|
439
466
|
times before failing with a non-recoverable `SCHEMA_NONCOMPLIANCE`.
|
|
440
467
|
|
|
441
468
|
A **plain JSON Schema object literal** works everywhere (this is the only option inside a script —
|
|
@@ -473,16 +500,17 @@ toStrictJsonSchema(schema); // OpenAI-strict-normalized (Codex outputSchema)
|
|
|
473
500
|
The backend for each agent is chosen from its `model` (preferred) or `tier` string:
|
|
474
501
|
|
|
475
502
|
- **Provider prefix** — `anthropic/…` or `claude/…` ⇒ Claude; `openai/…` or `codex/…` ⇒ Codex.
|
|
503
|
+
- **OpenCode prefix or id** — `opencode/…` or `opencode` ⇒ OpenCode.
|
|
476
504
|
- **Bare id** — matched by pattern: `codex` / `gpt` / `openai` / `o<digit>` ⇒ Codex;
|
|
477
505
|
`claude` / `opus` / `sonnet` / `haiku` / `anthropic` ⇒ Claude.
|
|
478
506
|
- **No match / no spec** — the default backend: `AGENTPRISM_DEFAULT_BACKEND` (`claude`, `codex`,
|
|
479
|
-
or any registered custom backend name; default `claude`).
|
|
507
|
+
`opencode`, or any registered custom backend name; default `claude`).
|
|
480
508
|
|
|
481
509
|
```ts
|
|
482
510
|
import { selectBackend } from "@automatalabs/workflows";
|
|
483
511
|
|
|
484
512
|
selectBackend({ model: "opus" }).id; // "claude"
|
|
485
|
-
selectBackend({ model: "gpt-5
|
|
513
|
+
selectBackend({ model: "gpt-5.5" }).id; // "codex"
|
|
486
514
|
selectBackend({ model: "anthropic/claude-sonnet" }).id; // "claude"
|
|
487
515
|
```
|
|
488
516
|
|
|
@@ -509,14 +537,16 @@ WorkflowManager, // stateful / resumable run manager
|
|
|
509
537
|
createAcpRunner, // () => AcpAgentRunner (the default AgentRunner; has .on(...) events)
|
|
510
538
|
AcpAgentRunner, // class — implements AgentRunner over ACP
|
|
511
539
|
InteractiveSession, // held-open multi-turn ACP session returned by openSession()
|
|
512
|
-
selectBackend, // pick
|
|
513
|
-
ClaudeBackend, CodexBackend,
|
|
540
|
+
selectBackend, // pick a built-in/custom backend from a model/tier spec
|
|
541
|
+
ClaudeBackend, CodexBackend, CustomAcpBackend,
|
|
542
|
+
resolveBackendRegistry, BACKENDS_ENV,
|
|
543
|
+
AGENT_METHODS, CLIENT_METHODS, ACP_AUTH_REQUIRED_ERROR_CODE,
|
|
514
544
|
clientCapabilitiesFor, adaptPromptContent,
|
|
515
545
|
toJsonSchema, toStrictJsonSchema,
|
|
516
546
|
TypedEventEmitter, // the tiny typed emitter backing runner.on(...)
|
|
517
547
|
|
|
518
548
|
// ── Errors ──
|
|
519
|
-
WorkflowError, WorkflowErrorCode, isWorkflowError, isProviderUsageLimit,
|
|
549
|
+
WorkflowError, WorkflowErrorCode, isWorkflowError, isProviderUsageLimit, isAuthRequired,
|
|
520
550
|
|
|
521
551
|
// ── Persistence paths ──
|
|
522
552
|
AGENTPRISM_PERSISTENCE_ROOT_ENV,
|
|
@@ -526,8 +556,10 @@ RunDynamicWorkflowOptions, WorkflowRunOptions, AgentOptions, ExecOptions,
|
|
|
526
556
|
ValidateWorkflowOptions, ValidateWorkflowReport, ValidatedAgentCall, ValidatedCheckpoint,
|
|
527
557
|
WorkflowManagerOptions, CheckpointOptions, WorkflowRunResult, WorkflowSnapshot,
|
|
528
558
|
WorkflowPathOptions, RunPersistence, RunPersistenceOptions,
|
|
529
|
-
AcpPoolOptions, AgentRunner, RunOptions, AgentResult, AgentUsage, JournalEntry,
|
|
559
|
+
AcpPoolOptions, AcpRunnerOptions, AgentRunner, RunOptions, AgentResult, AgentUsage, JournalEntry,
|
|
560
|
+
AgentSessionRef, AgentSessionRecord, WorkflowBackendConfig,
|
|
530
561
|
InteractiveSessionOptions, InteractiveTurn, PermissionResolver,
|
|
562
|
+
AuthResolver, AuthContext, AuthResolution, AuthMethodDescriptor, AuthCapableRunner,
|
|
531
563
|
ClientHandlers, FsHandlers, TerminalHandlers, McpHandlers, AcpSessionContext, NegotiatedCapabilities,
|
|
532
564
|
// ACP events: the runner.on(...) surface
|
|
533
565
|
AcpRunnerEventMap, AcpEventName, AcpEventListener, AcpEventContext,
|
|
@@ -563,8 +595,8 @@ the exhaustive option tables.
|
|
|
563
595
|
## See also
|
|
564
596
|
|
|
565
597
|
- **[`@automatalabs/mcp-server`](https://www.npmjs.com/package/@automatalabs/mcp-server)** — the
|
|
566
|
-
stdio MCP server built on this SDK. It wraps the same engine + ACP backend behind
|
|
567
|
-
|
|
598
|
+
stdio MCP server built on this SDK. It wraps the same engine + ACP backend behind `workflow`
|
|
599
|
+
and conditional auth tools (bin: `agentprism-workflow`) for any MCP host. Use it when you want the
|
|
568
600
|
**MCP-tool route** instead of embedding the runner in code.
|
|
569
601
|
|
|
570
602
|
## License
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@automatalabs/workflows",
|
|
3
|
-
"version": "0.23.
|
|
3
|
+
"version": "0.23.2",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"engines": {
|
|
6
6
|
"node": ">=22"
|
|
@@ -31,8 +31,8 @@
|
|
|
31
31
|
},
|
|
32
32
|
"dependencies": {
|
|
33
33
|
"@automatalabs/shared-types": "0.14.0",
|
|
34
|
-
"@automatalabs/
|
|
35
|
-
"@automatalabs/
|
|
34
|
+
"@automatalabs/workflow-engine": "0.12.0",
|
|
35
|
+
"@automatalabs/acp-agents": "0.22.2"
|
|
36
36
|
},
|
|
37
37
|
"devDependencies": {
|
|
38
38
|
"typebox": "1.3.2"
|