Repository navigation
Releases
Releases · Servoy/opencode-kiro-auth
v2.10.0
Added
- Claude Haiku 5.5 is now offered (
claude-haiku-5.5), Anthropic's fastest model with a 1M context window, at the 0.06x short-context rate (requests over 100K tokens bill at 0.3x, a Kiro-side split not modelled here, as with GPT-5.6). Text and image input, no effort dial until the account catalog confirms one. The retiredclaude-haiku-5-5-thinkingslug resolves to the same model for saved configs.
v2.9.0
Added
- Account selection now drains free quota before spending money. An account is kept last in the pool, regardless of selection strategy, only when serving it would bill right now — overage (paid usage past the included quota) is enabled AND its included quota is already spent. An overage account that still has free credits ranks alongside every other account and is used normally, so an account with overage on but credits left is preferred over one whose quota is gone. A billing account never 429s on a spent quota — it keeps serving and charging — so it is selected only once no other account is usable: every free bank spent, or rate-limit waits too long for the selector to wait out. A short 429 leaves an account in the running and is retried there first. The overage flag is read from
getUsageLimits'overageStatus, persisted per account (nullableoverage_enabled— NULL means "not yet learned from a usage sync", distinct from a confirmed free account), and carried forward from the fresher usage reading so turning overage off in Kiro takes effect on the next sync. Until an account's first usage sync the quota figure is the per-process request counter, not credits, so a billing decision waits for the sync and the account counts as free until then. The startup usage summary now marks each account's state ([overage: billing]/[overage: enabled, free credits left]).
Fixed
- A quota-exhausted account is no longer stuck "unhealthy" forever after its monthly quota resets. When an account hit "You have reached the limit." it was marked unhealthy with a recovery time, but the startup usage sync skipped every unhealthy account (
if (!acc.isHealthy) continue) and so never re-read it — leaving its stored quota and health frozen at the moment it ran out, long past the reset and its own recovery time. The startup sync now re-fetches usage for an unhealthy account whose recovery window has passed (keeping only the genuinely dead — revoked/expired credential, missing profileArn — and the still-resting skipped), so the fresh quota revives the account and its overage status is finally read. - A transient failure Kiro delivers inside an already-open stream (
MODEL_TEMPORARILY_UNAVAILABLE, "service is temporarily unavailable", throttling) is now backed off and retried on the same account instead of surfacing as a raw "Connection lost while reading the response". It only retries before the first chunk is emitted; once output has started the stream ends without a replay, per the Smithy rule that a started stream cannot be retried. - A server-side 500 or 503 no longer switches account after the retry budget — it backs off on the same account and fails there. Switching mid-session abandoned the conversationId and the warm server-side prompt cache, re-billing the rest of the session at full input rate. Account rotation is now reserved for failures where the account itself cannot continue (quota, dead or suspended credential).
v2.8.0
Another one from the community — thanks again to @manueltusset (Manuel Ristoff Tusset) for Kimi K3 and the catalog-driven request fields (#4). 🎉 It turns the one place model support kept breaking — guessing a model's reasoning channel from its name — into something read from the catalog itself.
Added
- Kimi K3. Offered once the account catalog is read, with its
low/high/maxreasoning dial. Experimental, available only in Kiro's US geography, and a Kiro Excluded Model (no AWS output indemnity). - Request fields derived from the catalog schema, not the model name. The old rule sent anything matching
gpt|openaitoreasoning.effortand everything else tooutput_config.effort— which broke on the first model that did not fit the split (Kimi, whose schema takesreasoningwith nomax_tokens). A newRequestFieldsProfilereads the channel, the levels, the off switch and themax_tokensceiling straight from each model's schema, falls back to the built-in lists while the catalog is cold, and sends a level a model lacks as the nearest one below it. (#4) - Diagnostics for a reply that breaks off mid-stream. A stream that errors part-way now logs
[STREAM] broke off convId=… after N events, and the SDK-client cache logs when a burst of concurrent sessions evicts or retires an in-use client — the three places one session could sever another's stream, none of which left a trace before. - A mapping contract test against a snapshot of what Kiro actually serves, plus tests for the retry strategy, the account cache/repository (against the real store), the message transformer and the SDK response handler. Overall coverage is up from ~89.9% to ~92.2%.
Fixed
- A reply no longer breaks off mid-stream when several sessions run at once. A retired SDK client's grace timer used to
destroy()the client 30s after it was retired, no matter what — severing the socket of any answer still streaming past the grace. With 2–3 sessions a dispose/re-init storm or a cache eviction retires a live client, so a large-context session (whose reply streams well past 30s) had its socket torn out from under it, and the user saw the answer simply stop with no error. The timer now defers toinFlight: a client still streaming is left alone and freed only when its stream ends. max_tokensand the effortoffswitch are sent only where the model's schema accepts them, instead of 400-ing a model that does not list them. GPT-5.6 Luna's drop ofmax_tokensand the Kimi rows are the visible effect. (#4)- Thinking-off on a model that cannot stop reasoning now warns once instead of silently charging for reasoning the user turned off.
- A dropped connection during a bearer-403 refresh, or a background catalog lookup, no longer marks a working account unhealthy or signs it out.
- Four existing tests were strengthened after a full-suite audit: one guarded a field the transformer never emits, three recomputed their expected value with the code's own formula — all now assert independently and are mutation-checked.
Removed
- The unused v1 non-SDK response path and the prompt-cache checkpoint builder (Kiro returns no cached-token counts for what this plugin sends), along with a few dead type mirrors and helpers.
Compatibility
- Works on OpenCode v1 and v2 from the same build; type-checked against
@opencode/pluginthrough 2.1.1. The catalog cache version is bumped, so the first request after upgrading refetches it once under the existing 30-minute TTL — no action needed.
Nightly Build master
v2.7.0
First community contribution — big thanks to @manueltusset (Manuel Ristoff Tusset) for building the Kiro API key sign-in (#3) and the Sonnet 5.5 / Opus 5.5 fixes (#2). 🎉
Added
- API key sign-in (opt-in).
KIRO_API_KEY(orapi_keyinkiro.json; the env var wins) is a first-class configuration source, not only an interactive paste. The sign-in prompt prefills from it with a masked hint (ksk_…1234) and the full key never appears; a typed-but-invalid value is still rejected on its own. Per Kiro's own documentation the API key is meant for CI and headless use. - Headless auto-register. With a key configured, the plugin registers the account on startup — no interactive login, no browser. The region comes from the key's own profile ARN, so you never set one.
- v2:
KIRO_API_KEYas anenvintegration method. The host connects from the variable itself, with no sign-in step, and keeps env methods out of the picker — so there is a single "Kiro API key" row, not two.
Fixed
- Sonnet 5.5 output limit corrected to the 128K the catalog reports (was defaulting to 64K). The
offthinking variant is no longer offered on Sonnet 5.5 or Opus 5.5 — the Kiro endpoint rejects it today, so neither model shows it until the service accepts it. (#2) - An API key now supersedes a same-profile IDC login on the first start, not the next, so one subscription does not run as a two-account pool. The removal is logged.
- Duplicate API-key accounts are collapsed on startup, folding on the key fingerprint.
kiro.dbis locked to0600andksk_keys are redacted from logs.
v2.6.1
Fixed
- On v2, register a managed host credential when a usable account exists in kiro.db but the host has none, so the provider registers without a manual
opencode auth import— the split-XDG-home dead end (e.g. Servoy's own home) that surfaced as "not available in your country".
Changed
- Log account count and the kiro.db read on v2 init, and warn when a usable account cannot register for lack of a host credential, so a store in the wrong XDG home is seen at a glance.
v2.6.0
Added
- Add Claude Sonnet 5.5 (1M context, 1.3x, xhigh effort dial).
Changed
[REQ]log now reportseffort=default/offinstead of an ambiguousnone, distinguishing Kiro's own default from an explicit off.[QUEUE]log always states whether a request waited, in which lane, and for how long, and logs a bypass when a single account skips the queue.[LOCK]log breaks a slow write intochainWait(ahead count),fileWaitandheld, and names the write, so one session waiting on another is visible rather than inferred.
v2.5.1
Fixed
- Honour
KIRO_IGNORE_XDGwhen set to a quoted, cased or1value (Windowssetxstores the quotes), not only the exact stringtrue. - Log the resolved config dir on v2 init, matching v1, instead of the project directory under a "configDir resolved" label.
- Stop the API-response log inventing an HTTP 200; log that the request was accepted, since the stream is unread at that point.
v2.5.0
Added
- Add Claude Opus 5.5 (1M context, 2.0x, xhigh effort dial).
- Add the GPT-5.6 Sol, Terra and Luna tiers (effort under
reasoning.effort,noneas the off switch). - Rotate the plugin log at 10MB with one kept generation, and prune API dumps older than 24h.
Fixed
- Show the sign-in form fields and forward the answer on v2 hosts.
- Escalate a dead refresh token to a sign-in prompt instead of looping.
- Key image carry-forward on the incoming message count, not the post-trim history.
- Stop resurrecting a screenshot after the conversation has moved on.