cpa-agents 0.1.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/LICENSE +21 -0
- package/README.md +146 -0
- package/dist/adapters/openclaw.d.ts +49 -0
- package/dist/adapters/openclaw.d.ts.map +1 -0
- package/dist/adapters/openclaw.js +186 -0
- package/dist/adapters/openclaw.js.map +1 -0
- package/dist/adapters/pi-harness.d.ts +38 -0
- package/dist/adapters/pi-harness.d.ts.map +1 -0
- package/dist/adapters/pi-harness.js +77 -0
- package/dist/adapters/pi-harness.js.map +1 -0
- package/dist/agent.d.ts +72 -0
- package/dist/agent.d.ts.map +1 -0
- package/dist/agent.js +148 -0
- package/dist/agent.js.map +1 -0
- package/dist/channel.d.ts +57 -0
- package/dist/channel.d.ts.map +1 -0
- package/dist/channel.js +113 -0
- package/dist/channel.js.map +1 -0
- package/dist/index.d.ts +30 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +34 -0
- package/dist/index.js.map +1 -0
- package/dist/process.d.ts +143 -0
- package/dist/process.d.ts.map +1 -0
- package/dist/process.js +273 -0
- package/dist/process.js.map +1 -0
- package/dist/scheduler.d.ts +50 -0
- package/dist/scheduler.d.ts.map +1 -0
- package/dist/scheduler.js +109 -0
- package/dist/scheduler.js.map +1 -0
- package/package.json +51 -0
package/dist/process.js
ADDED
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Process: the core unit of computation in the algebra.
|
|
3
|
+
*
|
|
4
|
+
* A Process is a function that takes a context (channels, signals)
|
|
5
|
+
* and returns a result. Processes compose via parallel, sequential,
|
|
6
|
+
* choice, and branch-fix-continue combinators.
|
|
7
|
+
*/
|
|
8
|
+
import { Channel, freshId, select } from "./channel.js";
|
|
9
|
+
export class TraceCollector {
|
|
10
|
+
events = [];
|
|
11
|
+
emit(event) {
|
|
12
|
+
this.events.push(event);
|
|
13
|
+
}
|
|
14
|
+
/** Get a serialisable session tree from the flat event log */
|
|
15
|
+
toTree() {
|
|
16
|
+
const nodes = new Map();
|
|
17
|
+
const roots = [];
|
|
18
|
+
for (const e of this.events) {
|
|
19
|
+
if (e.type === "spawn") {
|
|
20
|
+
const node = {
|
|
21
|
+
runId: e.runId,
|
|
22
|
+
name: e.name,
|
|
23
|
+
parentId: e.parentId,
|
|
24
|
+
events: [],
|
|
25
|
+
children: [],
|
|
26
|
+
};
|
|
27
|
+
nodes.set(e.runId, node);
|
|
28
|
+
if (e.parentId && nodes.has(e.parentId)) {
|
|
29
|
+
nodes.get(e.parentId).children.push(node);
|
|
30
|
+
}
|
|
31
|
+
else {
|
|
32
|
+
roots.push(node);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
const node = nodes.get(e.runId);
|
|
36
|
+
if (node) {
|
|
37
|
+
node.events.push(e);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
return roots;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
// ─── Combinators ────────────────────────────────────────────────
|
|
44
|
+
/**
|
|
45
|
+
* Parallel composition: P | Q
|
|
46
|
+
* Runs all processes concurrently and waits for all to complete.
|
|
47
|
+
*/
|
|
48
|
+
export function par(...processes) {
|
|
49
|
+
return async (ctx) => {
|
|
50
|
+
const results = await Promise.all(processes.map((p, i) => {
|
|
51
|
+
const childId = freshId("par");
|
|
52
|
+
ctx.trace.emit({
|
|
53
|
+
type: "spawn",
|
|
54
|
+
runId: childId,
|
|
55
|
+
parentId: ctx.runId,
|
|
56
|
+
name: `par[${i}]`,
|
|
57
|
+
ts: Date.now(),
|
|
58
|
+
});
|
|
59
|
+
const childCtx = {
|
|
60
|
+
...ctx,
|
|
61
|
+
runId: childId,
|
|
62
|
+
parentId: ctx.runId,
|
|
63
|
+
};
|
|
64
|
+
return p(childCtx).then((r) => {
|
|
65
|
+
ctx.trace.emit({ type: "done", runId: childId, ts: Date.now() });
|
|
66
|
+
return r;
|
|
67
|
+
});
|
|
68
|
+
}));
|
|
69
|
+
return results;
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Sequential composition: P ; Q
|
|
74
|
+
* Runs processes one after another, threading context.
|
|
75
|
+
*/
|
|
76
|
+
export function seq(...processes) {
|
|
77
|
+
return async (ctx) => {
|
|
78
|
+
let result;
|
|
79
|
+
for (const p of processes) {
|
|
80
|
+
if (ctx.signal.aborted)
|
|
81
|
+
throw new Error("Process aborted");
|
|
82
|
+
result = await p(ctx);
|
|
83
|
+
}
|
|
84
|
+
return result;
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Choice: P + Q (external choice)
|
|
89
|
+
*
|
|
90
|
+
* Waits for a message on any of the guard channels.
|
|
91
|
+
* The first channel that fires determines which branch runs.
|
|
92
|
+
* All other branches are discarded (committed choice).
|
|
93
|
+
*/
|
|
94
|
+
export function choice(branches) {
|
|
95
|
+
return async (ctx) => {
|
|
96
|
+
const alternatives = branches.map((b) => b.name);
|
|
97
|
+
let chosenIdx = -1;
|
|
98
|
+
const cases = branches.map((b, i) => ({
|
|
99
|
+
channel: b.guard,
|
|
100
|
+
handler: () => {
|
|
101
|
+
chosenIdx = i;
|
|
102
|
+
},
|
|
103
|
+
}));
|
|
104
|
+
await select(...cases);
|
|
105
|
+
ctx.trace.emit({
|
|
106
|
+
type: "branch",
|
|
107
|
+
runId: ctx.runId,
|
|
108
|
+
chosen: branches[chosenIdx].name,
|
|
109
|
+
alternatives,
|
|
110
|
+
ts: Date.now(),
|
|
111
|
+
});
|
|
112
|
+
return branches[chosenIdx].process(ctx);
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Branch-Fix-Continue: the tree pattern you described.
|
|
117
|
+
*
|
|
118
|
+
* 1. Run the main process.
|
|
119
|
+
* 2. If it signals a fix is needed (via the fix channel), pause main,
|
|
120
|
+
* run the fix process, then resume main from where it left off.
|
|
121
|
+
* 3. If the main completes without needing a fix, continue normally.
|
|
122
|
+
*
|
|
123
|
+
* This is the key pattern for AI agents: you're coding along,
|
|
124
|
+
* discover a lint error, branch to fix it, then rejoin the main flow.
|
|
125
|
+
*/
|
|
126
|
+
export function branchFix(opts) {
|
|
127
|
+
const maxFixes = opts.maxFixes ?? 5;
|
|
128
|
+
return async (ctx) => {
|
|
129
|
+
let fixCount = 0;
|
|
130
|
+
const fixChannel = new Channel(`${opts.name}_fix`);
|
|
131
|
+
const fixDone = new Channel(`${opts.name}_fixdone`);
|
|
132
|
+
const requestFix = async (reason) => {
|
|
133
|
+
if (fixCount >= maxFixes) {
|
|
134
|
+
throw new Error(`${opts.name}: exceeded max fix attempts (${maxFixes})`);
|
|
135
|
+
}
|
|
136
|
+
fixCount++;
|
|
137
|
+
ctx.trace.emit({
|
|
138
|
+
type: "fix_start",
|
|
139
|
+
runId: ctx.runId,
|
|
140
|
+
reason,
|
|
141
|
+
ts: Date.now(),
|
|
142
|
+
});
|
|
143
|
+
// Signal that a fix is needed
|
|
144
|
+
await fixChannel.send(reason);
|
|
145
|
+
// Wait for the fix to complete
|
|
146
|
+
await fixDone.receive();
|
|
147
|
+
ctx.trace.emit({
|
|
148
|
+
type: "fix_end",
|
|
149
|
+
runId: ctx.runId,
|
|
150
|
+
success: true,
|
|
151
|
+
ts: Date.now(),
|
|
152
|
+
});
|
|
153
|
+
};
|
|
154
|
+
const mainProcess = opts.main(requestFix);
|
|
155
|
+
// Run main and fix-listener concurrently
|
|
156
|
+
const mainPromise = mainProcess(ctx);
|
|
157
|
+
// Fix listener loop: runs in background
|
|
158
|
+
const fixListener = (async () => {
|
|
159
|
+
while (!fixChannel.closed) {
|
|
160
|
+
try {
|
|
161
|
+
const reason = await fixChannel.receive();
|
|
162
|
+
const fixProc = opts.fix(reason);
|
|
163
|
+
await fixProc(ctx);
|
|
164
|
+
await fixDone.send(undefined);
|
|
165
|
+
}
|
|
166
|
+
catch {
|
|
167
|
+
// Channel closed or fix failed — stop listening
|
|
168
|
+
break;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
})();
|
|
172
|
+
try {
|
|
173
|
+
const result = await mainPromise;
|
|
174
|
+
fixChannel.close();
|
|
175
|
+
fixDone.close();
|
|
176
|
+
return result;
|
|
177
|
+
}
|
|
178
|
+
catch (err) {
|
|
179
|
+
fixChannel.close();
|
|
180
|
+
fixDone.close();
|
|
181
|
+
throw err;
|
|
182
|
+
}
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Restriction: ν(name). Creates a fresh scoped channel.
|
|
187
|
+
* The channel is only visible to processes inside the scope.
|
|
188
|
+
*/
|
|
189
|
+
export function restrict(name, body) {
|
|
190
|
+
return async (ctx) => {
|
|
191
|
+
const ch = new Channel(name);
|
|
192
|
+
const scopedChannels = new Map(ctx.channels);
|
|
193
|
+
scopedChannels.set(name, ch);
|
|
194
|
+
const scopedCtx = { ...ctx, channels: scopedChannels };
|
|
195
|
+
try {
|
|
196
|
+
return await body(ch)(scopedCtx);
|
|
197
|
+
}
|
|
198
|
+
finally {
|
|
199
|
+
ch.close();
|
|
200
|
+
}
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* Replication: !P — spawn a new copy of P each time the trigger fires.
|
|
205
|
+
* Useful for server-like patterns where each incoming request
|
|
206
|
+
* gets its own agent process.
|
|
207
|
+
*/
|
|
208
|
+
export function replicate(trigger, handler) {
|
|
209
|
+
return async (ctx) => {
|
|
210
|
+
while (!ctx.signal.aborted && !trigger.closed) {
|
|
211
|
+
try {
|
|
212
|
+
const value = await trigger.receive();
|
|
213
|
+
const childId = freshId("repl");
|
|
214
|
+
ctx.trace.emit({
|
|
215
|
+
type: "spawn",
|
|
216
|
+
runId: childId,
|
|
217
|
+
parentId: ctx.runId,
|
|
218
|
+
name: "replicated",
|
|
219
|
+
ts: Date.now(),
|
|
220
|
+
});
|
|
221
|
+
const childCtx = {
|
|
222
|
+
...ctx,
|
|
223
|
+
runId: childId,
|
|
224
|
+
parentId: ctx.runId,
|
|
225
|
+
};
|
|
226
|
+
// Fire and forget — each replica runs independently
|
|
227
|
+
handler(value)(childCtx).catch((err) => {
|
|
228
|
+
ctx.trace.emit({
|
|
229
|
+
type: "error",
|
|
230
|
+
runId: childId,
|
|
231
|
+
error: String(err),
|
|
232
|
+
ts: Date.now(),
|
|
233
|
+
});
|
|
234
|
+
});
|
|
235
|
+
}
|
|
236
|
+
catch {
|
|
237
|
+
break;
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
};
|
|
241
|
+
}
|
|
242
|
+
/**
|
|
243
|
+
* Supervisor: wraps a process with retry + fallback semantics.
|
|
244
|
+
* On failure, can either restart the process or run a recovery process.
|
|
245
|
+
*/
|
|
246
|
+
export function supervisor(opts) {
|
|
247
|
+
const maxRetries = opts.maxRetries ?? 3;
|
|
248
|
+
return async (ctx) => {
|
|
249
|
+
let lastError;
|
|
250
|
+
for (let attempt = 0; attempt <= maxRetries; attempt++) {
|
|
251
|
+
try {
|
|
252
|
+
return await opts.process(ctx);
|
|
253
|
+
}
|
|
254
|
+
catch (err) {
|
|
255
|
+
lastError = err instanceof Error ? err : new Error(String(err));
|
|
256
|
+
ctx.trace.emit({
|
|
257
|
+
type: "error",
|
|
258
|
+
runId: ctx.runId,
|
|
259
|
+
error: lastError.message,
|
|
260
|
+
ts: Date.now(),
|
|
261
|
+
});
|
|
262
|
+
if (opts.onError && attempt < maxRetries) {
|
|
263
|
+
await opts.onError(lastError, attempt)(ctx);
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
if (opts.fallback) {
|
|
268
|
+
return opts.fallback(ctx);
|
|
269
|
+
}
|
|
270
|
+
throw lastError;
|
|
271
|
+
};
|
|
272
|
+
}
|
|
273
|
+
//# sourceMappingURL=process.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"process.js","sourceRoot":"","sources":["../src/process.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Scheduler: the runtime that executes process trees.
|
|
3
|
+
*
|
|
4
|
+
* Handles:
|
|
5
|
+
* - Process lifecycle (spawn, run, complete, error)
|
|
6
|
+
* - Cooperative scheduling via async/await
|
|
7
|
+
* - Deadlock detection (all processes blocked on channels, none can fire)
|
|
8
|
+
* - Graceful shutdown via AbortController
|
|
9
|
+
*/
|
|
10
|
+
import { type Process, type TraceCollector } from "./process.js";
|
|
11
|
+
export interface SchedulerOpts {
|
|
12
|
+
/** Timeout for the entire process tree (ms) */
|
|
13
|
+
timeout?: number;
|
|
14
|
+
/** Callback when a trace event is emitted */
|
|
15
|
+
onTrace?: (event: import("./process.js").TraceEvent) => void;
|
|
16
|
+
}
|
|
17
|
+
export declare class Scheduler {
|
|
18
|
+
private abortController;
|
|
19
|
+
private trace;
|
|
20
|
+
private opts;
|
|
21
|
+
constructor(opts?: SchedulerOpts);
|
|
22
|
+
/**
|
|
23
|
+
* Run a process tree to completion.
|
|
24
|
+
*/
|
|
25
|
+
run<T>(name: string, process: Process<T>): Promise<SchedulerResult<T>>;
|
|
26
|
+
/**
|
|
27
|
+
* Abort all running processes.
|
|
28
|
+
*/
|
|
29
|
+
abort(): void;
|
|
30
|
+
/**
|
|
31
|
+
* Get the current session tree (can be called mid-execution).
|
|
32
|
+
*/
|
|
33
|
+
getSessionTree(): import("./process.js").SessionNode[];
|
|
34
|
+
/**
|
|
35
|
+
* Get the flat event trace.
|
|
36
|
+
*/
|
|
37
|
+
getTrace(): import("./process.js").TraceEvent[];
|
|
38
|
+
}
|
|
39
|
+
export type SchedulerResult<T> = {
|
|
40
|
+
success: true;
|
|
41
|
+
value: T;
|
|
42
|
+
trace: TraceCollector;
|
|
43
|
+
sessionTree: import("./process.js").SessionNode[];
|
|
44
|
+
} | {
|
|
45
|
+
success: false;
|
|
46
|
+
error: Error;
|
|
47
|
+
trace: TraceCollector;
|
|
48
|
+
sessionTree: import("./process.js").SessionNode[];
|
|
49
|
+
};
|
|
50
|
+
//# sourceMappingURL=scheduler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scheduler.d.ts","sourceRoot":"","sources":["../src/scheduler.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,EACL,KAAK,OAAO,EAEZ,KAAK,cAAc,EAEpB,MAAM,cAAc,CAAC;AAEtB,MAAM,WAAW,aAAa;IAC5B,+CAA+C;IAC/C,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,6CAA6C;IAC7C,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,cAAc,EAAE,UAAU,KAAK,IAAI,CAAC;CAC9D;AAED,qBAAa,SAAS;IACpB,OAAO,CAAC,eAAe,CAAkB;IACzC,OAAO,CAAC,KAAK,CAAqB;IAClC,OAAO,CAAC,IAAI,CAAgB;gBAEhB,IAAI,GAAE,aAAkB;IAWpC;;OAEG;IACG,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;IAiE5E;;OAEG;IACH,KAAK,IAAI,IAAI;IAIb;;OAEG;IACH,cAAc;IAId;;OAEG;IACH,QAAQ;CAGT;AAED,MAAM,MAAM,eAAe,CAAC,CAAC,IACzB;IACE,OAAO,EAAE,IAAI,CAAC;IACd,KAAK,EAAE,CAAC,CAAC;IACT,KAAK,EAAE,cAAc,CAAC;IACtB,WAAW,EAAE,OAAO,cAAc,EAAE,WAAW,EAAE,CAAC;CACnD,GACD;IACE,OAAO,EAAE,KAAK,CAAC;IACf,KAAK,EAAE,KAAK,CAAC;IACb,KAAK,EAAE,cAAc,CAAC;IACtB,WAAW,EAAE,OAAO,cAAc,EAAE,WAAW,EAAE,CAAC;CACnD,CAAC"}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Scheduler: the runtime that executes process trees.
|
|
3
|
+
*
|
|
4
|
+
* Handles:
|
|
5
|
+
* - Process lifecycle (spawn, run, complete, error)
|
|
6
|
+
* - Cooperative scheduling via async/await
|
|
7
|
+
* - Deadlock detection (all processes blocked on channels, none can fire)
|
|
8
|
+
* - Graceful shutdown via AbortController
|
|
9
|
+
*/
|
|
10
|
+
import { freshId } from "./channel.js";
|
|
11
|
+
import { TraceCollector as TraceCollectorImpl, } from "./process.js";
|
|
12
|
+
export class Scheduler {
|
|
13
|
+
abortController;
|
|
14
|
+
trace;
|
|
15
|
+
opts;
|
|
16
|
+
constructor(opts = {}) {
|
|
17
|
+
this.abortController = new AbortController();
|
|
18
|
+
this.opts = opts;
|
|
19
|
+
this.trace = new (class extends TraceCollectorImpl {
|
|
20
|
+
emit(event) {
|
|
21
|
+
super.emit(event);
|
|
22
|
+
opts.onTrace?.(event);
|
|
23
|
+
}
|
|
24
|
+
})();
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Run a process tree to completion.
|
|
28
|
+
*/
|
|
29
|
+
async run(name, process) {
|
|
30
|
+
const runId = freshId("root");
|
|
31
|
+
const ctx = {
|
|
32
|
+
runId,
|
|
33
|
+
signal: this.abortController.signal,
|
|
34
|
+
trace: this.trace,
|
|
35
|
+
channels: new Map(),
|
|
36
|
+
};
|
|
37
|
+
this.trace.emit({
|
|
38
|
+
type: "spawn",
|
|
39
|
+
runId,
|
|
40
|
+
name,
|
|
41
|
+
ts: Date.now(),
|
|
42
|
+
});
|
|
43
|
+
let timeoutId;
|
|
44
|
+
try {
|
|
45
|
+
const resultPromise = process(ctx);
|
|
46
|
+
// Apply timeout if configured
|
|
47
|
+
let result;
|
|
48
|
+
if (this.opts.timeout) {
|
|
49
|
+
result = await Promise.race([
|
|
50
|
+
resultPromise,
|
|
51
|
+
new Promise((_, reject) => {
|
|
52
|
+
timeoutId = setTimeout(() => {
|
|
53
|
+
this.abortController.abort();
|
|
54
|
+
reject(new Error(`Scheduler timeout after ${this.opts.timeout}ms`));
|
|
55
|
+
}, this.opts.timeout);
|
|
56
|
+
}),
|
|
57
|
+
]);
|
|
58
|
+
}
|
|
59
|
+
else {
|
|
60
|
+
result = await resultPromise;
|
|
61
|
+
}
|
|
62
|
+
this.trace.emit({ type: "done", runId, ts: Date.now() });
|
|
63
|
+
return {
|
|
64
|
+
success: true,
|
|
65
|
+
value: result,
|
|
66
|
+
trace: this.trace,
|
|
67
|
+
sessionTree: this.trace.toTree(),
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
catch (err) {
|
|
71
|
+
const error = err instanceof Error ? err : new Error(String(err));
|
|
72
|
+
this.trace.emit({
|
|
73
|
+
type: "error",
|
|
74
|
+
runId,
|
|
75
|
+
error: error.message,
|
|
76
|
+
ts: Date.now(),
|
|
77
|
+
});
|
|
78
|
+
return {
|
|
79
|
+
success: false,
|
|
80
|
+
error,
|
|
81
|
+
trace: this.trace,
|
|
82
|
+
sessionTree: this.trace.toTree(),
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
finally {
|
|
86
|
+
if (timeoutId)
|
|
87
|
+
clearTimeout(timeoutId);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Abort all running processes.
|
|
92
|
+
*/
|
|
93
|
+
abort() {
|
|
94
|
+
this.abortController.abort();
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Get the current session tree (can be called mid-execution).
|
|
98
|
+
*/
|
|
99
|
+
getSessionTree() {
|
|
100
|
+
return this.trace.toTree();
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Get the flat event trace.
|
|
104
|
+
*/
|
|
105
|
+
getTrace() {
|
|
106
|
+
return this.trace.events;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
//# sourceMappingURL=scheduler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scheduler.js","sourceRoot":"","sources":["../src/scheduler.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "cpa-agents",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Concurrent Process Algebra for AI Agents — π-calculus primitives for Pi Harness and OpenClaw",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"import": "./dist/index.js",
|
|
11
|
+
"types": "./dist/index.d.ts"
|
|
12
|
+
},
|
|
13
|
+
"./adapters/pi": {
|
|
14
|
+
"import": "./dist/adapters/pi-harness.js",
|
|
15
|
+
"types": "./dist/adapters/pi-harness.d.ts"
|
|
16
|
+
},
|
|
17
|
+
"./adapters/openclaw": {
|
|
18
|
+
"import": "./dist/adapters/openclaw.js",
|
|
19
|
+
"types": "./dist/adapters/openclaw.d.ts"
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
"scripts": {
|
|
23
|
+
"clean": "rm -rf dist",
|
|
24
|
+
"build": "npm run clean && tsc",
|
|
25
|
+
"test": "tsx --test test/*.test.ts",
|
|
26
|
+
"coverage": "c8 --all --include='src/**/*.ts' --reporter=text --check-coverage --lines 80 --branches 80 --functions 80 --statements 80 npm test",
|
|
27
|
+
"check": "tsc --noEmit",
|
|
28
|
+
"prepublishOnly": "npm run check && npm run build && npm test && npm run coverage"
|
|
29
|
+
},
|
|
30
|
+
"files": [
|
|
31
|
+
"dist/**/*",
|
|
32
|
+
"README.md",
|
|
33
|
+
"LICENSE"
|
|
34
|
+
],
|
|
35
|
+
"keywords": [
|
|
36
|
+
"pi-calculus",
|
|
37
|
+
"process-algebra",
|
|
38
|
+
"ai-agents",
|
|
39
|
+
"concurrency",
|
|
40
|
+
"pi-harness",
|
|
41
|
+
"openclaw",
|
|
42
|
+
"orchestration"
|
|
43
|
+
],
|
|
44
|
+
"license": "MIT",
|
|
45
|
+
"devDependencies": {
|
|
46
|
+
"@types/node": "^25.6.0",
|
|
47
|
+
"c8": "^11.0.0",
|
|
48
|
+
"tsx": "^4.21.0",
|
|
49
|
+
"typescript": "^5.5.0"
|
|
50
|
+
}
|
|
51
|
+
}
|