Skip to content

fix: custom provider API key handling and OpenRouter support#847

Closed
seoeaa wants to merge 6 commits intoagentscope-ai:mainfrom
seoeaa:fix/custom-provider-api-key
Closed

fix: custom provider API key handling and OpenRouter support#847
seoeaa wants to merge 6 commits intoagentscope-ai:mainfrom
seoeaa:fix/custom-provider-api-key

Conversation

@seoeaa
Copy link
Copy Markdown
Contributor

@seoeaa seoeaa commented Mar 6, 2026

Changes

Custom Provider API Key Fixes

  • Frontend (CustomProviderModal.tsx): Changed from api_key_prefix field to api_key field for storing the actual API key
  • Backend (providers.py): Added api_key field to CreateCustomProviderRequest
  • Backend (store.py): Added api_key parameter to create_custom_provider function
  • Backend (providers.py): Return empty api_key_prefix for custom providers to avoid validation errors

OpenRouter Support

  • model_factory.py: Added HTTP-Referer and X-Title headers for OpenRouter API calls
  • store.py: Added OpenRouter header injection in _build_remote_provider_headers(), test_provider_connection(), discover_provider_models()

Localization

  • Added new translation keys for API key field labels in en.json, ru.json, zh.json

Root Cause

The original code incorrectly used api_key_prefix field (meant for validation prefixes like sk-) to store the actual API key. This caused authentication failures.

@gemini-code-assist
Copy link
Copy Markdown
Contributor

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly enhances the platform's flexibility and user experience by rectifying a critical issue with custom provider API key management, enabling seamless integration with OpenRouter, and expanding language support to include Russian. These changes collectively improve the reliability of external model connections and make the application more accessible to a broader user base.

Highlights

  • Custom Provider API Key Handling: The system now correctly handles API keys for custom providers by introducing a dedicated api_key field, resolving previous authentication failures where the api_key_prefix was mistakenly used for storage.
  • OpenRouter Support: Integration with OpenRouter has been added, including the necessary HTTP-Referer and X-Title headers for API calls to ensure proper identification and functionality.
  • Russian Localization: Comprehensive Russian language support has been introduced across the frontend, including new translation keys and an updated language switcher.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Changelog
  • console/src/api/types/provider.ts
    • Added the api_key field to the CreateCustomProviderRequest interface.
  • console/src/components/LanguageSwitcher.tsx
    • Updated language detection to use i18n.resolvedLanguage for better accuracy.
    • Added 'Русский' (Russian) to the language selection dropdown.
    • Refactored language label mapping for improved extensibility.
  • console/src/i18n.ts
    • Imported and registered Russian translation resources.
  • console/src/layouts/Sidebar.tsx
    • Included Russian update instructions in the UPDATE_MD constant.
    • Adjusted the update modal logic to support fetching localized update content, including Russian.
  • console/src/locales/en.json
    • Added new translation keys for 'API Key (optional)' label and placeholder.
  • console/src/locales/ru.json
    • Added a new file containing comprehensive Russian translations for the application UI.
  • console/src/locales/zh.json
    • Added new translation keys for 'API 密钥(可选)' label and placeholder.
  • console/src/pages/Settings/Models/components/modals/CustomProviderModal.tsx
    • Modified the custom provider modal to use the api_key field instead of api_key_prefix for input.
    • Changed the API key input field to a password type for security.
  • src/copaw/agents/model_factory.py
    • Implemented logic to inject HTTP-Referer and X-Title headers for OpenRouter API calls.
  • src/copaw/app/routers/providers.py
    • Added the api_key field to the CreateCustomProviderRequest Pydantic model.
    • Ensured custom providers return an empty api_key_prefix to prevent validation errors.
    • Passed the new api_key field when creating custom providers.
  • src/copaw/providers/models.py
    • Corrected the retrieval of base_url and api_key for custom providers.
  • src/copaw/providers/store.py
    • Updated _build_remote_provider_headers to accept base_url and inject OpenRouter specific headers.
    • Modified create_custom_provider to accept and store the new api_key parameter.
    • Passed base_url to header building functions during model discovery and connection testing.
    • Added debug logging for model connection tests.
    • In test_provider_connection, added OpenRouter specific headers to client arguments when instantiating chat models.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Generative AI Prohibited Use Policy, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request correctly addresses an issue with custom provider API key handling and introduces support for OpenRouter, along with adding Russian language localization. The changes are generally well-implemented. I've identified a couple of areas for improvement: one regarding inefficient data fetching in the frontend, and another related to duplicated code for OpenRouter header injection in the backend. My review includes suggestions to address these points to enhance efficiency and maintainability.

Comment on lines +1171 to +1176
# OpenRouter requires special headers for identification
if base_url and "openrouter.ai" in base_url.lower():
client_kwargs["default_headers"] = {
"HTTP-Referer": "https://github.com/copaw-ai/CoPaw",
"X-Title": "CoPaw",
}
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.

medium

The logic to add special headers for OpenRouter is duplicated in multiple places. This exact block is one instance. You can also find similar logic in _build_remote_provider_headers in this file (lines 204-207), and in _create_remote_model_instance in src/copaw/agents/model_factory.py (lines 408-412).

This duplication makes the code harder to maintain. If the headers need to be changed in the future, it will have to be done in three different places.

Additionally, the implementations are inconsistent. This one overwrites default_headers, while the one in model_factory.py correctly appends to it. This could lead to bugs if other default headers are needed.

I recommend centralizing this logic into a single helper function that returns the OpenRouter headers, and then call this function from all three places, ensuring you are updating the default_headers dictionary rather than overwriting it.

        # OpenRouter requires special headers for identification
        if base_url and "openrouter.ai" in base_url.lower():
            if "default_headers" not in client_kwargs:
                client_kwargs["default_headers"] = {}
            client_kwargs["default_headers"].update({
                "HTTP-Referer": "https://github.com/copaw-ai/CoPaw",
                "X-Title": "CoPaw",
            })

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.

1 participant