fix(auxiliary): fall back to main model for xai-oauth title gen etc.#31845
Closed
wysie wants to merge 1 commit into
Closed
fix(auxiliary): fall back to main model for xai-oauth title gen etc.#31845wysie wants to merge 1 commit into
wysie wants to merge 1 commit into
Conversation
When auxiliary tasks (title generation, compression, etc.) call resolve_provider_client without an explicit model while the main provider is xai-oauth, _build_xai_oauth_aux_client would early-return None because it requires a model. This caused HTTP 400s after switching from GPT to Grok-4.3. Now we fall back to _read_main_model() so auxiliary tasks continue to use the user's chosen Grok model instead of silently dropping to Step-2 fallbacks. Fixes auxiliary title generation (and similar) for xAI Grok OAuth users.
teknium1
pushed a commit
that referenced
this pull request
May 25, 2026
Aux callers (title generation, vision, session search, etc.) can reach
resolve_provider_client() without an explicit model when the user
picked their main provider via 'hermes model' and didn't bother
configuring a per-task auxiliary.<task>.model override. The
expectation in that case is universal: 'use my main model for side
tasks too.'
Before, the OAuth providers (xai-oauth, openai-codex) silently
returned (None, None) on an empty model — both lack a catalog default
because their accepted-model lists drift on the backend. That caused
_resolve_auto to drop to its Step-2 fallback chain (OpenRouter /
Nous / etc.), so aux tasks billed against the wrong subscription
without warning.
The fix is at the top of resolve_provider_client() — a single
3-step universal fallback that runs before any provider branch, so
no provider-specific empty-model guards are needed (now or for any
future provider we add):
1. caller-passed model (caller knew what they wanted)
2. provider's catalog default (cheap aux model, if registered)
3. user's main model from config.yaml
Behaviour by provider class:
- OAuth providers (xai-oauth, openai-codex) — no catalog default, so
step 3 applies. Title gen runs on grok-4.3 / gpt-5.4 against the
user's actual subscription instead of leaking to OpenRouter.
- API-key providers (anthropic, gemini, kimi-coding, etc.) — catalog
default wins at step 2, preserving the original 'cheap aux model'
behaviour. Anthropic users still get claude-haiku-4-5 for titles,
not opus.
- Explicit-model callers (auxiliary.<task>.model config, programmatic
callers) — caller wins at step 1, no surprise switching.
Salvaged from @wysie's PR #31845 which fixed the xai-oauth branch
specifically. The universal shape supersedes the per-branch fix
and covers openai-codex (same bug class) plus any future OAuth
providers.
4 new tests in TestResolveProviderClientUniversalModelFallback:
- empty_model_for_oauth_provider_falls_back_to_main_model
- empty_model_for_codex_also_uses_main_model
- empty_model_for_catalog_provider_uses_catalog_default
- explicit_model_takes_precedence_over_fallbacks
365/365 across tests/agent/test_auxiliary_*, tests/run_agent/test_codex_xai_oauth_recovery.py, tests/hermes_cli/test_auth_xai_oauth_provider.py, and tests/hermes_cli/test_plugin_auxiliary_tasks.py.
Co-authored-by: wysie <wysie@users.noreply.github.com>
teknium1
pushed a commit
that referenced
this pull request
May 25, 2026
Aux callers (title generation, vision, session search, etc.) can reach
resolve_provider_client() without an explicit model when the user
picked their main provider via 'hermes model' and didn't bother
configuring a per-task auxiliary.<task>.model override. The
expectation in that case is universal: 'use my main model for side
tasks too.'
Before, the OAuth providers (xai-oauth, openai-codex) silently
returned (None, None) on an empty model — both lack a catalog default
because their accepted-model lists drift on the backend. That caused
_resolve_auto to drop to its Step-2 fallback chain (OpenRouter /
Nous / etc.), so aux tasks billed against the wrong subscription
without warning.
The fix is at the top of resolve_provider_client() — a single
3-step universal fallback that runs before any provider branch, so
no provider-specific empty-model guards are needed (now or for any
future provider we add):
1. caller-passed model (caller knew what they wanted)
2. provider's catalog default (cheap aux model, if registered)
3. user's main model from config.yaml
Behaviour by provider class:
- OAuth providers (xai-oauth, openai-codex) — no catalog default, so
step 3 applies. Title gen runs on grok-4.3 / gpt-5.4 against the
user's actual subscription instead of leaking to OpenRouter.
- API-key providers (anthropic, gemini, kimi-coding, etc.) — catalog
default wins at step 2, preserving the original 'cheap aux model'
behaviour. Anthropic users still get claude-haiku-4-5 for titles,
not opus.
- Explicit-model callers (auxiliary.<task>.model config, programmatic
callers) — caller wins at step 1, no surprise switching.
Salvaged from @wysie's PR #31845 which fixed the xai-oauth branch
specifically. The universal shape supersedes the per-branch fix
and covers openai-codex (same bug class) plus any future OAuth
providers.
4 new tests in TestResolveProviderClientUniversalModelFallback:
- empty_model_for_oauth_provider_falls_back_to_main_model
- empty_model_for_codex_also_uses_main_model
- empty_model_for_catalog_provider_uses_catalog_default
- explicit_model_takes_precedence_over_fallbacks
365/365 across tests/agent/test_auxiliary_*, tests/run_agent/test_codex_xai_oauth_recovery.py, tests/hermes_cli/test_auth_xai_oauth_provider.py, and tests/hermes_cli/test_plugin_auxiliary_tasks.py.
Co-authored-by: wysie <wysie@users.noreply.github.com>
daletkc
pushed a commit
to daletkc/hermes-agent
that referenced
this pull request
May 25, 2026
…arch#31845) Aux callers (title generation, vision, session search, etc.) can reach resolve_provider_client() without an explicit model when the user picked their main provider via 'hermes model' and didn't bother configuring a per-task auxiliary.<task>.model override. The expectation in that case is universal: 'use my main model for side tasks too.' Before, the OAuth providers (xai-oauth, openai-codex) silently returned (None, None) on an empty model — both lack a catalog default because their accepted-model lists drift on the backend. That caused _resolve_auto to drop to its Step-2 fallback chain (OpenRouter / Nous / etc.), so aux tasks billed against the wrong subscription without warning. The fix is at the top of resolve_provider_client() — a single 3-step universal fallback that runs before any provider branch, so no provider-specific empty-model guards are needed (now or for any future provider we add): 1. caller-passed model (caller knew what they wanted) 2. provider's catalog default (cheap aux model, if registered) 3. user's main model from config.yaml Behaviour by provider class: - OAuth providers (xai-oauth, openai-codex) — no catalog default, so step 3 applies. Title gen runs on grok-4.3 / gpt-5.4 against the user's actual subscription instead of leaking to OpenRouter. - API-key providers (anthropic, gemini, kimi-coding, etc.) — catalog default wins at step 2, preserving the original 'cheap aux model' behaviour. Anthropic users still get claude-haiku-4-5 for titles, not opus. - Explicit-model callers (auxiliary.<task>.model config, programmatic callers) — caller wins at step 1, no surprise switching. Salvaged from @wysie's PR NousResearch#31845 which fixed the xai-oauth branch specifically. The universal shape supersedes the per-branch fix and covers openai-codex (same bug class) plus any future OAuth providers. 4 new tests in TestResolveProviderClientUniversalModelFallback: - empty_model_for_oauth_provider_falls_back_to_main_model - empty_model_for_codex_also_uses_main_model - empty_model_for_catalog_provider_uses_catalog_default - explicit_model_takes_precedence_over_fallbacks 365/365 across tests/agent/test_auxiliary_*, tests/run_agent/test_codex_xai_oauth_recovery.py, tests/hermes_cli/test_auth_xai_oauth_provider.py, and tests/hermes_cli/test_plugin_auxiliary_tasks.py. Co-authored-by: wysie <wysie@users.noreply.github.com>
bridge25
pushed a commit
to bridge25/hermes-agent
that referenced
this pull request
May 27, 2026
…arch#31845) Aux callers (title generation, vision, session search, etc.) can reach resolve_provider_client() without an explicit model when the user picked their main provider via 'hermes model' and didn't bother configuring a per-task auxiliary.<task>.model override. The expectation in that case is universal: 'use my main model for side tasks too.' Before, the OAuth providers (xai-oauth, openai-codex) silently returned (None, None) on an empty model — both lack a catalog default because their accepted-model lists drift on the backend. That caused _resolve_auto to drop to its Step-2 fallback chain (OpenRouter / Nous / etc.), so aux tasks billed against the wrong subscription without warning. The fix is at the top of resolve_provider_client() — a single 3-step universal fallback that runs before any provider branch, so no provider-specific empty-model guards are needed (now or for any future provider we add): 1. caller-passed model (caller knew what they wanted) 2. provider's catalog default (cheap aux model, if registered) 3. user's main model from config.yaml Behaviour by provider class: - OAuth providers (xai-oauth, openai-codex) — no catalog default, so step 3 applies. Title gen runs on grok-4.3 / gpt-5.4 against the user's actual subscription instead of leaking to OpenRouter. - API-key providers (anthropic, gemini, kimi-coding, etc.) — catalog default wins at step 2, preserving the original 'cheap aux model' behaviour. Anthropic users still get claude-haiku-4-5 for titles, not opus. - Explicit-model callers (auxiliary.<task>.model config, programmatic callers) — caller wins at step 1, no surprise switching. Salvaged from @wysie's PR NousResearch#31845 which fixed the xai-oauth branch specifically. The universal shape supersedes the per-branch fix and covers openai-codex (same bug class) plus any future OAuth providers. 4 new tests in TestResolveProviderClientUniversalModelFallback: - empty_model_for_oauth_provider_falls_back_to_main_model - empty_model_for_codex_also_uses_main_model - empty_model_for_catalog_provider_uses_catalog_default - explicit_model_takes_precedence_over_fallbacks 365/365 across tests/agent/test_auxiliary_*, tests/run_agent/test_codex_xai_oauth_recovery.py, tests/hermes_cli/test_auth_xai_oauth_provider.py, and tests/hermes_cli/test_plugin_auxiliary_tasks.py. Co-authored-by: wysie <wysie@users.noreply.github.com>
mathias3
pushed a commit
to mathias3/hermes-agent
that referenced
this pull request
May 28, 2026
…arch#31845) Aux callers (title generation, vision, session search, etc.) can reach resolve_provider_client() without an explicit model when the user picked their main provider via 'hermes model' and didn't bother configuring a per-task auxiliary.<task>.model override. The expectation in that case is universal: 'use my main model for side tasks too.' Before, the OAuth providers (xai-oauth, openai-codex) silently returned (None, None) on an empty model — both lack a catalog default because their accepted-model lists drift on the backend. That caused _resolve_auto to drop to its Step-2 fallback chain (OpenRouter / Nous / etc.), so aux tasks billed against the wrong subscription without warning. The fix is at the top of resolve_provider_client() — a single 3-step universal fallback that runs before any provider branch, so no provider-specific empty-model guards are needed (now or for any future provider we add): 1. caller-passed model (caller knew what they wanted) 2. provider's catalog default (cheap aux model, if registered) 3. user's main model from config.yaml Behaviour by provider class: - OAuth providers (xai-oauth, openai-codex) — no catalog default, so step 3 applies. Title gen runs on grok-4.3 / gpt-5.4 against the user's actual subscription instead of leaking to OpenRouter. - API-key providers (anthropic, gemini, kimi-coding, etc.) — catalog default wins at step 2, preserving the original 'cheap aux model' behaviour. Anthropic users still get claude-haiku-4-5 for titles, not opus. - Explicit-model callers (auxiliary.<task>.model config, programmatic callers) — caller wins at step 1, no surprise switching. Salvaged from @wysie's PR NousResearch#31845 which fixed the xai-oauth branch specifically. The universal shape supersedes the per-branch fix and covers openai-codex (same bug class) plus any future OAuth providers. 4 new tests in TestResolveProviderClientUniversalModelFallback: - empty_model_for_oauth_provider_falls_back_to_main_model - empty_model_for_codex_also_uses_main_model - empty_model_for_catalog_provider_uses_catalog_default - explicit_model_takes_precedence_over_fallbacks 365/365 across tests/agent/test_auxiliary_*, tests/run_agent/test_codex_xai_oauth_recovery.py, tests/hermes_cli/test_auth_xai_oauth_provider.py, and tests/hermes_cli/test_plugin_auxiliary_tasks.py. Co-authored-by: wysie <wysie@users.noreply.github.com>
Bryce-huang
pushed a commit
to wbkunlun/hermes-agent
that referenced
this pull request
May 29, 2026
…arch#31845) Aux callers (title generation, vision, session search, etc.) can reach resolve_provider_client() without an explicit model when the user picked their main provider via 'hermes model' and didn't bother configuring a per-task auxiliary.<task>.model override. The expectation in that case is universal: 'use my main model for side tasks too.' Before, the OAuth providers (xai-oauth, openai-codex) silently returned (None, None) on an empty model — both lack a catalog default because their accepted-model lists drift on the backend. That caused _resolve_auto to drop to its Step-2 fallback chain (OpenRouter / Nous / etc.), so aux tasks billed against the wrong subscription without warning. The fix is at the top of resolve_provider_client() — a single 3-step universal fallback that runs before any provider branch, so no provider-specific empty-model guards are needed (now or for any future provider we add): 1. caller-passed model (caller knew what they wanted) 2. provider's catalog default (cheap aux model, if registered) 3. user's main model from config.yaml Behaviour by provider class: - OAuth providers (xai-oauth, openai-codex) — no catalog default, so step 3 applies. Title gen runs on grok-4.3 / gpt-5.4 against the user's actual subscription instead of leaking to OpenRouter. - API-key providers (anthropic, gemini, kimi-coding, etc.) — catalog default wins at step 2, preserving the original 'cheap aux model' behaviour. Anthropic users still get claude-haiku-4-5 for titles, not opus. - Explicit-model callers (auxiliary.<task>.model config, programmatic callers) — caller wins at step 1, no surprise switching. Salvaged from @wysie's PR NousResearch#31845 which fixed the xai-oauth branch specifically. The universal shape supersedes the per-branch fix and covers openai-codex (same bug class) plus any future OAuth providers. 4 new tests in TestResolveProviderClientUniversalModelFallback: - empty_model_for_oauth_provider_falls_back_to_main_model - empty_model_for_codex_also_uses_main_model - empty_model_for_catalog_provider_uses_catalog_default - explicit_model_takes_precedence_over_fallbacks 365/365 across tests/agent/test_auxiliary_*, tests/run_agent/test_codex_xai_oauth_recovery.py, tests/hermes_cli/test_auth_xai_oauth_provider.py, and tests/hermes_cli/test_plugin_auxiliary_tasks.py. Co-authored-by: wysie <wysie@users.noreply.github.com> #AI commit#
mosaiq-systems
pushed a commit
to mosaiq-systems/hermes-agent
that referenced
this pull request
May 29, 2026
…arch#31845) Aux callers (title generation, vision, session search, etc.) can reach resolve_provider_client() without an explicit model when the user picked their main provider via 'hermes model' and didn't bother configuring a per-task auxiliary.<task>.model override. The expectation in that case is universal: 'use my main model for side tasks too.' Before, the OAuth providers (xai-oauth, openai-codex) silently returned (None, None) on an empty model — both lack a catalog default because their accepted-model lists drift on the backend. That caused _resolve_auto to drop to its Step-2 fallback chain (OpenRouter / Nous / etc.), so aux tasks billed against the wrong subscription without warning. The fix is at the top of resolve_provider_client() — a single 3-step universal fallback that runs before any provider branch, so no provider-specific empty-model guards are needed (now or for any future provider we add): 1. caller-passed model (caller knew what they wanted) 2. provider's catalog default (cheap aux model, if registered) 3. user's main model from config.yaml Behaviour by provider class: - OAuth providers (xai-oauth, openai-codex) — no catalog default, so step 3 applies. Title gen runs on grok-4.3 / gpt-5.4 against the user's actual subscription instead of leaking to OpenRouter. - API-key providers (anthropic, gemini, kimi-coding, etc.) — catalog default wins at step 2, preserving the original 'cheap aux model' behaviour. Anthropic users still get claude-haiku-4-5 for titles, not opus. - Explicit-model callers (auxiliary.<task>.model config, programmatic callers) — caller wins at step 1, no surprise switching. Salvaged from @wysie's PR NousResearch#31845 which fixed the xai-oauth branch specifically. The universal shape supersedes the per-branch fix and covers openai-codex (same bug class) plus any future OAuth providers. 4 new tests in TestResolveProviderClientUniversalModelFallback: - empty_model_for_oauth_provider_falls_back_to_main_model - empty_model_for_codex_also_uses_main_model - empty_model_for_catalog_provider_uses_catalog_default - explicit_model_takes_precedence_over_fallbacks 365/365 across tests/agent/test_auxiliary_*, tests/run_agent/test_codex_xai_oauth_recovery.py, tests/hermes_cli/test_auth_xai_oauth_provider.py, and tests/hermes_cli/test_plugin_auxiliary_tasks.py. Co-authored-by: wysie <wysie@users.noreply.github.com>
gweeteve
pushed a commit
to gweeteve/hermes-agent
that referenced
this pull request
Jun 2, 2026
…arch#31845) Aux callers (title generation, vision, session search, etc.) can reach resolve_provider_client() without an explicit model when the user picked their main provider via 'hermes model' and didn't bother configuring a per-task auxiliary.<task>.model override. The expectation in that case is universal: 'use my main model for side tasks too.' Before, the OAuth providers (xai-oauth, openai-codex) silently returned (None, None) on an empty model — both lack a catalog default because their accepted-model lists drift on the backend. That caused _resolve_auto to drop to its Step-2 fallback chain (OpenRouter / Nous / etc.), so aux tasks billed against the wrong subscription without warning. The fix is at the top of resolve_provider_client() — a single 3-step universal fallback that runs before any provider branch, so no provider-specific empty-model guards are needed (now or for any future provider we add): 1. caller-passed model (caller knew what they wanted) 2. provider's catalog default (cheap aux model, if registered) 3. user's main model from config.yaml Behaviour by provider class: - OAuth providers (xai-oauth, openai-codex) — no catalog default, so step 3 applies. Title gen runs on grok-4.3 / gpt-5.4 against the user's actual subscription instead of leaking to OpenRouter. - API-key providers (anthropic, gemini, kimi-coding, etc.) — catalog default wins at step 2, preserving the original 'cheap aux model' behaviour. Anthropic users still get claude-haiku-4-5 for titles, not opus. - Explicit-model callers (auxiliary.<task>.model config, programmatic callers) — caller wins at step 1, no surprise switching. Salvaged from @wysie's PR NousResearch#31845 which fixed the xai-oauth branch specifically. The universal shape supersedes the per-branch fix and covers openai-codex (same bug class) plus any future OAuth providers. 4 new tests in TestResolveProviderClientUniversalModelFallback: - empty_model_for_oauth_provider_falls_back_to_main_model - empty_model_for_codex_also_uses_main_model - empty_model_for_catalog_provider_uses_catalog_default - explicit_model_takes_precedence_over_fallbacks 365/365 across tests/agent/test_auxiliary_*, tests/run_agent/test_codex_xai_oauth_recovery.py, tests/hermes_cli/test_auth_xai_oauth_provider.py, and tests/hermes_cli/test_plugin_auxiliary_tasks.py. Co-authored-by: wysie <wysie@users.noreply.github.com>
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.
When auxiliary tasks (title generation, compression, session search, etc.) call resolve_provider_client without an explicit model while the main provider is xai-oauth, _build_xai_oauth_aux_client would early-return None. This caused HTTP 400s on auxiliary title generation after switching from GPT-family to grok-4.3 via xAI Grok OAuth.
Now we fall back to _read_main_model() so auxiliary tasks continue using the user's chosen Grok model instead of silently dropping to Step-2 fallbacks (OpenRouter/Nous/etc.).
This is a focused, isolated fix.