Merge pull request #1575 from walker1211/codex/fix-cliproxy-provider-routes

Fix CLIProxy provider routes for original backend
This commit is contained in:
Kai (Tam Nhu) Tran authored and GitHub committed 2026-06-22 16:11:28 -04:00
commit 05c203aff2
14 files changed
+451 -107

No files matched your search

+22 -3
View File
@@ -8,6 +8,8 @@ import {
resolveCliproxyBridgeProfile,
suggestCliproxyBridgeName,
} from '../../../src/api/services/cliproxy-profile-bridge';
import { invalidateConfigCache } from '../../../src/config/config-loader-facade';
import { clearConfigCache } from '../../../src/cliproxy/config/base-config-loader';
describe('cliproxy-profile-bridge', () => {
let tempHome = '';
@@ -17,6 +19,8 @@ describe('cliproxy-profile-bridge', () => {
tempHome = fs.mkdtempSync(path.join(os.tmpdir(), 'ccs-cliproxy-bridge-'));
originalCcsHome = process.env.CCS_HOME;
process.env.CCS_HOME = tempHome;
invalidateConfigCache();
clearConfigCache();
});
afterEach(() => {
@@ -25,18 +29,32 @@ describe('cliproxy-profile-bridge', () => {
} else {
process.env.CCS_HOME = originalCcsHome;
}
invalidateConfigCache();
clearConfigCache();
if (tempHome && fs.existsSync(tempHome)) {
fs.rmSync(tempHome, { recursive: true, force: true });
}
});
it('resolves routed profile payload for a local CLIProxy provider', () => {
function writeBackendConfig(backend: 'original' | 'plus'): void {
const ccsDir = path.join(tempHome, '.ccs');
fs.mkdirSync(ccsDir, { recursive: true });
fs.writeFileSync(
path.join(ccsDir, 'config.yaml'),
['version: 1', 'cliproxy:', ` backend: ${backend}`, ''].join('\n'),
'utf8'
);
invalidateConfigCache();
clearConfigCache();
}
it('resolves routed profile payload for a local original-backend CLIProxy provider', () => {
const bridge = resolveCliproxyBridgeProfile('gemini');
expect(bridge.name).toBe('gemini-api');
expect(bridge.baseUrl).toBe('http://127.0.0.1:8317/api/provider/gemini');
expect(bridge.routePath).toBe('/api/provider/gemini');
expect(bridge.baseUrl).toBe('http://127.0.0.1:8317/');
expect(bridge.routePath).toBe('/');
expect(bridge.models.default.length).toBeGreaterThan(0);
});
@@ -49,6 +67,7 @@ describe('cliproxy-profile-bridge', () => {
});
it('detects CLIProxy-backed profile metadata and normalizes localhost loopback URLs', () => {
writeBackendConfig('plus');
const metadata = resolveCliproxyBridgeMetadata({
env: {
ANTHROPIC_BASE_URL: 'http://localhost:8317/api/provider/gemini',
@@ -6,24 +6,61 @@ import {
buildCodexCliproxyProviderBaseUrl,
ensureCodexCliproxyProviderConfig,
} from '../../../src/targets/codex-cliproxy-provider-config';
import { invalidateConfigCache } from '../../../src/config/config-loader-facade';
import { clearConfigCache } from '../../../src/cliproxy/config/base-config-loader';
describe('codex cliproxy provider config repair', () => {
let tempHome: string;
let codexHome: string;
let configPath: string;
let env: NodeJS.ProcessEnv;
let originalCcsHome: string | undefined;
beforeEach(() => {
originalCcsHome = process.env.CCS_HOME;
tempHome = fs.mkdtempSync(path.join(os.tmpdir(), 'ccs-codex-provider-config-'));
codexHome = path.join(tempHome, '.codex');
configPath = path.join(codexHome, 'config.toml');
env = { CODEX_HOME: codexHome } as NodeJS.ProcessEnv;
process.env.CCS_HOME = tempHome;
invalidateConfigCache();
clearConfigCache();
});
afterEach(() => {
if (originalCcsHome !== undefined) {
process.env.CCS_HOME = originalCcsHome;
} else {
delete process.env.CCS_HOME;
}
invalidateConfigCache();
clearConfigCache();
fs.rmSync(tempHome, { recursive: true, force: true });
});
function writeBackendConfig(backend: 'original' | 'plus'): void {
const ccsDir = path.join(tempHome, '.ccs');
fs.mkdirSync(ccsDir, { recursive: true });
fs.writeFileSync(
path.join(ccsDir, 'config.yaml'),
['version: 1', 'cliproxy:', ` backend: ${backend}`, ''].join('\n'),
'utf8'
);
invalidateConfigCache();
clearConfigCache();
}
it('uses the original backend root URL by default', () => {
expect(buildCodexCliproxyProviderBaseUrl(8317)).toBe('http://127.0.0.1:8317');
});
it('uses the plus backend scoped Codex URL when configured', () => {
writeBackendConfig('plus');
expect(buildCodexCliproxyProviderBaseUrl(8317)).toBe(
'http://127.0.0.1:8317/api/provider/codex'
);
});
it('creates the cliproxy model provider when config.toml is missing', async () => {
const result = await ensureCodexCliproxyProviderConfig(8317, env);
@@ -32,6 +69,7 @@ describe('codex cliproxy provider config repair', () => {
const rawText = fs.readFileSync(configPath, 'utf8');
expect(rawText).toContain('[model_providers.cliproxy]');
expect(rawText).toContain('name = "CLIProxy Codex"');
expect(rawText).toContain('base_url = "http://127.0.0.1:8317"');
expect(rawText).toContain('env_key = "CLIPROXY_API_KEY"');
expect(rawText).not.toContain('model_provider = "cliproxy"');
});
@@ -78,7 +116,7 @@ wire_api = "responses"
expect(result.changed).toBe(true);
expect(result.envKey).toBe('CLIPROXY_API_KEY');
const rawText = fs.readFileSync(configPath, 'utf8');
expect(rawText).toContain('base_url = "http://localhost:8317/api/provider/codex"');
expect(rawText).toContain('base_url = "http://127.0.0.1:9321"');
expect(rawText).toContain('env_key = "CLIPROXY_API_KEY"');
expect(rawText).toContain('requires_openai_auth = false');
expect(rawText).toContain('supports_websockets = false');
@@ -142,7 +180,29 @@ supports_websockets = false
expect(fs.readFileSync(configPath, 'utf8')).toBe(rawText);
});
it('leaves a ready localhost provider unchanged', async () => {
it('repairs a stale ready localhost provider to the original backend root URL', async () => {
fs.mkdirSync(codexHome, { recursive: true });
const rawText = `[model_providers.cliproxy]
name = "CLIProxy Codex"
base_url = "http://localhost:8317/api/provider/codex"
env_key = "CLIPROXY_API_KEY"
wire_api = "responses"
requires_openai_auth = false
supports_websockets = false
`;
fs.writeFileSync(configPath, rawText, 'utf8');
const result = await ensureCodexCliproxyProviderConfig(8317, env);
expect(result.changed).toBe(true);
expect(result.envKey).toBe('CLIPROXY_API_KEY');
const repairedText = fs.readFileSync(configPath, 'utf8');
expect(repairedText).toContain('base_url = "http://127.0.0.1:8317"');
expect(repairedText).not.toContain('/api/provider/codex');
});
it('leaves a ready plus-backend localhost provider unchanged', async () => {
writeBackendConfig('plus');
fs.mkdirSync(codexHome, { recursive: true });
const rawText = `[model_providers.cliproxy]
name = "CLIProxy Codex"
@@ -188,7 +248,7 @@ supports_websockets = false
[model_providers.cliproxy]
name = "CLIProxy Codex"
base_url = "http://localhost:8317/api/provider/codex"
base_url = "http://127.0.0.1:8317"
env_key = "CLIPROXY_API_KEY"
wire_api = "responses"
requires_openai_auth = false
@@ -239,7 +299,7 @@ supports_websockets = false
[model_providers.cliproxy]
name = "CLIProxy Codex"
base_url = "http://localhost:8317/api/provider/codex"
base_url = "http://127.0.0.1:8317"
env_key = "CLIPROXY_API_KEY"
wire_api = "responses"
requires_openai_auth = false
+33 -2
View File
@@ -1,9 +1,12 @@
import { afterEach, describe, expect, it } from 'bun:test';
import { afterEach, beforeEach, describe, expect, it } from 'bun:test';
import { mkdtempSync, rmSync } from 'node:fs';
import { tmpdir } from 'node:os';
import { join } from 'node:path';
import type { UnifiedConfig } from '../../../../src/config/unified-config-types';
import { runBrowserSetup, type BrowserSetupDeps } from '../../../../src/utils/browser/browser-setup';
import {
runBrowserSetup,
type BrowserSetupDeps,
} from '../../../../src/utils/browser/browser-setup';
function createUnifiedConfig(userDataDir: string): UnifiedConfig {
return {
@@ -96,8 +99,36 @@ function createUnifiedConfig(userDataDir: string): UnifiedConfig {
describe('browser setup', () => {
let tempDir = '';
let originalBrowserUserDataDir: string | undefined;
let originalBrowserProfileDir: string | undefined;
let originalBrowserDevtoolsPort: string | undefined;
beforeEach(() => {
originalBrowserUserDataDir = process.env.CCS_BROWSER_USER_DATA_DIR;
originalBrowserProfileDir = process.env.CCS_BROWSER_PROFILE_DIR;
originalBrowserDevtoolsPort = process.env.CCS_BROWSER_DEVTOOLS_PORT;
delete process.env.CCS_BROWSER_USER_DATA_DIR;
delete process.env.CCS_BROWSER_PROFILE_DIR;
delete process.env.CCS_BROWSER_DEVTOOLS_PORT;
});
afterEach(() => {
if (originalBrowserUserDataDir !== undefined) {
process.env.CCS_BROWSER_USER_DATA_DIR = originalBrowserUserDataDir;
} else {
delete process.env.CCS_BROWSER_USER_DATA_DIR;
}
if (originalBrowserProfileDir !== undefined) {
process.env.CCS_BROWSER_PROFILE_DIR = originalBrowserProfileDir;
} else {
delete process.env.CCS_BROWSER_PROFILE_DIR;
}
if (originalBrowserDevtoolsPort !== undefined) {
process.env.CCS_BROWSER_DEVTOOLS_PORT = originalBrowserDevtoolsPort;
} else {
delete process.env.CCS_BROWSER_DEVTOOLS_PORT;
}
if (tempDir) {
rmSync(tempDir, { recursive: true, force: true });
tempDir = '';
@@ -5,6 +5,8 @@ import * as os from 'os';
import * as path from 'path';
import type { Server } from 'http';
import profileRoutes from '../../../src/web-server/routes/profile-routes';
import { invalidateConfigCache } from '../../../src/config/config-loader-facade';
import { clearConfigCache } from '../../../src/cliproxy/config/base-config-loader';
describe('profile-routes cliproxy bridge', () => {
let server: Server;
@@ -42,6 +44,8 @@ describe('profile-routes cliproxy bridge', () => {
tempHome = fs.mkdtempSync(path.join(os.tmpdir(), 'ccs-profile-routes-cliproxy-bridge-'));
originalCcsHome = process.env.CCS_HOME;
process.env.CCS_HOME = tempHome;
invalidateConfigCache();
clearConfigCache();
});
afterEach(() => {
@@ -50,6 +54,8 @@ describe('profile-routes cliproxy bridge', () => {
} else {
delete process.env.CCS_HOME;
}
invalidateConfigCache();
clearConfigCache();
if (tempHome && fs.existsSync(tempHome)) {
fs.rmSync(tempHome, { recursive: true, force: true });