diff --git a/screenshots/provider-responses-editor.png b/screenshots/provider-responses-editor.png new file mode 100644 index 000000000..4c1cb85b1 Binary files /dev/null and b/screenshots/provider-responses-editor.png differ diff --git a/src/_locales/en/main.json b/src/_locales/en/main.json index 445148a56..99a160c92 100644 --- a/src/_locales/en/main.json +++ b/src/_locales/en/main.json @@ -125,6 +125,18 @@ "The temperature parameter is not sent. The provider or model default is used.": "The temperature parameter is not sent. The provider or model default is used.", "The current model does not accept a custom temperature. The parameter will not be sent.": "The current model does not accept a custom temperature. The parameter will not be sent.", "API Url": "API Url", + "API Protocol": "API Protocol", + "Chat Completions URL": "Chat Completions URL", + "Responses URL": "Responses URL", + "Default protocol": "Default protocol", + "Use the global OpenAI setting where applicable; otherwise use Chat Completions.": "Use the global OpenAI setting where applicable; otherwise use Chat Completions.", + "Optional when Responses has an explicit URL.": "Optional when Responses has an explicit URL.", + "Leave empty to derive from the Chat Completions URL.": "Leave empty to derive from the Chat Completions URL.", + "Please enter a valid HTTP(S) Responses URL": "Please enter a valid HTTP(S) Responses URL", + "Chat Completions": "Chat Completions", + "Responses": "Responses", + "OpenAI API Protocol": "OpenAI API Protocol", + "Use Responses API (Azure preview)": "Use Responses API (Azure preview)", "Provider": "Provider", "Others": "Others", "API Modes": "API Modes", diff --git a/src/config/index.mjs b/src/config/index.mjs index 6267ef67c..94d6af771 100644 --- a/src/config/index.mjs +++ b/src/config/index.mjs @@ -19,6 +19,7 @@ import { canonicalizeModelKeyArray, } from './model-key-migrations.mjs' import { getNavigatorLanguage, resolvePreferredLanguageKey } from './language-data.mjs' +import { normalizeExplicitApiProtocol } from '../services/apis/provider-registry.mjs' export { getNavigatorLanguage } @@ -842,6 +843,8 @@ export const defaultConfig = { customChatGptWebApiUrl: 'https://chatgpt.com', customChatGptWebApiPath: '/backend-api/conversation', customOpenAiApiUrl: 'https://api.openai.com', + openaiApiProtocol: 'chat', + azureUseResponses: false, customAnthropicApiUrl: 'https://api.anthropic.com', disableWebModeHistory: true, hideContextMenu: false, @@ -1165,10 +1168,14 @@ function normalizeCustomProviderForStorage(provider, index, providerIdSet) { ) const completionsPath = ensureLeadingSlash(provider.completionsPath, '/v1/completions') const normalizedLegacyProviderIds = legacyProviderIds.length > 0 ? legacyProviderIds : undefined + const apiProtocol = normalizeExplicitApiProtocol(provider.apiProtocol) + const responsesUrl = normalizeText(provider.responsesUrl) const storageShapeChanged = (normalizeText(provider.chatCompletionsPath) || '/v1/chat/completions') !== chatCompletionsPath || (normalizeText(provider.completionsPath) || '/v1/completions') !== completionsPath || + provider.apiProtocol !== (apiProtocol || undefined) || + provider.responsesUrl !== (responsesUrl || undefined) || JSON.stringify(provider.legacyProviderIds) !== JSON.stringify(normalizedLegacyProviderIds) return { originalId, @@ -1186,6 +1193,8 @@ function normalizeCustomProviderForStorage(provider, index, providerIdSet) { completionsUrl: normalizeText(provider.completionsUrl), enabled: provider.enabled !== false, allowLegacyResponseField: provider.allowLegacyResponseField !== false, + ...(apiProtocol ? { apiProtocol } : {}), + ...(responsesUrl ? { responsesUrl } : {}), ...(sourceProviderId ? { sourceProviderId } : {}), ...(normalizedLegacyProviderIds ? { legacyProviderIds: normalizedLegacyProviderIds } : {}), }, diff --git a/src/popup/sections/AdvancedPart.jsx b/src/popup/sections/AdvancedPart.jsx index 017b9191f..38351bcb5 100644 --- a/src/popup/sections/AdvancedPart.jsx +++ b/src/popup/sections/AdvancedPart.jsx @@ -136,6 +136,20 @@ function ApiUrl({ config, updateConfig }) { }} /> +