Skip to content

v1.2.0

Choose a tag to compare

@viztor viztor released this 19 Oct 14:51
4e39d53

1.2.0 (2026-10-19)

Features

  • auth: the Console device flows, as measured (abd4bff)
  • bridge: serve the Gemini models through the plugin's own adapter (cbf3641)
  • catalog: carry each model's thinking level, which the shim dropped (2ae8647)
  • catalog: generate the wire-family endpoints instead of hard-coding them (c37f165)
  • catalog: retain a deprecated id the gateway still serves, and allow a manual withhold (1410905)
  • catalog: support canonical models.opencode.ai endpoint with models.dev fallback (0b62756)
  • catalog: trust the registry's deprecation flag, drop the hand lists (3238f02)
  • catalog: trust the registry's deprecation flag, drop the hand lists (b356bc6)
  • config: let the user pick the endpoint family and find the credential choice (1cb7dda)
  • context: add user-configurable context ceiling and non-destructive context window resolution (1ff889a)
  • credentials: a login is enough - its token joins the resolution chain (4a20653)
  • credentials: read the active org with a stored account (43a6810)
  • credentials: read the installation's own store, opt-in (7969e09)
  • credentials: the login token falls back to the installation's account (cda58fe)
  • credentials: use the installation's own login, opt-in (98389a4)
  • credentials: wire the opt-in reader into the key-source order (6ca6f3f)
  • debug: monitor every request the interceptor touches (7903fcb)
  • debug: rewire the request monitor on the restored file (a5ac9c1)
  • diagnostics: name the declared models the catalog cannot describe (bb9652b)
  • diagnostics: say why a hand-named model cannot be served (6e842c9)
  • endpoints: pair the credential's format with the endpoint family it belongs to (46d694c)
  • endpoints: the mount reads the plane's endpoint from the catalog (982eafe)
  • generations: the request shape follows the credential, like the endpoint does (b79883a)
  • login: a login in use — proactive refresh, one at a time (d41b023)
  • login: a stored login carries its owner, and the org rides the request (47d1778)
  • login: cache the plane the user picked, instead of resetting it to Zen (7a4a0c8)
  • login: let the sign-in row choose which of the two planes it writes to (b6fb336)
  • login: mount the login remote, which has no switch to be off (ed9067e)
  • login: one login credential reader, carrying the org with the token (213e48d)
  • login: the contract a settings surface calls, and the token it never sees (bd7ee71)
  • login: the host half of the flow, and the credential it keeps (77afbfb)
  • login: the settings card, and the last piece of the surface (678a8f7)
  • models: a keyless deployment is offered only what it can call (cf0eaae)
  • models: add per-model configuration overrides for context window and capabilities (cba0f03)
  • models: decorate resolveModelInfo so the picker shows the Effort row (af7cb2e)
  • models: the thinking level reaches the model object, from the catalog (390da89)
  • models: wrap the plane route's adapter, so dispatch sees the model's reasoning (c7c1945)
  • paths: resolve an OpenCode installation the way OpenCode does (b9de902)
  • pool: rotate on a refused credential, wherever it happened (2fc9285)
  • pool: several credentials, one active, opt-in by declaration (84cdfbc)
  • provider: build the gateway's providers from pi's protocols (7c531ff)
  • routing: machinery to take a provider route over from its adapter (f77cbf1)
  • routing: say the route on the model, where the host dispatches on it (21a9c1c)
  • tokens: store a login as a grant, atomically (4eb90b1)
  • v1: add v1 chat completions protocol fixtures and endpoint test suites (7c84c88)
  • verify: keep the script that finds invisible catalog bugs, and run it (3daa63a)

Fixes

  • auth: classify the new endpoint family's tier, and say so when no credential resolves (d048eda)
  • auth: one credential, on the protocol's own header (4964618)
  • bridge: give the provider the auth resolver pi actually calls (0245292)
  • bridge: inherit the installed catalog entry instead of enumerating fields (f4f649e)
  • card: give the three blocks above the form room to read as three (b3c1aaa)
  • catalog: the /models listing is the catalog surface — it seeds (baf34cd)
  • catalog: widen the models.dev timeout, which was tighter than the endpoint (a9320f5)
  • ci: spell the token URL as a template, where an escaped placeholder is allowed (7124c88)
  • ci: the build-script placeholders pnpm wrote into the workspace file (492e4d7)
  • cli-version: see a copy that says the version bare (eb3c612)
  • config: claim the Google route, and stop the shipped row claiming one we never mount (fc3d6ad)
  • credentials: a login refreshes the org the next request carries (045ca0d)
  • credentials: capture the optional service instead of reading it off the context (57fe770)
  • credentials: one sign-in serves both planes (4b06295)
  • credentials: read legacy credential rows, which is all a real install has (4a38ff3)
  • credentials: register the pool rotator through ctx.provide (ff8aa90)
  • credentials: the configured org wins over the login's (212189b)
  • credentials: the login's token is refreshed before it is handed out (e15de30)
  • diagnostics: name the free tier when that is what filtered a model (1842833)
  • diagnostics: report what actually MOUNTED, not just what was claimed (18cb24f)
  • diagnostic: state the reason it computed, not a cause it never checked (af579b2)
  • diagnostics: the logger only buffers, so say it on the console (81839d0)
  • diagnostics: the meter's own report could throw before it printed (ae3a264)
  • discovery,meter: stop re-adding retired models, and make the meter's registration idempotent (9b8dffd)
  • discovery: a model that cannot work is not offered, for hand-listed ones too (e315f95)
  • discovery: a non-record answer is the same group-killer as a throw, one step quieter (7cd9781)
  • discovery: do not offer a free-tier model, which cannot work from here (de6b85c)
  • discovery: free-tier models are not offered, measured with a valid key (0798bbd)
  • discovery: free-tier models are not offered, measured with a valid key (14a8423)
  • discovery: join the hidden protocol routes' models into the picker's list (473640b)
  • discovery: offer the free-tier models, because a signed-in deployment can run them (2ae749c)
  • discovery: one unresolvable model must not remove the whole provider group (3e40395)
  • errors: a 403 on this gateway is a refusal, never a bad key (80a5be5)
  • errors: the refusal text must not carry the status it rewrites (8ed411e)
  • free-tier: request-body injection, catalog is_free, session counter band (f206ba7)
  • identity: the User-Agent is the CLI's version, with no SDK tail (484cc28)
  • lifecycle: an installer that throws took the rest of apply down with it (1dca0e3)
  • lifecycle: publish both services through ctx.provide when ctx.plugin is absent (d04eb18)
  • limits: read the moved page instead of failing on it (0392872)
  • login: the row renders, and the remote is resolved per call (d524b86)
  • login: the row's absence now says why, like the meter's (3d49c99)
  • login: the sign-in row never rendered because its remote was never mounted (f7421dd)
  • messages: send anthropic-version, and make the mock enforce both wire formats (06bffbe)
  • meter: key the once-per-activation guard on the ROOT context, not the argument (52bbbfd)
  • meter: one guarded remote read, and a keyless free turn that does not warn (a9ec913)
  • meter: restore the bounded fallback that registers the meter when the inject gate never opens (9cc4315)
  • meter: say why the meter renders nothing, instead of rendering nothing quietly (31b25ef)
  • meter: the meter registered twice, and the second registration threw (04727fd)
  • meter: the read had three silent exits, and the meter cannot tell them apart (43a2e97)
  • meter: the two catches that made a silent meter unfixable (63f9fd4)
  • meter: two optional chains made a mount that never happened silent (aacd4e6)
  • models,session: probe the gateway instead of trusting a flag, and drop the disproven band (51252b5)
  • models: call the wrapped adapter on the adapter, and wrap only the plane routes (10a2861)
  • models: dispatch takes the levels the picker offers (3be49a0)
  • models: enforce UNSERVED_PLANE_SDKS in isServableModel (49af0fa)
  • models: give the plane route its models, and stop the meter dying on a guarded read (6f75cc1)
  • models: give the plane route's own models their reasoning, so dispatch sees it (2aa6435)
  • models: make the catalog authoritative for a plane route's context and reasoning (13f04db)
  • models: never widen past the declaration, and let it override the catalog (8185b99)
  • models: reasoning is required by pi, so it is always set (fba1201)
  • models: remove artificial Zen free-tier model gate and allow serving free models (7eee20a)
  • models: retire the one dead row among the active set, measured (9f85ca8)
  • models: stop injecting the catalog into the picker; respect the declared list (56b4093)
  • models: stop offering Zen's free tier, which is measured to refuse here (df5c774)
  • pass 403 through untouched, and stop the refresh widening the list either (29158fc)
  • pool: a refused key is marked failed, and the README documents rotation (029831b)
  • pool: rotation must publish, or only this plugin's routes see it (1ca906b)
  • project: the header names the repository, not the folder the session started in (e7682b7)
  • provider: mount each internal route on its protocol's base (2598c03)
  • remote: combine remotes into single Typert contribution and wire model reasoning/context configs (1ea142b)
  • responses: reach the host plugin on both loader generations (ef9776c)
  • routes: a hand-listed model is routed by the family its id names (4bcf9bf)
  • routes: give each wire family its own base instead of deriving it from one (f3845ae)
  • routes: route cross-plane and responses models correctly and check adapter map for registration (a4f1a4f)
  • routing: an unreadable model declaration is not an empty one (7ab03b4)
  • routing: mistral cannot be served, so it is no longer offered (ebf32f4)
  • routing: repair a retired endpoint, do not rewrite a declared one (fc0da59)
  • routing: the dispatch is per ROUTE, not per model — and the record said otherwise (f53ec2e)
  • session: a session id the gateway rejects is replaced, not sent (352f2a9)
  • session: follow 1.19.0, not 2.x - the version this plugin emulates (95c5e51)
  • session: mint DESCENDING ids in the band the gateway admits (9536e10)
  • session: mint the vendor's shape and drop the clamp (f52a75e)
  • session: the affinity pair is for relays, as 1.19.0 splits it (521900a)
  • session: the four session headers are not one value, and two were missing (4169fef)
  • settings: the card named a font token the host does not have (e56d7f1)
  • settings: the card reads until the remote answers, not once (b8adacc)
  • settings: wait on the mount's settlement, not a service name that never appears (7ca25f9)
  • store: the credential value is JSON, so extract the token from it (a4d0daa)
  • test: the import block belongs after the module docstring, and basename was lost (9e06009)
  • test: the lint error I committed and pushed in the previous commit (26f310a)
  • the constant my own control left behind (d13df2f)
  • the free tier works through this plugin, and six places said it did not (99e38df)
  • tools: the injected tool schemas had the wrong field names and missing fields (8078cde)
  • tools: the schemas were corrected against 2.x, and this plugin emulates 1.19.0 (3bbf2a3)
  • ua: the CLI version we claim, and a check that keeps it true (0efbb64)
  • usage: name which of the three ways the host half went missing (b117672)
  • usage: the Go quota base has one public route, and it is not on the inference family (010196f)

Documentation

  • a comment that says google is excluded, and a paragraph stuck in the past tense (e16ed05)
  • a login buys the ask, not yet the answer (025faa1)
  • a missing session reads as a bad credential, measured (d9bc91f)
  • a model on the wrong protocol route, measured end to end (f4b11eb)
  • a model the catalog does not carry cannot be routed at all (79c8eb2)
  • a name from a replaced design, and the sweep that needed two contexts (576ec4c)
  • agents: 'nothing calls it' was wrong - a test helper calls gatewayHeaders (7cde203)
  • agents: a source change needs a process restart, not a page reload (55d4ebb)
  • agents: gatewayHeaders is a second copy of the header policy, and it has drifted (8f019a2)
  • agents: how the dead-export sweep lies, before someone believes it (1be7446)
  • agents: login-session is not dead code, it is the half that is missing (95e900d)
  • agents: login-session.ts is referenced by nothing but its own test (cc7f146)
  • agents: the allowance lookup is written twice, and the tested one is unused (64add94)
  • agents: the bundle gate's local-only ETARGET, and why it is not ours (d7a2f0f)
  • agents: the client-import rule named two files, and the tree has eight (c936616)
  • agents: the gatewayHeaders note described a function that left src/ (fef8bb2)
  • agents: the module this session added and did not map (bf23165)
  • agents: the module this session added and did not map, again (f8dda0b)
  • agents: the mount is async and the card reads the remote synchronously (47d53ae)
  • agents: the note I wrote one commit ago said it was unreferenced (58bc21d)
  • agents: the race was real, and it was not the cause here (4703b9c)
  • agents: the rule that cost a host, and a repo map six modules behind (85d8bb4)
  • agents: the second generated file, which the map did not name (39fb67d)
  • agents: the sweep that lies, in its general form (ea8d9e9)
  • agents: the two login-flow conveniences are unused, and that is the whole story (6f0618f)
  • agents: the wrong-context sweep, third instance (bb192a7)
  • agents: vp pack alone produces a bundle the client loader cannot find (f835ec1)
  • api: the account token serves paid models, so a login is worth building (de81265)
  • api: the claim that a session token unlocks the free tier is false (214496e)
  • api: the ClientHello attempt, so nobody repeats it (a576ca6)
  • api: the table and the conclusion that the correction two rounds ago missed (a025e42)
  • api: what the free tier's gate is not, by exclusion (b26e52a)
  • catalog: the counts the new model moved (964f8e7)
  • code: the comment described a guard that was removed, and the map copied it (d9a2d13)
  • config: the keySource description named an order the code does not use (83a3c7f)
  • correct the inject rule I misread, and record the session rule (abd01ae)
  • correct the two claims that produced the bugs, not just the code (5790bae)
  • credentials: 2.0 already solves the priority problem, with orElse (7738a95)
  • credentials: a login token is not a credential the gateway serves (859fb6f)
  • credentials: a pool holds API keys, and that is measured (0e99fe1)
  • credentials: a section headed 'Not built yet' whose contents were built (57ec82c)
  • credentials: a sign-in should serve both planes, and today it serves one (c049a57)
  • credentials: correct the note - the empty-reference case is deliberate (0def186)
  • credentials: correcting the plan, including the part I have not traced (da29ce6)
  • credentials: five roots, no auth.json, and a home that can move (eddaf7c)
  • credentials: rotation writes on every turn, and why that clause exists (3eacb88)
  • credentials: the auth modes, enumerated from the source (bfc39eb)
  • credentials: the credential path is not a constant, and does not branch on the OS (0805416)
  • credentials: the device-flow client is built; storage and surface are not (1e20417)
  • credentials: the edit is settled, only its test is missing (ee6a8ea)
  • credentials: the edit that is easy to miss, found by tracing the data flow (0412dd4)
  • credentials: the handoff for free and paid authentication (f839b34)
  • credentials: the login remote is built; the card that calls it is not (14a70ce)
  • credentials: the loginToken field is not dropped, so the wiring is fine (3510e63)
  • credentials: the OAuth heading read as a claim about the whole gateway (845be06)
  • credentials: the one thing the first test attempt got wrong (4d8c635)
  • credentials: the OpenCode credential is three kinds, and auth.json is the legacy one (9fb3b8f)
  • credentials: the opt-in assertion, measured (61b29f3)
  • credentials: the opt-in reader needs no dependency after all (82dd3ad)
  • credentials: the org cache is warmed once, and a login happens after (7f06036)
  • credentials: the plane's base URL is the catalog's, not a literal (b3f476f)
  • credentials: the pool is built; the logins are what is left (2d95d3d)
  • credentials: the pool owns a reference, it does not write behind one (9abc906)
  • credentials: the questions that are no longer open (994bad8)
  • credentials: the request path, traced (14af724)
  • credentials: the second attempt narrows the test to one line (ad853e1)
  • credentials: the shape of the org-cache fix, since the hook cannot await (6ee3227)
  • credentials: the shape the opt-in reader would read, from the schema (f67395d)
  • credentials: the status says what exists, including the session layer (11b8f8b)
  • credentials: the status understated what is built, and one claim was stale (7c4cf34)
  • credentials: the two gaps either side of the named error (1d9ab09)
  • credentials: the two obstacles the wiring attempt hit (b382a73)
  • credentials: the wiring has two call sites, not one (a811d1e)
  • credentials: the wiring is two files and one new input (349401d)
  • credentials: the wiring, written down while it is still small (83bb312)
  • credentials: the Zen free tier, refused exhaustively (f91accf)
  • credentials: verify the pool's reference against the real provider (28ff5b8)
  • credentials: what a pool can reach, measured against the seam (1f1768a)
  • credentials: where the login's token joins the chain, and in what order (f7d2db2)
  • credentials: which of the two config mechanisms the step should use (576e4ba)
  • deep-dive: four claims that had drifted from the code (cb59969)
  • deep-dive: the auto-review section kept the conclusion this session overturned (4bc2e14)
  • deep-dive: three comparison rows read as promises the plugin cannot keep (58a25bb)
  • e2e: stop attributing a retired model's measurements to its replacement (215ed18)
  • findings: probe the usage route — the old URL 404s, the fixed one answers 401 (89e5481)
  • findings: record the picker join and how to spot it failing (88567d5)
  • findings: the shim is stale and three dead rows are still offered (2e3ee2d)
  • let a stale deployment say so, as the next step (4271d5c)
  • limits: what the new page looks like, so the HTML path is a small job (2d5fb9f)
  • login: the row renders now, and two places still said it did not (7defdea)
  • login: two descriptions that lagged the behaviour they describe (6e96729)
  • meter: the screenshots are generated on demand, and a checkout has none (5db5b1a)
  • meter: the settings summary has a retry, and its own doc said it did not (b6b2c49)
  • models-discovery: correct the model-info override account (d164ddb)
  • notes: auto review has two failure modes, and only one is about the model (197fa97)
  • notes: both remotes absent at once, and the two console lines that would say why (28e289d)
  • notes: credentials.md is current, including the conclusion that matters most (9c37fab)
  • notes: every count in the documentation, checked against the data (c509170)
  • notes: mark the endpoint claim as a hypothesis, because it was one (b303699)
  • notes: nine sweeps, six findings and three clean results (0718548)
  • notes: reading deep-dive.md end to end, two findings and one clean check (331d32e)
  • notes: record that pi's installed opencode catalog is a stale vintage (d44882a)
  • notes: record the placeholder lint trap and the pipeline that hid it (bfc5589)
  • notes: seventeen sweeps, and the fourth time a sweep asked the wrong question (094dd30)
  • notes: the artifacts, checked against everything this session changed (992f49b)
  • notes: the auth-key-and-refresh-key premise does not hold, read out of the client (14265e7)
  • notes: the card and the meter read one service differently (477d8e5)
  • notes: the card's read is a timing bug, not an argument bug (d176697)
  • notes: the class stops at probe, and the sweep is complete (ee8073d)
  • notes: the count gap is closed, and nothing else restates one (fe0cedf)
  • notes: the coverage ratchet, checked against the code this session added (942d9ce)
  • notes: the diagnostic a user sees, written down where they would look (b3d83b8)
  • notes: the diagnostic I added has no test, and that is written down (7713be3)
  • notes: the duplicate-count sweep, broadened, comes back clean (3e10c93)
  • notes: the endpoint chain, read out of the client instead of inferred (8da8c53)
  • notes: the free-tier claim swept clean, and the one place it was right (aa01329)
  • notes: the free-tier claim, swept in the form that has no keyword (2e61a46)
  • notes: the handoff is current, which was worth checking rather than assuming (25c5dfd)
  • notes: the language-pair drift resists automation, and last round's claim was too optimistic (7619f37)
  • notes: the link sweep, done in the context the earlier one got wrong (09cff48)
  • notes: the mount's base URL should be data, and the four steps to make it so (b2272af)
  • notes: the network-failure-read-as-data class, and where it stops (6e05a32)
  • notes: the paired READMEs, checked by fact rather than by line count (d07864b)
  • notes: the phantom route was the only one (7522413)
  • notes: the prose totals are still unguarded, and the attempt is recorded (34264fe)
  • notes: the sign-in row has the card's race, one step worse (051a04f)
  • notes: the sweep that found the third instance found six more (f03aa38)
  • notes: the tests, checked against the rule the repository states (8d03b34)
  • notes: the two gaps the failed subagent left, answered by hand (9524fcb)
  • notes: twelve sweeps, and the commands were clean (5a523c1)
  • notes: where the productive work ends, and what the remaining condition is (10f3f4f)
  • notes: where the sweeps stop being worth running (6831b25)
  • notes: why one document's counts never drifted and the others' did (c258b91)
  • notes: x-opencode-request cannot be sent from here, and it is a data problem (319838a)
  • opencode-mistral is not a route, and opencode-google is (fe652b1)
  • planes: 'a free turn' meant a plan-included one, and the words differ here (cef4f53)
  • planes: the first table in the file contradicted the section below it (7477082)
  • planes: the same count twice in one file, and the second copy was stale (884bad3)
  • protocol: record the per-protocol base and what each test layer proves (74d7102)
  • protocol: the table said eight google models are unserved, and every count was stale (1d63dc2)
  • readme: auto-review inherits the session's route, and that is the whole story (e7cc8b7)
  • readme: the card has eight controls, and the two READMEs drifted apart (201784d)
  • readme: the card has seven controls, and the eighth was never one (26d8849)
  • readme: the fallback removes one cause of the 403, not the 403 (39d8b1f)
  • readme: the fourth protocol family is served, and the README said it was not (5227ea3)
  • readme: the free tier was never the headers' fault (94ba0ba)
  • readme: the free tier's row, and a paragraph that said the login was not built (7fa797e)
  • readme: the meter's row now says restart the process, not just the page (60b3a14)
  • readme: the meter's row said one cause where the console now names the real one (798f453)
  • readme: the other place that said eight (465bd1a)
  • readme: the sign-in row, and the fastest way to tell a restart happened (ad6fa7c)
  • readme: the two guarantees, now that they hold for hand-listed models too (110749c)
  • redirect-planes: the plane table was stale in every cell but one (7b1c684)
  • redirect-planes: three claims the bridge and the Go routes invalidated (eac983f)
  • redirect-planes: what is verified, and in which composition (a9e4919)
  • routing: the default format is the case that does nothing (d5f4a2b)
  • routing: the quoted table is the table the code has (fc93e88)
  • routing: the three conditions the automatic pi-ai path needs, and which two a plugin cannot meet (5880e06)
  • routing: why one provider cannot serve mixed protocols, traced to the line (7bad741)
  • session: record the measured rule, and credit the PR that found it (e950477)
  • session: the band is real — correct §3.1 and the script that "refuted" it (5d0b00e)
  • spec out OpenCode 1.19.0's API, measured (0865eaf)
  • the catalog counts were a regeneration behind (992e00a)
  • the credential decides the plane, not the endpoint (9013cec)
  • the credential the user already has, and this plugin does not read (bdd17f9)
  • the Go count I missed, and the measurement that hid it (95ee932)
  • the host's mount is sound, so the handshake's client side is what is left (517543b)
  • the meter's open case, and everything already excluded from it (7a09ead)
  • the other half of I1 - a hand-listed model is still offered (1a1170a)
  • the status said the card was not built, one round after it was (f7306a7)
  • the token mystery is a database row, and the org is stored with it (db0c6a9)
  • three more places that said the free tier was reachable (d428388)
  • what a self-built provider must carry, measured not assumed (74149f3)
  • why the protocol table is narrow, and who unblocks Google (0ad433e)
  • withdraw the two free-tier claims the last sweep missed (aac6857)
  • zh: the Chinese README kept two claims the English one had corrected (fec387c)
  • zh: the Google claim survived the fix I made two rounds ago (39a2423)
  • zh: the screenshots section, one round behind its English pair (d85a789)