Retry launch against the tenant's live default when a pinned model has no credential - #281
Merged
Conversation
A definition's pinned model can predate the tenant's current connection (a provider was disconnected, or none was connected when the pin was baked in). These prove deployAtHead retries once against fallbackModel when the pinned model has no launchable source, and skips the retry when there is nothing new to try.
A definition's own pinned model (foldedBody.model) was always tried verbatim and, on failure, thrown as InferenceResolutionError -- even when the tenant had since connected a different provider. A fresh "Just start talking" workbench invited Myra's already-seeded definition, which had claude-sonnet-5 baked in from before any provider was connected (or from a provider since disconnected), so connecting Ollama never helped: the credential-less anthropic pin kept winning every launch. deployAtHead now retries once against fallbackModel -- the tenant's current live default, the same (provider, model) Settings' "Default model & fallbacks" list heads -- whenever the definition's own pinned model fails to resolve. platform-adapter.ts's resolveFallbackModel now always computes that live default (previously only when the definition declared no model of its own), so it is available as the retry target for every launch and wake, not just one with an empty pin. This makes reconnecting a different provider heal every agent already pinned to the old one -- new and existing alike -- rather than only a freshly created one, and a credential-less provider row can no longer permanently outrank a connected one it once preceded.
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
A freshly created workbench (and any workbench that invites the tenant's own
assistant/Myra definition) could resolveclaude-sonnet-5and fail withInferenceResolutionErroreven when the tenant had connected a working Ollama provider and nothing else — because Myra's definition was deployed once, at first-login, with a concrete model baked into itsworkflow.json, and launch never re-checked that pin against the tenant's current catalog.Confirmed against the local dev DB (not inferred): the
assistantworkflow_definition for the reproduction's tenant was created ~56 minutes before its Ollama credential existed, and that tenant has noanthropicmodel_provider/credential at all — yet its definition still namesclaude-sonnet-5, and that pin always won.What changed
packages/folded-runs/src/launch.ts'sdeployAtHeadnow retries once againstfallbackModel(the tenant's live default) whenever the definition's own pinned model fails to resolve, instead of throwing immediately.packages/chat/src/platform-adapter.ts'sresolveFallbackModelnow always computes the tenant's live default (previously only when the definition declared no model at all), so it is available as the retry target on every launch and wake — not just a definition with an empty pin.Net effect:
Layer 2 (explicit per-agent model override) already exists via
POST /agent-definitions'modelfield and Settings' per-provider "make default" reorder — untouched by this PR. Full provider-agnostic "capability need, not a model name" resolution and a UI to add an arbitrary uncatalogued model are out of scope for this fix; see CL-6569 for the scope note.Linear: CL-6569
Test plan
bun testgreen inpackages/folded-runs(71 -> 73 pass; 2 new tests proving the retry fires/doesn't fire) andpackages/chat(644 pass unchanged)tsc --noEmitclean in both packageseslintclean on changed files;prettier --checkcleanassistantdefinition vs. its tenant's Ollama credential; tenant'smodel_offeringtable)