fix(*): stop a static read from starting a login - #255
Merged
Conversation
…ts endpoint Three LiteLLM drivers ship a device-flow authenticator, and every entry point that resolves a model reaches it. With no token file on disk, reading a Copilot model's context window printed six GitHub device codes to stdout and blocked for 410 seconds: two full three-attempt login cycles, because the bare and the openrouter-prefixed candidate reach the same driver. session.create runs that read before the first turn, so the symptom was a gateway that hung on opening the picker, and the agent loop runs it again every turn. The cost estimate, which runs after every call, hung the same way through cost_per_token. One function answers whether a model can be handed to LiteLLM at all, and both lookups consult it; a guard test fails if either decides for itself. It asks the installed package -- a driver either ships authenticator.py or it does not -- rather than carrying a list that would need regenerating on every LiteLLM bump and would bring the hang back for whatever a stale copy missed. The window lookup reads the price table before asking, which answers all 49 rows those three drivers have between them. The ask stays for everything that cannot prompt, because it does more than normalize keys: for an openrouter-prefixed candidate it derives OpenRouter's own numbers, which are in no row. Reading the table with a prefix-stripping fallback looked like a free replacement and was not -- it answered three MiniMax models with the direct figure where LiteLLM had reported OpenRouter's. Verified across the 132 candidates Raven offers: no window and no rate differs from before. Azure OpenAI could be picked from the curated list and never worked. Its endpoint contains the tenant's own resource name, so there is nothing to default to, and its client raises on an empty api_base -- but the wizard classified the need for an endpoint by name, matching only the self-hosted entry, and asked Azure for a key alone. The model picker knew better and kept its own list of the two, which is the same fact answered twice with one answer wrong. It is a registry field now, and both read it. Co-authored-by: Claude (claude-opus-5[1m]) <noreply@anthropic.com>
arelchan
approved these changes
Jul 31, 2026
0xKT
added a commit
that referenced
this pull request
Jul 31, 2026
## Summary Bump the package version from 0.1.9 to 0.1.10 (patch release). 22 PRs merged since v0.1.9, no breaking changes. Features: - #260 feat(tui): list the providers that work, and the rest one level down - #252 feat(*): offer every supported provider in the onboarding picker - #251 feat(tools): read images with read_file, and fix four silent type-check bugs - #239 feat: add shell command approval flow - #217 feat: rework the TUI transcript into collapsible episodes - #220 feat(cli): nudge raven upgrade in the tui status bar when behind - #209 feat(providers): add MiniMax Global and CN OAuth Refactors: - #259 refactor(*): one answer to which credentials a provider needs - #249 refactor(providers): unify provider management on litellm The remaining PRs are fixes (#255, #256, #258, #253, #238, #226), test work (#236, #230, #224), docs (#250, #215, #200), and benchmark tooling (#207). ## Type - [ ] Fix - [ ] Feature - [ ] Docs - [ ] CI / tooling - [ ] Refactor - [x] Other ## Verification - [x] Relevant tests pass locally - [x] Relevant lint / type checks pass locally - [ ] User-facing docs or screenshots are updated when needed Bump is limited to `pyproject.toml` and `uv.lock` (`uv lock` sync). Local preflight covers the branch CI checks (commit lint, PR title and body lint, ruff, large-file gate). ## Risk - [x] Security impact considered - [x] Backward compatibility considered - [x] Rollback path is clear for risky changes Version-only change; no code or behavior change. Rollback is a revert of this commit. ## Related Issues N/A Co-authored-by: Claude (claude-opus-5[1m]) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Two things a user hits without doing anything unusual.
A static read started a login. Three LiteLLM drivers ship a device-flow
authenticator, and every entry point that resolves a model reaches it. With no
token file on disk, reading a Copilot model's context window printed six GitHub
device codes to stdout and blocked for 410 seconds -- two full three-attempt login
cycles, because the bare and the openrouter-prefixed candidate reach the same
driver.
session.createruns that read before the first turn, so the symptom was agateway that hung on opening the picker, and the agent loop runs it again every
turn. The cost estimate, which runs after every call, hung the same way through
cost_per_token.One function now answers whether a model can be handed to LiteLLM at all, and both
lookups consult it. It asks the installed package -- a driver either ships
authenticator.pyor it does not -- rather than carrying a list that would needregenerating on every LiteLLM bump, where a stale copy brings the hang back for
whatever it missed.
The window lookup reads the price table before asking, which covers all 49 rows
those three drivers have between them. The ask stays for everything that cannot
prompt, because it does more than normalize keys: for an openrouter-prefixed
candidate it derives OpenRouter's own numbers, which are in no table row.
Azure OpenAI could be picked and never worked. Its endpoint contains the
tenant's own resource name, so there is nothing to default to, and its client
raises on an empty
api_base. The wizard decided who needs an endpoint by name,matching only the self-hosted entry, and asked Azure for a key alone -- while the
model picker kept its own list of the two providers that need one. The same fact,
answered twice, one answer wrong. It is a registry field now and both read it.
Type
Verification
Measured before and after on the paths that hung:
Behaviour parity checked by running the old and new implementations side by side
over the 132 model candidates Raven offers, excluding the four families that would
hang the old one: no context window and no rate differs.
Every test added here was checked by breaking the code it covers and confirming it
fails. Two of those runs found the test rather than the code -- one assertion
passed no field name to the helper it was testing, and one probe raised an
exception the lookup deliberately swallows -- and both were rewritten until the
mutation bit.
Risk
A model belonging to one of the three interactive-login drivers, with no row in the
price table, now resolves to no context window instead of eventually returning one
after the login attempts time out. The caller keeps its configured window, which is
what it already does for any unknown model.
Picking Azure OpenAI in the wizard now asks for an endpoint and a deployment name
in addition to the key. Existing Azure sections are untouched.
Rollback is the revert of this branch.
Related Issues
#254 -- the same assumption in the vendor step, for providers Raven carries no spec
for. Not fixed here: that one needs somewhere to keep credentials that are not a
single key. Azure had the same shape while being in the curated list, which is the
half fixed here.