fix(providers): ключ не доходил до адаптера; счётчик аккаунтов расходился
Ключ API. add_account сохраняет его через ProfileAuthManager, а адаптеры NVIDIA и OpenRouter читали только profile.auth_config из router_profiles.yaml — туда ключ не попадает. Запрос уходил без заголовка Authorization, и провайдер отвечал «401: Header of type authorization was missing», хотя список моделей тем же ключом получался: обнаружение читает ключ из хранилища, а адаптер читал из конфигурации. Проверено: auth_config в yaml пуст, адаптер теперь находит ключ в хранилище учётных данных. Счётчик аккаунтов. Значок в меню брал readiness.accounts_connected_count (строго AUTHENTICATED), а карточка на странице считала профили правилом «не NOT_CONFIGURED». Владелец видел 9 в меню и 3 на странице. Приведено к одному определению — тому же, что у страницы. 609 passed, ruff clean, релизный гейт 10/10. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
4b6533281e
commit
266fc51adf
3 changed files with 33 additions and 3 deletions
|
|
@ -38,6 +38,20 @@ class NvidiaAdapter(BaseProviderAdapter):
|
||||||
if key:
|
if key:
|
||||||
return str(key).strip()
|
return str(key).strip()
|
||||||
|
|
||||||
|
# Ключ, введённый в мастере, сохраняется через ProfileAuthManager, а не в
|
||||||
|
# auth_config из router_profiles.yaml. Адаптер читал только второе место и
|
||||||
|
# уходил без заголовка Authorization: провайдер отвечал 401 «Header of type
|
||||||
|
# authorization was missing», хотя список моделей тем же ключом получался.
|
||||||
|
try:
|
||||||
|
from antigravity_provider.router.profile_manager import ProfileAuthManager
|
||||||
|
|
||||||
|
stored = ProfileAuthManager.load_profile_auth(profile.provider, profile.profile_id) or {}
|
||||||
|
key = stored.get("api_key") or stored.get("token")
|
||||||
|
if key:
|
||||||
|
return str(key).strip()
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
|
||||||
suffix = profile.profile_id.upper().replace("-", "_")
|
suffix = profile.profile_id.upper().replace("-", "_")
|
||||||
for candidate in (f"NVIDIA_API_KEY_{suffix}", "NVIDIA_API_KEY", "NV_API_KEY"):
|
for candidate in (f"NVIDIA_API_KEY_{suffix}", "NVIDIA_API_KEY", "NV_API_KEY"):
|
||||||
val = os.environ.get(candidate, "").strip()
|
val = os.environ.get(candidate, "").strip()
|
||||||
|
|
|
||||||
|
|
@ -41,6 +41,20 @@ class OpenRouterAdapter(BaseProviderAdapter):
|
||||||
if key:
|
if key:
|
||||||
return str(key).strip()
|
return str(key).strip()
|
||||||
|
|
||||||
|
# Ключ, введённый в мастере, сохраняется через ProfileAuthManager, а не в
|
||||||
|
# auth_config из router_profiles.yaml. Адаптер читал только второе место и
|
||||||
|
# уходил без заголовка Authorization: провайдер отвечал 401 «Header of type
|
||||||
|
# authorization was missing», хотя список моделей тем же ключом получался.
|
||||||
|
try:
|
||||||
|
from antigravity_provider.router.profile_manager import ProfileAuthManager
|
||||||
|
|
||||||
|
stored = ProfileAuthManager.load_profile_auth(profile.provider, profile.profile_id) or {}
|
||||||
|
key = stored.get("api_key") or stored.get("token")
|
||||||
|
if key:
|
||||||
|
return str(key).strip()
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
|
||||||
suffix = profile.profile_id.upper().replace("-", "_")
|
suffix = profile.profile_id.upper().replace("-", "_")
|
||||||
for candidate in (f"OPENROUTER_API_KEY_{suffix}", "OPENROUTER_API_KEY"):
|
for candidate in (f"OPENROUTER_API_KEY_{suffix}", "OPENROUTER_API_KEY"):
|
||||||
val = os.environ.get(candidate, "").strip()
|
val = os.environ.get(candidate, "").strip()
|
||||||
|
|
|
||||||
|
|
@ -576,9 +576,11 @@ function updateGlobalHeader() {
|
||||||
const readiness = currentSnapshot.readiness || {};
|
const readiness = currentSnapshot.readiness || {};
|
||||||
renderAccountSummary(currentSnapshot);
|
renderAccountSummary(currentSnapshot);
|
||||||
const allProfiles = Object.values(currentSnapshot.all_profiles || {});
|
const allProfiles = Object.values(currentSnapshot.all_profiles || {});
|
||||||
const connectedAccounts = readiness.accounts_connected_count ?? allProfiles.filter(
|
// Одно число — одно определение. Готовность считает строго AUTHENTICATED,
|
||||||
(p) => isConnectedProfile(p)
|
// а страница аккаунтов — всё, что не NOT_CONFIGURED. Из-за двух определений
|
||||||
).length;
|
// значок в меню показывал 9, а карточка на той же странице — 3.
|
||||||
|
// Берём то же правило, что и страница аккаунтов: расходиться они не должны.
|
||||||
|
const connectedAccounts = allProfiles.filter((p) => isConnectedProfile(p)).length;
|
||||||
|
|
||||||
if (elements.navAccountsCount) elements.navAccountsCount.textContent = connectedAccounts;
|
if (elements.navAccountsCount) elements.navAccountsCount.textContent = connectedAccounts;
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue