fix(bridge): self-heal an unroutable model instead of failing every turn - #419
Open
Ivancheng7 wants to merge 2 commits into
Open
Ivancheng7 wants to merge 2 commits into
Ivancheng7 wants to merge 2 commits into
Conversation
A session-level model override lives in the session store and outlives the
endpoint that routed it. When an Anthropic-compatible gateway changes its
alias set (or a model is retired), every later turn of that session fails
with the same "API Error: 400 unknown provider for model <name>" and the
user has to know about /model reset to recover.
- error-classifiers: isUnknownModelError() / modelFromUnknownModelError().
- message-bridge: retryAfterUnknownModel() clears the session override,
audits task_model_fallback and re-runs the same turn with no model flag, so
the endpoint resolves its own default; wired into the chat turn (stream end
and thrown-error paths) and the API task path before the error card.
- executor-registry: acquire({ ignoreRegistryDefaultModel: true }) spawns
without a model flag instead of falling back to the registry default (the
bot-level model can be the unroutable one).
- audit: task_model_fallback event.
- Tests: classifier phrasings, including the observed proxy 400.
no-useless-escape: '/' inside a character class needs no backslash.
This branch has not been deployed
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.
Problem
A session-level model override (
/model <name>) is stored with the session and outlives the endpoint that used to route that name. When an Anthropic-compatible gateway changes its alias set — or a model is retired — every later turn of that session fails with the sameand keeps failing, because the override is never invalidated. The user has to know about
/model resetto recover. The same applies when the bot-level model inbots.jsonis the unroutable one.Change
error-classifiers.ts:isUnknownModelError()/modelFromUnknownModelError()recognize the rejection (observed:unknown provider for model ..., plus the commonunknown model,invalid model,no such model,model ... does not existphrasings).message-bridge.ts: newretryAfterUnknownModel(). On this error it clears the session override (setSessionModel(chatId, undefined)), audits atask_model_fallbackevent, and re-runs the same turn with no model flag, so the endpoint resolves its own default. Wired into three places, mirroring the existing stale-session retry: the chat turn at stream end, the chat turn's thrown-error path, and the API task path — all before the error card is rendered.executor-registry.ts:acquire({ ignoreRegistryDefaultModel: true })spawns/respawns without a model flag instead of falling back to the registry default (which can itself be the unroutable name).runOneTurnforwardsforceEndpointDefaultModelto it and dropsmodelon the legacy path.If the retry also fails, the error card explains what was attempted; the turn is not silently swallowed.
Tests
tests/model-fallback-classifier.test.ts(new): the observed proxy 400 and the common phrasings match; unrelated failures (context overflow, connection refused) do not; model-name extraction.Full local suite: no new failures.