fix: usage script provider credential resolution (#1479)

The JS-script usage path resolved {{apiKey}}/{{baseUrl}} with env-only
field guessing, so apps that store credentials elsewhere (Codex:
auth.OPENAI_API_KEY + config.toml base_url) always got empty values and
custom-template queries failed despite a fully configured provider.

- query_usage / test_usage_script now delegate to
  Provider::resolve_usage_credentials, the same per-app resolver used by
  the native balance/coding-plan path and mirrored by the frontend
  getProviderCredentials; explicit non-empty script values still win
- test_usage_script loads the provider and applies the same fallback,
  so testing matches what a saved script does
- the custom-template variable preview shows the effective values
  (script overrides first, then provider config) instead of always
  showing provider credentials
- extract_codex_base_url documents and test-locks the frontend-mirror
  invariant: non-active [model_providers.*] sections are never read

Reworked from the original patch to reuse the existing resolver instead
of duplicating per-app extraction.

Co-authored-by: Jason <farion1231@gmail.com>
This commit is contained in:
pa001024
2026-06-10 22:57:27 +08:00
committed by GitHub
parent 4f911727d2
commit 9ea303b224
4 changed files with 189 additions and 60 deletions
+3 -7
View File
@@ -108,17 +108,13 @@ impl Provider {
.unwrap_or(false)
}
/// Resolve `(base_url, api_key)` for native usage queries (balance /
/// coding-plan) from the stored provider config.
/// Resolve `(base_url, api_key)` for usage queries (native balance /
/// coding-plan and the JS-script `{{apiKey}}`/`{{baseUrl}}` fallback)
/// from the stored provider config.
///
/// Each app persists credentials in a different shape, so callers must pass
/// the owning app type. This mirrors the frontend `getProviderCredentials`
/// in `UsageScriptModal.tsx`.
///
/// TODO: the env-only helpers in `services/provider/usage.rs`
/// (`extract_api_key_from_provider` / `extract_base_url_from_provider`)
/// duplicate this per-app logic on the JS-script path and could delegate
/// here in a follow-up to remove the remaining copy.
pub fn resolve_usage_credentials(
&self,
app_type: &crate::app_config::AppType,