@tangle-network/agent-eval 0.191.0 → 0.193.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/CHANGELOG.md +61 -0
- package/dist/adapters/http.d.ts +2 -2
- package/dist/analyst/index.d.ts +6 -6
- package/dist/analyst/index.js +3 -3
- package/dist/{analyze-runs-SCSWYpy0.js → analyze-runs-B6gv7vAT.js} +2 -2
- package/dist/{analyze-runs-SCSWYpy0.js.map → analyze-runs-B6gv7vAT.js.map} +1 -1
- package/dist/{benchmark-command-3tZJnD82.js → benchmark-command-DVhUPU7H.js} +7 -7
- package/dist/{benchmark-command-3tZJnD82.js.map → benchmark-command-DVhUPU7H.js.map} +1 -1
- package/dist/benchmarks/index.d.ts +3 -3
- package/dist/benchmarks/index.js +3 -3
- package/dist/campaign/index.d.ts +5 -5
- package/dist/campaign/index.js +12 -12
- package/dist/{campaign-C8iWEF0M.js → campaign-DdE6S80e.js} +15 -328
- package/dist/campaign-DdE6S80e.js.map +1 -0
- package/dist/{campaign-evidence-BqjlTM3P.js → campaign-evidence-DJc60F9C.js} +11 -46
- package/dist/campaign-evidence-DJc60F9C.js.map +1 -0
- package/dist/cli.js +47 -10
- package/dist/cli.js.map +1 -1
- package/dist/{client-wFyDisxi.d.ts → client-dMMKoQNS.d.ts} +2 -2
- package/dist/{client-wFyDisxi.d.ts.map → client-dMMKoQNS.d.ts.map} +1 -1
- package/dist/contract/index.d.ts +7 -7
- package/dist/contract/index.js +10 -10
- package/dist/{default-registry-DK_9aVJf.d.ts → default-registry-C3HTE08O.d.ts} +3 -3
- package/dist/{default-registry-DK_9aVJf.d.ts.map → default-registry-C3HTE08O.d.ts.map} +1 -1
- package/dist/{define-agent-eval-P28y7mI1.d.ts → define-agent-eval-DQJvVa1P.d.ts} +15 -24
- package/dist/{define-agent-eval-P28y7mI1.d.ts.map → define-agent-eval-DQJvVa1P.d.ts.map} +1 -1
- package/dist/{define-agent-eval-BE43YTm4.js → define-agent-eval-DkPbnJEY.js} +9 -10
- package/dist/define-agent-eval-DkPbnJEY.js.map +1 -0
- package/dist/diagnosis/index.js +1 -1
- package/dist/{dspy-rlm-engine-MfpwoEaj.js → dspy-rlm-engine-BX34vPVY.js} +2 -2
- package/dist/{dspy-rlm-engine-MfpwoEaj.js.map → dspy-rlm-engine-BX34vPVY.js.map} +1 -1
- package/dist/{engine-vNiM02Ub.d.ts → engine-DjRV55F9.d.ts} +2 -2
- package/dist/{engine-vNiM02Ub.d.ts.map → engine-DjRV55F9.d.ts.map} +1 -1
- package/dist/evaluation.d.ts +1 -1
- package/dist/experiment/index.d.ts +2 -2
- package/dist/experiment/index.js +4 -4
- package/dist/{external-optimizer-process-xFTliuiK.js → external-optimizer-process-D-Sab4v3.js} +3 -62
- package/dist/external-optimizer-process-D-Sab4v3.js.map +1 -0
- package/dist/{external-optimizer-subprocess-B234V9V0.js → external-optimizer-subprocess-kbqC-iWf.js} +64 -3
- package/dist/external-optimizer-subprocess-kbqC-iWf.js.map +1 -0
- package/dist/hosted/index.d.ts +2 -2
- package/dist/hosted/index.js +1 -1
- package/dist/{index-D-TN7ZRM.d.ts → index-0jEtpSM7.d.ts} +3 -3
- package/dist/{index-D-TN7ZRM.d.ts.map → index-0jEtpSM7.d.ts.map} +1 -1
- package/dist/{index-I4UJGRno.d.ts → index-Bj96W0jZ.d.ts} +28 -2
- package/dist/{index-I4UJGRno.d.ts.map → index-Bj96W0jZ.d.ts.map} +1 -1
- package/dist/{index-CzfnASj_.d.ts → index-DMPLG226.d.ts} +400 -374
- package/dist/index-DMPLG226.d.ts.map +1 -0
- package/dist/{index-DH-MWH5f.d.ts → index-DWQNDqPd.d.ts} +7 -7
- package/dist/{index-DH-MWH5f.d.ts.map → index-DWQNDqPd.d.ts.map} +1 -1
- package/dist/index.d.ts +9 -9
- package/dist/index.js +9 -292
- package/dist/index.js.map +1 -1
- package/dist/jev.d.ts +1 -1
- package/dist/{journal-c3qY0SDP.js → journal-DvKCvjty.js} +94 -2
- package/dist/{journal-c3qY0SDP.js.map → journal-DvKCvjty.js.map} +1 -1
- package/dist/ledger-core/index.d.ts +2 -2
- package/dist/ledger-core/index.js +2 -2
- package/dist/{llm-judge-NJOHM0iA.js → llm-judge-ChbWfeWl.js} +2653 -656
- package/dist/llm-judge-ChbWfeWl.js.map +1 -0
- package/dist/{matrix-CgqdFm5N.d.ts → matrix-CNu13gg8.d.ts} +2 -2
- package/dist/{matrix-CgqdFm5N.d.ts.map → matrix-CNu13gg8.d.ts.map} +1 -1
- package/dist/multishot/golden/index.d.ts +1 -1
- package/dist/multishot/index.d.ts +2 -2
- package/dist/openapi.json +1 -1
- package/dist/paired-delta-test-BF-FEP8V.js +78 -0
- package/dist/paired-delta-test-BF-FEP8V.js.map +1 -0
- package/dist/{paired-promotion-decision-6cn3bLc3.js → paired-promotion-decision-DTKl6-G8.js} +4 -77
- package/dist/paired-promotion-decision-DTKl6-G8.js.map +1 -0
- package/dist/{produced-state-CY-L7CqS.js → produced-state-BqeIaIp2.js} +3 -3
- package/dist/{produced-state-CY-L7CqS.js.map → produced-state-BqeIaIp2.js.map} +1 -1
- package/dist/{promotion-policy-CfMNUro2.js → promotion-policy-Cy5OV8BV.js} +3 -3
- package/dist/{promotion-policy-CfMNUro2.js.map → promotion-policy-Cy5OV8BV.js.map} +1 -1
- package/dist/rl.d.ts +1 -1
- package/dist/rl.js +1 -1
- package/dist/{search-ledger-CQ8Uy4FK.js → search-ledger-CJiAEU3j.js} +164 -36
- package/dist/search-ledger-CJiAEU3j.js.map +1 -0
- package/dist/{search-ledger-file-EvdDZRhv.js → search-ledger-file-DY0AXX3W.js} +2 -2
- package/dist/{search-ledger-file-EvdDZRhv.js.map → search-ledger-file-DY0AXX3W.js.map} +1 -1
- package/dist/{search-ledger-types-C9anU2DX.d.ts → search-ledger-types-B3El5xgS.d.ts} +95 -11
- package/dist/search-ledger-types-B3El5xgS.d.ts.map +1 -0
- package/dist/{search-shipper-C55V7HE3.js → search-shipper-DUlwlCsK.js} +3 -3
- package/dist/{search-shipper-C55V7HE3.js.map → search-shipper-DUlwlCsK.js.map} +1 -1
- package/dist/search-summary-BhY8p0Av.js +378 -0
- package/dist/search-summary-BhY8p0Av.js.map +1 -0
- package/dist/{semantic-concept-judge-Bt7bXAAo.js → semantic-concept-judge-Bg-560H0.js} +3 -3
- package/dist/{semantic-concept-judge-Bt7bXAAo.js.map → semantic-concept-judge-Bg-560H0.js.map} +1 -1
- package/dist/{sequential-lwJOTRON.js → sequential-C21_PP7F.js} +2 -2
- package/dist/{sequential-lwJOTRON.js.map → sequential-C21_PP7F.js.map} +1 -1
- package/dist/{skillopt-optimization-method-DwO3TOAV.js → skillopt-optimization-method-DXQdaBjx.js} +7 -7
- package/dist/{skillopt-optimization-method-DwO3TOAV.js.map → skillopt-optimization-method-DXQdaBjx.js.map} +1 -1
- package/dist/{statistical-heldout-BED3wBtX.d.ts → statistical-heldout-D-xBpbrd.d.ts} +2 -2
- package/dist/{statistical-heldout-BED3wBtX.d.ts.map → statistical-heldout-D-xBpbrd.d.ts.map} +1 -1
- package/dist/{statistical-heldout-GcLIPxk4.js → statistical-heldout-DANVmyug.js} +2 -2
- package/dist/{statistical-heldout-GcLIPxk4.js.map → statistical-heldout-DANVmyug.js.map} +1 -1
- package/dist/{store-tool-spans-Cfh9XUCm.d.ts → store-tool-spans-BxrfuU2t.d.ts} +4 -4
- package/dist/{store-tool-spans-Cfh9XUCm.d.ts.map → store-tool-spans-BxrfuU2t.d.ts.map} +1 -1
- package/dist/{tool-groups-D-mkeN0N.d.ts → tool-groups-BC9O7Epn.d.ts} +2 -2
- package/dist/tool-groups-BC9O7Epn.d.ts.map +1 -0
- package/dist/trace-repair/index.d.ts +1 -1
- package/dist/traces.d.ts +2 -2
- package/dist/{types-BmQRs661.d.ts → types-BWwRXofp.d.ts} +340 -17
- package/dist/types-BWwRXofp.d.ts.map +1 -0
- package/dist/{types-ClK-sHs8.d.ts → types-qoxUfKQg.d.ts} +2 -2
- package/dist/{types-ClK-sHs8.d.ts.map → types-qoxUfKQg.d.ts.map} +1 -1
- package/docs/campaign-proposers.md +14 -16
- package/docs/search-ledger.md +129 -3
- package/package.json +1 -1
- package/dist/campaign-C8iWEF0M.js.map +0 -1
- package/dist/campaign-evidence-BqjlTM3P.js.map +0 -1
- package/dist/claim-BGOUqoMq.d.ts +0 -38
- package/dist/claim-BGOUqoMq.d.ts.map +0 -1
- package/dist/define-agent-eval-BE43YTm4.js.map +0 -1
- package/dist/external-optimizer-process-xFTliuiK.js.map +0 -1
- package/dist/external-optimizer-subprocess-B234V9V0.js.map +0 -1
- package/dist/index-CzfnASj_.d.ts.map +0 -1
- package/dist/llm-judge-NJOHM0iA.js.map +0 -1
- package/dist/paired-promotion-decision-6cn3bLc3.js.map +0 -1
- package/dist/search-ledger-CQ8Uy4FK.js.map +0 -1
- package/dist/search-ledger-types-C9anU2DX.d.ts.map +0 -1
- package/dist/tool-groups-D-mkeN0N.d.ts.map +0 -1
- package/dist/types-BmQRs661.d.ts.map +0 -1
package/docs/search-ledger.md
CHANGED
|
@@ -54,10 +54,13 @@ The same code runs in the producer's journal, the kernel, and the Intelligence v
|
|
|
54
54
|
- **Graph:** a node exists before an edge or cell names it, and a cell's node already has an edge. A parent registered before its child and already in the tree, so the graph is acyclic. A parent in another search appears only on a `derive` edge that matches `derivedFrom`.
|
|
55
55
|
- **Re-proposal:** identical content is a second edge into the existing node, counted as a re-proposal.
|
|
56
56
|
- **Splits:** a task belongs to one split and one unit. With `heldOutUnits`, no test unit appears in train or selection. Stages match splits: `claim` cells run on test, `screen` and `rung` on selection.
|
|
57
|
-
- **Seal:** only the root (the first registered node) and nodes decided `finalist` run test cells.
|
|
57
|
+
- **Seal:** only the root (the first registered node) and nodes decided `finalist` run test cells. The root is never a finalist, at most 3 nodes are, and none is added once a claim cell exists.
|
|
58
|
+
- **Claim start:** once a node is decided `finalist`, the search only claims: no operation, node, edge or non-claim cell follows.
|
|
59
|
+
- **Parents:** a node decided `invalid` (by admission or by the divergence rule) never appears as a parent on a later edge.
|
|
58
60
|
- **Attempts:** attempts count from 1 without gaps. A `passed` or `failed` outcome is final; only a retryable `errored` outcome admits another attempt.
|
|
59
61
|
- **Budget:** at every `cell-allocated` and `operation-started`, committed spend plus open reservations plus the unspent claim reserve plus the new reservation stays within `maxUsd`. Spend above a reservation is recorded as overspend, never refused. An unknown cost counts as its proven floor.
|
|
60
|
-
- **Completion:** `search-closed` needs every allocated cell settled or cancelled, every started operation recorded, and every node with an edge and a terminal decision.
|
|
62
|
+
- **Completion:** `search-closed` needs every allocated cell settled or cancelled, every started operation recorded, and every node with an edge and a terminal decision.
|
|
63
|
+
- **Claim:** the claim names every node decided `finalist`, estimates each against the root on test, and tests each at `1 - (1 - confidence) / k` for its k finalists. A `ship` claim needs a promoted finalist, held-out test units, a pinned judge, and every test unit scored by the root and the shipped finalist; any other claim keeps the root.
|
|
61
64
|
|
|
62
65
|
A ledger written under another schema tag, such as the retired `tangle.search-ledger.v1` candidate-slot format, is refused with the tag named.
|
|
63
66
|
It is never translated.
|
|
@@ -114,6 +117,28 @@ Its variance is the search's pooled between-unit variance of those improvements
|
|
|
114
117
|
The root sits at exactly 0, and the pooled variance stays null until some node shares 2 units with the root.
|
|
115
118
|
Posterior numbers steer spend and claim nothing; a claim comes from the sealed test split.
|
|
116
119
|
|
|
120
|
+
## The agent's view
|
|
121
|
+
|
|
122
|
+
`renderSearchSummary(state, { split, limit? })` turns a `SearchStateView` into compact text: the leading nodes against the root with their estimates, the most recently discarded nodes with the measurement that discarded them, and a log of recent proposals — as AIDE's journal summary does.
|
|
123
|
+
`agent-eval search show <ledger>` verifies a ledger and prints this for a terminal, on the search's own ranking split (`selection` when the search declares one, else `train`); there is no local HTML renderer.
|
|
124
|
+
|
|
125
|
+
```ts
|
|
126
|
+
import { renderSearchSummary, searchProposerView } from '@tangle-network/agent-eval/campaign'
|
|
127
|
+
|
|
128
|
+
renderSearchSummary(state, { split: 'train' })
|
|
129
|
+
// search s1 — vb/coder — maximize composite
|
|
130
|
+
// 12 nodes · 34 settled cells (2 open) · $1.42 known
|
|
131
|
+
// status: open
|
|
132
|
+
//
|
|
133
|
+
// Leading nodes (vs root, train split):
|
|
134
|
+
// node_… (advanced rung 2): Δ=+0.0821 [0.0340, 0.1290] dashed, sign p=0.0156 (8 units)
|
|
135
|
+
// ...
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
`ProposeContext.train` (a `SearchProposerView`) and `ProposeContext.summary` (this text, always rendered on `split: 'train'`) are how `runOptimization`'s proposal step hands a proposer the search so far.
|
|
139
|
+
`searchProposerView(state)` has no parameter that can select another split: its `scoredCells`/`unitScores` always read `'train'`, so a proposer built on it cannot reach the sealed selection or test split even by mistake.
|
|
140
|
+
`ProposeContext.parents` carries every parent the policy chose, primary first, with its artifact — `currentSurface` is `parents[0].artifact`; a `merge` proposal needs every parent, and the built-in `incumbent`/`crowdedFrontierParent` policies always choose one.
|
|
141
|
+
|
|
117
142
|
## Record a search
|
|
118
143
|
|
|
119
144
|
`SearchRecorder` writes each fact the moment it exists.
|
|
@@ -134,13 +159,108 @@ const cellId = await recorder.allocateCell({ nodeId: root.nodeId, taskId, split:
|
|
|
134
159
|
await recorder.settleCell({ cellId, outcome, accounting, identity, runRecord })
|
|
135
160
|
```
|
|
136
161
|
|
|
137
|
-
`runOptimization
|
|
162
|
+
`runOptimization` and `selfImprove` run on the kernel below and return the receipt on `searchHistory`.
|
|
138
163
|
The loop's scenarios are its proposer's feedback, so they are the train split; its promotions are budget decisions and it makes no claim.
|
|
139
164
|
|
|
140
165
|
`gepaOptimizationMethod({ searchLedger: { identity } })` records GEPA's search when it finishes.
|
|
141
166
|
`importGepaPopulation` turns the population into nodes and `correlated` edges and reports collapsed duplicates.
|
|
142
167
|
`importExternalEvaluations` turns every callback evaluation into an `external` cell; a candidate GEPA evaluated but kept out of its population gets an `unknown` edge and is decided `pruned`.
|
|
143
168
|
|
|
169
|
+
## Run a search: the kernel
|
|
170
|
+
|
|
171
|
+
`runSearch` is the one loop every optimizer runs on.
|
|
172
|
+
It separates three decisions: where to expand (a `SearchPolicy`), where to spend rollouts (a `SearchAllocator`), and what to claim (the claim step on the sealed test split).
|
|
173
|
+
There is no generation barrier.
|
|
174
|
+
A lane that frees up takes the next allocated cell: claim cells first, then rung and root cells, then screens, then train cells.
|
|
175
|
+
The policy proposes when no cell waits, fewer than twice the lanes' capacity run, and the cap admits one proposal and its expected screens.
|
|
176
|
+
|
|
177
|
+
```ts
|
|
178
|
+
import { incumbent, runSearch, SearchRecorder, uniform } from '@tangle-network/agent-eval/campaign'
|
|
179
|
+
|
|
180
|
+
const policy = incumbent({ patience: 3 })
|
|
181
|
+
const allocation = uniform({ reps: 1 })
|
|
182
|
+
const recorder = await SearchRecorder.open({ ledger }, {
|
|
183
|
+
...opening,
|
|
184
|
+
policy: { expansion: policy.name, allocation: allocation.name, seed },
|
|
185
|
+
})
|
|
186
|
+
const { state, leader, reason, claim } = await runSearch({
|
|
187
|
+
recorder, root, codec, policy, allocation, proposer, executor, maxExpansions: 10,
|
|
188
|
+
})
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
The ports:
|
|
192
|
+
|
|
193
|
+
- **Executor:** `lanes()` declares pools of slots, each `hard` (it enforces `cellUsd` per cell) or `estimate` (it cannot); `place(cell)` picks a cell's lane; `run(work)` runs one attempt and returns its outcome, accounting and identity; `adopt(work)` returns an attempt an earlier process finished, or null.
|
|
194
|
+
An environment fault is an `errored` outcome; a rejection stops the search.
|
|
195
|
+
- **Proposer:** `propose({ parents, operator, leader })` returns children with a label, a rationale and optional typed `attribution`, plus the operation's accounting.
|
|
196
|
+
Its output is stored as a `proposal` blob on `operation-recorded` before any child is registered.
|
|
197
|
+
- **Codec:** `node(recorder, artifact)` content-addresses an artifact, `diff` stores the parent-to-child diff, and `load` reads a node's artifact back.
|
|
198
|
+
- **Policy:** `expand(view)` returns parents and an operator, or null to wait; `leader(view)` names the node the search keeps.
|
|
199
|
+
The view holds the policy split (selection, or train when a search has none) and no test cell.
|
|
200
|
+
`incumbent({ patience })` is the hill climb: it expands the leader once every earlier child is screened, and a node that scored every unit of its screen leads when it beats the leader on the units they share.
|
|
201
|
+
`crowdedFrontierParent({ seed })` draws the parent from the Pareto frontier by a seeded crowded tournament and keeps the incumbent's leader rule.
|
|
202
|
+
- **Allocator:** `plan(state, nodeId)` lists the cells a node needs now; the kernel allocates the ones the ledger lacks.
|
|
203
|
+
`uniform({ reps })` gives the root every train and selection task as `root` cells, and every other node every train task (`train`) and selection task (`screen`).
|
|
204
|
+
|
|
205
|
+
**Budget.**
|
|
206
|
+
Every reservation passes the ledger's admission rule: committed spend plus open reservations plus the unspent claim reserve plus the new hold stays within `maxUsd`.
|
|
207
|
+
The kernel checks `state.budget.headroomUsd` first and prices an expansion as one proposal plus `childrenPerProposal` screens.
|
|
208
|
+
A hard lane holds its maximum; an estimate lane holds 1.5 times the p99 of its settled cells once 20 settled, else its prior.
|
|
209
|
+
Spend above a hold is recorded as overspend, never refused.
|
|
210
|
+
Expansion stops at `maxNodes`, `maxExpansions`, the deadline, after `patience` expansions without a new leader, when the cap cannot admit one more expansion, or when the proposer stops.
|
|
211
|
+
Allocated cells still run; at the deadline the ones not yet started are cancelled.
|
|
212
|
+
A search without a test split closes with no claim: the leader is decided `selected` when it has a scored cell, and every other undecided node `rejected` with its estimate against the leader.
|
|
213
|
+
A search with a test split closes with its claim (below).
|
|
214
|
+
|
|
215
|
+
**Divergence.**
|
|
216
|
+
When a node's cells finish, the kernel compares it with its primary parent.
|
|
217
|
+
If its train mean rose on the train units they share while its selection interval against the parent (6 or more units, not indeterminate) lies wholly on the worse side, the node is decided `invalid` with rule `divergence` and the interval as its basis.
|
|
218
|
+
Train is what the proposer reads, so a gain there that selection contradicts is the signature of fitting the feedback instead of the task.
|
|
219
|
+
An invalid node is never a parent and never a finalist.
|
|
220
|
+
|
|
221
|
+
**Resume.**
|
|
222
|
+
The ledger is the only checkpoint.
|
|
223
|
+
Running the kernel again on an open ledger replays it and continues.
|
|
224
|
+
An operation that started without a result is recorded `failed` with an unknown cost and a floor of 0, and the next proposal runs under a new operation id.
|
|
225
|
+
A recorded proposal whose children were not all registered is finished from its stored output.
|
|
226
|
+
A cell the ledger shows unsettled is offered to `executor.adopt` before its first dispatch, so an attempt that finished before the restart is recorded once and not run again.
|
|
227
|
+
Aborting the `signal` pauses the search: in-flight cells are aborted, a scored result that still arrives is recorded, an attempt that ends in an error while the search stops stays unsettled (the error may be the interruption), and the ledger stays open.
|
|
228
|
+
One kernel runs a ledger file at a time on a host: a second one is refused by a pid lock beside the ledger, and a killed holder's lock is reclaimed.
|
|
229
|
+
A closed ledger returns its result; more work on a closed search is a new search.
|
|
230
|
+
|
|
231
|
+
`scripts/search-sim.ts` runs the real kernel, ledger, policies and claim over a seeded synthetic objective, proposer and executor.
|
|
232
|
+
`kill-resume` SIGKILLs it at random ledger positions and compares the resumed search with an uninterrupted one.
|
|
233
|
+
`claims --searches 200 --null` runs 200 searches in which no node differs from the root and reports how often the claim ships, with Wilson and Clopper-Pearson intervals; `--plant-gain X` plants a real gain to measure how often the claim finds it.
|
|
234
|
+
|
|
235
|
+
## The claim
|
|
236
|
+
|
|
237
|
+
A search that declares a test split ends in its claim, made once, on test data no node was selected on.
|
|
238
|
+
`runSearch` refuses to start such a search without a selection split, a claim `minimumEffect`, and a pinned judge.
|
|
239
|
+
Under a cap it also refuses a `reservedClaimUsd` below `searchClaimReserveUsd({ testTasks, reps, cellUsd })`, the hold for the root and 3 finalists on every test task, or a cap that cannot also cover the root and one screening round.
|
|
240
|
+
Size the reserve at the hold the lane will take: an estimate lane holds 1.5 times the p99 of its settled cells once 20 settled.
|
|
241
|
+
|
|
242
|
+
When expansion stops, the kernel:
|
|
243
|
+
|
|
244
|
+
1. **Fixes the design.** `planSearchClaim` ranks the finalists: at most 3 non-root nodes, not invalid, that scored every selection unit and beat the root's mean on them, best selection mean first.
|
|
245
|
+
It fixes the estimator (binary when every unit is one task at one repeat and every pre-test score is 0 or one value, else continuous).
|
|
246
|
+
It checks power: `pairedPromotionPower` simulates the claim's own `decidePairedPromotion` call at a true improvement of `minimumEffect`, with the search's pooled between-unit selection variance, on the test units, at the Bonferroni confidence.
|
|
247
|
+
It keeps the largest k whose power reaches 0.8 and whose test cells the unspent claim reserve and headroom cover.
|
|
248
|
+
The plan is stored as the `claim-plan` blob on the `claim` operation before any test cell exists.
|
|
249
|
+
2. **Seals the family.** Each planned finalist is decided `finalist` with its selection estimate against the root.
|
|
250
|
+
From here the search only claims.
|
|
251
|
+
3. **Runs the test together.** The root's and the finalists' test cells are allocated task by task and dispatched before anything else, so drift over a long search cannot bias the pairs. They run past the deadline, on the reserve held since the start.
|
|
252
|
+
4. **Decides.** `decideSearchClaim` tests each finalist against the root with `decidePairedPromotion` on per-unit test means at confidence `1 - 0.05 / k`, requiring every test unit.
|
|
253
|
+
The promoted finalist with the largest improvement is `selected` and the claim is `ship`; otherwise the claim is `hold` and the root is kept.
|
|
254
|
+
Every other open node is `rejected` with its selection estimate against the root.
|
|
255
|
+
|
|
256
|
+
When the power check fails (a continuous claim needs at least 20 test units to be decided at all) or the reserve cannot cover one finalist, the claim closes as `test-cannot-resolve` and spends nothing on test cells.
|
|
257
|
+
The claim records its rule (`SEARCH_CLAIM_RULE`, whose revision digests every parameter), the family-wise confidence, the power check, each finalist's test estimate and deciding interval, and its reason.
|
|
258
|
+
A verifier recomputes it with `decideSearchClaim(state, plan)` from the stored plan and the test cells.
|
|
259
|
+
A judge change is a changed `search-opened` header, which `SearchRecorder.open` refuses; it starts a derived search instead of mixing verdicts.
|
|
260
|
+
|
|
261
|
+
`compareOptimizationMethods` keeps its own held-out comparison for black-box methods such as GEPA, which return one winner and never see the test split.
|
|
262
|
+
A method's search ledger closes before the comparison starts, so the comparison cannot add claim cells to it.
|
|
263
|
+
|
|
144
264
|
## Ship a search
|
|
145
265
|
|
|
146
266
|
A hosted store (Intelligence, or the reference receiver in `examples/hosted-ingest-server/`) receives a search through the [hosted ingest wire](./hosted-ingest-spec.md).
|
|
@@ -185,7 +305,13 @@ Those claims need the sealed test split, the claim's power check, and held-out e
|
|
|
185
305
|
- `src/campaign/search-ledger.ts`: schemas, canonical ordering, the codec, and `FileSearchLedger`.
|
|
186
306
|
- `src/campaign/search-state.ts`: `SearchState`, the invariants and read model, and the id functions.
|
|
187
307
|
- `src/campaign/estimate-node.ts`: `estimateNode`, `estimateNodeFromCells` and `searchPosterior`.
|
|
308
|
+
- `src/campaign/search-summary.ts`: `renderSearchSummary` and `searchProposerView`.
|
|
188
309
|
- `src/campaign/search-ledger-recording.ts`: `SearchRecorder` and the surface helpers.
|
|
310
|
+
- `src/campaign/search-kernel.ts`: `runSearch`, the executor, proposer and codec ports, `searchPolicyView` and `searchDivergence`.
|
|
311
|
+
- `src/campaign/search-claim.ts`: `planSearchClaim`, `decideSearchClaim` and `searchClaimReserveUsd`.
|
|
312
|
+
- `src/campaign/search-policy.ts`: `SearchPolicy`, `incumbent` and `crowdedFrontierParent`.
|
|
313
|
+
- `src/campaign/allocation.ts`: `SearchAllocator` and `uniform`.
|
|
314
|
+
- `src/campaign/presets/run-optimization.ts`: `runOptimization` as a search on the kernel.
|
|
189
315
|
- `src/campaign/gepa-search-import.ts`: the GEPA population and evaluation importers.
|
|
190
316
|
- `src/campaign/search-history-receipt.ts`: receipts and admission.
|
|
191
317
|
- `src/ledger-core/`: hashing, locking, durable appends, chain verification, and the trusted-head pin.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tangle-network/agent-eval",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.193.0",
|
|
4
4
|
"description": "Evaluate and improve AI agents from runs, traces, judges, and feedback. Compare candidates, cluster failures, measure lift, and gate releases.",
|
|
5
5
|
"homepage": "https://github.com/tangle-network/agent-eval#readme",
|
|
6
6
|
"repository": {
|