Skip to content

Fix usage script variable replacement for custom providers#2031

Open
West-Pavilion wants to merge 2 commits intofarion1231:mainfrom
West-Pavilion:fix-usage-script-provider-vars
Open

Fix usage script variable replacement for custom providers#2031
West-Pavilion wants to merge 2 commits intofarion1231:mainfrom
West-Pavilion:fix-usage-script-provider-vars

Conversation

@West-Pavilion
Copy link
Copy Markdown
Contributor

@West-Pavilion West-Pavilion commented Apr 12, 2026

This fixes a pretty confusing usage-query bug in custom templates.

If a provider is using the custom usage template, the UI shows {{apiKey}} and {{baseUrl}} as supported variables. In practice, though, they could fail to resolve unless the raw values were pasted directly into the script.

What changed

  • make usage-script test execution fall back to the provider's saved credentials when the usage form fields are left empty
  • extend provider credential extraction so Codex / OpenAI-style providers can resolve OPENAI_API_KEY and base_url from their stored config
  • accept lowercase aliases like {{apikey}} and {{baseurl}} in addition to the existing variable names
  • add focused tests for Codex credential fallback and template replacement behavior

Verification

  • cargo test codex --lib
  • cargo test test_build_script_with_vars_supports_legacy_lowercase_aliases --lib

This should make the actual behavior line up with what the modal tells users.

Copilot AI review requested due to automatic review settings April 12, 2026 16:43
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR fixes usage-script variable substitution for custom providers by improving template placeholder replacement and making usage-script test execution fall back to stored provider credentials when form fields are empty, aligning actual behavior with what the UI indicates.

Changes:

  • Add forgiving template replacement (supports legacy lowercase aliases like {{apikey}}, {{baseurl}}, etc.).
  • Extend provider credential extraction (including Codex/OpenAI-style config parsing for base URL and API key lookup).
  • Update usage-script test execution to fall back to saved provider credentials when test inputs are left blank, and add focused tests.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.

File Description
src-tauri/src/usage_script.rs Adds alias-aware template variable replacement and a regression test for lowercase placeholders.
src-tauri/src/services/provider/usage.rs Improves credential/base URL extraction and adds provider-credential fallback during usage-script test execution, plus tests for Codex TOML parsing.

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

.or_else(|| env.get("ANTHROPIC_API_KEY"))
.or_else(|| env.get("OPENROUTER_API_KEY"))
.or_else(|| env.get("GOOGLE_API_KEY"))
.or_else(|| env.get("GEMINI_API_KEY"))
Copy link

Copilot AI Apr 12, 2026

Choose a reason for hiding this comment

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

extract_api_key_from_provider currently checks several keys under settings_config.env, but it does not consider OPENAI_API_KEY. Other parts of the codebase treat env.OPENAI_API_KEY as a valid source (e.g., Codex provider auth extraction), so usage script credential fallback can fail for providers that store the key there. Include env.get("OPENAI_API_KEY") in the env key chain (and keep the existing auth/options fallbacks).

Suggested change
.or_else(|| env.get("GEMINI_API_KEY"))
.or_else(|| env.get("GEMINI_API_KEY"))
.or_else(|| env.get("OPENAI_API_KEY"))

Copilot uses AI. Check for mistakes.
Comment on lines +292 to +299
let provider_credentials = || -> Option<(Option<String>, Option<String>)> {
let providers = state.db.get_all_providers(app_type.as_str()).ok()?;
let provider = providers.get(provider_id)?;
Some((
extract_api_key_from_provider(provider),
extract_base_url_from_provider(provider),
))
};
Copy link

Copilot AI Apr 12, 2026

Choose a reason for hiding this comment

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

In test_usage_script, the provider fallback path swallows database errors and missing-provider cases via get_all_providers(...).ok()? and providers.get(provider_id)?. When this happens, the script is executed with empty credentials, which can produce misleading user-facing errors and makes real DB/provider issues hard to diagnose. Consider returning an AppError when fallback credentials are needed but the provider lookup fails, instead of silently defaulting to empty strings.

Copilot uses AI. Check for mistakes.
Comment on lines +293 to +297
let providers = state.db.get_all_providers(app_type.as_str()).ok()?;
let provider = providers.get(provider_id)?;
Some((
extract_api_key_from_provider(provider),
extract_base_url_from_provider(provider),
Copy link

Copilot AI Apr 12, 2026

Choose a reason for hiding this comment

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

test_usage_script fetches providers using state.db.get_all_providers(...), which loads all providers (and their endpoint subqueries) just to read one provider’s credentials. This can be unnecessarily expensive if the modal’s “Test” is run frequently. Prefer using a targeted lookup like state.db.get_provider_by_id(provider_id, app_type.as_str()) for the fallback path.

Suggested change
let providers = state.db.get_all_providers(app_type.as_str()).ok()?;
let provider = providers.get(provider_id)?;
Some((
extract_api_key_from_provider(provider),
extract_base_url_from_provider(provider),
let provider = state
.db
.get_provider_by_id(provider_id, app_type.as_str())
.ok()?;
Some((
extract_api_key_from_provider(&provider),
extract_base_url_from_provider(&provider),

Copilot uses AI. Check for mistakes.
@farion1231
Copy link
Copy Markdown
Owner

@codex review

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 88e61e6911

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines 90 to +93
.or_else(|| env.get("ANTHROPIC_API_KEY"))
.or_else(|| env.get("OPENROUTER_API_KEY"))
.or_else(|| env.get("GOOGLE_API_KEY"))
.or_else(|| env.get("GEMINI_API_KEY"))
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Handle OPENAI_API_KEY in env credential fallback

test_usage_script now relies on extract_api_key_from_provider when the usage-form API key is empty, but this extractor’s env lookup omits OPENAI_API_KEY. That means providers storing OpenAI tokens under settings_config.env.OPENAI_API_KEY (a format already supported by the Codex adapter) still resolve to an empty key during script testing, so the new fallback behavior fails for those providers. Adding this env key to the lookup chain would make the fallback consistent with existing provider auth extraction.

Useful? React with 👍 / 👎.

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