@shapeshift-labs/frontier-swarm 0.1.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 +62 -2
- package/benchmarks/package-bench.mjs +35 -1
- package/dist/index.d.ts +632 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1016 -5
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -36,7 +36,7 @@ The published Frontier package family is generated from one shared package catal
|
|
|
36
36
|
- [`@shapeshift-labs/frontier-workflow`](https://www.npmjs.com/package/@shapeshift-labs/frontier-workflow): Serializable durable workflow/process manifests for Frontier apps, including steps, waits, approvals, timers, retries, expected patches, compensation, records, timelines, and registry graph output.
|
|
37
37
|
- [`@shapeshift-labs/frontier-worker`](https://www.npmjs.com/package/@shapeshift-labs/frontier-worker): Serializable worker and edge task descriptors for Frontier apps, including queues, idempotency keys, retry and timeout policy, declared reads/writes/effects, snapshots, patch outputs, produced assets, execution records, logs, trace links, proof hashes, dedupe indexes, and registry graph output.
|
|
38
38
|
- [`@shapeshift-labs/frontier-queue`](https://www.npmjs.com/package/@shapeshift-labs/frontier-queue): Serializable durable queue state, leases, retries, dedupe keys, patch-carrying jobs, dead-letter records, replay evidence, and queue inspection for Frontier apps.
|
|
39
|
-
- [`@shapeshift-labs/frontier-swarm-codex`](https://www.npmjs.com/package/@shapeshift-labs/frontier-swarm-codex): Node Codex CLI adapter for Frontier swarm plans, including prompt rendering, worktree and snapshot workspaces, Codex argument
|
|
39
|
+
- [`@shapeshift-labs/frontier-swarm-codex`](https://www.npmjs.com/package/@shapeshift-labs/frontier-swarm-codex): Node Codex CLI adapter for Frontier swarm plans, including prompt rendering, worktree and snapshot workspaces, Codex argument compatibility, JSONL capture, verification commands, pid-backed stop, collect buckets, merge bundles, and result artifacts.
|
|
40
40
|
- [`@shapeshift-labs/frontier-kv`](https://www.npmjs.com/package/@shapeshift-labs/frontier-kv): Serializable in-memory key/value state for Frontier apps, including TTL, versioned compare-and-set, batched patch mutations, scans, watchers, snapshots, JSONL event evidence, and replay verification.
|
|
41
41
|
- [`@shapeshift-labs/frontier-kv-locks`](https://www.npmjs.com/package/@shapeshift-labs/frontier-kv-locks): Lease-style lock records on top of Frontier KV, including acquire, renew, release, fencing tokens, expiration, owner evidence, and replayable lock events.
|
|
42
42
|
- [`@shapeshift-labs/frontier-kv-rate-limit`](https://www.npmjs.com/package/@shapeshift-labs/frontier-kv-rate-limit): Patch-native rate limit buckets for Frontier KV, including fixed windows, sliding windows, token buckets, deterministic refill, consume evidence, and reset records.
|
|
@@ -203,6 +203,55 @@ const tasks = defineSwarmTasks([{
|
|
|
203
203
|
const plan = createSwarmPlan(manifest, tasks, { limit: 4 });
|
|
204
204
|
```
|
|
205
205
|
|
|
206
|
+
## 1000-Agent Control Plane
|
|
207
|
+
|
|
208
|
+
Large swarms need a control plane, not just a flat worker loop. `frontier-swarm` now exports deterministic data helpers for that layer:
|
|
209
|
+
|
|
210
|
+
```ts
|
|
211
|
+
import {
|
|
212
|
+
checkSwarmBudget,
|
|
213
|
+
createSwarmArtifactIndex,
|
|
214
|
+
createSwarmEventStream,
|
|
215
|
+
createSwarmLeases,
|
|
216
|
+
createSwarmMergePlan,
|
|
217
|
+
createSwarmQueueSnapshot,
|
|
218
|
+
createSwarmReviewPlan,
|
|
219
|
+
createSwarmSchedule,
|
|
220
|
+
routeSwarmEventToMailboxes
|
|
221
|
+
} from '@shapeshift-labs/frontier-swarm';
|
|
222
|
+
|
|
223
|
+
const schedule = createSwarmSchedule({
|
|
224
|
+
plan,
|
|
225
|
+
maxReadyJobs: 100,
|
|
226
|
+
maxConcurrencyKeyConcurrency: { 'runtime-state': 1 },
|
|
227
|
+
maxComputeConcurrency: { deep: 40 }
|
|
228
|
+
});
|
|
229
|
+
|
|
230
|
+
const leases = createSwarmLeases({
|
|
231
|
+
schedule,
|
|
232
|
+
workerId: 'worker-a',
|
|
233
|
+
leaseMs: 15 * 60 * 1000,
|
|
234
|
+
count: 10
|
|
235
|
+
});
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
The scale APIs are runtime-neutral and serializable:
|
|
239
|
+
|
|
240
|
+
- dependency DAGs are compiled into `plan.graph`,
|
|
241
|
+
- `createSwarmSchedule` returns ready, blocked, running, completed, and failed jobs under lane/compute/contention limits,
|
|
242
|
+
- `createSwarmLeases` gives workers expiring leases with fencing tokens,
|
|
243
|
+
- lane/task `capabilities` and `resourceRequirements` can reserve browser work with lower concurrency, port pools, profile directories, and explicit capability checks,
|
|
244
|
+
- `createSwarmQueueSnapshot` and run checkpoints give durable queue/run-store adapters a stable serialization shape,
|
|
245
|
+
- `createSwarmEventStream` and `routeSwarmEventToMailboxes` route global, lane, task, and worker events into coordinator-facing JSONL streams,
|
|
246
|
+
- `checkSwarmBudget` records token/cost/time/retry budget decisions,
|
|
247
|
+
- `createSwarmArtifactIndex` groups evidence, timelines, logs, and produced files,
|
|
248
|
+
- `createSwarmReviewPlan` samples or requires reviewer assignments,
|
|
249
|
+
- `createSwarmMergePlan` blocks jobs with failed checks, required reviews, ownership violations, or conflicting changed paths,
|
|
250
|
+
- job results include merge-readiness classification: `discovery-only`, `patch-candidate`, `verified-patch`, `rejected`, or `blocked`,
|
|
251
|
+
- `ownershipRegions` allow hot files to be split into semantic regions such as `content.docs.*` or `adminSettings.quota.*`; merge conflict detection prefers changed regions when workers report them,
|
|
252
|
+
- `createSwarmMergeBundle` builds a compact worker `merge.json` shape with touched owned files, patch path, evidence, verification, queue items satisfied, risk, and disposition,
|
|
253
|
+
- `decomposeSwarmFeature` creates an initial task queue for feature work across lanes.
|
|
254
|
+
|
|
206
255
|
## Hierarchical Compute
|
|
207
256
|
|
|
208
257
|
Higher swarm layers can choose compute for lower layers without binding the core package to Codex or any other runtime. Compute resolution is deterministic:
|
|
@@ -220,7 +269,18 @@ That lets a parent swarm route implementation jobs to a deep model while evidenc
|
|
|
220
269
|
- `defineSwarmManifest`, `createSwarmManifest`
|
|
221
270
|
- `defineSwarmTasks`
|
|
222
271
|
- `compileSwarm`, `validateSwarmManifest`
|
|
272
|
+
- `createSwarmTaskSelection`
|
|
223
273
|
- `createSwarmPlan`, `createSwarmRun`
|
|
274
|
+
- `createSwarmSchedule`, `createSwarmLeases`
|
|
275
|
+
- `createSwarmQueueSnapshot`, `createSwarmRunCheckpoint`
|
|
276
|
+
- `createSwarmEventStream`, `createSwarmMailbox`, `routeSwarmEventToMailboxes`
|
|
277
|
+
- `checkSwarmBudget`
|
|
278
|
+
- `createSwarmArtifactIndex`
|
|
279
|
+
- `createSwarmReviewPlan`, `createSwarmMergePlan`
|
|
280
|
+
- `createSwarmMergeBundle`
|
|
281
|
+
- `classifySwarmMergeReadiness`, `classifySwarmMergeDisposition`
|
|
282
|
+
- `resolveSwarmChangedRegions`
|
|
283
|
+
- `decomposeSwarmFeature`
|
|
224
284
|
- `recordSwarmEvent`, `completeSwarmJob`
|
|
225
285
|
- `resolveSwarmCompute`
|
|
226
286
|
- `checkSwarmOwnership`, `matchesGlob`
|
|
@@ -235,7 +295,7 @@ Run the package-local benchmark:
|
|
|
235
295
|
npm run bench
|
|
236
296
|
```
|
|
237
297
|
|
|
238
|
-
The benchmark writes `benchmarks/results/frontier-swarm-package-bench-latest.json` when run from the monorepo. These are Frontier-only package measurements for plan creation, manifest validation, hierarchical compute resolution, ownership checks,
|
|
298
|
+
The benchmark writes `benchmarks/results/frontier-swarm-package-bench-latest.json` when run from the monorepo. These are Frontier-only package measurements for plan creation, manifest validation, hierarchical compute resolution, ownership checks, scheduling/leases, queue snapshots, merge bundle creation, event routing, run checkpoints, JSONL, and proof hashing.
|
|
239
299
|
|
|
240
300
|
## Source Repository
|
|
241
301
|
|
|
@@ -5,12 +5,19 @@ import { fileURLToPath } from 'node:url';
|
|
|
5
5
|
import {
|
|
6
6
|
checkSwarmOwnership,
|
|
7
7
|
createSwarmManifest,
|
|
8
|
+
createSwarmEventStream,
|
|
9
|
+
createSwarmLeases,
|
|
10
|
+
createSwarmMergeBundle,
|
|
8
11
|
createSwarmPlan,
|
|
9
12
|
createSwarmProof,
|
|
13
|
+
createSwarmQueueSnapshot,
|
|
10
14
|
createSwarmRun,
|
|
15
|
+
createSwarmRunCheckpoint,
|
|
16
|
+
createSwarmSchedule,
|
|
11
17
|
decodeSwarmJsonl,
|
|
12
18
|
defineSwarmTasks,
|
|
13
19
|
encodeSwarmJsonl,
|
|
20
|
+
routeSwarmEventToMailboxes,
|
|
14
21
|
resolveSwarmCompute,
|
|
15
22
|
validateSwarmManifest
|
|
16
23
|
} from '../dist/index.js';
|
|
@@ -31,6 +38,9 @@ let plan = createSwarmPlan(manifest, tasks, { limit: 64 });
|
|
|
31
38
|
let run = createSwarmRun({ plan });
|
|
32
39
|
let jsonl = encodeSwarmJsonl([plan, run]);
|
|
33
40
|
let cursor = 0;
|
|
41
|
+
let schedule = createSwarmSchedule({ plan, maxReadyJobs: 128 });
|
|
42
|
+
let leases = createSwarmLeases({ schedule, workerId: 'bench-worker', now: 1000, leaseMs: 60000, count: 16 });
|
|
43
|
+
let eventStream = createSwarmEventStream({ runId: 'bench', root: 'agent-runs/bench/streams', lanes: manifest.lanes });
|
|
34
44
|
|
|
35
45
|
const rows = [
|
|
36
46
|
measure('create-plan-' + taskCount, 8, () => {
|
|
@@ -49,7 +59,31 @@ const rows = [
|
|
|
49
59
|
return jsonl.length;
|
|
50
60
|
}),
|
|
51
61
|
measure('jsonl-decode', 16, () => decodeSwarmJsonl(jsonl).length),
|
|
52
|
-
measure('proof', 16, () => createSwarmProof(plan).hash.length)
|
|
62
|
+
measure('proof', 16, () => createSwarmProof(plan).hash.length),
|
|
63
|
+
measure('schedule-lease-' + taskCount, 8, () => {
|
|
64
|
+
schedule = createSwarmSchedule({ plan, maxReadyJobs: 128, maxComputeConcurrency: { fast: 64, deep: 32 } });
|
|
65
|
+
leases = createSwarmLeases({ schedule, workerId: 'bench-worker', now: 1000 + cursor++, leaseMs: 60000, count: 16 });
|
|
66
|
+
return schedule.ready.length + leases.length;
|
|
67
|
+
}),
|
|
68
|
+
measure('queue-snapshot-' + taskCount, 8, () => {
|
|
69
|
+
const snapshot = createSwarmQueueSnapshot({ plan, run, leases, generatedAt: 2000 + cursor++ });
|
|
70
|
+
return snapshot.summary.jobCount + snapshot.summary.leaseCount;
|
|
71
|
+
}),
|
|
72
|
+
measure('run-checkpoint-' + taskCount, 16, () => createSwarmRunCheckpoint({ run, sequence: cursor++ }).hash.length),
|
|
73
|
+
measure('merge-bundle-' + taskCount, 32, () => createSwarmMergeBundle({
|
|
74
|
+
job: plan.jobs[cursor % plan.jobs.length],
|
|
75
|
+
result: {
|
|
76
|
+
jobId: plan.jobs[cursor++ % plan.jobs.length].id,
|
|
77
|
+
status: 'completed',
|
|
78
|
+
changedPaths: ['src/runtime/file.ts'],
|
|
79
|
+
verification: [{ status: 0 }]
|
|
80
|
+
},
|
|
81
|
+
patchPath: 'agent-runs/bench/changes.patch'
|
|
82
|
+
}).id.length),
|
|
83
|
+
measure('event-route-' + taskCount, 64, () => {
|
|
84
|
+
eventStream = createSwarmEventStream({ runId: 'bench', root: 'agent-runs/bench/streams', lanes: manifest.lanes });
|
|
85
|
+
return routeSwarmEventToMailboxes(eventStream, { type: 'agent.evidence', jobId: plan.jobs[cursor++ % plan.jobs.length].id, lane: 'runtime' }).length;
|
|
86
|
+
})
|
|
53
87
|
];
|
|
54
88
|
|
|
55
89
|
const report = {
|