@tangle-network/agent-runtime 0.89.0 → 0.90.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 (56) hide show
  1. package/README.md +51 -18
  2. package/dist/agent.d.ts +53 -2
  3. package/dist/agent.js +166 -4
  4. package/dist/agent.js.map +1 -1
  5. package/dist/analyst-loop.d.ts +1 -1
  6. package/dist/{chunk-PIPPLSOF.js → chunk-4IBAMGBE.js} +33 -3
  7. package/dist/chunk-4IBAMGBE.js.map +1 -0
  8. package/dist/chunk-5QOB7H74.js +387 -0
  9. package/dist/chunk-5QOB7H74.js.map +1 -0
  10. package/dist/chunk-74SBMDTO.js +214 -0
  11. package/dist/chunk-74SBMDTO.js.map +1 -0
  12. package/dist/{chunk-BQPFZE2C.js → chunk-MHK62APK.js} +5 -5
  13. package/dist/{chunk-N7EJV7N3.js → chunk-QSNSMJSZ.js} +3417 -3393
  14. package/dist/chunk-QSNSMJSZ.js.map +1 -0
  15. package/dist/{chunk-VNOOH22O.js → chunk-XMOU4WEY.js} +74 -3
  16. package/dist/chunk-XMOU4WEY.js.map +1 -0
  17. package/dist/{chunk-5AVV7KAH.js → chunk-XQEISTK2.js} +2 -2
  18. package/dist/{worktree-harness-CX_McRLp.d.ts → completion-gate-BDaBP8dd.d.ts} +44 -44
  19. package/dist/{coordination-CuDLO8wj.d.ts → coordination-DxHduZg7.d.ts} +414 -226
  20. package/dist/environment-provider.d.ts +3 -3
  21. package/dist/index.d.ts +156 -13
  22. package/dist/index.js +316 -70
  23. package/dist/index.js.map +1 -1
  24. package/dist/intelligence.d.ts +2 -2
  25. package/dist/knowledge.d.ts +120 -0
  26. package/dist/knowledge.js +28 -0
  27. package/dist/knowledge.js.map +1 -0
  28. package/dist/lifecycle.js +1 -1
  29. package/dist/{loop-runner-bin-hQDUL8Ld.d.ts → loop-runner-bin-D3GmB2Ru.d.ts} +2 -2
  30. package/dist/loop-runner-bin.d.ts +5 -5
  31. package/dist/loop-runner-bin.js +5 -5
  32. package/dist/loops.d.ts +46 -141
  33. package/dist/loops.js +3 -3
  34. package/dist/mcp/bin.js +2 -2
  35. package/dist/mcp/index.d.ts +8 -9
  36. package/dist/mcp/index.js +7 -7
  37. package/dist/{openai-tools-BnrOmGjN.d.ts → openai-tools-D0xmzo0y.d.ts} +1 -1
  38. package/dist/profiles.d.ts +196 -5
  39. package/dist/profiles.js +8 -0
  40. package/dist/profiles.js.map +1 -1
  41. package/dist/{router-client-r8y_VFVM.d.ts → router-client-DJImUDlm.d.ts} +1 -1
  42. package/dist/supervise-BpCdssu0.d.ts +131 -0
  43. package/dist/{types-Driepl87.d.ts → types-DAJQRIUD.d.ts} +2 -2
  44. package/dist/{types-ESeMOj94.d.ts → types-Dnk189QA.d.ts} +1 -1
  45. package/dist/{worktree-fanout-D6xR2CIA.d.ts → worktree-fanout-CfRXYmgV.d.ts} +3 -3
  46. package/package.json +12 -4
  47. package/skills/agent-runtime-adoption/SKILL.md +74 -24
  48. package/skills/build-with-agent-runtime/SKILL.md +3 -3
  49. package/skills/loop-writer/SKILL.md +6 -5
  50. package/skills/supervise/SKILL.md +2 -2
  51. package/dist/chunk-N7EJV7N3.js.map +0 -1
  52. package/dist/chunk-PIPPLSOF.js.map +0 -1
  53. package/dist/chunk-VNOOH22O.js.map +0 -1
  54. package/dist/otel-export-BKmNwiCb.d.ts +0 -180
  55. /package/dist/{chunk-BQPFZE2C.js.map → chunk-MHK62APK.js.map} +0 -0
  56. /package/dist/{chunk-5AVV7KAH.js.map → chunk-XQEISTK2.js.map} +0 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tangle-network/agent-runtime",
3
- "version": "0.89.0",
3
+ "version": "0.90.0",
4
4
  "description": "Shared task-lifecycle skeleton for agents: a recursive loop kernel for chat turns, one-shot tasks, and multi-attempt loops, with trace capture and eval-gated self-improvement. Domain behavior lives in adapters; scoring and ship-gates in @tangle-network/agent-eval.",
5
5
  "homepage": "https://github.com/tangle-network/agent-runtime#readme",
6
6
  "repository": {
@@ -49,6 +49,11 @@
49
49
  "import": "./dist/lifecycle.js",
50
50
  "default": "./dist/lifecycle.js"
51
51
  },
52
+ "./knowledge": {
53
+ "types": "./dist/knowledge.d.ts",
54
+ "import": "./dist/knowledge.js",
55
+ "default": "./dist/knowledge.js"
56
+ },
52
57
  "./profiles": {
53
58
  "types": "./dist/profiles.d.ts",
54
59
  "import": "./dist/profiles.js",
@@ -94,9 +99,9 @@
94
99
  },
95
100
  "devDependencies": {
96
101
  "@biomejs/biome": "^2.4.15",
97
- "@tangle-network/agent-eval": "^0.103.2",
98
- "@tangle-network/agent-interface": ">=0.14.0 <1.0.0",
99
- "@tangle-network/sandbox": ">=0.8.0 <1.0.0",
102
+ "@tangle-network/agent-eval": "^0.108.1",
103
+ "@tangle-network/agent-interface": "^0.19.0",
104
+ "@tangle-network/sandbox": "^0.9.7",
100
105
  "@types/node": "^25.9.3",
101
106
  "playwright": "^1.61.0",
102
107
  "tsup": "^8.0.0",
@@ -138,5 +143,8 @@
138
143
  "playwright": {
139
144
  "optional": true
140
145
  }
146
+ },
147
+ "dependencies": {
148
+ "@tangle-network/agent-knowledge": "^1.11.1"
141
149
  }
142
150
  }
@@ -54,10 +54,12 @@ Topology is the **one recursive agent tree**: each round an agent decides to ref
54
54
  construction; the body is harness-re-verified, so an authored strategy can't
55
55
  fabricate a win. Use when the right shape is task-dependent (scout-then-fanout,
56
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.
57
+ - **`createCoordinationTools`** (from `@tangle-network/agent-runtime/mcp`) the
58
+ agent-driving-agent loop: a driver agent spawns / steers / awaits child agents
59
+ (and sub-drivers) through MCP verbs over a live `Scope`, recursively. Use when a
60
+ driver should reason about and orchestrate its workers in natural language. From
61
+ `/loops` the equivalent surfaces are `serveCoordinationMcp` (the verbs as an HTTP
62
+ MCP over a live `Scope`) and the offline `driverAgent`.
61
63
 
62
64
  Topology is **orthogonal to harness** — a strategy decides the shape; the executor
63
65
  decides which harness (claude-code / codex / opencode / pi / router) runs each
@@ -100,6 +102,12 @@ agent-driving-agent loop), expose `createCoordinationTools` over a live `Scope`
100
102
 
101
103
  - `runLoop` validates `ctx.sandboxClient.create` exists or throws
102
104
  `ValidationError`. Never stub a `null` client.
105
+ - Build that client with `resolveSandboxClient({ backend })` (from
106
+ `@tangle-network/agent-runtime/loops`) — the one call that selects the sandbox /
107
+ bridge (cli-bridge) / router transport `runLoop` drives; do not hand-construct it.
108
+ Its sibling `resolveAgentBackend` is a DIFFERENT resolver — it resolves the CHAT
109
+ leg (`runChatThroughRuntime` / `runAgentTaskStream`) and returns an
110
+ `AgentExecutionBackend`, not a feeder for `resolveSandboxClient`.
103
111
  - The kernel emits `loop.started / iteration.dispatch / iteration.ended /
104
112
  decision / ended` via `ctx.traceEmitter`. Wire it to the same OTLP sink as the
105
113
  chat path so loop telemetry is queryable.
@@ -108,17 +116,19 @@ agent-driving-agent loop), expose `createCoordinationTools` over a live `Scope`
108
116
  - Dynamic driver: set the kernel's `runLoop` `maxIterations >=` the driver's so
109
117
  the driver's cap governs and the loop closes on a clean `'done'`.
110
118
 
111
- ## Campaign bridge — `loopDispatch`
119
+ ## Campaign bridge — `loopCampaignDispatch` / `loopDispatch`
112
120
 
113
121
  To run `runLoop` as an agent-eval campaign cell, do NOT hand-build the ExecCtx +
114
122
  forward trace + report usage every time (the third is silent — forgetting it
115
- yields a `{0,0}` cell `assertRealBackend` reads as a stub). Use the one bridge,
116
- `loopDispatch` (the old `loopCampaignDispatch` name was consolidated away; verify
117
- in `src/runtime/index.ts`):
123
+ yields a `{0,0}` cell `assertRealBackend` reads as a stub). Use the bridge. Both
124
+ are exported from `src/runtime/index.ts` and are distinct sibling adapters, NOT a
125
+ rename: `loopCampaignDispatch` returns a `DispatchFn` for plain `runCampaign` /
126
+ `runEvalCampaign`; `loopDispatch` returns a `ProfileDispatchFn` and is the
127
+ `runProfileMatrix` variant (it adds the profile axis).
118
128
 
119
129
  ```ts
120
- import { loopDispatch } from '@tangle-network/agent-runtime/loops'
121
- const dispatch = loopDispatch({
130
+ import { loopCampaignDispatch } from '@tangle-network/agent-runtime/loops'
131
+ const dispatch = loopCampaignDispatch({
122
132
  sandboxClient,
123
133
  toLoopOptions: (scenario, profile) => ({ driver, agentRun, output, validator, task: toTask(scenario) }),
124
134
  // toArtifact? — defaults to result.winner?.output
@@ -126,19 +136,59 @@ const dispatch = loopDispatch({
126
136
  // pass `dispatch` to runCampaign / runEvalCampaign; usage + trace are auto-forwarded
127
137
  ```
128
138
 
129
- `loopDispatch` doubles as the `runProfileMatrix` variant (the `profile` arg is an axis).
139
+ For the common shape — a fixed set of `cases` + a `prompt` builder + a `score`
140
+ fn, swept across profiles — prefer the declarative facade
141
+ `defineLeaderboard({ cases, prompt, score })` (from
142
+ `@tangle-network/agent-runtime/loops`). It composes
143
+ `expandProfileAxes × loopDispatch × naiveDriver` into one call, exposes
144
+ `.run(argv?)` (CLI-flag parsing + matrix) and `.toBenchmarkAdapter()`, and yields
145
+ a ranked leaderboard. Reach for raw `loopDispatch` only when a cell needs a custom
146
+ driver/validator.
130
147
 
131
- ## Identity-gated optimization — agent-eval's `selfImprove`
148
+ ## Identity-gated optimization — agent-runtime's `improve()` (facade over agent-eval's `selfImprove`)
132
149
 
133
- The optimization entry point is **`selfImprove`** (`@tangle-network/agent-eval/contract`),
134
- NOT agent-runtime agent-runtime contributes the code-surface `improvementDriver`
135
- (`/improvement`, the git-worktree path) you pass to it as `driver` to optimize CODE
136
- instead of a string. `selfImprove` optimizes any text/config surface (system /
137
- planner / judge rubric) and is **identity-gated by construction**: it runs evals,
138
- proposes candidates (default driver `gepaDriver`), and a held-out gate ships a winner
139
- only if it beats the baseline. `result.winner.surface` is the **baseline unless
140
- `result.gateDecision === 'ship'`** — so registering a surface for optimization can
141
- never regress it; it only improves when held-out data earns it.
150
+ **Start with `improve()`** the one pluggable RSI verb, exported at the
151
+ `@tangle-network/agent-runtime` package ROOT (its own header: "the ONE public,
152
+ surface-pluggable RSI verb. A thin facade over agent-eval's `selfImprove`"). Real
153
+ signature is 3-arg, NOT a single options object:
154
+
155
+ ```ts
156
+ improve<TScenario, TArtifact>(
157
+ profile: AgentProfile,
158
+ findings: unknown[],
159
+ opts: ImproveOptions,
160
+ ): Promise<ImproveResult>
161
+ ```
162
+
163
+ `opts`: `surface?: 'prompt'|'skills'|'tools'|'mcp'|'hooks'|'code'` (default
164
+ `'prompt'`), `scenarios`, `judge`, `agent`, `gate?: 'holdout'|'none'` (default
165
+ `'holdout'`; `'none'` forces `generations = 0`), plus `budget?` / `llm?` /
166
+ `generator?` / `code?` / `skills?` / `runDir?`. It picks the default proposer for
167
+ the surface (`gepaProposer` for `'prompt'`, `skillOptProposer` for `'skills'`;
168
+ `'code'`/`'tools'`/`'mcp'`/`'hooks'` throw `ConfigError` unless you pass
169
+ `opts.generator` or `opts.code`), extracts the baseline from the profile, runs
170
+ `selfImprove` with the held-out gate, and on a ship verdict writes the winner back
171
+ into the profile field. Returns `ImproveResult { profile, shipped, lift,
172
+ gateDecision, raw }` — deploy with `if (out.shipped) deploy(out.profile)`:
173
+
174
+ ```ts
175
+ import { improve } from '@tangle-network/agent-runtime'
176
+ const out = await improve(profile, findings, {
177
+ surface: 'prompt', scenarios, judge, agent, gate: 'holdout', llm,
178
+ })
179
+ if (out.shipped) deploy(out.profile)
180
+ ```
181
+
182
+ **Drop to `selfImprove`** (`@tangle-network/agent-eval/contract`) only when you
183
+ need finer control — a custom proposer/gate, or the code-surface git-worktree path
184
+ via agent-runtime's `improvementDriver` (`/improvement`), which you pass to it as
185
+ `proposer` to optimize CODE instead of a string. `selfImprove` optimizes any
186
+ text/config surface (system / planner / judge rubric) and is **identity-gated by
187
+ construction**: it runs evals, proposes candidates (default proposer
188
+ `gepaProposer`), and a held-out gate ships a winner only if it beats the baseline.
189
+ `result.winner.surface` is the **baseline unless `result.gateDecision === 'ship'`**
190
+ — so registering a surface for optimization can never regress it; it only improves
191
+ when held-out data earns it.
142
192
 
143
193
  ```ts
144
194
  import { selfImprove } from '@tangle-network/agent-eval/contract'
@@ -148,8 +198,8 @@ const result = await selfImprove({
148
198
  scenarios,
149
199
  judge,
150
200
  budget: { holdoutScenarios, generations: 3, populationSize: 2 },
151
- llm: { baseUrl, apiKey, model: REFLECTION_MODEL }, // drives the default gepaDriver
152
- // driver? — pass agent-runtime's improvementDriver to optimize CODE (worktree) instead of a string
201
+ llm: { baseUrl, apiKey, model: REFLECTION_MODEL }, // drives the default gepaProposer
202
+ // proposer? — pass agent-runtime's improvementDriver to optimize CODE (worktree) instead of a string
153
203
  // gate? — defaults to a held-out gate; pass defaultProductionGate for red-team hardening
154
204
  })
155
205
  // use result.winner.surface unconditionally: it's the baseline until a candidate genuinely wins
@@ -157,7 +207,7 @@ const result = await selfImprove({
157
207
 
158
208
  ### selfImprove gotchas — read before wiring
159
209
 
160
- - **`gepaDriver` mutates TEXT only**, and its only structural guard is `##` H2
210
+ - **`gepaProposer` mutates TEXT only**, and its only structural guard is `##` H2
161
211
  headings (`preserveSections`) + `maxSentenceEdits`. Make load-bearing sections
162
212
  of your prompt real `##` headings, and treat the output schema as fixed code —
163
213
  GEPA optimizes the prose, never the envelope/contract.
@@ -92,8 +92,8 @@ to its native default (`HARNESS_NATIVE_MODEL`) — never silently dropped.
92
92
  | **Spawn N coding agents on isolated git worktrees, keep the one whose patch passes checks** | `worktreeFanout` + `createWorktreeCliExecutor` + `gateOnDeliverable(DeliverableSpec)` over a raw `WorktreePatchArtifact`, winner via `selectValidWinner` — `/loops` — NOT a hand-rolled spawn-loop / "coder" role | canonical-api §3.1 / §5 |
93
93
  | **Sandbox coding rollout** (fresh box/round, or persistent+resume) | `runLoop(options)` / `openSandboxRun(client, opts, deliverable)` — `/loops` | canonical-api §3.1 |
94
94
  | **Optimize a CODE surface** in a gated loop | `improvementDriver({ worktree, generator })` — root `.` | canonical-api §3.4 |
95
- | **Optimize a PROMPT/config surface** (one call) | `selfImprove({ agent, scenarios, judge, baselineSurface })` `agent-eval/contract` | canonical-api §3.4 |
96
- | **Gate: ship/hold a candidate** (campaign ctx) | `defaultProductionGate` / `heldOutGate` / `composeGate` — `agent-eval/contract` | canonical-api §3.4 |
95
+ | **Optimize a PROMPT/config surface** (one call) — START HERE | `improve(profile, findings, { surface, gate })` — root `.` (the one pluggable RSI verb; picks the default proposer from `surface` — `gepaProposer` for prompt, `skillOptProposer` for skills — and wraps `selfImprove`; drop to `selfImprove({ agent, scenarios, judge, baselineSurface })` from `agent-eval/contract` only for the lower-level loop) | canonical-api §3.4 |
96
+ | **Gate: ship/hold a candidate** (campaign ctx) | `defaultProductionGate` / `heldOutGate` / `composeGate` — `agent-eval/contract`; `neutralizationGate` (footprint-matched PLACEBO gate — proves a held-out lift is CONTENT, not added prompt/mount footprint) — `agent-eval/campaign` | canonical-api §3.4 |
97
97
  | **Gate: ship/hold from a `BenchmarkReport`** (per-task cells) | `promotionGate({ report, incumbent, candidate })` — `/loops` | canonical-api §3.4 |
98
98
  | **Run the full multi-generation flywheel + certify** | `runStrategyEvolution(config)` — `/loops` | canonical-api §3.4 |
99
99
  | **Observe a run** (cost/time waterfall, OTLP) | `createWaterfallCollector()` — `/loops`; `createOtelExporter` attached via `composeRuntimeHooks(...)` — root `.` | canonical-api §2 |
@@ -110,7 +110,7 @@ holds the load-bearing invariant the parallel breaks:
110
110
  `loopUntil` + `runPersonified` (threads executor seams; equal-k; selector≠judge
111
111
  firewall; journal/replay — a parallel runner silently fails to wire the seams).
112
112
  - "skill optimizer" / "topology mutator" that opens branches + applies patches
113
- **≈** `improvementDriver` (code surface) or `selfImprove`/`gepaDriver` (prompt
113
+ **≈** `improvementDriver` (code surface) or `selfImprove`/`gepaProposer` (prompt
114
114
  surface) — both gated on a frozen holdout.
115
115
  - "profile-seam" / agent-config wrapper carrying model+prompt+tools+role **≈**
116
116
  `AgentProfile` (it IS that bundle) + `definePersona` (the run record);
@@ -30,7 +30,8 @@ The driver owns strategy.
30
30
  | Review from several lenses | `panel` |
31
31
  | Simulated user/product eval | `defineConversation` + `runConversation` |
32
32
  | Dynamic topology / drivers of drivers | `Scope` or sandbox driver + `createCoordinationTools` |
33
- | Mutate a shared repo | git branch/clone loop with typed merge outcomes |
33
+ | Run N coding workers on isolated worktrees, gate each, pick best patch | `worktreeFanout` |
34
+ | Mutate a shared repo | git branch/clone loop with typed merge outcomes (`gitWorkspace` seam) |
34
35
 
35
36
  If a fixed combinator solves it, do not use a dynamic driver.
36
37
 
@@ -110,9 +111,9 @@ const result = await createSupervisor<Task, Output>().run(driver, task, supervis
110
111
  ```
111
112
 
112
113
  When the driver lives in a sandbox, expose the same verbs through
113
- `createCoordinationTools`: `spawn_worker`, `await_event`, `observe_worker`,
114
- `steer_worker`, `list_questions`, `answer_question`, `ask_parent`, `stop`, and
115
- optional analyst tools.
114
+ `createCoordinationTools`: `spawn_agent`, `await_event`, `observe_agent`,
115
+ `steer_agent`, `list_questions`, `answer_question`, `ask_parent`, `stop`, and
116
+ optional analyst tools (`list_analysts`, `run_analyst`).
116
117
 
117
118
  ## Role Boundaries
118
119
 
@@ -133,7 +134,7 @@ with unresolved `blocks-run` questions.
133
134
  Steer sparingly: only when an analyst finds a concrete mistake, a loop is
134
135
  duplicating work, a parent/Pi answers a blocker, or a verifier reveals a specific
135
136
  fix a running worker can still use. Delivery is through `Scope.send` or
136
- `steer_worker`; failed delivery means spawn a fresh corrected attempt.
137
+ `steer_agent`; failed delivery means spawn a fresh corrected attempt.
137
138
 
138
139
  ## Workspace Loops
139
140
 
@@ -10,7 +10,7 @@ You are a supervisor. You do NOT do the work yourself — you design and drive s
10
10
  ## Loop
11
11
 
12
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`:
13
+ 2. **Author** a worker per sub-task by calling `spawn_agent` with a complete `profile`:
14
14
  - `name` — a short id.
15
15
  - `skills` — the skill files the worker should carry (by name), OR `systemPrompt` — rich, specific instructions for this sub-task.
16
16
  - `model` — the model best suited to this sub-task (optional).
@@ -21,4 +21,4 @@ You are a supervisor. You do NOT do the work yourself — you design and drive s
21
21
 
22
22
  ## Authoring sub-supervisors
23
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.
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_agent`, just a profile that carries this skill.