Skip to content

Unify OpenAI-compatible providers and custom provider flow#930

Open
PeterDaveHello wants to merge 2 commits intoChatGPTBox-dev:masterfrom
PeterDaveHello:refactor/openai-provider-platform
Open

Unify OpenAI-compatible providers and custom provider flow#930
PeterDaveHello wants to merge 2 commits intoChatGPTBox-dev:masterfrom
PeterDaveHello:refactor/openai-provider-platform

Conversation

@PeterDaveHello
Copy link
Copy Markdown
Member

@PeterDaveHello PeterDaveHello commented Feb 24, 2026

User description

This PR unifies OpenAI-compatible API execution into a shared core + provider registry,
and completes the custom provider workflow in API Modes.

Included changes

  • Consolidated OpenAI-compatible request logic into shared execution path
  • Unified provider resolution/secret lookup for built-in and custom providers
  • Added config-driven custom provider flow in API Modes
  • Kept GPT-5/OpenAI token param behavior (max_completion_tokens where required)
  • Hardened migration for legacy configs/sessions (provider IDs, keys, custom URL mapping)
  • Fixed settings/key update edge cases and stream completion signaling consistency

Compatibility

  • No intended breaking behavior for existing users
  • Existing configs are migrated with backward-compatible handling
  • Existing OpenAI-compatible providers continue to work under unified config management

Validation

  • npm run lint passed
  • npm run build passed

GitHub Copilot PR summary

This pull request introduces a major refactor to how OpenAI-compatible and custom API providers are managed and configured. The changes unify the handling of various OpenAI-compatible APIs (including custom, Ollama, DeepSeek, Moonshot, ChatGLM, OpenRouter, AIML, and legacy GPT Completion APIs) under a single provider system, and add a robust migration and normalization layer for user configuration. This will make it easier to add new providers, manage secrets, and ensure backward compatibility with legacy config data.

Key changes include:

Unification and Refactor of API Provider Handling

  • Consolidated all OpenAI-compatible API providers (custom, Ollama, DeepSeek, Moonshot, ChatGLM, OpenRouter, AIML, GPT Completion, etc.) to be handled by a single generateAnswersWithOpenAICompatibleApi function, replacing multiple specific imports and execution branches in src/background/index.mjs. This simplifies the codebase and centralizes provider logic. [1] [2] [3] [4]

  • Added isUsingOpenAICompatibleApiSession utility to determine if a session should be routed through the unified OpenAI-compatible API handler.

Configuration Schema and Migration

  • Introduced a configuration schema versioning system and a comprehensive migration function (migrateUserConfig) in src/config/index.mjs. This function normalizes provider IDs, migrates legacy secrets, deduplicates and renames custom providers, and ensures all config data is up-to-date and consistent.

  • Updated the default config to include new fields: customOpenAIProviders, providerSecrets, and configSchemaVersion.

Popup UI and Provider Management

  • Refactored the API modes section in the popup UI (src/popup/sections/ApiModes.jsx) to use the new provider registry and normalization logic. Added helpers for provider ID normalization, uniqueness, and base URL sanitization.

  • Ensured that UI state and config updates are consistent with the new provider structure, and that legacy custom providers are handled gracefully.


References:

  • Unified provider imports and execution: [1] [2] [3] [4]
  • Added isUsingOpenAICompatibleApiSession:
  • Config migration and normalization:
  • Default config updates:
  • Popup/provider UI refactor:

PR Type

Enhancement, Tests, Documentation


Description

  • Unified OpenAI-compatible provider system: Consolidated all OpenAI-compatible API providers (custom, Ollama, DeepSeek, Moonshot, ChatGLM, OpenRouter, AIML) into a single shared execution path via generateAnswersWithOpenAICompatibleApi, eliminating duplicate provider-specific implementations

  • Configuration migration and schema versioning: Introduced comprehensive migrateUserConfig function that normalizes provider IDs, consolidates legacy secrets, handles custom provider deduplication, and maintains backward compatibility with existing configs

  • Unified provider registry: Created provider-registry.mjs with centralized provider resolution logic supporting both built-in and custom providers, with secret lookup and endpoint URL construction

  • Custom provider UI workflow: Refactored API Modes popup to support custom provider creation/editing with provider selector dropdown, validation, and dynamic provider list management

  • Provider secret management: Added buildProviderSecretUpdate utility for managing provider secrets across built-in and custom providers with legacy field support

  • API mode normalization: Implemented normalizeApiMode utility to ensure consistent API mode object structure throughout the codebase

  • Stream completion signaling: Fixed stream completion consistency to emit final message with { answer: null, done: true, session } format

  • Comprehensive test coverage: Added 16 config migration tests, 8 provider registry tests, and additional tests for provider utilities and stream handling

  • Multilingual support: Updated localization strings across 12 languages for custom provider UI labels and validation messages

  • Removed 6 provider-specific API modules: Deleted ollama-api.mjs, chatglm-api.mjs, aiml-api.mjs, moonshot-api.mjs, openrouter-api.mjs, and deepseek-api.mjs as functionality consolidated into unified handler


Diagram Walkthrough

flowchart LR
  A["Legacy Provider APIs<br/>Ollama, DeepSeek, etc."] -->|"Consolidated"| B["generateAnswersWithOpenAICompatibleApi"]
  C["User Config<br/>Legacy format"] -->|"migrateUserConfig"| D["Normalized Config<br/>customOpenAIProviders<br/>providerSecrets"]
  B -->|"Resolves via"| E["provider-registry"]
  E -->|"Looks up"| D
  F["API Modes UI"] -->|"Uses"| G["Provider utilities<br/>createProviderId<br/>parseChatCompletionsUrl"]
  G -->|"Updates via"| H["buildProviderSecretUpdate"]
  H -->|"Persists to"| D
Loading

File Walkthrough

Relevant files
Enhancement
13 files
index.mjs
Configuration migration and provider registry unification

src/config/index.mjs

  • Added comprehensive configuration migration system with
    migrateUserConfig function to normalize provider IDs, consolidate
    legacy secrets, and handle custom provider deduplication
  • Introduced new config fields: customOpenAIProviders, providerSecrets,
    and configSchemaVersion for unified provider management
  • Implemented migration logic that promotes legacy customUrl and apiKey
    fields into provider-based storage while maintaining backward
    compatibility
  • Enhanced getUserConfig to automatically persist migrated configuration
    changes to storage
+474/-3 
ApiModes.jsx
Custom provider UI editor and provider selector integration

src/popup/sections/ApiModes.jsx

  • Refactored API modes UI to support custom provider management with
    create/edit provider dialogs
  • Added provider selector dropdown and validation for provider name and
    chat completions URL
  • Implemented sanitizeApiModeForSave to ensure proper provider ID and
    API key handling during save
  • Integrated getCustomOpenAIProviders and provider utilities for dynamic
    provider list management
+303/-46
provider-registry.mjs
Unified provider registry and resolution system                   

src/services/apis/provider-registry.mjs

  • Created unified provider registry with getAllOpenAIProviders,
    getProviderById, and resolveOpenAICompatibleRequest functions
  • Implemented provider resolution logic that handles both built-in
    providers (OpenAI, DeepSeek, Ollama, etc.) and custom providers
  • Added getProviderSecret function to resolve API keys from
    providerSecrets map with fallback to legacy fields
  • Provides endpoint URL construction and normalization for various
    provider configurations
+362/-0 
GeneralPart.jsx
Unified provider detection and API key management               

src/popup/sections/GeneralPart.jsx

  • Replaced individual provider detection functions with unified
    resolveOpenAICompatibleRequest call
  • Updated API key input and balance check to use provider-resolved
    credentials via buildProviderSecretUpdate
  • Simplified provider-specific UI logic by consolidating multiple
    isUsingXxxApiModel checks into single isUsingOpenAICompatibleProvider
    flag
+45/-123
openai-api.mjs
OpenAI-compatible API core extraction and unification       

src/services/apis/openai-api.mjs

  • Extracted common OpenAI-compatible request logic into new
    generateAnswersWithOpenAICompatible core function
  • Added generateAnswersWithOpenAICompatibleApi as unified entry point
    that resolves provider configuration and delegates to core
  • Implemented touchOllamaKeepAlive for Ollama-specific keep-alive
    handling
  • Simplified legacy API functions to delegate to unified core
    implementation
+98/-160
index.mjs
Unified background API execution routing                                 

src/background/index.mjs

  • Consolidated multiple provider-specific imports into single
    generateAnswersWithOpenAICompatibleApi call
  • Added isUsingOpenAICompatibleApiSession utility to route all
    OpenAI-compatible providers through unified handler
  • Removed individual provider execution branches for custom, Ollama,
    DeepSeek, Moonshot, ChatGLM, OpenRouter, and AIML APIs
+19/-68 
openai-compatible-core.mjs
OpenAI-compatible API core implementation                               

src/services/apis/openai-compatible-core.mjs

  • Created new core module with generateAnswersWithOpenAICompatible
    function handling both chat and completion endpoints
  • Implements unified request body construction, streaming response
    parsing, and message answer building
  • Supports legacy response field handling via allowLegacyResponseField
    parameter for backward compatibility
  • Centralizes token parameter handling and error management for all
    OpenAI-compatible providers
+160/-0 
model-name-convert.mjs
API mode normalization and comparison utilities                   

src/utils/model-name-convert.mjs

  • Added normalizeApiMode function to ensure consistent API mode object
    structure with default values
  • Updated apiModeToModelName and getApiModesFromConfig to use normalized
    API modes for safer property access
  • Enhanced isApiModeSelected comparison logic to normalize both sides
    before comparing relevant fields
+40/-5   
init-session.mjs
Session initialization API mode normalization                       

src/services/init-session.mjs

  • Added import of normalizeApiMode utility function
  • Applied normalizeApiMode to session initialization to ensure API mode
    objects have consistent structure
+6/-2     
custom-api.mjs
Consolidate custom API into unified OpenAI-compatible handler

src/services/apis/custom-api.mjs

  • Removed 84 lines of duplicated OpenAI-compatible API request logic
  • Replaced custom implementation with call to unified
    generateAnswersWithOpenAICompatible function
  • Simplified function to delegate to shared core with provider-specific
    parameters
+11/-92 
provider-secret-utils.mjs
Provider secret update utility for API modes                         

src/popup/sections/provider-secret-utils.mjs

  • New utility module with buildProviderSecretUpdate function for
    managing provider secrets
  • Handles both built-in and custom provider secret updates with legacy
    field support
  • Clears inherited mode-level keys matching old provider secrets
  • Syncs selected mode keys to new provider secret values
+78/-0   
api-modes-provider-utils.mjs
Provider configuration utilities for API modes UI               

src/popup/sections/api-modes-provider-utils.mjs

  • New utility module with helper functions for provider management in
    API modes UI
  • createProviderId generates unique normalized provider IDs avoiding
    conflicts
  • parseChatCompletionsEndpointUrl validates and parses chat completions
    endpoint URLs
  • resolveProviderChatEndpointUrl resolves endpoint URL from provider
    configuration
+79/-0   
wrappers.mjs
API mode normalization in port listener                                   

src/services/wrappers.mjs

  • Added import of normalizeApiMode function from model-name-convert
    utility
  • Added normalization of session.apiMode during port listener
    registration
  • Ensures API mode is normalized before processing in message handlers
+6/-1     
Tests
5 files
migrate-user-config.test.mjs
Configuration migration test suite                                             

tests/unit/config/migrate-user-config.test.mjs

  • Added 16 comprehensive test cases covering config migration scenarios
    including legacy URL/key consolidation, provider ID normalization, and
    deduplication
  • Tests validate migration of custom providers from legacy customUrl
    fields, secret key consolidation, and backward compatibility
  • Covers edge cases like trailing slashes in URLs, multiple modes with
    same URL but different keys, and schema version updates
+447/-0 
provider-registry.test.mjs
Provider registry resolution test suite                                   

tests/unit/services/apis/provider-registry.test.mjs

  • Added 8 test cases validating provider resolution logic including
    endpoint type detection and URL normalization
  • Tests cover custom provider resolution by normalized ID, legacy URL
    matching, and duplicate /v1 path prevention
  • Validates correct endpoint URL construction for OpenAI, Ollama, and
    custom providers
+161/-0 
provider-secret-utils.test.mjs
Unit tests for provider secret update logic                           

tests/unit/popup/provider-secret-utils.test.mjs

  • New test file with 114 lines covering the buildProviderSecretUpdate
    function
  • Tests validate provider secret updates for both built-in and custom
    providers
  • Tests verify clearing of inherited mode-level keys and syncing of
    selected mode keys
  • Tests ensure unrelated providers are not modified during secret
    updates
+114/-0 
api-modes-provider-utils.test.mjs
Unit tests for API modes provider utilities                           

tests/unit/popup/api-modes-provider-utils.test.mjs

  • New test file with 60 lines covering provider utility functions
  • Tests validate provider ID creation with conflict avoidance
  • Tests verify chat completions endpoint URL parsing and validation
  • Tests ensure endpoint URL resolution from provider base URL and path
+60/-0   
openai-api-compat.test.mjs
Stream completion signaling consistency tests                       

tests/unit/services/apis/openai-api-compat.test.mjs

  • Updated existing test to expect { answer: null, done: true, session }
    final message instead of { done: true }
  • Added new test case for fallback done message when stream ends without
    finish reason
  • New test verifies stream completion signaling consistency for
    incomplete streams
+39/-1   
Documentation
13 files
main.json
Japanese localization updates                                                       

src/_locales/ja/main.json

  • Added Japanese translations for Custom Provider and Provider UI labels
  • Added error message translation for Chat Completions URL validation
+3/-0     
main.json
Turkish localization updates                                                         

src/_locales/tr/main.json

  • Added Turkish translations for Custom Provider and Provider UI labels
  • Added error message translation for Chat Completions URL validation
+3/-0     
main.json
Traditional Chinese localization updates                                 

src/_locales/zh-hant/main.json

  • Added Traditional Chinese translations for Custom Provider and
    Provider UI labels
  • Added error message translation for Chat Completions URL validation
+3/-0     
main.json
Russian localization updates                                                         

src/_locales/ru/main.json

  • Added Russian translations for Custom Provider and Provider UI labels
  • Added error message translation for Chat Completions URL validation
+3/-0     
main.json
Italian localization updates                                                         

src/_locales/it/main.json

  • Added Italian translations for Custom Provider and Provider UI labels
  • Added error message translation for Chat Completions URL validation
+3/-0     
main.json
French localization updates                                                           

src/_locales/fr/main.json

  • Added French translations for Custom Provider and Provider UI labels
  • Added error message translation for Chat Completions URL validation
+3/-0     
main.json
German localization updates                                                           

src/_locales/de/main.json

  • Added German translations for Custom Provider and Provider UI labels
  • Added error message translation for Chat Completions URL validation
+3/-0     
main.json
Korean localization updates                                                           

src/_locales/ko/main.json

  • Added Korean translations for Custom Provider and Provider UI labels
  • Added error message translation for Chat Completions URL validation
+3/-0     
main.json
Spanish localization updates                                                         

src/_locales/es/main.json

  • Added Spanish translations for Custom Provider and Provider UI labels
  • Added error message translation for Chat Completions URL validation
+3/-0     
main.json
Indonesian localization updates                                                   

src/_locales/in/main.json

  • Added Indonesian translations for Custom Provider and Provider UI
    labels
  • Added error message translation for Chat Completions URL validation
+3/-0     
main.json
Portuguese localization updates                                                   

src/_locales/pt/main.json

  • Added Portuguese translations for Custom Provider and Provider UI
    labels
  • Added error message translation for Chat Completions URL validation
+3/-0     
main.json
Simplified Chinese localization updates                                   

src/_locales/zh-hans/main.json

  • Added Simplified Chinese translations for Custom Provider and Provider
    UI labels
  • Added error message translation for Chat Completions URL validation
+3/-0     
main.json
Localization strings for custom provider UI                           

src/_locales/en/main.json

  • Added new localization string "Custom Provider" for UI display
  • Added new localization string "Provider" for provider selection UI
  • Added new localization string "Please enter a full Chat Completions
    URL" for URL validation error message
+3/-0     
Configuration changes
1 files
openai-provider-mappings.mjs
Provider ID and legacy field mapping configuration             

src/config/openai-provider-mappings.mjs

  • New configuration mapping module with provider ID to legacy API key
    field mappings
  • Defines LEGACY_API_KEY_FIELD_BY_PROVIDER_ID for 8 built-in providers
  • Provides reverse mapping LEGACY_SECRET_KEY_TO_PROVIDER_ID for
    migration
  • Maps legacy group names to normalized provider IDs via
    OPENAI_COMPATIBLE_GROUP_TO_PROVIDER_ID
+30/-0   
Additional files
6 files
aiml-api.mjs +0/-12   
chatglm-api.mjs +0/-14   
deepseek-api.mjs +0/-12   
moonshot-api.mjs +0/-12   
ollama-api.mjs +0/-36   
openrouter-api.mjs +0/-12   

Summary by CodeRabbit

  • New Features

    • Provider manager UI: create/edit/select custom providers, choose provider per API mode, shared vs mode-specific API keys, provider delete-guarding, balance/check billing UI, provider-aware AI labels.
  • Refactor

    • Unified OpenAI‑compatible request/streaming flow and consolidated provider resolution; normalized API-mode/session shapes and provider-secret override/migration flows.
  • Chores

    • Automated migration to new provider/config schema and queued, resilient config persistence.
  • Tests

    • Broad unit-test expansion covering migrations, provider registry, streaming core, UI/provider flows, and secret override logic.

Open with Devin

Loading
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants