From 019c11d07e082acf401cfc7f008757df0cd98a05 Mon Sep 17 00:00:00 2001 From: Yang Zhi Date: Wed, 8 Apr 2026 16:18:07 +0800 Subject: [PATCH] fix(fallback): preserve provider-specific headers when activating fallback When _try_activate_fallback() swaps to a new provider (e.g. kimi-coding), resolve_provider_client() correctly injects provider-specific default_headers (like KimiCLI User-Agent) into the returned OpenAI client. However, _client_kwargs was saved with only api_key and base_url, dropping those headers. Every subsequent API call rebuilds the client from _client_kwargs via _create_request_openai_client(), producing a bare OpenAI client without the required headers. Kimi Coding rejects this with 403; Copilot would lose its auth headers similarly. This patch reads _custom_headers from the fallback client (where the OpenAI SDK stores the default_headers kwarg) and includes them in _client_kwargs so any client rebuild preserves provider-specific headers. Fixes #6075 --- run_agent.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/run_agent.py b/run_agent.py index b8ed44ef7..d1c8980d8 100644 --- a/run_agent.py +++ b/run_agent.py @@ -4968,9 +4968,21 @@ class AIAgent: # Swap OpenAI client and config in-place self.api_key = fb_client.api_key self.client = fb_client + # Preserve provider-specific headers that + # resolve_provider_client() may have baked into + # fb_client via the default_headers kwarg. The OpenAI + # SDK stores these in _custom_headers. Without this, + # subsequent request-client rebuilds (via + # _create_request_openai_client) drop the headers, + # causing 403s from providers like Kimi Coding that + # require a User-Agent sentinel. + fb_headers = getattr(fb_client, "_custom_headers", None) + if not fb_headers: + fb_headers = getattr(fb_client, "default_headers", None) self._client_kwargs = { "api_key": fb_client.api_key, "base_url": fb_base_url, + **({"default_headers": dict(fb_headers)} if fb_headers else {}), } # Re-evaluate prompt caching for the new provider/model