calm-artist-7206
09/11/2026, 1:47 PMfallback_llm e.g. “glm” profile on the pr-review automation running on open source repositories
• we merged a tiny improvement in speed, to fall back to it without waiting retries
• but it needs set in the automation.
• (it’s an attribute on the LLM)
(currently it fails everywhere because GPT-Sol is exhausted, for 4 days)
I won’t be here today until late. Fwiw @quick-window-91705 @limited-student-10747 the agent is telling me we could just add it in the Plugin script, but I’m not so sure; it’s saved in automations.db and I’m not familiar enough with editing automations path and its safety in the 5 minutes I got 😅🙏 but I could look into it tomorrow or somethinghundreds-twilight-32833
09/11/2026, 2:38 PMlimited-student-10747
09/11/2026, 2:41 PMlimited-student-10747
09/11/2026, 2:42 PMfresh-machine-37269
09/11/2026, 2:42 PMcalm-artist-7206
09/11/2026, 2:46 PMcalm-artist-7206
09/11/2026, 2:46 PMfresh-machine-37269
09/11/2026, 2:46 PMopenhands-sdk has a FallbackStrategy class with a fallback_llms list (ordered profile names), and LLM.fallback_strategy field. It kicks in on transient errors (rate limit, timeout, 503, etc.) after retries, and falls back to those named profiles. See openhands/sdk/llm/fallback_strategy.py and the 39_llm_fallback.py example. OpenRouter-style routing/`allow_fallbacks` metadata is also handled in the SDK.
• Frontend (not supported): the Agent Canvas frontend (src/components/features/settings/llm-profiles/) has zero references to `fallback_strategy`/`fallback_llms`. The profile form only exposes model, api_key, base_url, auth type, subscription vendor, and provider connection — no fallback field.
• The catch: fallback_strategy is marked exclude=True on the LLM model ("Excluded from serialization; must be reconfigured after load"). So even if you hand-crafted a profile JSON with a fallback, save_profile → to_persisted() drops it. It doesn't survive profile persistence at all.
Net: today it's code-level only — you construct FallbackStrategy(fallback_llms=[...]) on the LLM object in code (e.g. in an automation/plugin script, exactly the "attribute on the LLM" the thread mentioned), not via the profile editor. If you want it as a first-class profile field, it needs backend changes (remove the exclude, persist the field, expose it in the profile/settings schema) plus frontend work (a fallback picker in the profile form).calm-artist-7206
09/11/2026, 2:48 PMlimited-student-10747
09/11/2026, 2:49 PMfresh-machine-37269
09/11/2026, 2:50 PMexclude=True on the field. fallback_strategy is declared with exclude=True ("Excluded from serialization; must be reconfigured after load"). The schema exporter explicitly drops any excluded nested field — if nested_field.exclude: continue (openhands/sdk/settings/model.py, the LLM section loop). So the field never appears in the /api/settings/agent-schema payload the frontend renders from.
2. No settings metadata. The renderer only emits a field when it carries SettingsFieldMetadata (via field_meta() in json_schema_extra). fallback_strategy has none, so even without the exclude flag, settings_metadata() returns None → continue, and it's skipped.
3. It's a nested FallbackStrategy model with a list of profile names, not a scalar. Even if (1) and (2) were fixed, the schema renderer's type inference would just treat it as an "object", and there's no built-in control for "pick an ordered list of other LLM profiles" — the fallback_llms list refers to profile-store names resolved at runtime, which is a relationship the generic schema form can't express today.
And separately from rendering: to_persisted() uses exclude semantics, so the value is also dropped on save/load — fallback_strategy doesn't survive profile persistence regardless of the UI.
So the schema renderer is working as designed — it's guarding against unannotated/unknown settings, not against a field the backend has deliberately excluded from both serialization and schema. To make it renderable you'd need to: remove exclude=True, add field_meta(...) metadata, teach the value-type inference / form to handle an ordered list of profile names, and persist the field through `to_persisted`/`from_persisted`.