Skip to content

Retry launch against the tenant's live default when a pinned model has no credential - #281

Merged
TheGreatAxios merged 2 commits into
mainfrom
cl-default-model-route
Aug 22, 2026
Merged

Retry launch against the tenant's live default when a pinned model has no credential#281
TheGreatAxios merged 2 commits into
mainfrom
cl-default-model-route

Conversation

@TheGreatAxios

Copy link
Copy Markdown
Contributor

Summary

A freshly created workbench (and any workbench that invites the tenant's own assistant/Myra definition) could resolve claude-sonnet-5 and fail with InferenceResolutionError even 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 its workflow.json, and launch never re-checked that pin against the tenant's current catalog.

Confirmed against the local dev DB (not inferred): the assistant workflow_definition for the reproduction's tenant was created ~56 minutes before its Ollama credential existed, and that tenant has no anthropic model_provider/credential at all — yet its definition still names claude-sonnet-5, and that pin always won.

What changed

  • packages/folded-runs/src/launch.ts's deployAtHead now retries once against fallbackModel (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's resolveFallbackModel now 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:

  1. A newly created workbench uses the tenant's connected route. (the reported repro)
  2. Changing the connected provider now heals existing agents too (Myra included), not just freshly created ones — no "applies to new agents only" caveat needed.
  3. A credential-less/disconnected provider's stale pin can never permanently outrank a connected one.

Layer 2 (explicit per-agent model override) already exists via POST /agent-definitions' model field 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 test green in packages/folded-runs (71 -> 73 pass; 2 new tests proving the retry fires/doesn't fire) and packages/chat (644 pass unchanged)
  • tsc --noEmit clean in both packages
  • eslint clean on changed files; prettier --check clean
  • Root cause confirmed against real local Postgres data (timeline of assistant definition vs. its tenant's Ollama credential; tenant's model_offering table)
  • Live browser click-through (connect Ollama, new bench, real reply from the Studio endpoint) — not performed by this agent; no browser-automation tool was available, and reusing the attached dev session's auth cookie was correctly blocked by the permission system as a credential-extraction risk. Needs confirmation before merge.

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.
@TheGreatAxios
TheGreatAxios merged commit 33f6664 into main Aug 22, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant