Skip to content

fix: auxiliary compression auth bypass for OAuth providers (Nous) - #6992

Closed
Aaryan2304 wants to merge 3 commits into
NousResearch:mainfrom
Aaryan2304:fix/auxiliary-compression-oauth-auth
Closed

fix: auxiliary compression auth bypass for OAuth providers (Nous)#6992
Aaryan2304 wants to merge 3 commits into
NousResearch:mainfrom
Aaryan2304:fix/auxiliary-compression-oauth-auth

Conversation

@Aaryan2304

Copy link
Copy Markdown

Problem

When using Nous Portal OAuth authentication, the auxiliary compression client fails with HTTP 401, causing silent context loss on session resume.

Root Cause

In _resolve_task_provider_model(), when the compression task config has both summary_provider: nous and summary_base_url set (in the compression: section of config.yaml), the code forces the provider to "custom" — even when auxiliary.compression.provider is explicitly set to "nous".

The "custom" handler does not call _try_nous() (the OAuth auth reader from auth.json). Instead, it creates an OpenAI client with an empty or wrong API key, resulting in 401 errors and silent session context loss.

Secondary Issue

cfg_api_key from the task config was dropped on three return paths (lines 1860, 1870, 1875), meaning explicit API keys were silently ignored.

Impact

This affects all Nous OAuth users. Any model on Nous hits this when sessions grow large enough to trigger context compression. Since compression failure prevents session save, users lose all conversation context on resume.

Fix

  1. Pass cfg_api_key through on all return paths
  2. Honour explicit provider when base_url is also set — ensures OAuth providers use their _try_*() functions that read tokens from auth.json

When auxiliary.compression is configured with a known provider (e.g.
'nous') and a summary_base_url is also set in the compression section,
_resolve_task_provider_model() forced the provider to 'custom', which
bypassed OAuth token lookup from auth.json and caused 401 errors.

Changes in _resolve_task_provider_model():
- Pass cfg_api_key through on all return paths (previously dropped on
  lines 1860, 1870, 1875)
- When cfg_base_url is set but cfg_provider is a known provider (not
  'auto' or 'custom'), honour the provider instead of routing to the
  'custom' handler. This ensures OAuth providers like 'nous' and
  'openai-codex' continue to read tokens from auth.json via their
  dedicated _try_*() functions.

Config patterns now working correctly:
 1. provider: nous, api_key: ''         → reads auth.json via _try_nous()
 2. provider: nous, api_key: sk-xxx     → uses explicit key
 3. compression.summary_provider: nous
    + compression.summary_base_url: ... → honours 'nous' provider
Copilot AI review requested due to automatic review settings April 10, 2026 06:31

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes auxiliary context-compression routing so OAuth-backed providers (notably Nous Portal) don’t get accidentally routed through the generic “custom endpoint” path, which bypasses auth token lookup and can cause HTTP 401s and lost session context.

Changes:

  • Propagates cfg_api_key through more _resolve_task_provider_model() return paths (so explicitly configured API keys aren’t dropped).
  • Adjusts provider/base_url precedence so an explicitly configured provider can be honored even when a base_url is also present (avoiding OAuth auth bypass).
  • Adds explanatory inline comments describing the OAuth bypass failure mode.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread agent/auxiliary_client.py
Comment on lines 1872 to 1880
if cfg_base_url:
# When a provider is explicitly configured (not "auto"), honour it
# even if a base_url is also set. Providers like "nous" and
# "openai-codex" use OAuth tokens from auth.json — routing them
# through the "custom" handler bypasses that auth lookup and
# causes 401 errors.
if cfg_provider and cfg_provider not in ("auto", "custom"):
return cfg_provider, resolved_model, cfg_base_url, cfg_api_key
return "custom", resolved_model, cfg_base_url, cfg_api_key

Copilot AI Apr 10, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new cfg_base_url handling changes the previously documented/advertised precedence where a configured base_url forces the request through the "custom" handler. With this change, any explicitly configured provider (including "main" and API-key providers) will now win even when base_url is set, and the base_url value will be effectively ignored by resolve_provider_client for non-"custom" providers. If the intent is only to avoid bypassing OAuth for specific providers (e.g., "nous" / "openai-codex"), consider narrowing this exception to just those providers (and keeping base_url→custom semantics for others), and update the function docstring/comments accordingly so config behavior matches docs.

Copilot uses AI. Check for mistakes.
Comment thread agent/auxiliary_client.py Outdated
Comment on lines +1873 to +1879
# When a provider is explicitly configured (not "auto"), honour it
# even if a base_url is also set. Providers like "nous" and
# "openai-codex" use OAuth tokens from auth.json — routing them
# through the "custom" handler bypasses that auth lookup and
# causes 401 errors.
if cfg_provider and cfg_provider not in ("auto", "custom"):
return cfg_provider, resolved_model, cfg_base_url, cfg_api_key

Copilot AI Apr 10, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change is addressing a subtle precedence/auth interaction (provider + base_url + api_key) but there’s no regression test covering the reported scenario (e.g., compression summary_provider=nous with a summary_base_url set should still route through the Nous OAuth path rather than instantiating a custom OpenAI client). Adding a focused unit test around _resolve_task_provider_model/get_text_auxiliary_client would help prevent future auth bypass regressions.

Copilot uses AI. Check for mistakes.
…roxies

The previous broad check (provider not in 'auto'/'custom') would have
broken proxy setups for OpenRouter, Anthropic, and other API-key
providers that rely on the 'custom' handler when a base_url is set.

Narrow to only OAuth providers ('nous', 'openai-codex', 'codex') that
read tokens from auth.json via _try_*() handlers. All other providers
with a base_url continue to route through the 'custom' handler as
before.
Covers the exact bug scenario (summary_provider=nous + summary_base_url
routing to 'custom' instead of nous handler) plus boundary cases:
- Non-OAuth providers still use 'custom' when base_url is set
- Codex OAuth provider gets same exception as nous
- Nous without base_url still works
- cfg_api_key passthrough with explicit provider
- Custom provider with base_url unchanged
@teknium1

Copy link
Copy Markdown
Contributor

Thanks for the thorough investigation and well-written tests, Aaryan! After tracing the full resolution chain, the scenario this fixes requires a manually misconfigured config (summary_provider: nous + summary_base_url set together) — a combination that doesn't occur through normal setup or agent configuration. The Nous provider handler already knows its own base URL, so summary_base_url is never needed alongside it.

The cfg_api_key passthrough changes are also effectively no-ops since _try_nous(), _try_openrouter(), etc. handle their own auth discovery from auth.json / env vars and don't use the explicit_api_key parameter.

Your actual symptom (sessions losing messages on resume) was the mid-loop compression persistence bug fixed in PR #7001 — the session was being created but zero messages were flushed to it. That fix is already on main.

Appreciate you digging into this and reporting the issue — it led directly to finding the real bug.

@teknium1 teknium1 closed this Apr 10, 2026
@Aaryan2304

Copy link
Copy Markdown
Author

No worries, more PRs on the way 😎
All bugs must be eliminated 😈

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.

3 participants