@tangle-network/agent-runtime 0.53.0 → 0.54.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.
Files changed (71) hide show
  1. package/README.md +27 -16
  2. package/dist/agent.d.ts +1 -1
  3. package/dist/agent.js +5 -3
  4. package/dist/agent.js.map +1 -1
  5. package/dist/analyst-loop.d.ts +1 -1
  6. package/dist/analyst-loop.js +2 -2
  7. package/dist/{chunk-K5M3SHEU.js → chunk-2BDXWZUC.js} +5 -34
  8. package/dist/chunk-2BDXWZUC.js.map +1 -0
  9. package/dist/chunk-A73RADPB.js +281 -0
  10. package/dist/chunk-A73RADPB.js.map +1 -0
  11. package/dist/chunk-FRBWCJLP.js +396 -0
  12. package/dist/chunk-FRBWCJLP.js.map +1 -0
  13. package/dist/chunk-GRAGM4MC.js +72 -0
  14. package/dist/chunk-GRAGM4MC.js.map +1 -0
  15. package/dist/{chunk-K6WP7PYW.js → chunk-JTH2FPCK.js} +3231 -424
  16. package/dist/chunk-JTH2FPCK.js.map +1 -0
  17. package/dist/{chunk-P4QNEXFC.js → chunk-KJH62YEK.js} +2 -2
  18. package/dist/{chunk-HNUXAZIJ.js → chunk-P5OKDSLB.js} +2 -2
  19. package/dist/{chunk-GSUO5QS6.js → chunk-VLF5RHEQ.js} +2 -5
  20. package/dist/{chunk-GSUO5QS6.js.map → chunk-VLF5RHEQ.js.map} +1 -1
  21. package/dist/{chunk-JFIYKDXF.js → chunk-XRYEZPR6.js} +2 -1
  22. package/dist/chunk-XRYEZPR6.js.map +1 -0
  23. package/dist/{coder-LKm3Mczw.d.ts → coder-CEkUFv8h.d.ts} +1 -1
  24. package/dist/{types-CNDJCL_0.d.ts → coordination-BMzskrUR.d.ts} +268 -2
  25. package/dist/{kb-gate-CKfykcYQ.d.ts → delegates-BPLIl8EC.d.ts} +491 -566
  26. package/dist/index.d.ts +7 -7
  27. package/dist/index.js +23 -80
  28. package/dist/index.js.map +1 -1
  29. package/dist/intelligence.d.ts +2 -2
  30. package/dist/kb-gate-CuzMYGYM.d.ts +76 -0
  31. package/dist/{loop-runner-bin-D4Ir7b00.d.ts → loop-runner-bin-BGpVVyXp.d.ts} +6 -27
  32. package/dist/loop-runner-bin.d.ts +5 -5
  33. package/dist/loop-runner-bin.js +6 -5
  34. package/dist/loops.d.ts +8 -6
  35. package/dist/loops.js +32 -8
  36. package/dist/mcp/bin.js +94 -30
  37. package/dist/mcp/bin.js.map +1 -1
  38. package/dist/mcp/index.d.ts +9 -272
  39. package/dist/mcp/index.js +45 -365
  40. package/dist/mcp/index.js.map +1 -1
  41. package/dist/{openai-tools-CKfR3EMh.d.ts → openai-tools-CoeLQ7Uo.d.ts} +1 -1
  42. package/dist/profiles.d.ts +2 -2
  43. package/dist/profiles.js +4 -4
  44. package/dist/{router-client-B0Qi1NiN.d.ts → router-client-30Y_pca8.d.ts} +1 -1
  45. package/dist/{run-loop-DgVhucoR.d.ts → run-loop-DluzfJ2h.d.ts} +1 -1
  46. package/dist/runtime.d.ts +424 -23
  47. package/dist/runtime.js +32 -8
  48. package/dist/topology.d.ts +54 -1
  49. package/dist/topology.js +222 -0
  50. package/dist/topology.js.map +1 -1
  51. package/dist/{types-CklkW4Eh.d.ts → types-C8rNlxfV.d.ts} +4 -4
  52. package/dist/workflow.d.ts +2 -2
  53. package/dist/workflow.js +4 -2
  54. package/dist/workflow.js.map +1 -1
  55. package/package.json +5 -5
  56. package/skills/agent-runtime-adoption/SKILL.md +54 -46
  57. package/skills/build-with-agent-runtime/SKILL.md +12 -8
  58. package/skills/loop-writer/SKILL.md +9 -1
  59. package/skills/supervise/SKILL.md +24 -0
  60. package/dist/chunk-5M2WDWBI.js +0 -908
  61. package/dist/chunk-5M2WDWBI.js.map +0 -1
  62. package/dist/chunk-AYRQZRDV.js +0 -623
  63. package/dist/chunk-AYRQZRDV.js.map +0 -1
  64. package/dist/chunk-FO4DCM7R.js +0 -1356
  65. package/dist/chunk-FO4DCM7R.js.map +0 -1
  66. package/dist/chunk-JFIYKDXF.js.map +0 -1
  67. package/dist/chunk-K5M3SHEU.js.map +0 -1
  68. package/dist/chunk-K6WP7PYW.js.map +0 -1
  69. package/dist/driver-B2RKkVJW.d.ts +0 -221
  70. /package/dist/{chunk-P4QNEXFC.js.map → chunk-KJH62YEK.js.map} +0 -0
  71. /package/dist/{chunk-HNUXAZIJ.js.map → chunk-P5OKDSLB.js.map} +0 -0
@@ -35,58 +35,66 @@ A `Driver<Task, Output, Decision>` is just `plan(task, history) → Task[]`
35
35
  (`[task]`→refine, N copies→fanout, `[]`→stop) + `decide(history) → Decision`.
36
36
  Topology is data; the kernel is topology-agnostic.
37
37
 
38
- ### Topology drivers — `@tangle-network/agent-runtime/loops`
39
-
40
- > **Stale-name correction (gen-6 consolidation, #165):** the standalone
41
- > `createRefineDriver` / `createFanoutVoteDriver` factories were **removed** —
42
- > refine/fanout collapsed into the one recursive agent tree. Canonical today:
43
- > the personify combinators `loopUntil`(depth/refine) / `fanout`(breadth/vote)
44
- > and the `Strategy` values `refine` / `sample`, plus `createDriver` for an
45
- > agent-authored topology. Verify names in `src/runtime/index.ts`; see
46
- > `build-with-agent-runtime` + `docs/canonical-api.md` §3.1/§3.3 for the live
47
- > signatures. Likewise `createSandboxPlanner` is gone — pass a `TopologyPlanner`
48
- > to `createDriver({ planner })` directly.
38
+ ### Topology — `@tangle-network/agent-runtime/loops`
39
+
40
+ Topology is the **one recursive agent tree**: each round an agent decides to refine, fan out, spawn a sub-agent, or stop — and a spawned child can itself be a driver. The surfaces:
49
41
 
50
42
  - **`refine` / `loopUntil`** — one attempt/round, validator-gated; iterate over
51
43
  one evolving artifact until valid or budget-capped. Use for incremental
52
- patches, document revision, anything monotonic. (Replaces `createRefineDriver`.)
44
+ patches, document revision, anything monotonic.
53
45
  - **`sample` / `fanout`** — N attempts at equal budget, score once, pick the
54
46
  winner via the single-sourced selector. Use for multi-harness coder fanout,
55
- redundant research with disagreement detection. (Replaces `createFanoutVoteDriver`.)
56
- - **`createDriver({ planner, maxIterations?, maxFanout? })`** — **the
57
- agent authors the topology.** `plan`/`decide` are backed by an injected
58
- `TopologyPlanner` that emits one `TopologyMove` per round
59
- (`{kind:'refine',task}` | `{kind:'fanout',tasks}` | `{kind:'stop'}`). The
60
- planner is invoked once per round in `plan()`; `decide()` reads the cached move
61
- so an LLM planner is never double-called. Use when the right shape is
62
- task-dependent (scout-then-fanout, refine-then-branch, decompose).
63
-
64
- Topology is **orthogonal to harness**: a driver returns `Task[]`; the kernel
65
- round-robins `agentRuns[]` to decide which harness (claude-code / codex /
66
- opencode / pi) runs each branch. One driver spans all backends, including
67
- fanning a single round across several.
68
-
69
- ### Wiring an LLM planner — inject a `TopologyPlanner`
70
-
71
- `createDriver({ planner })` takes an injected `TopologyPlanner` (the standalone
72
- `createSandboxPlanner` factory was removed in the gen-6 consolidation — verify
73
- the live shape in `src/runtime/driver.ts` / `src/runtime/index.ts`). The planner
74
- is the brain (it may call any harness/LLM to author the move); the driver maps
75
- each `TopologyMove` onto kernel structure.
47
+ redundant research with disagreement detection.
48
+ - **`runAgentic({ surface, task, mode|strategy, budget })`** /
49
+ **`defineStrategy(name, body)`** — author the topology as a `Strategy` on the
50
+ keystone `Supervisor`. `runAgentic` runs a built-in `mode` (`'depth'`→refine,
51
+ `'breadth'`→sample) or a custom `strategy`; `defineStrategy` composes
52
+ `ctx.shot()` (one harness-scored attempt) + `ctx.critique()` (the firewalled
53
+ analyst trajectory in, never scores) in ~15 lines. Equal-k holds by
54
+ construction; the body is harness-re-verified, so an authored strategy can't
55
+ fabricate a win. Use when the right shape is task-dependent (scout-then-fanout,
56
+ refine-then-branch, decompose).
57
+ - **`createCoordinationTools`** the agent-driving-agent loop: a driver agent
58
+ spawns / steers / awaits child agents (and sub-drivers) through MCP verbs over a
59
+ live `Scope`, recursively. Use when a driver should reason about and orchestrate
60
+ its workers in natural language.
61
+
62
+ Topology is **orthogonal to harness** — a strategy decides the shape; the executor
63
+ decides which harness (claude-code / codex / opencode / pi / router) runs each
64
+ node. One driver spans all backends.
65
+
66
+ ### Authoring an agent-chosen topology `runAgentic` / `defineStrategy`
67
+
68
+ The agent authors its own topology by composing two firewalled steps inside a
69
+ `Strategy` on the keystone `Supervisor` — `ctx.shot()` (one harness-scored worker
70
+ attempt over an artifact) and `ctx.critique()` (the analyst — trajectory in,
71
+ never scores). `runAgentic` runs it over one `AgenticSurface` on a conserved
72
+ budget pool, so equal-k holds by construction.
76
73
 
77
74
  ```ts
78
- import { createDriver, runLoop, type TopologyPlanner } from '@tangle-network/agent-runtime/loops'
79
-
80
- const planner: TopologyPlanner<Task, Out> = {/* plan() one {kind:'refine'|'fanout'|'stop',…} per round */}
81
- const result = await runLoop({
82
- driver: createDriver({ planner, maxIterations: 8 }),
83
- agentRuns: workerSpecs, output, validator, task, ctx: { sandboxClient: client },
75
+ import { runAgentic, defineStrategy } from '@tangle-network/agent-runtime/loops'
76
+
77
+ const sampleThenRefine = defineStrategy('sampleThenRefine', async (ctx) => {
78
+ const h = await ctx.surface.open(ctx.task)
79
+ let best = await ctx.shot({ handle: h }) // one breadth attempt
80
+ for (let i = 1; i < ctx.budget && best && best.score < 1; i++) {
81
+ const steer = await ctx.critique(best.messages) // analyst — trajectory only
82
+ if (!steer) break
83
+ best = await ctx.shot({ handle: h, messages: best.messages, steer })
84
+ }
85
+ await ctx.surface.close(h)
86
+ return { score: best?.score ?? 0, resolved: (best?.score ?? 0) >= 1, completions: 0, progression: [], shots: 0 }
84
87
  })
88
+
89
+ const result = await runAgentic({ surface, task, strategy: sampleThenRefine, budget: 4 })
85
90
  ```
86
91
 
87
- The planner emits a JSON envelope (`{ kind, tasks?, n?, rationale }`); a missing,
88
- unparseable, or unknown-kind envelope throws `PlannerError` the loop never runs
89
- a topology nobody chose.
92
+ The deliverable score is **harness-verified** computed from the shots the
93
+ harness actually brokered and scored via `surface.score()`, never the value the
94
+ (possibly authored) body returns; an authored strategy can only report what its
95
+ real shots achieved. For an LLM driving *another* agent through MCP verbs (the
96
+ agent-driving-agent loop), expose `createCoordinationTools` over a live `Scope`
97
+ (see the recursive-driver section below) instead of authoring a fixed strategy.
90
98
 
91
99
  ### Driver gotchas
92
100
 
@@ -173,10 +181,10 @@ Mount it on a production `AgentProfile.mcp`; do not re-implement delegation.
173
181
 
174
182
  ## Acceptance checklist
175
183
 
176
- - [ ] Topology is a `Driver`/combinator, not hard-coded control flow. Reuse
177
- `refine`/`loopUntil`, `sample`/`fanout`, or the agent-authored `createDriver`;
178
- build a custom `Driver` against `loops/types.ts:Driver` only when none fit —
179
- never fork the kernel.
184
+ - [ ] Topology is a combinator/`Strategy`, not hard-coded control flow. Reuse
185
+ `refine`/`loopUntil`, `sample`/`fanout`, or author one with
186
+ `runAgentic`/`defineStrategy` (or `createCoordinationTools` for an
187
+ agent-driving-agent loop) — never fork the kernel.
180
188
  - [ ] `runLoop` is bridged to campaigns via `loopDispatch` (usage + trace
181
189
  auto-forwarded), not a hand-rolled ExecCtx.
182
190
  - [ ] Every optimizable prompt is registered through `selfImprove` (or the
@@ -60,7 +60,7 @@ signature + the exact "do NOT build".
60
60
  | **Author a new topology/strategy compactly** | `defineStrategy(name, body)` w/ `ctx.shot()`+`ctx.critique()` — `/loops` | canonical-api §3.3 |
61
61
  | **Add a stateful tool-using domain** | implement `AgenticSurface` (5 hooks) — `/loops` | canonical-api §3.3 |
62
62
  | **Benchmark: compare strategies + significance + Pareto on a domain** | `runBenchmark({ environment, tasks, worker, strategies })` — `/loops` | canonical-api §3.3 |
63
- | **Benchmark: add/run an external benchmark from the harness** | `ADAPTERS`/`resolveAdapter(key)` + `runExperiment` `bench` | canonical-api §3.3 |
63
+ | **Benchmark: add/run an external benchmark from the harness** | `ADAPTERS`/`resolveAdapter(key)` + a bench gate (`*-gate.mts`) over `openSandboxRun` + `sandboxAgentRun` (`bench/src/sandbox-run.ts`) | canonical-api §3.3 |
64
64
  | **Sandbox coding rollout** (fresh box/round, or persistent+resume) | `runLoop(options)` / `openSandboxRun(client, opts, deliverable)` — `/runtime` | canonical-api §3.1 |
65
65
  | **Optimize a CODE surface** in a gated loop | `improvementDriver({ worktree, generator })` — `/improvement` | canonical-api §3.4 |
66
66
  | **Optimize a PROMPT/config surface** (one call) | `selfImprove({ agent, scenarios, judge, baselineSurface })` — `agent-eval/contract` | canonical-api §3.4 |
@@ -68,7 +68,7 @@ signature + the exact "do NOT build".
68
68
  | **Gate: ship/hold from a `BenchmarkReport`** (per-task cells) | `promotionGate({ report, incumbent, candidate })` — `/runtime` | canonical-api §3.4 |
69
69
  | **Run the full multi-generation flywheel + certify** | `runStrategyEvolution(config)` — `/runtime` | canonical-api §3.4 |
70
70
  | **Compose the prod sandbox profile** (eval/prod parity) | `composeProductionAgentProfile(base, opts)` — `/mcp` | canonical-api §3.2 |
71
- | **Observe a run** (cost/time waterfall, live tree, OTLP) | `createWaterfallCollector` / `createTopologyView` / `createOtelExporter` via `composeRuntimeHooks(...)` — root | canonical-api §3.5 |
71
+ | **Observe a run** (cost/time waterfall, live tree, OTLP) | `createWaterfallCollector` / `createOtelExporter` via `composeRuntimeHooks(...)` — root; `createTopologyView` / `renderTopologyTree` — `/topology` | canonical-api §3.5 |
72
72
  | **State any A/B claim** | `pairedLift` (bench) over `pairedBootstrap`/`heldoutSignificance` (substrate) | canonical-api §3.5 |
73
73
  | **Observe/ship with billing-boundary** | `withTangleIntelligence(agent, { project, effort })` — `/intelligence` | canonical-api §7 (now live on main — verify) |
74
74
 
@@ -105,18 +105,22 @@ surface with `selfImprove` → certify on a frozen holdout with the gate.** For
105
105
  multi-generation flywheel, replace the measure/certify steps with one
106
106
  `runStrategyEvolution(...)` and read `report.verdict` (NOT `report.trajectory`)
107
107
  as the evidence. For a sandbox coding rollout judged by an external deterministic
108
- checker, use the bench path: `runExperiment({ adapter: resolveAdapter(...),
109
- sandboxClient, agentRun: sandboxAgentRun({ profile }), arms: [randomArm(...),
110
- analystArm(...)] })` `arms[0]` is the mandatory equal-compute control.
108
+ checker, use the bench-gate path: `resolveAdapter(...)` to pick the benchmark,
109
+ then `openSandboxRun(client, { agentRun: sandboxAgentRun({ profile }), ... },
110
+ deliverable)` per task, A/B-ing a blind arm against an `llmAnalyst`-steered arm
111
+ at equal compute (both helpers live in `bench/src/sandbox-run.ts`; the blind arm
112
+ is the mandatory equal-compute control). See `bench/src/commit0-gate.mts` /
113
+ `gate.ts` for the live shape.
111
114
 
112
115
  ## Two substrates — pick one, don't invent a third
113
116
 
114
117
  Both implement the same recursive-decision atom over the one `Executor` port and
115
118
  share `defaultSelectWinner`. **Reactive** (`Supervisor`/`Scope` + personify
116
119
  combinators: `runPersonified`/`runAgentic`/`runBenchmark`) — prefer for NEW
117
- recursive work; equal-k by construction. **Round-synchronous** (`runLoop` +
118
- `createDriver`, `runExperiment`) sandbox coding rollouts against external
119
- benchmarks. The full when-which map is `docs/canonical-api.md` §6.
120
+ recursive work; equal-k by construction. **Round-synchronous** (`runLoop` driven
121
+ by a caller-supplied `Driver`, plus the bench gates over `openSandboxRun`)
122
+ sandbox coding rollouts against external benchmarks. The full when-which map is
123
+ `docs/canonical-api.md` §6.
120
124
 
121
125
  ## Observe / ship with the Intelligence SDK
122
126
 
@@ -37,9 +37,17 @@ If a fixed combinator solves it, do not use a dynamic driver.
37
37
  ## Minimal Sandbox Loop
38
38
 
39
39
  ```ts
40
+ // runLoop takes a caller-supplied Driver directly (plan() → Task[]; decide() → terminal).
41
+ // `[task]` → refine, N copies → fanout, `[]` → stop. Keep it this small or use a Strategy.
42
+ const refineDriver: Driver<Task, Out, 'done' | 'fail'> = {
43
+ name: 'refine',
44
+ plan: async (task, history) => (history.at(-1)?.verdict?.valid ? [] : [task]),
45
+ decide: (history) => (history.at(-1)?.verdict?.valid ? 'done' : 'fail'),
46
+ }
47
+
40
48
  const trace: unknown[] = []
41
49
  const result = await runLoop({
42
- driver: createDriver({ planner, maxIterations: 4 }),
50
+ driver: refineDriver,
43
51
  agentRun: agentRunSpec,
44
52
  output,
45
53
  validator: executableGate,
@@ -0,0 +1,24 @@
1
+ ---
2
+ name: supervise
3
+ description: Decompose a task into sub-tasks, author a worker AgentProfile for each, drive and verify the workers, and settle only when a deployable check passes. Carrying this skill is what makes an agent a supervisor.
4
+ ---
5
+
6
+ # Supervise
7
+
8
+ You are a supervisor. You do NOT do the work yourself — you design and drive specialist worker agents.
9
+
10
+ ## Loop
11
+
12
+ 1. **Decompose** the task into the smallest set of sub-tasks a single focused worker can each deliver.
13
+ 2. **Author** a worker per sub-task by calling `spawn_worker` with a complete `profile`:
14
+ - `name` — a short id.
15
+ - `skills` — the skill files the worker should carry (by name), OR `systemPrompt` — rich, specific instructions for this sub-task.
16
+ - `model` — the model best suited to this sub-task (optional).
17
+ Write the instructions a power user would write — never a one-liner. **Never spawn a worker with an empty profile.** The quality of the worker is the quality of the profile you author.
18
+ 3. **Await** each worker with `await_next`. Its result reports `valid: true` only if the worker's deployable check passed.
19
+ 4. **On failure**, author a *new* worker whose profile names the specific failure and how to fix it — never blindly retry the same profile.
20
+ 5. **Stop** (reply with no tool call) once the work is delivered. Only a delivered (`valid: true`) worker counts; you cannot declare done yourself.
21
+
22
+ ## Authoring sub-supervisors
23
+
24
+ If a sub-task is itself too large for one worker, author it as a **sub-supervisor**: give its profile a `skills` list that includes `supervise`. It will decompose and drive its own workers one level deeper. This is not a special call — it is the same `spawn_worker`, just a profile that carries this skill.