Skip to content

Fail over when one assignment rejects an advertised model #150

Description

@masterkain

problem

an upstream assignment can advertise a model through discovery and catalog metadata while rejecting inference for that same model. sanitized failure shapes can include:

  • structured model_not_found
  • HTTP 404 invalid_request_error with param=model and no specific error code

when accounts with different model entitlements share a Pool, this assignment-specific serving rejection can terminate the request even though another assignment in the existing route plan may be able to serve the model

expected behavior

  • keep /models as the existing Pool-level union filtered by API-key policy; serving health must not mutate catalog visibility
  • classify only canonical assignment-specific model-unavailable outcomes, with catalog provenance required for the code-less invalid_request_error shape
  • before any downstream-visible output, retry internally on the next eligible assignment already present in the route plan without rewriting the requested model
  • produce one downstream request or connection with ordered assignment attempts; no client retry or reconnect should be required
  • record safe model/assignment/route-class lifecycle state through the existing database-backed demotion and circuit mechanisms
  • mark an attempt retryable_failed and increment retry count only when an actual handoff occurs
  • preserve the final sanitized upstream failure when no later candidate exists
  • preserve hard pins for previous-response continuity, file affinity, and already-live upstream websockets
  • retain fallback candidates for soft session preferences
  • apply failover to direct HTTP, pre-visible SSE terminal events, and pre-visible websocket terminal events
  • never retry after visible SSE/websocket output, and leave compact routes outside this behavior
  • keep recovery bounded through the existing configurable circuit thresholds and half-open probe lifecycle

catalog visibility and routing eligibility must remain separate: a model backed only by degraded visible assignments may remain listed while inference returns no_eligible_backend

admin observability

make the existing Routing footer block on /admin/upstreams open a read-only panel that shows, per visible Pool assignment:

  • advertised model ids and observed/preserved catalog provenance
  • per-assignment capabilities, preserving unknown values
  • separately labeled HTTP, SSE, and websocket serving signals from bounded Pool-level circuit state

the panel must remain metadata-only, read-only, authorization-bounded, and constant-query with respect to assignment and model count

safety constraints

  • no broad 404 => retry rule, message substring matching, or plan/account-label inference
  • no fallback for malformed requests, globally invalid models, continuation misses, hard pins, compact routes, or post-visible failures
  • no model alias rewrite, catalog exclusion metadata, new process-local health state, or UI-triggered probe/sync/mutation
  • no raw provider body, prompt, token, credential, websocket frame, or unsanitized error message in persistence, logs, UI, tests, docs, or evidence

acceptance criteria

  • HTTP, SSE, and websocket controlled two-assignment tests prove first-assignment rejection and second-assignment success within one client request/connection
  • generic 404, missing-provenance, post-visible, compact, hard-pin, shortlist-exhaustion, and final-candidate controls preserve their defined terminal behavior
  • accounting, demotion, circuit state, recovery thresholds, and multi-node visibility are truthful and tested
  • degraded-only model visibility remains independent from routing eligibility
  • the Routing panel presents safe per-assignment provenance, capabilities, and route-class serving signals without N+1 queries
  • focused tests, precommit, quality, controlled smoke, and responsive accessibility checks pass

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions