Repository navigation
Releases: sanshanya/better-model-provider
Release list
0.0.8 — registry-first install, contract seam at dsh 0.2.0-rc.2
Distribution and documentation release — the registry page now teaches the right install command, and the contract seam walks with upstream. Client bytes remain identical to 0.0.6/0.0.7 (lib/client.js 56,854 B, sha256 ab67b15c02bed7d494313d1a9a55787280e6977e29bf63cad6f4676d83c70e67).
- README now leads with the npm install (
dsh plugin --profile web add better-model-provider); the#mastergit path and the bare-repo-URL story stay as documented alternates. - Contract devDependencies moved atomically to dsh 0.2.0-rc.2 (the five packages cannot move one at a time — their inter-peers pin the same release); typecheck and contract verified green against the 0.2.0-rc.2 declaration surface; nightly canaries kept all three lanes green through 2026-10-09.
- Dependabot patrol grouped (@deepseek-ai/dsh-*) so future upstream bumps land as one atomic PR.
Compat table (README): 0.2.0-rc.2 (npm latest/next) · 0.2.1-alpha.1 · 0.1.7-rc.2 · 0.1.5-rc.3 — all verified end-to-end.
Install: better-model-provider (npm) or github:sanshanya/better-model-provider#master
0.0.7 — admit dsh 0.2.x
Admits the dsh 0.2 line — verified end-to-end on dsh 0.2.0-rc.1 (integration graph=66 rows, inject=6/6; functional 4/4, plus a 0.1.7-rc.1 regression), with typecheck and contract green against the 0.2.0-rc.1 declaration surface. Peer ranges converge to a single >=0.1.2-alpha.1 <0.3.0 — see CHANGELOG for the exact interval and its admission semantics.
Also in this release:
- Management-page identity: self-drawn manifest icon + zh/en localized title and description (both ride this artifact)
- Residual-override cleanup (one explicit click) after the official page rewrote a catalog-route model list
- Canary self-heals: ANSI-colored transcripts no longer defeat the
Tests Ncheck; the assert now follows the spec'sserved=tail; green legs close stale red issues - Client bytes unchanged from 0.0.6 (lib/client.js 56,854 B, sha256 ab67b15c02bed7d494313d1a9a55787280e6977e29bf63cad6f4676d83c70e67) — this release moves protocol and metadata, not client code
Install: github:sanshanya/better-model-provider#master
0.0.6
A subtraction release. Behaviour is unchanged — the golden lane is the only test now, and it passes on dsh-v0.1.7-rc.1 (integration 1 + functional 4) and dsh-v0.1.5-rc.3 (1 + 4): real harness boot, real browser, persisted write + revert.
| 0.0.4 | 0.0.5 | 0.0.6 | |
|---|---|---|---|
| tracked files | 47 | 56 | 39 |
src/ lines |
2,813 | 2,923 | 2,681 |
| verification tooling | — | 932 | 122 |
lib/client.js |
56,642 B | 58,462 B | 55,689 B |
What left
- The call adapter (
toCarrierFrame/toCarrierError/ RPC-ID boxing;wire.ts292 → 136): the page now calls the mountedremote.settings/remote.llmservices' own positional signatures and theirRemoteResultenvelope — one wire vocabulary instead of two. - The contract mirror (
types.ts226 → 151): contract types are imported where they are consumed instead of being re-exported through aliases, so an upstream rename surfaces on the consuming line. store.ts's AbortController machinery: no read accepts a signal, so it could never cancel anything. The generation fence that actually protects the render stays.- The hermetic test surface (8 specs,
tests/helpers.ts,tests/manifest.client.spec.ts, roster generator and snapshots; 3,385 lines undertests/): they asserted against hand-projected fake faces and were green while the same source had 53 real contract errors. The inject-row truth they guarded is now asserted against the served boot graph inside the integration lane — plugin row present, everydsh.client.injectid names a real row, the retireddsh-client-runtimeabsent, the row's ownclient.jsfetched and served. docs/compatibility.md(255 lines of claims citing/tmptranscripts that will not exist for the next reader): the facts moved into the README compatibility table.
What is kept, and why
Named in CONTRIBUTING.md with the failure each prevents: the never-throw remote probe with its exactly-once latch and partial-pair sequencing (a synchronous apply inside the harness's sequential namespace mount throws in the loader entry and fails the whole page), probing via ctx.get instead of inject (declaring a namespace parks the fiber), the payload-agnostic internal/service re-probe, the wire-code type with its conflict-copy branch, the generation fence, and the schema-rehydration walk.
Gates
lint · typecheck · verify:contract (a 9-line tsconfig.contract.json overlay compiling src/ only, so no test-side shim can sit inside the program — that shim is how 0.0.4 passed while its client entry named four members 0.1.7 had removed) · build · verify:pack (strict bare-consumer probe of the packed artifact with no skipLibCheck; 21 upstream barrel gaps tolerated, any in-artifact diagnostic fatal) · the two golden lanes.
@deepseek-ai/schemastery is held at 3.18.1 through an npm overrides entry: the incidental 3.18.4 re-resolution accounted for 1,615 bytes — a third of the artifact — and the type-owner devDeps this package needs peer ~3.18.4, so a plain direct pin breaks npm ci.
Honest notes
- Verification tooling is 122 lines, 2 over the 120 this release aimed for (the comment recording why the overlay inherits
skipLibCheck: trueis worth them). - The
settings/conflictlocalized-copy branch and the remote-probe failure arms are reasoned and named, but the golden lane cannot reach them. - Lines
0.1.2-alpha.1…0.1.6-alpha.2remain admitted by the peer range, never lane-verified.
0.0.5
Re-verified on dsh 0.1.7-rc.1 (npm next) and dsh 0.1.5-rc.3 (npm latest). Feature surface unchanged.
Verified, not asserted
Both real-harness lanes pass on both lines: integration proves the running host advertises and serves the plugin's client module; functional proves all four browser workflows — schema-derived vocabulary, capability write + revert, catalog override + reset, dormant-route onboarding.
Every compatibility sentence is mapped claim-by-claim to a lane transcript or a harness file:line in docs/compatibility.md.
The red lanes were stale oracles, not a broken plugin
On 0.1.7 the section mounted, the rows rendered and the writes landed. Three lane assumptions had gone stale: web resources became document-relative and combo-batched (eeb9b03465, first tagged dsh-v0.1.7-alpha.1); the home settings.yaml was retired into a one-time import whose writes persist to profiles/<name>/cordis.patch.yml (601d6761e4, same tag); and a settings.mutate round trip that takes 423–505 ms at 0.1.7 (10–34 ms at 0.1.5) raced the lane's next click.
Contract, manifest, gates
- Type seam retyped against the published 0.1.7-rc.1 declarations —
IApiClient,RpcError,ConfigurableProviderView,DiscoveredModelViewno longer exist upstream. Newverify:contractproves every consumed name resolves to a real declaration, in both lines and in the packedlib/. dsh.client.injectnames six rows that exist on both lines, held bytests/manifest.client.spec.tsagainst regenerable per-line rosters. The removeddsh-client-runtimeid was inert — no mount failure was fixed.- The untestable ≤0.1.1
connection.apigeneration and the incomplete hyphen-code fold are deleted; the fiber no longer injectsconnection. - Peer ranges are enumerated per published line from
>=0.1.2-alpha.1, so npm's peer rule and dsh's admission gate agree on every published version (0 disagreements measured).engines.noderaised to^22.19.0 || >=24.0.0to match the harness. verify:pack's consumer probe is provisioned from our own devDependencies and fails on any in-artifact diagnostic (negative control recorded). The live canary coverslatest/next/alpha, asserts the generation it boots, and fails a leg whose dist-tag resolved but whose lane skipped.
Known limitations
- Editing a pi-ai route on the official Models page writes the whole
modelsarray, which makesmodelOverridesillegal for that route (llm-pi-ai/src/catalog.ts:850-852); the plugin then rewrites the array instead of sparse leaves. Documented, not fixed. inputandcontextWindow/maxTokensare natively editable upstream for the same provider family and are documented as not differentiators.reasoningEfforts(with wire spellings) and sparsemodelOverridesremain this plugin's unique value.- Real CI canary behaviour and the intermediate lines 0.1.2-alpha.1 … 0.1.6-alpha.2 are admitted but not lane-verified.
0.0.4
兼容 dsh 0.1.2-alpha.2:把重命名的 Remote 错误码(settings/conflict 等)在适配层折回旧拼写,CAS 冲突的本地化提示恢复正常;错误转发改为逐字段构造,防 RemoteError 实例的不可枚举 message 被 spread 丢失。
CI live 金丝雀升级为双频道雷达:rc / alpha 各自按 npm dist-tag 解析当前版本并独立复验,按日运行,亮了自动开追踪 issue。
验证:214 项单测全过、wire.ts 100% 覆盖、两条 live lane 在 alpha.2 真实启动下 5/5。
0.0.3 — dual-generation Remote seam for dsh 0.1.2-alpha.1
dsh master (0.1.2-alpha.1) removed connection.api and moved the settings/llm remotes onto traced remote.<ns> Cordis services with positional signatures, listConfigurableProviders, and a slim {ok, value} | {ok, error} envelope. One dual-generation seam adapts both generations: the published npm line (rc.7–0.1.1-rc.2) runs unchanged, and source-master harnesses work again.
Mounting is race-proof and never throws: registration defers onto cordis service arrivals until the Remote face completes (master mounts namespaces sequentially), names the awaited namespace in either mount order, and contains a throwing section mount instead of letting it escape into cordis dispatch or brick the shell.
Live lanes follow the web login gate (full token URL → 303 cookie exchange; pre-auth line degrades to plain traffic on the same path) and fetch the advertised rev-keyed combo URLs.
Verified: 213/218 hermetic with wire.ts at 100% on all four coverage metrics; integration + functional lanes green on the real 0.1.2-alpha.1 master checkout (schema vocabulary, CAS write/revert, catalog overrides, dormant-route onboarding). Served bundle 56,510 bytes.
Install: dsh plugin --profile web add github:sanshanya/better-model-provider#master (zero-build artifacts published by CI).
better-model-provider 0.0.2 — official-catalog capability management
Highlights from CHANGELOG [0.0.2]
-
Zero-build distribution. CI publishes ready-built artifacts to the
masterbranch on every green main push:dsh plugin --profile web add github:sanshanya/better-model-provider#masternever runs a local build,
sidestepping the pnpmallowBuildscatch described for source installs.
The CI bundle matches a localnpm run buildbyte-for-byte on the verified
commit. -
Promise shape corrected.
@deepseek-ai/schemasteryis a build-time
asset only (esbuild bundles it into the client half; the runtime never
requires it): moved todevDependenciesinstead ofpeerDependencies. -
Boundary copy tracks rc.8's own settings pages. The dedicated-adapter
note now names where those families genuinely declare capability (their
own settings pages — llm-deepseek's per-modelinputModalitieslanded in
rc.8), since "in their adapter code" read stale the moment rc.8 shipped
configuration for it. -
Official catalog providers are now manageable (sparse capability
overrides). A configured catalog route shows an "official catalog"
card; Manage official models lazily asksllm.discoverModels— the
configuration-time seam that answers catalog routes from the installed
catalog itself, endpoint round-trip free and dead-baseURL proof — and
renders the official models with their official capacity baselines. Edits
write sparsemodelOverrides[id]leaves; untouched fields keep following
catalog updates. Reasoning overrides start with explicitly blank wires
(the official spelling is never fabricated), and Reset to official
defaults lifts exactly the overridden leaves (entry when it carried
nothing else, the whole dict when it was the last occupant). Ownership,
not the route label, decides the write mode: a catalog route whose
models[]the user owns edits that list like any declared route and is
tagged official · user-listed; the adapter treats an empty user
models[]as no list, so that route still overlays the catalog. -
Installed-but-unconfigured catalog providers onboard from the page.
The directory already carries every built-in provider; they now wait as
compact rows behind a Manage official providers region — picking one
unfolds the ordinary catalog card inline, and the first override write
materializes its profile. No bootstrap document, no keys (still the
official Models page's); and the lifecycle closes: a reset of the last
override on an onboarding-minted profile lifts the shell too, returning
the route to the dormant list instead of leaving an active{}ghost.
The on-page note states the boundary in owning-namespace terms: routes
under dedicated namespaces (llm-deepseek / llm-openai-codex) declare
capabilities in their adapters and never appear — while a pi-ai catalog
route of the same brand name is a different route and does appear. -
Correctness repairs inside the write and render paths. Declared-row
writes re-anchor by model id when the render-time index has drifted
(previously a wrong-model silent write); pure-inherit catalog patches
collapse the emptied override entry like resets do (a stranded{}entry
passed today's validation only to freeze the namespace on a future
catalog upgrade); structured leaves are cloned at the write seam; the
section no longer re-renders with a changed hook count on write-mode
flips, and catalog discovery memoization invalidates with each load
generation. -
Module layout.
CapabilitiesSection.tsx(899 LOC) split into
editors.tsx/rows.tsx/cards.tsxbehind a thin section; the
four-field capability vocabulary and the capacity-field/管理-card
helpers now have one source each; test suites consolidated onto
writeModeOftables and shared mount/schema helpers (−3 tests, −300+
assertion lines). -
Artifact economics + gates. The client bundle ships without its
sourcemap (the map outweighed the bundle 4×) anddocs/no longer rides
the tarball (the README links the raw URL): packed artifact ≈ −76%.
verify:packnow executes the bundle under a stubbed module loader and
asserts thename/inject/applytriple in addition to the consumer
type probe;preparebecameprepack(install no longer builds); the
probe typechecks with the repo-lockfile typescript. -
Contract line follows the published
0.1.0-rc.7(npm published
2026-08-17; ancestry rc.2 → rc.3 → rc.6 → rc.7, no rc.4/5). Peer and dev
dependencies and the live-lane bundle pins moved from rc.6; typecheck is
the arbiter (the wire faces are unchanged). Verified against a real rc.7
harness: the packed plugin registers in a fresh profile (integration),
and the real-browser lane walks declared write + revert, catalog
override + reset, and dormant-route onboarding intosettings.yaml. -
Install + release hygiene. Both READMEs document the GitHub
build-script catch (pnpm does not run a git dependency'sprepare;
allow the printed key underallowBuildsin the profile's
pnpm-workspace.yaml) and state that alink:install must build
first. Package metadata completed (repository,homepage,bugs,
keywords);buildcleanslib/first; the coverage exemption for the
host keepalive is disclosed.