diff --git a/package.json b/package.json index 0f240e73..0c0c9774 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@kaitranntt/ccs", - "version": "7.74.0-dev.16", + "version": "7.74.0-dev.17", "description": "Claude Code Switch - Instant profile switching between Claude, GLM, Kimi, and more", "keywords": [ "cli", diff --git a/src/cliproxy/management-api-client.ts b/src/cliproxy/management-api-client.ts index dc9de153..f7d5c9d7 100644 --- a/src/cliproxy/management-api-client.ts +++ b/src/cliproxy/management-api-client.ts @@ -20,6 +20,7 @@ import type { CliproxyRoutingStrategy } from './types'; /** Default timeout for management operations (longer than health check) */ const DEFAULT_TIMEOUT_MS = 5000; +const ROUTING_STRATEGY_PATH = '/v0/management/routing/strategy'; /** Default port for HTTPS protocol */ const DEFAULT_HTTPS_PORT = 443; @@ -232,7 +233,7 @@ export class ManagementApiClient { * Get the global credential routing strategy from CLIProxy. */ async getRoutingStrategy(): Promise { - const response = await this.request<{ strategy?: string }>('GET', '/routing/strategy'); + const response = await this.request<{ strategy?: string }>('GET', ROUTING_STRATEGY_PATH); return response.data?.strategy === 'fill-first' ? 'fill-first' : 'round-robin'; } @@ -240,7 +241,7 @@ export class ManagementApiClient { * Update the global credential routing strategy on CLIProxy. */ async putRoutingStrategy(strategy: CliproxyRoutingStrategy): Promise { - await this.request('PUT', '/routing/strategy', { value: strategy }); + await this.request('PUT', ROUTING_STRATEGY_PATH, { value: strategy }); return strategy; } diff --git a/src/cliproxy/routing-strategy-http.ts b/src/cliproxy/routing-strategy-http.ts index 33d7b070..81eeb558 100644 --- a/src/cliproxy/routing-strategy-http.ts +++ b/src/cliproxy/routing-strategy-http.ts @@ -7,13 +7,18 @@ import { } from './proxy-target-resolver'; const ROUTING_TIMEOUT_MS = 5000; +const CLIPROXY_ROUTING_MANAGEMENT_PATH = '/v0/management/routing/strategy'; + +export function getCliproxyRoutingManagementUrl(target: ProxyTarget): string { + return buildProxyUrl(target, CLIPROXY_ROUTING_MANAGEMENT_PATH); +} export async function fetchCliproxyRoutingResponse( target: ProxyTarget, method: 'GET' | 'PUT', body?: Record ): Promise { - const url = buildProxyUrl(target, '/routing/strategy'); + const url = getCliproxyRoutingManagementUrl(target); const headers = buildManagementHeaders( target, body ? { 'Content-Type': 'application/json' } : {} diff --git a/tests/unit/cliproxy/management-api-client.test.ts b/tests/unit/cliproxy/management-api-client.test.ts index 12641a25..df498534 100644 --- a/tests/unit/cliproxy/management-api-client.test.ts +++ b/tests/unit/cliproxy/management-api-client.test.ts @@ -128,7 +128,7 @@ describe('management-api-client', () => { expect(strategy).toBe('round-robin'); expect(fetchMock).toHaveBeenCalledWith( - 'http://localhost:8317/routing/strategy', + 'http://localhost:8317/v0/management/routing/strategy', expect.objectContaining({ method: 'PUT', body: JSON.stringify({ value: 'round-robin' }), diff --git a/tests/unit/cliproxy/routing-strategy-http.test.ts b/tests/unit/cliproxy/routing-strategy-http.test.ts new file mode 100644 index 00000000..6a3e9463 --- /dev/null +++ b/tests/unit/cliproxy/routing-strategy-http.test.ts @@ -0,0 +1,32 @@ +import { describe, expect, it } from 'bun:test'; +import { getCliproxyRoutingManagementUrl } from '../../../src/cliproxy/routing-strategy-http'; +import type { ProxyTarget } from '../../../src/cliproxy/proxy-target-resolver'; + +describe('routing-strategy-http', () => { + it('builds the local management URL for routing strategy reads', () => { + const target: ProxyTarget = { + host: '127.0.0.1', + port: 8317, + protocol: 'http', + isRemote: false, + }; + + expect(getCliproxyRoutingManagementUrl(target)).toBe( + 'http://127.0.0.1:8317/v0/management/routing/strategy' + ); + }); + + it('builds the remote management URL for routing strategy writes', () => { + const target: ProxyTarget = { + host: 'proxy.example.com', + port: 443, + protocol: 'https', + allowSelfSigned: true, + isRemote: true, + }; + + expect(getCliproxyRoutingManagementUrl(target)).toBe( + 'https://proxy.example.com:443/v0/management/routing/strategy' + ); + }); +});