Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 7 additions & 4 deletions containers/api-proxy/providers/anthropic.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
* Body transforms: model alias rewriting + optional prompt-cache optimisations
*/

const { normalizeApiTarget, normalizeBasePath, composeBodyTransforms } = require('../proxy-utils');
const { composeBodyTransforms, createBaseAdapterConfig } = require('../proxy-utils');

let makeAnthropicTransform, loadCustomTransform, EXTENDED_CACHE_BETA;
try {
Expand All @@ -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');
Expand Down
11 changes: 7 additions & 4 deletions containers/api-proxy/providers/gemini.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
* Gemini SDK versions append alongside the header.
*/

const { normalizeApiTarget, normalizeBasePath, stripGeminiKeyParam } = require('../proxy-utils');
const { stripGeminiKeyParam, createBaseAdapterConfig } = require('../proxy-utils');

/**
* Create the Google Gemini provider adapter.
Expand All @@ -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;

Expand Down
11 changes: 7 additions & 4 deletions containers/api-proxy/providers/openai.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
* Base path: OPENAI_API_BASE_PATH (default: /v1 for the public endpoint)
*/

const { normalizeApiTarget, normalizeBasePath } = require('../proxy-utils');
const { createBaseAdapterConfig } = require('../proxy-utils');

/**
* Create the OpenAI provider adapter.
Expand All @@ -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.
Expand Down
24 changes: 24 additions & 0 deletions containers/api-proxy/proxy-utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -170,11 +170,35 @@ 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<string, string|undefined>} 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 };
Comment on lines +189 to +193
}

module.exports = {
normalizeApiTarget,
normalizeBasePath,
buildUpstreamPath,
stripGeminiKeyParam,
shouldStripHeader,
composeBodyTransforms,
createBaseAdapterConfig,
};
Loading