From 4d386a05ce8a4ddd98f8012bd474daab77affb73 Mon Sep 17 00:00:00 2001 From: Landon Cox Date: Mon, 4 May 2026 07:49:08 -0700 Subject: [PATCH 1/2] refactor: extract createBaseAdapterConfig helper Extract the repeated API-key/target/base-path initialization pattern from openai.js, anthropic.js, and gemini.js into a shared createBaseAdapterConfig() helper in proxy-utils.js. Closes #2479 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- containers/api-proxy/providers/anthropic.js | 11 ++++++---- containers/api-proxy/providers/gemini.js | 11 ++++++---- containers/api-proxy/providers/openai.js | 11 ++++++---- containers/api-proxy/proxy-utils.js | 24 +++++++++++++++++++++ 4 files changed, 45 insertions(+), 12 deletions(-) diff --git a/containers/api-proxy/providers/anthropic.js b/containers/api-proxy/providers/anthropic.js index b7f7d73a..d285180c 100644 --- a/containers/api-proxy/providers/anthropic.js +++ b/containers/api-proxy/providers/anthropic.js @@ -11,7 +11,7 @@ * Body transforms: model alias rewriting + optional prompt-cache optimisations */ -const { normalizeApiTarget, normalizeBasePath, composeBodyTransforms } = require('../proxy-utils'); +const { normalizeApiTarget, normalizeBasePath, composeBodyTransforms, createBaseAdapterConfig } = require('../proxy-utils'); let makeAnthropicTransform, loadCustomTransform, EXTENDED_CACHE_BETA; try { @@ -34,9 +34,12 @@ try { * @returns {import('./index').ProviderAdapter} */ function createAnthropicAdapter(env, deps = {}) { - const apiKey = (env.ANTHROPIC_API_KEY || '').trim() || undefined; - const rawTarget = normalizeApiTarget(env.ANTHROPIC_API_TARGET) || 'api.anthropic.com'; - const basePath = normalizeBasePath(env.ANTHROPIC_API_BASE_PATH); + const { apiKey, rawTarget, basePath } = createBaseAdapterConfig(env, { + keyEnvVar: 'ANTHROPIC_API_KEY', + targetEnvVar: 'ANTHROPIC_API_TARGET', + basePathEnvVar: 'ANTHROPIC_API_BASE_PATH', + defaultTarget: 'api.anthropic.com', + }); // ── Anthropic-specific optimisations ────────────────────────────────────── const autoCache = (env.AWF_ANTHROPIC_AUTO_CACHE === '1' || env.AWF_ANTHROPIC_AUTO_CACHE === 'true'); diff --git a/containers/api-proxy/providers/gemini.js b/containers/api-proxy/providers/gemini.js index 344de5e5..2e23b18c 100644 --- a/containers/api-proxy/providers/gemini.js +++ b/containers/api-proxy/providers/gemini.js @@ -13,7 +13,7 @@ * Gemini SDK versions append alongside the header. */ -const { normalizeApiTarget, normalizeBasePath, stripGeminiKeyParam } = require('../proxy-utils'); +const { normalizeApiTarget, normalizeBasePath, stripGeminiKeyParam, createBaseAdapterConfig } = require('../proxy-utils'); /** * Create the Google Gemini provider adapter. @@ -23,9 +23,12 @@ const { normalizeApiTarget, normalizeBasePath, stripGeminiKeyParam } = require(' * @returns {import('./index').ProviderAdapter} */ function createGeminiAdapter(env, deps = {}) { - const apiKey = (env.GEMINI_API_KEY || '').trim() || undefined; - const rawTarget = normalizeApiTarget(env.GEMINI_API_TARGET) || 'generativelanguage.googleapis.com'; - const basePath = normalizeBasePath(env.GEMINI_API_BASE_PATH); + const { apiKey, rawTarget, basePath } = createBaseAdapterConfig(env, { + keyEnvVar: 'GEMINI_API_KEY', + targetEnvVar: 'GEMINI_API_TARGET', + basePathEnvVar: 'GEMINI_API_BASE_PATH', + defaultTarget: 'generativelanguage.googleapis.com', + }); const bodyTransform = deps.bodyTransform || null; diff --git a/containers/api-proxy/providers/openai.js b/containers/api-proxy/providers/openai.js index 6332de8d..1b13d118 100644 --- a/containers/api-proxy/providers/openai.js +++ b/containers/api-proxy/providers/openai.js @@ -10,7 +10,7 @@ * Base path: OPENAI_API_BASE_PATH (default: /v1 for the public endpoint) */ -const { normalizeApiTarget, normalizeBasePath } = require('../proxy-utils'); +const { normalizeApiTarget, normalizeBasePath, createBaseAdapterConfig } = require('../proxy-utils'); /** * Create the OpenAI provider adapter. @@ -20,9 +20,12 @@ const { normalizeApiTarget, normalizeBasePath } = require('../proxy-utils'); * @returns {import('./index').ProviderAdapter} */ function createOpenAIAdapter(env, deps = {}) { - const apiKey = (env.OPENAI_API_KEY || '').trim() || undefined; - const rawTarget = normalizeApiTarget(env.OPENAI_API_TARGET) || 'api.openai.com'; - const explicitBasePath = normalizeBasePath(env.OPENAI_API_BASE_PATH); + const { apiKey, rawTarget, basePath: explicitBasePath } = createBaseAdapterConfig(env, { + keyEnvVar: 'OPENAI_API_KEY', + targetEnvVar: 'OPENAI_API_TARGET', + basePathEnvVar: 'OPENAI_API_BASE_PATH', + defaultTarget: 'api.openai.com', + }); // For the default OpenAI endpoint, unversioned clients (e.g. Codex CLI sending // /responses) need a /v1 prefix to reach the correct versioned API surface. diff --git a/containers/api-proxy/proxy-utils.js b/containers/api-proxy/proxy-utils.js index afd94553..c511c105 100644 --- a/containers/api-proxy/proxy-utils.js +++ b/containers/api-proxy/proxy-utils.js @@ -170,6 +170,29 @@ function composeBodyTransforms(first, second) { }; } +/** + * Extract common adapter configuration from environment variables. + * + * Every non-Copilot adapter repeats the same three-line pattern to read + * an API key, normalize a target hostname, and normalize a base path. + * This helper centralizes that logic so each adapter only specifies env + * var names and a default target. + * + * @param {Record} env - Environment variables + * @param {object} opts + * @param {string} opts.keyEnvVar - e.g. 'OPENAI_API_KEY' + * @param {string} opts.targetEnvVar - e.g. 'OPENAI_API_TARGET' + * @param {string} opts.basePathEnvVar - e.g. 'OPENAI_API_BASE_PATH' + * @param {string} opts.defaultTarget - e.g. 'api.openai.com' + * @returns {{ apiKey: string|undefined, rawTarget: string, basePath: string }} + */ +function createBaseAdapterConfig(env, { keyEnvVar, targetEnvVar, basePathEnvVar, defaultTarget }) { + const apiKey = (env[keyEnvVar] || '').trim() || undefined; + const rawTarget = normalizeApiTarget(env[targetEnvVar]) || defaultTarget; + const basePath = normalizeBasePath(env[basePathEnvVar]); + return { apiKey, rawTarget, basePath }; +} + module.exports = { normalizeApiTarget, normalizeBasePath, @@ -177,4 +200,5 @@ module.exports = { stripGeminiKeyParam, shouldStripHeader, composeBodyTransforms, + createBaseAdapterConfig, }; From 1518f873624c69a07faa5ce03d406a653aab1d57 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 4 May 2026 14:59:29 +0000 Subject: [PATCH 2/2] fix: remove unused normalizeApiTarget/normalizeBasePath imports --- containers/api-proxy/providers/anthropic.js | 2 +- containers/api-proxy/providers/gemini.js | 2 +- containers/api-proxy/providers/openai.js | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/containers/api-proxy/providers/anthropic.js b/containers/api-proxy/providers/anthropic.js index d285180c..1c482eab 100644 --- a/containers/api-proxy/providers/anthropic.js +++ b/containers/api-proxy/providers/anthropic.js @@ -11,7 +11,7 @@ * Body transforms: model alias rewriting + optional prompt-cache optimisations */ -const { normalizeApiTarget, normalizeBasePath, composeBodyTransforms, createBaseAdapterConfig } = require('../proxy-utils'); +const { composeBodyTransforms, createBaseAdapterConfig } = require('../proxy-utils'); let makeAnthropicTransform, loadCustomTransform, EXTENDED_CACHE_BETA; try { diff --git a/containers/api-proxy/providers/gemini.js b/containers/api-proxy/providers/gemini.js index 2e23b18c..b08763a7 100644 --- a/containers/api-proxy/providers/gemini.js +++ b/containers/api-proxy/providers/gemini.js @@ -13,7 +13,7 @@ * Gemini SDK versions append alongside the header. */ -const { normalizeApiTarget, normalizeBasePath, stripGeminiKeyParam, createBaseAdapterConfig } = require('../proxy-utils'); +const { stripGeminiKeyParam, createBaseAdapterConfig } = require('../proxy-utils'); /** * Create the Google Gemini provider adapter. diff --git a/containers/api-proxy/providers/openai.js b/containers/api-proxy/providers/openai.js index 1b13d118..8df7bac9 100644 --- a/containers/api-proxy/providers/openai.js +++ b/containers/api-proxy/providers/openai.js @@ -10,7 +10,7 @@ * Base path: OPENAI_API_BASE_PATH (default: /v1 for the public endpoint) */ -const { normalizeApiTarget, normalizeBasePath, createBaseAdapterConfig } = require('../proxy-utils'); +const { createBaseAdapterConfig } = require('../proxy-utils'); /** * Create the OpenAI provider adapter.