omp-llm-role 1.0.0 → 1.2.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 +202 -12
- package/agents/designer.md +4 -3
- package/docs/dev/README.md +44 -7
- package/docs/dev/agent-authoring.md +59 -1
- package/docs/dev/architecture.md +106 -28
- package/docs/dev/ci.md +163 -0
- package/docs/dev/current-state.md +364 -24
- package/docs/dev/data-sources.md +231 -38
- package/docs/dev/explorer.md +175 -46
- package/docs/dev/quirks.md +77 -4
- package/docs/dev/releasing.md +130 -17
- package/docs/dev/scoring.md +851 -27
- package/docs/dev/testing.md +253 -0
- package/docs/dev/writes-and-state.md +232 -28
- package/docs/llm-role-rankings.md +149 -148
- package/package.json +814 -80
- package/skills/omp-llm-role-create-agent/SKILL.md +7 -1
- package/src/agent-architect.ts +148 -19
- package/src/agent-create.ts +800 -40
- package/src/agent-file.ts +2 -5
- package/src/architect-provenance.ts +16 -0
- package/src/availability.ts +191 -15
- package/src/benchmark-author.ts +9 -4
- package/src/benchmark-sources.ts +283 -18
- package/src/cli/create-role.ts +29 -1
- package/src/cli/llm-role-rank.ts +40 -1
- package/src/config-edit.ts +207 -80
- package/src/engine.ts +519 -75
- package/src/error-report.ts +562 -0
- package/src/explorer/boot.ts +36 -24
- package/src/explorer/explain.ts +128 -13
- package/src/explorer/scopes.ts +110 -0
- package/src/explorer/server.ts +126 -33
- package/src/extension.ts +464 -48
- package/src/features.ts +105 -0
- package/src/project-registry.ts +65 -0
- package/src/project-setup.ts +382 -0
- package/src/prompts/agent-creation-architect.md +2 -0
- package/src/prompts/project-profile-architect.md +33 -0
- package/src/prompts/project-profile-user.md +8 -0
- package/src/provider-display.ts +67 -0
- package/src/role-archetypes.ts +12 -2
- package/src/role-settings.ts +22 -0
- package/src/settings.ts +211 -24
- package/src/state.ts +1 -1
- package/src/updater.ts +234 -37
- package/web/app.js +434 -12
- package/web/index.html +1 -0
- package/web/style.css +44 -1
- package/docs/dev/spec.md +0 -633
|
@@ -1,11 +1,348 @@
|
|
|
1
|
-
# Current state (2026-10-
|
|
1
|
+
# Current state (2026-10-11)
|
|
2
2
|
|
|
3
|
-
Dated snapshot of the ranking as of the date in the heading —
|
|
4
|
-
eligible counts, per-role leaders,
|
|
3
|
+
Dated snapshot of the ranking and the landed work as of the date in the heading —
|
|
4
|
+
matched/priced/eligible counts, per-role leaders, the open defects, and the
|
|
5
|
+
per-issue work log below. It is refreshed by
|
|
5
6
|
regenerating the report (`node src/cli/llm-role-rank.ts --out docs/llm-role-rankings.md`) and
|
|
6
7
|
copying the new numbers here; release prose belongs in
|
|
7
|
-
[`../../CHANGELOG.md`](../../CHANGELOG.md), not in this file. The
|
|
8
|
-
are the 2026-10-
|
|
8
|
+
[`../../CHANGELOG.md`](../../CHANGELOG.md), not in this file. The model-level
|
|
9
|
+
ranking numbers below are the 2026-10-09 measurement (the input-price blend basis
|
|
10
|
+
#21, the #17/#18/#19/#20 wave and the #34–#40 focus-axis/capability-flag work);
|
|
11
|
+
the provider-pin numbers are the 2026-10-11 measurement (spec #71; see the top
|
|
12
|
+
bullet). Neither is re-derived on read.
|
|
13
|
+
|
|
14
|
+
- Provider ordering: value-for-money route score (2026-10-11, spec #71): the
|
|
15
|
+
auto-pin route basis changed from the route's own value (`q_route −
|
|
16
|
+
λ·priceEff_route`) to a min/max-normalized **value-for-money score** `vfm =
|
|
17
|
+
wT·tNorm − wP·pNorm` (`wT = wTput/(wPrice+wTput)`, `wP =
|
|
18
|
+
wPrice/(wPrice+wTput)`; `tNorm`/`pNorm` min/max over the candidate set), with a
|
|
19
|
+
new **soft** `filters.preferredMinThroughput` floor (routes at or above sort
|
|
20
|
+
first; below-floor routes are kept and sorted last) that the `providerPinning`
|
|
21
|
+
preset sets to 50. `routeValue` is deleted. The model-level ranking is
|
|
22
|
+
unchanged — the report is not regenerated (the ranking CLI does not apply
|
|
23
|
+
capability features and no shipped role sets `preferOwnProvider`). Measured
|
|
24
|
+
2026-10-11 on the current endpoints cache with the live lock's expanded defs
|
|
25
|
+
(all four capabilities on, `cacheHitRate 0.9`; `deepseek/deepseek-v4.1-flash`,
|
|
26
|
+
11 allowed providers, 12 allowed routes):
|
|
27
|
+
`morph/fp8` ($0.0840,
|
|
28
|
+
103 tok/s) wins `default`, `smol`, `commit`, `task`, `advisor`; `coreweave/fp8`
|
|
29
|
+
($0.1978, 185.5 tok/s) wins `slow`, `tiny`, `designer`; `decart/fp4` ($0.0639,
|
|
30
|
+
72 tok/s) wins `vision`, `plan`.
|
|
31
|
+
|
|
32
|
+
- Auto-pin chain expansion (2026-10-10, issue #69): with `providerPinning` on,
|
|
33
|
+
the fallback chain no longer stops at three providers per model — the primary
|
|
34
|
+
model contributes every gate-passing route except the pinned best, then each
|
|
35
|
+
`fallbackChainDepth` fallback model contributes every gate-passing route, in
|
|
36
|
+
score order (the `vfm` route score — spec #71 replaced the original
|
|
37
|
+
route-value order) and deduped by provider slug, so a down provider fails over
|
|
38
|
+
to another provider of the same model before the chain switches models. Chain
|
|
39
|
+
length is data-driven (`(R_primary − 1) + Σ R_fallback`) instead of the fixed
|
|
40
|
+
`2 + 3·fallbackChainDepth`; the manual-`providerPin` and no-pin paths are
|
|
41
|
+
unchanged. The ranking numbers are unchanged — the chain is a write-side
|
|
42
|
+
shape, not a ranking input.
|
|
43
|
+
- Opt-in error reporting (2026-10-08, issue #48): a new `errorReporting` setting
|
|
44
|
+
(`off` — the default — `ask`, `auto`) turns a genuinely unexpected failure — a
|
|
45
|
+
command handler throwing, or a `runUpdater` abort whose `RunResult.defect` is
|
|
46
|
+
set (a `ConfigEditError`/self-check mismatch or the catch-all throw; the
|
|
47
|
+
enumerated environment aborts stay notify-only) — into one structured report
|
|
48
|
+
(plugin version, runtime, platform, the failing command, error
|
|
49
|
+
name/message/stack, timestamp) filed on `Gott50/omp-llm-role`. `ask` surfaces
|
|
50
|
+
the exact payload and files on confirmation, degrading to a notified prefilled
|
|
51
|
+
`…/issues/new` URL in a session with no UI; `auto` files without asking; `off`
|
|
52
|
+
is byte-identical to the pre-#48 behaviour. A token (`GITHUB_TOKEN` → `GH_TOKEN`
|
|
53
|
+
→ `gh auth token`, never stored) uses the API; no token, or a 401/403/404 (a
|
|
54
|
+
fine-grained PAT without Issues:write answers 404), falls through to the
|
|
55
|
+
prefilled URL. The payload is redacted (home dir → `~`, token-shaped strings →
|
|
56
|
+
`<redacted>`) and carries no config contents, model selectors, prompts or
|
|
57
|
+
history rows. A fingerprint marker dedupes a repeat onto the existing open
|
|
58
|
+
issue, and the path is capped (one open issue per fingerprint, one creation per
|
|
59
|
+
fingerprint per UTC day, 3 per UTC day). The ledger of what was filed, offered
|
|
60
|
+
or suppressed is `llm-role-error-reports.json` under the agent dir. The ranking
|
|
61
|
+
numbers are unchanged — reporting is a side channel, not a ranking input.
|
|
62
|
+
|
|
63
|
+
- Empty-collection spellings accepted (2026-10-08, issues #54 + #55): a config
|
|
64
|
+
whose `task.disabledAgents` is spelled `null` — or whose `retry.fallbackChains`
|
|
65
|
+
/ `modelRoles` body is the serializer's own indented `{}` / `[]` line — used to
|
|
66
|
+
throw inside `parseConfig`, so **every session start aborted with `config edit
|
|
67
|
+
refused: disabledAgents: inline value is not supported (block sequence
|
|
68
|
+
expected)` and no role was ever refreshed**. omp re-serializes `config.yml`
|
|
69
|
+
through Bun's `YAML.stringify` (`stringifyYamlConfig`), which spells an empty
|
|
70
|
+
collection exactly that way, so those spellings now read as the empty
|
|
71
|
+
collection and the patch path rewrites the placeholder line into the block
|
|
72
|
+
form (`disabledAgents:` + `- "designer"`); any other inline value on a managed
|
|
73
|
+
key line still throws. Verified against a copy of the real
|
|
74
|
+
`~/.omp/agent/config.yml` (which carries `disabledAgents: null`): the run wrote
|
|
75
|
+
and reported 8 decisions instead of aborting — and the real file carries its own
|
|
76
|
+
production confirmation. Its 2026-10-08T16:34Z `session-start` run wrote the
|
|
77
|
+
config while `disabledAgents: null` was present (config, `llm-role-state.json`
|
|
78
|
+
and `llm-role-history.jsonl` are all stamped 18:34:17 local), which pre-fix was
|
|
79
|
+
impossible: the read threw before any write. The write is recognizably the
|
|
80
|
+
plugin's surgical one, not omp's serializer: a *changed* role line is re-quoted
|
|
81
|
+
(`tiny: "…deepseek-v4.1-flash:off"`) while an unchanged one stays byte-identical
|
|
82
|
+
(`smol: …deepseek-v4.1-flash:off`), the previously plugin-written
|
|
83
|
+
`openrouter/inclusionai/ling-3.0-flash` chain key is pruned (a dumper never
|
|
84
|
+
prunes), and the chain keys the plugin does not own (`web:`,
|
|
85
|
+
`openrouter/~deepseek/…`) keep their unquoted items. The placeholder is left in
|
|
86
|
+
place because the agent sync had nothing to add or remove — `patchDisabledAgents`
|
|
87
|
+
early-returns then, by design. The same probe turned up two more defects, one of
|
|
88
|
+
them tracked as its own issue (#55 — a different error-report fingerprint): the
|
|
89
|
+
parent-block variant of this class — an empty `task:` + ` {}` / `retry:` + ` {}`
|
|
90
|
+
used to take the new child key *after* the `{}` line, YAML no parser accepts,
|
|
91
|
+
with the read-back self-check still passing, i.e. **silent corruption** — now
|
|
92
|
+
has the child key replace the `{}` line, and a prune-only patch creates nothing;
|
|
93
|
+
and #55's block-bound bug (`chainEntries` scanned to the end of `retry:`
|
|
94
|
+
instead of to the end of `fallbackChains:`, so any sibling `retry.*` key
|
|
95
|
+
aborted every run with `unexpected line in fallbackChains block`) is fixed by
|
|
96
|
+
bounding the scan at the key's own indent. Ranking numbers unchanged.
|
|
97
|
+
|
|
98
|
+
- Capability presets (2026-10-07, issue #40): one opt-in flag per capability
|
|
99
|
+
(`features.<id>` global, `roles.<role>.features.<id>` per role) applies the
|
|
100
|
+
plugin's recommended settings to a role; every flag ships **off** and no
|
|
101
|
+
shipped role sets one, so the resolved roles are byte-identical to
|
|
102
|
+
`DEFAULT_ROLES` until a user opts in. The registry (`FEATURES` in
|
|
103
|
+
`src/features.ts`) is the single source of truth and `expandFeatures` the
|
|
104
|
+
single precedence implementation (`effective def = shipped default ⊕
|
|
105
|
+
preset(enabled flags) ⊕ explicit user keys`; a per-role `false` beats a global
|
|
106
|
+
`true`; an explicit knob always wins). Grounding on the 2026-10-09 cache
|
|
107
|
+
(`default` role, 146 eligible; the `providerPinning` row is re-measured on the
|
|
108
|
+
2026-10-11 cache):
|
|
109
|
+
|
|
110
|
+
| Flag | Recommended settings | Measured effect |
|
|
111
|
+
|---|---|---|
|
|
112
|
+
| `endpointCeilings` | `filters.tools: true`, `filters.minOutputTokens: 16384` | 146 → 135 eligible, leader unchanged (`deepseek-v4.1-flash`, 0.37 $/M) |
|
|
113
|
+
| `cachePricing` | `cacheHitRate: 0.5` | 146 eligible, leader unchanged, its `priceEff` 0.3732 → 0.3522 (−5.6 %) |
|
|
114
|
+
| `providerPinning` | `preferOwnProvider: true`, `filters.preferredMinThroughput: 50` | per-model policy, never changes eligibility; prices each model on its **best route** (max `vfm` among the filter-passing, non-degraded, priced routes, cap-respecting; the soft 50 tok/s floor sorts below-floor routes last; ties by slug then id) — 144 of 144 routed models have a candidate route (2026-10-11), so the soft basis covers the whole routed field |
|
|
115
|
+
| `costCap` | `filters.maxPriceUsdPerM: 10` | 146 → 137 eligible (the top ≈6 %), leader unchanged; pool p90 7.8, p95 11.1 $/M, every leader 0.20–3.71 $/M |
|
|
116
|
+
|
|
117
|
+
`providerPinning`'s recommended setting is a **soft per-model policy**
|
|
118
|
+
(`preferOwnProvider`), not a hard `providerPin`: a hard pin would make a model
|
|
119
|
+
with no matching route ineligible and empty most of a role's pool, so the
|
|
120
|
+
policy prices a model on its **best route** — the max-`vfm` route (the
|
|
121
|
+
value-for-money score, with the soft 50 tok/s floor sorting below-floor routes
|
|
122
|
+
last) among the filter-passing, non-degraded, priced routes (thinking-adjusted
|
|
123
|
+
price ≤ `maxPriceUsdPerM`; ties by slug then id) — and falls back to the
|
|
124
|
+
`1/price²` blend only when the model has no candidate route. The basis is soft:
|
|
125
|
+
it never changes eligibility, and on the 2026-10-11 cache every one of the 144
|
|
126
|
+
routed models has a candidate route, so the capability covers the whole routed
|
|
127
|
+
field (the old own-lab slug-prefix rule matched only 51 of 149). `minContextTokens`
|
|
128
|
+
is deliberately not in the `endpointCeilings` bundle (an absolute floor cannot
|
|
129
|
+
express the video's fraction-of-the-model's-own-window complaint). The flags
|
|
130
|
+
are settable from `create-role.ts`, `/create-agent`, `/project-roles`
|
|
131
|
+
(`--feature`/`--list-features`) and the explorer's Features panel; the ranking
|
|
132
|
+
numbers are unchanged until a flag is turned on.
|
|
133
|
+
|
|
134
|
+
- Cross-source axis (2026-10-07, issue #38): the focus-metric gate gained the
|
|
135
|
+
cross-source axis — the zeroeval per-benchmark payload's **second, independent**
|
|
136
|
+
set of the price/throughput/context quantities (`input_cost_per_million`/
|
|
137
|
+
`output_cost_per_million`/`speed_rps`/`context_window`, read by
|
|
138
|
+
`parseBenchmarkPayloadMeta` onto `BenchmarkPayloadMeta.crossSource`, keyed by
|
|
139
|
+
the entry's `model_id`) compared against the plugin's own `price`/`context`.
|
|
140
|
+
The join is **direct on the bare id** (the generic llm-stats benchmark's
|
|
141
|
+
`entries[].model_id` is the llm-stats id, the same space as `Model.id`); the
|
|
142
|
+
axis reports the median relative divergence per axis against
|
|
143
|
+
`PRICE_AGREEMENT_TOLERANCE` (0.5, a **chosen, tunable heuristic**).
|
|
144
|
+
`speedAgreement` is **informational only** and excluded from `status` (the
|
|
145
|
+
units differ — rps vs tok/s — and re-deriving throughput from `speed_rps` is
|
|
146
|
+
out of scope). It is an **annotation, never a gate** (`belowBarReason` has no
|
|
147
|
+
cross-source branch) and it never feeds `price`/`weightPrice` or any ranking
|
|
148
|
+
input — the `1/price²` blend is unchanged (a test pins `rankRole`
|
|
149
|
+
byte-identical with the annotation on). It is `unknown` when no model joined or
|
|
150
|
+
the payload carried none of the four fields. The ranking numbers are unchanged
|
|
151
|
+
— the axis is a create-agent/explorer annotation, not a weight.
|
|
152
|
+
|
|
153
|
+
- Provenance axis (2026-10-07, issue #37): the focus-metric gate gained the
|
|
154
|
+
provenance axis — the benchmark's owner (the catalog row's `dataset_org_id`,
|
|
155
|
+
falling back to `dataset_slug`) and the source's own per-entry org mix (the
|
|
156
|
+
dominant lab and its share, read from each row's `organization_id`, falling
|
|
157
|
+
back to `provider_id`), below-bar above `FOCUS_PROVENANCE_DOMINANT_SHARE` (0.5,
|
|
158
|
+
a **chosen, tunable heuristic** — the per-entry org mix is not measurable from
|
|
159
|
+
the repo's caches at implementation time). It is the **source's own claim**
|
|
160
|
+
about who publishes the benchmark and whose scores it carries: an independent
|
|
161
|
+
cross-check on the pool-derived `composition` axis (whose rule is unchanged),
|
|
162
|
+
with `compositionAgreement` recording whether the two concur (`disagree` when
|
|
163
|
+
exactly one flags `below-bar`, `agree` when both or neither, `unknown` when the
|
|
164
|
+
payload carries no org mix). It is an **annotation, never a gate**
|
|
165
|
+
(`belowBarReason` has no provenance branch), so a vendor-populated source is
|
|
166
|
+
warned but never drops a discovered candidate; it is `unknown` when there is
|
|
167
|
+
neither an owner nor a payload org mix. The three catalog fields (`datasetId`/
|
|
168
|
+
`datasetOrgId`/`datasetSlug`) ride `BenchmarkCatalogEntry` behind the cache
|
|
169
|
+
shape guard (a pre-#37 cache is refetched); the per-entry org mix rides
|
|
170
|
+
`BenchmarkPayloadMeta.provenance`. The ranking numbers are unchanged — the axis
|
|
171
|
+
is a create-agent/explorer annotation, not a weight.
|
|
172
|
+
|
|
173
|
+
- Maintenance axis (2026-10-07, issue #36): the focus-metric gate gained the
|
|
174
|
+
maintenance axis — the catalog row's `updated_at` age in months against
|
|
175
|
+
`FOCUS_DATASET_STALENESS_MONTHS` (12), with `version_count`/`star_count`
|
|
176
|
+
carried as supporting detail. This is the **dataset-date** axis, distinct from
|
|
177
|
+
the model-date `freshness` axis: a benchmark whose dataset was last touched
|
|
178
|
+
years ago but whose rows include one recent model passes freshness and is
|
|
179
|
+
caught here. It is an **annotation, never a gate** (`belowBarReason` has no
|
|
180
|
+
maintenance branch), so a stale dataset is warned but never drops a discovered
|
|
181
|
+
candidate; it is `unknown` when the catalog row is absent or its `updated_at`
|
|
182
|
+
is missing/unparseable. The four fields (`updatedAt`/`versionCount`/
|
|
183
|
+
`latestVersionRowCount`/`starCount`) ride `BenchmarkCatalogEntry` behind the
|
|
184
|
+
cache shape guard (a pre-#36 cache is refetched). The ranking numbers are
|
|
185
|
+
unchanged — the axis is a create-agent/explorer annotation, not a weight.
|
|
186
|
+
|
|
187
|
+
- Modality axis (2026-10-07, issue #35): the focus-metric gate gained the
|
|
188
|
+
modality axis — the catalog row's `modality` (text 514, multimodal 194, image 19,
|
|
189
|
+
audio 9, video 2, null 7 of 745) and the payload's per-entry `multimodal`
|
|
190
|
+
share. It is an **annotation, never a gate**: there is no role modality field,
|
|
191
|
+
so the axis is never `below-bar` and never a drop reason; it is `unknown` only
|
|
192
|
+
when neither the catalog row nor the payload carries a modality signal. The
|
|
193
|
+
catalog row's `modality` rides `BenchmarkCatalogEntry` behind the cache shape
|
|
194
|
+
guard (a pre-#35 cache is refetched); the per-entry `multimodal` rides
|
|
195
|
+
`BenchmarkPayloadMeta.modality`. The ranking numbers are unchanged — the axis
|
|
196
|
+
is a create-agent/explorer annotation, not a weight.
|
|
197
|
+
|
|
198
|
+
- Trust axis (2026-10-07, issue #34): the focus-metric gate gained a fifth axis —
|
|
199
|
+
the per-entry `self_reported` share of a benchmark payload, below-bar above
|
|
200
|
+
`FOCUS_SELF_REPORTED_MAX_SHARE` (0.5). Measured live: `verified` is uniformly
|
|
201
|
+
`false`; `self_reported` varies (gpqa 19/20, deepswe-1.1 14/20,
|
|
202
|
+
terminal-bench-4.0 10/20, aa-omniscience-index 2/3, automationbench-aa 0/1, the
|
|
203
|
+
general benchmarks ~20/20), so a strict-majority bar flags the mostly
|
|
204
|
+
vendor-submitted sources while passing an independently measured one. The
|
|
205
|
+
catalog row's `is_community` (20/745 true) rides `BenchmarkCatalogEntry` behind
|
|
206
|
+
a cache shape guard and is surfaced on the trust axis as `community` (issue
|
|
207
|
+
#43), so a community-submitted benchmark is visible even before its scores are
|
|
208
|
+
loaded. The ranking numbers are unchanged — the axis is a
|
|
209
|
+
create-agent discovery gate, not a weight.
|
|
210
|
+
|
|
211
|
+
- Explorer scope switcher (2026-10-06, issue #28): the explorer is no longer
|
|
212
|
+
user-level only. A **scope** is a role-config source — the user-level lock
|
|
213
|
+
file, or one project where `/project-roles` was used. `startExplorer` resolves
|
|
214
|
+
the scope list (the user-level scope, the projects in the new global registry
|
|
215
|
+
`llm-role-projects.json`, and the session's project when its cwd has a project
|
|
216
|
+
role config) and opens on the session's project when present, else user-level.
|
|
217
|
+
A project scope reads the project lock merged over the user-level lock — the
|
|
218
|
+
updater's own read — and Export writes that scope's lock file through the same
|
|
219
|
+
validate → backup → atomic path. The ranking dataset is loaded once as the
|
|
220
|
+
union of every known scope's resolved roles, so a metric only one scope
|
|
221
|
+
weights (a project-only declared `bench:<id>`) is fetched and switching is
|
|
222
|
+
free. The registry is written by the project-aware `runUpdater` immediately
|
|
223
|
+
after `resolveProjectDir()` and before any early return (guarded only by
|
|
224
|
+
`dryRun`), so a day-stamped no-op session start still registers; entries whose
|
|
225
|
+
project lock file is gone are pruned on the next write. New `POST /api/scope`;
|
|
226
|
+
`GET /api/bootstrap` gains `scopes`/`activeScope`. Verified live (headless
|
|
227
|
+
Chromium): the header lists both scopes, the project is selected by default,
|
|
228
|
+
switching to user drops the project role and repoints the lock path, and a
|
|
229
|
+
registry entry with no lock file renders disabled with a reason tooltip.
|
|
230
|
+
|
|
231
|
+
- Measurement wave (2026-10-06, issues #31–#33): three candidate axes were
|
|
232
|
+
measured and **not** landed — guardrail/alignment (#31: the semantically
|
|
233
|
+
relevant catalog entries sit at one model, the best-covered candidate covers
|
|
234
|
+
5.0% of the field vs the 35% floor, and the safety/security entries that carry
|
|
235
|
+
data are collinear with `general`, r 0.89–1.00), per-task cost (#32: no
|
|
236
|
+
per-task or per-role token profile exists — the only per-model profile the
|
|
237
|
+
plugin already has is OpenRouter's platform-wide traffic, ~10–14× the plugin's
|
|
238
|
+
own input/req, so the $/M price stays the price axis), and agentic multi-agent
|
|
239
|
+
axes (#33: no catalog benchmark measures delegation/teams/handoffs/swarms/
|
|
240
|
+
recovery/a2a, the one multi-agent eval is below the 3-model floor, and the
|
|
241
|
+
20-entry endpoint cap makes the coverage bar unreachable). Numbers and verdicts
|
|
242
|
+
in `scoring.md`.
|
|
243
|
+
|
|
244
|
+
- Endpoints cache shape guard (2026-10-06, issue #30): `readEndpointsCache` now
|
|
245
|
+
also rejects a cache whose records lack `cacheReadPrice` (alongside
|
|
246
|
+
`weightPrice`/`contextLength`), so a cache written before the cache-read
|
|
247
|
+
pricing landed is refetched instead of leaving every route's cache-read price
|
|
248
|
+
`undefined` and a role's `cacheHitRate` silently inert. The fix forces a
|
|
249
|
+
refetch on the first run after the upgrade; the refreshed measurement is
|
|
250
|
+
400 models, throughput-matched 152/400, priced 151.
|
|
251
|
+
|
|
252
|
+
- Wave (2026-10-06): the `1/price²` blend now weights routes by the **input
|
|
253
|
+
(prompt) price** — the router's sort key — while reporting the billed 3:1 blend
|
|
254
|
+
under that distribution (issue #21), so prices moved; endpoint capability
|
|
255
|
+
filters (#18), the four-axis benchmark-quality gate (#17), provider pinning
|
|
256
|
+
(#19) and route-aware pricing (#20) landed. The domain-knowledge (#23) and
|
|
257
|
+
truthfulness (#24) axes were measured and **not** landed (`scoring.md`). Fresh
|
|
258
|
+
measurement: 400 models, throughput-matched 152/400, priced 151. Eligible:
|
|
259
|
+
`default`/`smol`/`slow`/`plan`/`commit`/`tiny`/`task`/`advisor` 143, `vision`
|
|
260
|
+
75, `designer` 88. Leaders: `default`/`task`/`designer` DeepSeek-V4.1-Flash,
|
|
261
|
+
`smol`/`commit` Muse Spark 1.1 (was DeepSeek-V4.1-Flash), `slow`/`plan`/
|
|
262
|
+
`advisor` Muse Spark 1.3, `vision` Qwen3.8 Flash, `tiny` Muse Spark 1.1 (was
|
|
263
|
+
Gemini 3.1 Flash-Lite).
|
|
264
|
+
|
|
265
|
+
- `plan` cost posture (2026-10-03, issue #16): `plan`'s `price` raised 0.12 → 0.25
|
|
266
|
+
(λ 0.00682 → 0.01667) so the posture binds on the **reachable** pool — the pool
|
|
267
|
+
the selector is chosen from. Measured reachable leader-flip w_price 0.2175 (Hy4
|
|
268
|
+
preview → DeepSeek-V4.1-Flash) vs full-pool 0.311 (Muse Spark 1.3 → Qwen3.8
|
|
269
|
+
Flash); 0.25 flips the actionable pick while the full-pool #1 is unchanged.
|
|
270
|
+
Non-price weights rescaled by 0.852273: `general` 0.6, `long_context` 0.116676,
|
|
271
|
+
`throughput` 0.033324 (Σ(non-price) = 0.75 = 1 − price; `q` unchanged). The
|
|
272
|
+
reachable flip rides on `long_context` imputation (39% coverage; DeepSeek's
|
|
273
|
+
index is null → capability fill 0.195, not a measured weakness). Full-pool
|
|
274
|
+
`plan` #1 stays Muse Spark 1.3 (value 0.837 → 0.801); reachable #1 Hy4 preview →
|
|
275
|
+
DeepSeek-V4.1-Flash. The other nine roles are untouched.
|
|
276
|
+
|
|
277
|
+
- Keyed-catalog availability fast path (2026-10-03, issue #15): the updater now consumes
|
|
278
|
+
the shared `KeyAvailability` primitive — when the account's OpenRouter "Filter the
|
|
279
|
+
model catalog for API keys" setting is on, allowed candidates skip the probe and
|
|
280
|
+
key-blocked candidates are pruned from the walk order (the budget counts candidates
|
|
281
|
+
examined, so pre-seeding a blocked verdict would not save it); candidates in neither
|
|
282
|
+
catalog are still probed, and `no-filter`/`unavailable` degrade to the probe walk with
|
|
283
|
+
no abort path. Measured on this account (setting on): keyed `GET /api/v1/models`
|
|
284
|
+
returned 108 rows vs 466 public; after `rankingIdOf` normalization 107 keyed ranking
|
|
285
|
+
ids ⊆ 454 public, 347 blocked. A 6-blocked/6-allowed probe cross-check agreed 6/6
|
|
286
|
+
blocked and 5/6 allowed (the sixth probed `unknown`, which counts as usable).
|
|
287
|
+
|
|
288
|
+
- Role-weight rebalance (2026-10-03, issue #13): `math` dropped from `plan` and
|
|
289
|
+
`slow` (collinear with `reasoning`, r 0.919, and missing for 18% of the pool —
|
|
290
|
+
a coverage penalty, not a quality signal) and its share moved to the
|
|
291
|
+
consolidated `general` axis (capability-preserving, 100% coverage), not
|
|
292
|
+
`throughput` (which would have tripled `slow`'s speed weight and flipped both
|
|
293
|
+
leaders to a cheap/fast model). `general`+`reasoning` merged into `general`
|
|
294
|
+
in `default`/`slow`/`plan`/`advisor` (a pure relabel: `general`~`reasoning`
|
|
295
|
+
r 0.984, so the combined capability share is unchanged). `smol`/`commit`
|
|
296
|
+
`price` raised 0.30/0.35 → 0.45 (the measured binding threshold; non-price
|
|
297
|
+
weights rescaled proportionally, so it is a posture change, not a capability
|
|
298
|
+
change). `plan`'s description drops the now-unweighted `math`. New weights:
|
|
299
|
+
`default` general 0.4926/code 0.1705/agents 0.1137/tool_calling 0.0947/
|
|
300
|
+
throughput 0.0285/price 0.10; `slow` general 0.60/code 0.18/agents 0.13/
|
|
301
|
+
throughput 0.04/price 0.05; `plan` general 0.704/long_context 0.1369/
|
|
302
|
+
throughput 0.0391/price 0.12 (superseded by issue #16, above); `advisor`
|
|
303
|
+
general 0.5947/long_context 0.1004/
|
|
304
|
+
price 0.20/throughput 0.1049; `smol` price 0.45/throughput 0.22/general
|
|
305
|
+
0.1571/code 0.0943/tool_calling 0.0786; `commit` price 0.45/throughput
|
|
306
|
+
0.2285/general 0.2369/code 0.0846. Leaders: `default` DeepSeek-V4.1-Flash
|
|
307
|
+
(unchanged), `slow`/`plan` → Muse Spark 1.3, `advisor` Muse Spark 1.3
|
|
308
|
+
(unchanged), `smol`/`commit` → DeepSeek-V4.1-Flash. `required`, `thinking`,
|
|
309
|
+
`filters`, `enabled` and the `vision`/`tiny`/`task`/`designer` weights are
|
|
310
|
+
unchanged.
|
|
311
|
+
|
|
312
|
+
- Designer weight reconciliation (2026-10-03, issue #12): `designer` `code`
|
|
313
|
+
0.10 → 0.06 (collinear with `website`, r 0.890, so it double-counted one
|
|
314
|
+
capability axis) and the freed 0.04 moved to the independent axes (`price`
|
|
315
|
+
+0.02, `throughput` +0.02), per Scoring rule 5. New weights: general 0.26/
|
|
316
|
+
code 0.06/vision 0.18/throughput 0.15/price 0.17/website 0.18 (Σ = 1.00,
|
|
317
|
+
Σ(non-price) = 0.83 = 1 − 0.17); λ 0.00882 → 0.010241. The `design` archetype
|
|
318
|
+
now derives its `weights`/`required` from `DEFAULT_ROLES.designer` by
|
|
319
|
+
reference (the `general` archetype's pattern), so the two design weightings
|
|
320
|
+
cannot diverge. `required`, `thinking`, `filters.image`, `enabled` and the
|
|
321
|
+
description are unchanged; the leader is unchanged (a refinement, not a
|
|
322
|
+
re-ranking).
|
|
323
|
+
|
|
324
|
+
- Coverage-safe benchmark discovery + agent-write hardening in `/create-agent`
|
|
325
|
+
(2026-10-03, issue #11): discovery now refuses a benchmark that would turn `q`
|
|
326
|
+
into a coverage score — a fill-0 metric whose catalog coverage is below 35% of
|
|
327
|
+
the ranking field is dropped (non-fatal, with a reason), while a capability-
|
|
328
|
+
filled metric (`writing`/`website`/`bench:<id>`, fill 0.195) stays weightable at
|
|
329
|
+
any coverage. The focus set is capped at 3 (priority order preserved) so one
|
|
330
|
+
benchmark keeps a decisive share. The handler loads the ranking universe once
|
|
331
|
+
(the same daily-cached chain the updater/explorer use) for the field size,
|
|
332
|
+
per-metric coverage, and the differentiation comparison; a failed load skips
|
|
333
|
+
the share rule (fill rule still applies, coverage annotated `unknown`). The
|
|
334
|
+
report prints each focus metric's coverage and warns below the bar; `--dry-run`
|
|
335
|
+
and `--json` carry the same signal. Free-text extraction no longer folds
|
|
336
|
+
`general`/`price`/`throughput` (every archetype weights them) but keeps
|
|
337
|
+
`reasoning`. The agent file is written **before** the role, and a failed role
|
|
338
|
+
write rolls it back (restoring the prior file on a `--force` re-create, else
|
|
339
|
+
removing the new one), so a partial failure never leaves a dangling role, a
|
|
340
|
+
retry needs no `--force`, and the user's prior agent is never destroyed. The
|
|
341
|
+
step-3 benchmark prompt previews the request's resolved weights (`resolveRole`),
|
|
342
|
+
so the "already in this role's weights" marker appears live. The vendored
|
|
343
|
+
architect prompt carries a source-version marker (`ARCHITECT_PROMPT_VERSION`)
|
|
344
|
+
asserted by a test. Unit-tested in `tests/create-agent.test.ts` and
|
|
345
|
+
`tests/architect-provenance.test.ts`.
|
|
9
346
|
|
|
10
347
|
- Benchmark discovery in `/create-agent` (2026-10-02, issue #10): when a purpose
|
|
11
348
|
is given, the command fetches the llm-stats benchmark catalog (745 rows,
|
|
@@ -44,13 +381,15 @@ are the 2026-10-02 measurement and are not re-derived on read.
|
|
|
44
381
|
explorer's `/api/bootstrap` listed the external metric with its derived
|
|
45
382
|
metadata. Unit-tested in `tests/benchmark-sources.test.ts`.
|
|
46
383
|
|
|
47
|
-
- Release (2026-10-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
384
|
+
- Release (2026-10-03): `Gott50/omp-llm-role` is public, `main` is pushed, and
|
|
385
|
+
`omp-llm-role@1.0.0` is published to npm (`npm view omp-llm-role version` →
|
|
386
|
+
`1.0.0`). All three install routes were verified against the real URLs in
|
|
387
|
+
throwaway HOMEs (omp 18.4.12): npm (`omp plugin install omp-llm-role`), git
|
|
388
|
+
(`github:Gott50/omp-llm-role`) and marketplace
|
|
389
|
+
(`omp-llm-role@gott50-plugins`) each installed 1.0.0, and each post-install
|
|
390
|
+
session run wrote `modelRoles` + `retry.fallbackChains` into that HOME's
|
|
391
|
+
`config.yml` and landed the three daily caches in the installed copy. See
|
|
392
|
+
Releasing.
|
|
54
393
|
|
|
55
394
|
- `/create-agent` free-text form (2026-10-02): the command now accepts a
|
|
56
395
|
plain-language request as well as flags. `parseCreateAgentInput` splits the
|
|
@@ -314,18 +653,18 @@ are the 2026-10-02 measurement and are not re-derived on read.
|
|
|
314
653
|
0.663, margin 0.039 > `switchMargin`), because the incumbent has no Design
|
|
315
654
|
Arena data and takes the neutral fill while MiMo carries a measured 0.97.
|
|
316
655
|
The other nine roles are untouched (only `designer` weights `website`).
|
|
317
|
-
-
|
|
318
|
-
-
|
|
656
|
+
- 408 llm-stats models; OpenRouter matched 155/408 (throughput), 153 priced (the
|
|
657
|
+
2026-10-08 snapshot read 155/407 — the daily cache moved, not the code; the
|
|
658
|
+
#34–#40 axes and flags leave every ranking byte-identical until a flag is
|
|
659
|
+
turned on).
|
|
660
|
+
- Eligible per role: 146 (vision 75, designer 89, image-input filter).
|
|
319
661
|
- Value-ranking leaders (this report, thinking-adjusted prices; the *ranking*
|
|
320
662
|
leaders, before the account's provider whitelist drops the blocked ones):
|
|
321
|
-
`default` DeepSeek-V4.1-Flash (0.810), `smol`
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
blocked → Hy4), `designer` DeepSeek-V4.1-Flash (0.787). The suffix pass moved
|
|
327
|
-
`default` and `advisor` onto their reachable leaders (Muse Spark 1.3 and
|
|
328
|
-
GPT-5.6 Sol were blocked).
|
|
663
|
+
`default` DeepSeek-V4.1-Flash (0.810), `smol` DeepSeek-V4.1-Flash (0.729),
|
|
664
|
+
`slow` DeepSeek-V4.1-Flash (0.832), `vision` DeepSeek-V4.1-Flash (0.730),
|
|
665
|
+
`plan` Muse Spark 1.3 (0.793), `commit` DeepSeek-V4.1-Flash (0.762), `tiny`
|
|
666
|
+
Muse Spark 1.1 (0.791), `task` DeepSeek-V4.1-Flash (0.754), `advisor`
|
|
667
|
+
Muse Spark 1.3 (0.787), `designer` DeepSeek-V4.1-Flash (0.787).
|
|
329
668
|
- Thinking-adjusted pricing landed (2026-09-27): the suffix table moved into
|
|
330
669
|
`DEFAULT_ROLES` as a per-role `thinking` field, and the price axis scales by
|
|
331
670
|
the level's factor for thinking-capable models — `slow` (`:max`, ×7.86)
|
|
@@ -373,8 +712,9 @@ are the 2026-10-02 measurement and are not re-derived on read.
|
|
|
373
712
|
cannot re-add keys outside `settings.roles` `patchModelRoles` selects. The
|
|
374
713
|
owner-written `retry.fallbackChains` key
|
|
375
714
|
`openrouter/~deepseek/deepseek-v4-flash-latest` is now unreferenced by any
|
|
376
|
-
role; it is left in place deliberately (
|
|
377
|
-
|
|
715
|
+
role; it is left in place deliberately (unwritten, unreferenced keys are never
|
|
716
|
+
pruned — see [`writes-and-state.md`](writes-and-state.md)), so removing it is a
|
|
717
|
+
manual call.
|
|
378
718
|
- Plugin verified live (2026-09-23) with the provider-allowlist probe: the
|
|
379
719
|
account's allowed-providers whitelist excludes first-party openai/azure/
|
|
380
720
|
anthropic endpoints, so the probe gate rewrote `slow` → GLM-5.3 (`:max`),
|