Skip to content

Context-window rejections: fail over to a larger-context model without cooling down the healthy route #106

Description

@sakshamyadav090

On a CONTEXT_WINDOW_EXCEEDED failure (dsh core's canonical code for a 400 "maximum context length"), the plugin already switches if the code is in triggerCodes — verified with dsh-llm-fallbacks 0.4.2 against a fake provider. Three things are off, one of them undocumented:

  1. commit() suppresses the from route for cooldownMs (escalating under half-open recovery). The route is healthy; the request was too big. The next short prompt goes to the fallback for no reason, and a half-open probe is spent.
  2. Candidates are not filtered by context window, so the chain can fall over to a model that cannot fit the request either — which then fails and gets cooled down too.
  3. README does not say triggerCodes accepts CONTEXT_WINDOW_EXCEEDED, or what happens to compaction when it does.

What I measured (Failover Bench: a fake OpenAI-compatible provider whose fb-s12-context-length model answers every request with a 400 "maximum context length"; dsh 0.1.2-rc.1 through the Python SDK; chain [fake/fb-ok]):

  • default triggerCodes: two attempts on the primary, then an error — the plugin never sees the code.
  • with CONTEXT_WINDOW_EXCEEDED added: one attempt on the primary, immediate switch, complete answer from the fallback in 2.6 s. Compaction was not attempted — this plugin's agent/request-error listener handled the rejection before compaction-basic got to it.
  • the cooldown in (1) follows from commit() calling states.suppress unconditionally; I could not observe it from outside, because each harness request runs in a fresh process.

Repro: python -m failoverbench run --system systems/dsh.yaml --profile full --only S12 in https://github.com/failoverbench/failoverbench (gateways/dsh/setup.sh writes the two harness homes and their settings).

Proposal (PR to follow): request-scoped switches (scope: 'request') that skip the suppress/recovery bookkeeping; a context-window candidate filter using the catalog's contextWindow when present, else llm.resolveModelInfo(provider, model).context.contextWindow (unknown → keep the candidate); README/CONCEPTS text.

Two questions for you: should CONTEXT_WINDOW_EXCEEDED be in the default triggerCodes? And should a context-window trigger give compaction the first try (switch only if the compacted retry still overflows), or switch immediately, as it does today?

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions