cpa-agents 0.2.0 → 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 +158 -68
- package/dist/adapters/openclaw.d.ts +16 -4
- package/dist/adapters/openclaw.d.ts.map +1 -1
- package/dist/adapters/openclaw.js +100 -42
- package/dist/adapters/openclaw.js.map +1 -1
- package/dist/adapters/pi-harness.d.ts +58 -4
- package/dist/adapters/pi-harness.d.ts.map +1 -1
- package/dist/adapters/pi-harness.js +197 -37
- package/dist/adapters/pi-harness.js.map +1 -1
- package/dist/agent.js +2 -2
- package/dist/agent.js.map +1 -1
- package/dist/channel.d.ts +9 -2
- package/dist/channel.d.ts.map +1 -1
- package/dist/channel.js +138 -17
- package/dist/channel.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/jsonl.d.ts +25 -0
- package/dist/jsonl.d.ts.map +1 -0
- package/dist/jsonl.js +53 -0
- package/dist/jsonl.js.map +1 -0
- package/dist/process.d.ts.map +1 -1
- package/dist/process.js +68 -37
- package/dist/process.js.map +1 -1
- package/dist/scheduler.d.ts +14 -3
- package/dist/scheduler.d.ts.map +1 -1
- package/dist/scheduler.js +32 -1
- package/dist/scheduler.js.map +1 -1
- package/dist/session-tree.d.ts +3 -0
- package/dist/session-tree.d.ts.map +1 -0
- package/dist/session-tree.js +29 -0
- package/dist/session-tree.js.map +1 -0
- package/dist/version.d.ts +3 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +10 -0
- package/dist/version.js.map +1 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,14 +1,44 @@
|
|
|
1
1
|
# cpa-agents
|
|
2
2
|
|
|
3
|
-
Concurrent Process Algebra for AI Agents.
|
|
3
|
+
Concurrent Process Algebra for AI Agents.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
`cpa-agents` combines three layers:
|
|
6
|
+
- process algebra (pi-calculus primitives for concurrency/communication)
|
|
7
|
+
- fork algebra (relational composition and paired derivations)
|
|
8
|
+
- operator algebra (practical control flow: rollback, retries, guards, timeout)
|
|
9
|
+
|
|
10
|
+
Designed for [Pi Coding Agent](https://github.com/earendil-works/pi) (`@earendil-works/pi-coding-agent`), [OpenClaw](https://github.com/openclaw/openclaw), and standalone TypeScript workflows.
|
|
11
|
+
|
|
12
|
+
## Install
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
npm install cpa-agents
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Quick start
|
|
19
|
+
|
|
20
|
+
```typescript
|
|
21
|
+
import { Scheduler, par, agentProcess } from "cpa-agents";
|
|
6
22
|
|
|
7
|
-
|
|
23
|
+
const scheduler = new Scheduler({ timeout: 60_000 });
|
|
8
24
|
|
|
9
|
-
|
|
25
|
+
const research = par(
|
|
26
|
+
agentProcess(webSearchAgent, "latest React patterns"),
|
|
27
|
+
agentProcess(codeSearchAgent, "auth middleware examples"),
|
|
28
|
+
);
|
|
10
29
|
|
|
11
|
-
|
|
30
|
+
const result = await scheduler.run("research", research);
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Why
|
|
34
|
+
|
|
35
|
+
Most agent harnesses implement orchestration with ad-hoc control flow and minimal runtime semantics. This library provides formal, typed primitives for:
|
|
36
|
+
- concurrent task execution
|
|
37
|
+
- explicit synchronization and communication
|
|
38
|
+
- fix-and-resume branching
|
|
39
|
+
- provenance and rollback-aware workflows
|
|
40
|
+
|
|
41
|
+
## Layer 1: Process algebra
|
|
12
42
|
|
|
13
43
|
| π-calculus | cpa-agents | What it does |
|
|
14
44
|
|---|---|---|
|
|
@@ -19,26 +49,28 @@ This library gives you that model. The primitives come from Robin Milner's π-ca
|
|
|
19
49
|
| `ν(x).P` | `restrict(name, body)` | Create a fresh scoped channel |
|
|
20
50
|
| `!P` | `replicate(trigger, handler)` | Spawn new P for each incoming message |
|
|
21
51
|
|
|
22
|
-
|
|
52
|
+
Core runtime exports:
|
|
53
|
+
- `Channel`, `select`
|
|
54
|
+
- `par`, `seq`, `choice`, `branchFix`, `restrict`, `replicate`, `supervisor`
|
|
55
|
+
- `Scheduler`
|
|
23
56
|
|
|
24
|
-
### Branch-fix-continue
|
|
57
|
+
### Branch-fix-continue
|
|
25
58
|
|
|
26
|
-
|
|
59
|
+
Pattern for "run -> detect error -> fix -> resume".
|
|
27
60
|
|
|
28
61
|
```typescript
|
|
29
|
-
import { branchFix, Scheduler } from
|
|
62
|
+
import { branchFix, Scheduler } from "cpa-agents";
|
|
30
63
|
|
|
31
64
|
const workflow = branchFix<string>({
|
|
32
|
-
name:
|
|
65
|
+
name: "implement-feature",
|
|
33
66
|
maxFixes: 3,
|
|
34
67
|
|
|
35
68
|
main: (requestFix) => async (ctx) => {
|
|
36
|
-
const code = await coder.invoke(
|
|
69
|
+
const code = await coder.invoke("add auth middleware", ctx.signal);
|
|
37
70
|
const check = await linter.invoke(code, ctx.signal);
|
|
38
71
|
|
|
39
72
|
if (!check.pass) {
|
|
40
|
-
|
|
41
|
-
await requestFix(check.errors.join('; '));
|
|
73
|
+
await requestFix(check.errors.join("; "));
|
|
42
74
|
}
|
|
43
75
|
|
|
44
76
|
return code;
|
|
@@ -50,96 +82,154 @@ const workflow = branchFix<string>({
|
|
|
50
82
|
});
|
|
51
83
|
|
|
52
84
|
const scheduler = new Scheduler({ timeout: 60_000 });
|
|
53
|
-
const result = await scheduler.run(
|
|
54
|
-
// result.sessionTree shows the full branch history
|
|
85
|
+
const result = await scheduler.run("feature", workflow);
|
|
55
86
|
```
|
|
56
87
|
|
|
57
|
-
|
|
88
|
+
## Layer 2: Fork algebra (relations)
|
|
89
|
+
|
|
90
|
+
Fork algebra models relation composition and paired derivations over the same input.
|
|
58
91
|
|
|
59
92
|
```typescript
|
|
60
|
-
import {
|
|
93
|
+
import { rel, fork, compose, meet, join, toProcess } from "cpa-agents";
|
|
61
94
|
|
|
62
|
-
const
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
);
|
|
95
|
+
const parse = rel("parse", async (input: string) => [input.trim()]);
|
|
96
|
+
const enrich = rel("enrich", async (input: string) => [`${input}:meta`]);
|
|
97
|
+
const validate = rel("validate", async (input: string) => [input.length > 0 ? "ok" : "bad"]);
|
|
98
|
+
|
|
99
|
+
const composed = compose(parse, enrich);
|
|
100
|
+
const paired = fork(enrich, validate);
|
|
67
101
|
|
|
68
|
-
const
|
|
102
|
+
const proc = toProcess(composed, "task payload", "all");
|
|
103
|
+
const run = await scheduler.run("fork-layer", proc);
|
|
69
104
|
```
|
|
70
105
|
|
|
71
|
-
|
|
106
|
+
Key exports:
|
|
107
|
+
- `rel`, `detRel`
|
|
108
|
+
- `compose`, `fork`, `forkN`
|
|
109
|
+
- `converse` (provenance mapping, not rollback)
|
|
110
|
+
- `meet`, `join`, `identity`, `empty`
|
|
111
|
+
- `proj1`, `proj2`, `domRestrict`, `ranRestrict`
|
|
112
|
+
- `toProcess`, `forkToProcess`, `verifyAxioms`
|
|
113
|
+
|
|
114
|
+
## Layer 3: Operator algebra (control flow)
|
|
115
|
+
|
|
116
|
+
Operator layer provides shell-style and reliability-focused control flow.
|
|
72
117
|
|
|
73
118
|
```typescript
|
|
74
|
-
import {
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
)
|
|
119
|
+
import {
|
|
120
|
+
and,
|
|
121
|
+
or,
|
|
122
|
+
pipe,
|
|
123
|
+
saga,
|
|
124
|
+
invertible,
|
|
125
|
+
retryWithBackoff,
|
|
126
|
+
timeout,
|
|
127
|
+
} from "cpa-agents";
|
|
128
|
+
|
|
129
|
+
const guardedDeploy = and(buildProcess, deployProcess); // A && B
|
|
130
|
+
const withFallback = or(primaryProcess, fallbackProcess); // A || B
|
|
131
|
+
const piped = pipe(fetchProcess, (data) => transformProcess(data)); // A | B
|
|
132
|
+
|
|
133
|
+
const transactional = saga([
|
|
134
|
+
invertible(createBranch, deleteBranch),
|
|
135
|
+
invertible(writeChanges, revertChanges),
|
|
136
|
+
invertible(runChecks, cleanupChecks),
|
|
137
|
+
]);
|
|
138
|
+
|
|
139
|
+
const resilient = retryWithBackoff({
|
|
140
|
+
process: timeout(30_000, transactional),
|
|
141
|
+
maxAttempts: 3,
|
|
142
|
+
});
|
|
90
143
|
```
|
|
91
144
|
|
|
92
|
-
|
|
145
|
+
Key exports:
|
|
146
|
+
- `attempt`, `unwrap`
|
|
147
|
+
- `and`, `or`, `ifThenElse`, `pipe`, `pipeChain`
|
|
148
|
+
- `bg`, `waitAll`, `not`, `andChain`, `orChain`, `subshell`
|
|
149
|
+
- `invertible`, `runInvertible`, `saga`
|
|
150
|
+
- `guard`, `guardValue`, `timeout`, `retryWithBackoff`
|
|
151
|
+
|
|
152
|
+
## OpenClaw integration
|
|
153
|
+
|
|
154
|
+
```typescript
|
|
155
|
+
// ~/.openclaw/skills/cpa-agents/index.ts
|
|
156
|
+
import { createOpenClawSkill } from "cpa-agents/adapters/openclaw";
|
|
157
|
+
export default createOpenClawSkill();
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
Supported commands:
|
|
161
|
+
- `parallel`
|
|
162
|
+
- `branch-fix`
|
|
163
|
+
- `fan-out`
|
|
164
|
+
- `status`
|
|
165
|
+
|
|
166
|
+
Skill authoring docs are in `skills/cpa-agents/SKILL.md`.
|
|
167
|
+
|
|
168
|
+
## Pi Harness integration
|
|
169
|
+
|
|
170
|
+
Pi upstream lives at [`earendil-works/pi`](https://github.com/earendil-works/pi) with packages `@earendil-works/pi-coding-agent`, `@earendil-works/pi-agent-core`, and `@earendil-works/pi-ai`. The adapter below targets the extension API and expects `piCtx.agent.run(task)`:
|
|
93
171
|
|
|
94
172
|
```typescript
|
|
95
173
|
// .pi/extensions/cpa.ts
|
|
96
|
-
import { createPiCpaExtension } from
|
|
97
|
-
export default createPiCpaExtension();
|
|
174
|
+
import { createPiCpaExtension } from "cpa-agents/adapters/pi";
|
|
98
175
|
|
|
99
|
-
|
|
100
|
-
// /cpa:par implement auth | write tests | update docs
|
|
101
|
-
// /cpa:fix refactor the database layer
|
|
102
|
-
// /cpa:tree
|
|
176
|
+
export default createPiCpaExtension();
|
|
103
177
|
```
|
|
104
178
|
|
|
105
|
-
|
|
179
|
+
Extension commands: `cpa:par`, `cpa:fix`, `cpa:tree`, `cpa:retry`, `cpa:fallback`, `cpa:saga`, `cpa:fan-out`.
|
|
180
|
+
|
|
181
|
+
For standalone workflows outside the extension, wire factories via `configurePiBridge()` or pass `bridge` per factory:
|
|
106
182
|
|
|
107
183
|
```typescript
|
|
108
|
-
|
|
109
|
-
import { createOpenClawSkill } from 'cpa-agents/adapters/openclaw';
|
|
110
|
-
export default createOpenClawSkill();
|
|
184
|
+
import { configurePiBridge, piSubAgent } from "cpa-agents/adapters/pi";
|
|
111
185
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
186
|
+
configurePiBridge({
|
|
187
|
+
runSubAgent: async ({ prompt }, signal) => host.run(prompt, { signal }),
|
|
188
|
+
runTool: async ({ tool, args }, signal) => host.runTool(tool, args, { signal }),
|
|
189
|
+
});
|
|
115
190
|
```
|
|
116
191
|
|
|
117
|
-
## Session tree
|
|
192
|
+
## Session tree and trace
|
|
118
193
|
|
|
119
|
-
Every
|
|
194
|
+
Every scheduler run emits:
|
|
195
|
+
- `sessionTree` (hierarchical execution tree)
|
|
196
|
+
- `trace` (flat event list)
|
|
197
|
+
|
|
198
|
+
Persist traces as JSONL (Pi-compatible) and reload them:
|
|
120
199
|
|
|
121
200
|
```typescript
|
|
122
|
-
|
|
201
|
+
import { Scheduler, loadJsonlTree, eventsToSessionTree } from "cpa-agents";
|
|
202
|
+
|
|
203
|
+
const scheduler = new Scheduler();
|
|
204
|
+
const sink = scheduler.attachJsonl("./session.jsonl");
|
|
205
|
+
|
|
206
|
+
const result = await scheduler.run("workflow", myProcess);
|
|
207
|
+
await sink.close();
|
|
208
|
+
|
|
209
|
+
const tree = await loadJsonlTree("./session.jsonl");
|
|
210
|
+
// or: eventsToSessionTree(result.trace.events)
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
Inspect the live tree:
|
|
214
|
+
|
|
215
|
+
```typescript
|
|
216
|
+
const result = await scheduler.run("workflow", myProcess);
|
|
123
217
|
|
|
124
218
|
for (const node of result.sessionTree) {
|
|
125
219
|
console.log(node.name, node.runId);
|
|
126
220
|
for (const child of node.children) {
|
|
127
|
-
console.log(
|
|
221
|
+
console.log(" └─", child.name);
|
|
128
222
|
}
|
|
129
223
|
}
|
|
130
224
|
```
|
|
131
225
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
## Design decisions
|
|
135
|
-
|
|
136
|
-
**Synchronous rendezvous channels**, not buffered queues. A `send` blocks until a `receive` matches it. This is the π-calculus default and prevents the subtle bugs you get when messages pile up in buffers unobserved.
|
|
226
|
+
## Development
|
|
137
227
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
228
|
+
```bash
|
|
229
|
+
npm run check
|
|
230
|
+
npm test
|
|
231
|
+
npm run coverage
|
|
232
|
+
```
|
|
143
233
|
|
|
144
234
|
## License
|
|
145
235
|
|
|
@@ -3,19 +3,33 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Integrates cpa-agents as an OpenClaw skill.
|
|
5
5
|
*/
|
|
6
|
-
import { type TraceEvent
|
|
6
|
+
import { type TraceEvent } from "../process.js";
|
|
7
7
|
import { type AgentCall } from "../agent.js";
|
|
8
8
|
import { type SchedulerResult } from "../scheduler.js";
|
|
9
|
-
|
|
9
|
+
import { sessionTreeToMarkdown } from "../session-tree.js";
|
|
10
|
+
export { sessionTreeToMarkdown };
|
|
11
|
+
export declare const SKILL_MD: string;
|
|
12
|
+
export interface OpenClawBridge {
|
|
13
|
+
runTool: (tool: string, args: Record<string, unknown>, signal?: AbortSignal) => Promise<unknown>;
|
|
14
|
+
readMemory: (key: string, signal?: AbortSignal) => Promise<string>;
|
|
15
|
+
writeMemory: (input: {
|
|
16
|
+
key: string;
|
|
17
|
+
value: string;
|
|
18
|
+
}, signal?: AbortSignal) => Promise<void>;
|
|
19
|
+
}
|
|
20
|
+
/** Connect standalone openclawTool/workspaceAgent factories to a gateway. */
|
|
21
|
+
export declare function configureOpenClawBridge(bridge: OpenClawBridge | undefined): void;
|
|
10
22
|
export declare function openclawTool<TInput, TOutput>(opts: {
|
|
11
23
|
name: string;
|
|
12
24
|
tool: string;
|
|
13
25
|
buildArgs: (input: TInput) => Record<string, unknown>;
|
|
14
26
|
parseResult: (raw: unknown) => TOutput;
|
|
27
|
+
bridge?: OpenClawBridge;
|
|
15
28
|
}): AgentCall<TInput, TOutput>;
|
|
16
29
|
export declare function workspaceAgent(opts: {
|
|
17
30
|
name: string;
|
|
18
31
|
workspacePath?: string;
|
|
32
|
+
bridge?: OpenClawBridge;
|
|
19
33
|
}): {
|
|
20
34
|
readMemory: AgentCall<string, string>;
|
|
21
35
|
writeMemory: AgentCall<{
|
|
@@ -44,6 +58,4 @@ export declare function createOpenClawSkill(): {
|
|
|
44
58
|
skillMd: string;
|
|
45
59
|
handleCommand(command: string, args: Record<string, unknown>, openclawCtx: OpenClawContext): Promise<SchedulerResult<unknown>>;
|
|
46
60
|
};
|
|
47
|
-
export declare function sessionTreeToMarkdown(nodes: SessionNode[], depth?: number): string;
|
|
48
|
-
export {};
|
|
49
61
|
//# sourceMappingURL=openclaw.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"openclaw.d.ts","sourceRoot":"","sources":["../../src/adapters/openclaw.ts"],"names":[],"mappings":"AAAA;;;;GAIG;
|
|
1
|
+
{"version":3,"file":"openclaw.d.ts","sourceRoot":"","sources":["../../src/adapters/openclaw.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAGL,KAAK,UAAU,EAIhB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,KAAK,SAAS,EAAwB,MAAM,aAAa,CAAC;AAEnE,OAAO,EAAa,KAAK,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAClE,OAAO,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAG3D,OAAO,EAAE,qBAAqB,EAAE,CAAC;AAIjC,eAAO,MAAM,QAAQ,QAoGpB,CAAC;AAIF,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,CACP,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,MAAM,CAAC,EAAE,WAAW,KACjB,OAAO,CAAC,OAAO,CAAC,CAAC;IACtB,UAAU,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IACnE,WAAW,EAAE,CACX,KAAK,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EACrC,MAAM,CAAC,EAAE,WAAW,KACjB,OAAO,CAAC,IAAI,CAAC,CAAC;CACpB;AAID,6EAA6E;AAC7E,wBAAgB,uBAAuB,CACrC,MAAM,EAAE,cAAc,GAAG,SAAS,GACjC,IAAI,CAEN;AAaD,wBAAgB,YAAY,CAAC,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE;IAClD,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACtD,WAAW,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,OAAO,CAAC;IACvC,MAAM,CAAC,EAAE,cAAc,CAAC;CACzB,GAAG,SAAS,CAAC,MAAM,EAAE,OAAO,CAAC,CAa7B;AAED,wBAAgB,cAAc,CAAC,IAAI,EAAE;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,MAAM,CAAC,EAAE,cAAc,CAAC;CACzB,GAAG;IACF,UAAU,EAAE,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC,WAAW,EAAE,SAAS,CAAC;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EAAE,IAAI,CAAC,CAAC;CAC9D,CAoBA;AAID,UAAU,eAAe;IACvB,OAAO,CAAC,EAAE;QACR,EAAE,EAAE,MAAM,CAAC;QACX,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,CAAC;KAC3C,CAAC;IACF,KAAK,EAAE;QACL,GAAG,EAAE,CACH,IAAI,EAAE,MAAM,EACZ,IAAI,CAAC,EAAE;YAAE,MAAM,CAAC,EAAE,WAAW,CAAC;YAAC,KAAK,CAAC,EAAE,MAAM,CAAA;SAAE,KAC5C,OAAO,CAAC;YAAE,MAAM,EAAE,MAAM,CAAC;YAAC,MAAM,CAAC,EAAE,MAAM,EAAE,CAAA;SAAE,CAAC,CAAC;KACrD,CAAC;CACH;AAED,wBAAgB,mBAAmB;;;;2BASpB,MAAM,QACT,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,eAChB,eAAe,GAC3B,OAAO,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC;EA4LvC"}
|
|
@@ -5,7 +5,11 @@
|
|
|
5
5
|
*/
|
|
6
6
|
import { par, branchFix, } from "../process.js";
|
|
7
7
|
import { agentProcess, fanOut } from "../agent.js";
|
|
8
|
+
import { invertible, or, retryWithBackoff, saga, timeout } from "../operators.js";
|
|
8
9
|
import { Scheduler } from "../scheduler.js";
|
|
10
|
+
import { sessionTreeToMarkdown } from "../session-tree.js";
|
|
11
|
+
import { VERSION } from "../version.js";
|
|
12
|
+
export { sessionTreeToMarkdown };
|
|
9
13
|
// ─── SKILL.md content ───────────────────────────────────────────
|
|
10
14
|
export const SKILL_MD = `# cpa-agents — Concurrent Process Algebra
|
|
11
15
|
|
|
@@ -30,7 +34,7 @@ export default createOpenClawSkill();
|
|
|
30
34
|
### 3) Ensure OpenClaw can execute skills
|
|
31
35
|
- OpenClaw Gateway must be running.
|
|
32
36
|
- Your skill runtime must allow async tool execution.
|
|
33
|
-
- Keep this package at version \`
|
|
37
|
+
- Keep this package at version \`${VERSION}\` or newer.
|
|
34
38
|
|
|
35
39
|
## Commands
|
|
36
40
|
|
|
@@ -58,6 +62,30 @@ Input:
|
|
|
58
62
|
{ "task": "draft API design", "models": ["model-a", "model-b"], "timeout": 300000 }
|
|
59
63
|
\`\`\`
|
|
60
64
|
|
|
65
|
+
### cpa:retry
|
|
66
|
+
Retry a task with exponential backoff and per-attempt timeout.
|
|
67
|
+
|
|
68
|
+
Input:
|
|
69
|
+
\`\`\`json
|
|
70
|
+
{ "task": "fix flaky test", "maxAttempts": 3, "initialDelayMs": 250, "stepTimeout": 60000 }
|
|
71
|
+
\`\`\`
|
|
72
|
+
|
|
73
|
+
### cpa:fallback
|
|
74
|
+
Run fallback task if primary task fails.
|
|
75
|
+
|
|
76
|
+
Input:
|
|
77
|
+
\`\`\`json
|
|
78
|
+
{ "primary": "run strict analyzer", "fallback": "run lightweight analyzer" }
|
|
79
|
+
\`\`\`
|
|
80
|
+
|
|
81
|
+
### cpa:saga
|
|
82
|
+
Run multiple steps with rollback compensation on failure.
|
|
83
|
+
|
|
84
|
+
Input:
|
|
85
|
+
\`\`\`json
|
|
86
|
+
{ "steps": ["create branch", "apply patch", "run validation"] }
|
|
87
|
+
\`\`\`
|
|
88
|
+
|
|
61
89
|
### cpa:status
|
|
62
90
|
Get current process tree/status for the current session.
|
|
63
91
|
|
|
@@ -78,34 +106,48 @@ Input:
|
|
|
78
106
|
- **Gateway not connected**
|
|
79
107
|
- Start OpenClaw Gateway and retry.
|
|
80
108
|
- **Unknown command**
|
|
81
|
-
- Use one of: \`parallel\`, \`branch-fix\`, \`fan-out\`, \`status\`.
|
|
109
|
+
- Use one of: \`parallel\`, \`branch-fix\`, \`fan-out\`, \`retry\`, \`fallback\`, \`saga\`, \`status\`.
|
|
82
110
|
- **Timeout errors**
|
|
83
111
|
- Increase \`timeout\` in command args.
|
|
84
112
|
- **No session events**
|
|
85
113
|
- Confirm session context has \`appendEvent\` enabled.
|
|
86
114
|
`;
|
|
87
|
-
|
|
115
|
+
let configuredOpenClawBridge;
|
|
116
|
+
/** Connect standalone openclawTool/workspaceAgent factories to a gateway. */
|
|
117
|
+
export function configureOpenClawBridge(bridge) {
|
|
118
|
+
configuredOpenClawBridge = bridge;
|
|
119
|
+
}
|
|
120
|
+
function resolveOpenClawBridge(explicit) {
|
|
121
|
+
const bridge = explicit ?? configuredOpenClawBridge;
|
|
122
|
+
if (!bridge) {
|
|
123
|
+
throw new Error("OpenClaw bridge not connected. Pass bridge to the factory, call configureOpenClawBridge(), " +
|
|
124
|
+
"or use createOpenClawSkill() with openclawCtx.agent.");
|
|
125
|
+
}
|
|
126
|
+
return bridge;
|
|
127
|
+
}
|
|
88
128
|
export function openclawTool(opts) {
|
|
89
129
|
return {
|
|
90
130
|
name: `openclaw:${opts.name}`,
|
|
91
|
-
invoke: async (
|
|
92
|
-
|
|
93
|
-
|
|
131
|
+
invoke: async (input, signal) => {
|
|
132
|
+
const bridge = resolveOpenClawBridge(opts.bridge);
|
|
133
|
+
const raw = await bridge.runTool(opts.tool, opts.buildArgs(input), signal);
|
|
134
|
+
return opts.parseResult(raw);
|
|
94
135
|
},
|
|
95
136
|
};
|
|
96
137
|
}
|
|
97
138
|
export function workspaceAgent(opts) {
|
|
139
|
+
const getBridge = () => resolveOpenClawBridge(opts.bridge);
|
|
98
140
|
return {
|
|
99
141
|
readMemory: {
|
|
100
142
|
name: `workspace:read:${opts.name}`,
|
|
101
|
-
invoke: async (
|
|
102
|
-
|
|
143
|
+
invoke: async (key, signal) => {
|
|
144
|
+
return getBridge().readMemory(key, signal);
|
|
103
145
|
},
|
|
104
146
|
},
|
|
105
147
|
writeMemory: {
|
|
106
148
|
name: `workspace:write:${opts.name}`,
|
|
107
|
-
invoke: async (
|
|
108
|
-
|
|
149
|
+
invoke: async (input, signal) => {
|
|
150
|
+
await getBridge().writeMemory(input, signal);
|
|
109
151
|
},
|
|
110
152
|
},
|
|
111
153
|
};
|
|
@@ -114,7 +156,7 @@ export function createOpenClawSkill() {
|
|
|
114
156
|
const schedulers = new Map();
|
|
115
157
|
return {
|
|
116
158
|
name: "cpa-agents",
|
|
117
|
-
version:
|
|
159
|
+
version: VERSION,
|
|
118
160
|
skillMd: SKILL_MD,
|
|
119
161
|
async handleCommand(command, args, openclawCtx) {
|
|
120
162
|
const scheduler = new Scheduler({
|
|
@@ -126,6 +168,19 @@ export function createOpenClawSkill() {
|
|
|
126
168
|
const sessionId = openclawCtx.session?.id ?? "unknown";
|
|
127
169
|
schedulers.set(sessionId, scheduler);
|
|
128
170
|
try {
|
|
171
|
+
const runTask = (task, model) => async (ctx) => {
|
|
172
|
+
const result = await openclawCtx.agent.run(task, {
|
|
173
|
+
model,
|
|
174
|
+
signal: ctx.signal,
|
|
175
|
+
});
|
|
176
|
+
if (result.errors?.length) {
|
|
177
|
+
throw new Error(result.errors.join("; "));
|
|
178
|
+
}
|
|
179
|
+
return result.output;
|
|
180
|
+
};
|
|
181
|
+
const runTaskVoid = (task, model) => async (ctx) => {
|
|
182
|
+
await runTask(task, model)(ctx);
|
|
183
|
+
};
|
|
129
184
|
switch (command) {
|
|
130
185
|
case "parallel": {
|
|
131
186
|
const tasks = args.tasks;
|
|
@@ -182,20 +237,52 @@ export function createOpenClawSkill() {
|
|
|
182
237
|
});
|
|
183
238
|
return scheduler.run("fan-out", proc);
|
|
184
239
|
}
|
|
240
|
+
case "retry": {
|
|
241
|
+
const task = args.task;
|
|
242
|
+
const model = args.model;
|
|
243
|
+
const maxAttempts = args.maxAttempts ?? 3;
|
|
244
|
+
const initialDelayMs = args.initialDelayMs ?? 250;
|
|
245
|
+
const stepTimeout = args.stepTimeout ?? 60_000;
|
|
246
|
+
const proc = retryWithBackoff({
|
|
247
|
+
process: timeout(stepTimeout, runTask(task, model)),
|
|
248
|
+
maxAttempts,
|
|
249
|
+
initialDelayMs,
|
|
250
|
+
});
|
|
251
|
+
return scheduler.run("retry", proc);
|
|
252
|
+
}
|
|
253
|
+
case "fallback": {
|
|
254
|
+
const primary = args.primary;
|
|
255
|
+
const fallback = args.fallback;
|
|
256
|
+
const model = args.model;
|
|
257
|
+
const proc = async (ctx) => {
|
|
258
|
+
const result = await or(runTask(primary, model), runTask(fallback, model))(ctx);
|
|
259
|
+
if (!result.ok) {
|
|
260
|
+
throw result.error;
|
|
261
|
+
}
|
|
262
|
+
return result.value;
|
|
263
|
+
};
|
|
264
|
+
return scheduler.run("fallback", proc);
|
|
265
|
+
}
|
|
266
|
+
case "saga": {
|
|
267
|
+
const steps = args.steps ?? [];
|
|
268
|
+
const model = args.model;
|
|
269
|
+
const proc = saga(steps.map((step) => invertible(runTask(step, model), () => runTaskVoid(`Rollback/undo the effects of this step: ${step}`, model))));
|
|
270
|
+
return scheduler.run("saga", proc);
|
|
271
|
+
}
|
|
185
272
|
case "status": {
|
|
186
273
|
const s = schedulers.get(sessionId);
|
|
187
274
|
if (!s) {
|
|
188
275
|
return {
|
|
189
276
|
success: true,
|
|
190
277
|
value: { message: "No active CPA processes" },
|
|
191
|
-
trace: scheduler
|
|
278
|
+
trace: scheduler.traceCollector,
|
|
192
279
|
sessionTree: [],
|
|
193
280
|
};
|
|
194
281
|
}
|
|
195
282
|
return {
|
|
196
283
|
success: true,
|
|
197
284
|
value: { tree: s.getSessionTree() },
|
|
198
|
-
trace: s
|
|
285
|
+
trace: s.traceCollector,
|
|
199
286
|
sessionTree: s.getSessionTree(),
|
|
200
287
|
};
|
|
201
288
|
}
|
|
@@ -209,33 +296,4 @@ export function createOpenClawSkill() {
|
|
|
209
296
|
},
|
|
210
297
|
};
|
|
211
298
|
}
|
|
212
|
-
// ─── Session tree serialization ─────────────────────────────────
|
|
213
|
-
export function sessionTreeToMarkdown(nodes, depth = 0) {
|
|
214
|
-
const indent = " ".repeat(depth);
|
|
215
|
-
let md = "";
|
|
216
|
-
for (const node of nodes) {
|
|
217
|
-
const status = node.events.some((e) => e.type === "error")
|
|
218
|
-
? "error"
|
|
219
|
-
: node.events.some((e) => e.type === "done")
|
|
220
|
-
? "done"
|
|
221
|
-
: "running";
|
|
222
|
-
md += `${indent}- **${node.name}** (${node.runId}) [${status}]\n`;
|
|
223
|
-
const branches = node.events.filter((e) => e.type === "branch");
|
|
224
|
-
for (const b of branches) {
|
|
225
|
-
if (b.type === "branch") {
|
|
226
|
-
md += `${indent} - Branch: chose "${b.chosen}" from [${b.alternatives.join(", ")}]\n`;
|
|
227
|
-
}
|
|
228
|
-
}
|
|
229
|
-
const fixes = node.events.filter((e) => e.type === "fix_start" || e.type === "fix_end");
|
|
230
|
-
for (const f of fixes) {
|
|
231
|
-
if (f.type === "fix_start") {
|
|
232
|
-
md += `${indent} - Fix started: ${f.reason}\n`;
|
|
233
|
-
}
|
|
234
|
-
}
|
|
235
|
-
if (node.children.length > 0) {
|
|
236
|
-
md += sessionTreeToMarkdown(node.children, depth + 1);
|
|
237
|
-
}
|
|
238
|
-
}
|
|
239
|
-
return md;
|
|
240
|
-
}
|
|
241
299
|
//# sourceMappingURL=openclaw.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"openclaw.js","sourceRoot":"","sources":["../../src/adapters/openclaw.ts"],"names":[],"mappings":"AAAA;;;;GAIG;
|
|
1
|
+
{"version":3,"file":"openclaw.js","sourceRoot":"","sources":["../../src/adapters/openclaw.ts"],"names":[],"mappings":"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"}
|