mirror of
https://github.com/tiennm99/ccs.git
synced 2026-09-02 12:19:35 +00:00
Merge pull request #161 from kaitranntt/kai/feat/remote-proxy-config
fix(cliproxy): use /v1/models for remote proxy health check
This commit is contained in:
@@ -48,9 +48,10 @@ const DEFAULT_TIMEOUT_MS = 2000;
|
||||
|
||||
/**
|
||||
* Get default port for protocol
|
||||
* HTTP defaults to 8317 (CLIProxyAPI default), HTTPS to 443 (standard SSL)
|
||||
*/
|
||||
function getDefaultPort(protocol: 'http' | 'https'): number {
|
||||
return protocol === 'https' ? 443 : 80;
|
||||
return protocol === 'https' ? 443 : 8317;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -139,6 +140,9 @@ function createHttpsAgent(allowSelfSigned: boolean): https.Agent | undefined {
|
||||
/**
|
||||
* Check health of remote CLIProxyAPI instance
|
||||
*
|
||||
* Uses /v1/models endpoint for health check since CLIProxyAPI doesn't expose /health.
|
||||
* This endpoint is always available and returns 200 when the server is operational.
|
||||
*
|
||||
* @param config Remote proxy client configuration
|
||||
* @returns RemoteProxyStatus with reachability and latency
|
||||
*/
|
||||
@@ -157,8 +161,8 @@ export async function checkRemoteProxy(
|
||||
};
|
||||
}
|
||||
|
||||
// Use smart URL building - omit port if it's the default for the protocol
|
||||
const url = buildProxyUrl(host, port, protocol, '/health');
|
||||
// Use /v1/models as health check - CLIProxyAPI doesn't have /health endpoint
|
||||
const url = buildProxyUrl(host, port, protocol, '/v1/models');
|
||||
const startTime = Date.now();
|
||||
|
||||
try {
|
||||
|
||||
@@ -105,14 +105,15 @@ describe('remote-proxy-client', () => {
|
||||
});
|
||||
|
||||
describe('health check URL construction', () => {
|
||||
it('should construct correct health check URL pattern', () => {
|
||||
// CLIProxyAPI uses /v1/models for health checks (no /health endpoint)
|
||||
it('should construct correct health check URL pattern using /v1/models', () => {
|
||||
const config: RemoteProxyClientConfig = {
|
||||
host: '192.168.1.100',
|
||||
port: 8317,
|
||||
protocol: 'http',
|
||||
};
|
||||
const expectedUrl = `${config.protocol}://${config.host}:${config.port}/health`;
|
||||
expect(expectedUrl).toBe('http://192.168.1.100:8317/health');
|
||||
const expectedUrl = `${config.protocol}://${config.host}:${config.port}/v1/models`;
|
||||
expect(expectedUrl).toBe('http://192.168.1.100:8317/v1/models');
|
||||
});
|
||||
|
||||
it('should construct HTTPS URL when protocol is https', () => {
|
||||
@@ -121,8 +122,8 @@ describe('remote-proxy-client', () => {
|
||||
port: 443,
|
||||
protocol: 'https',
|
||||
};
|
||||
const expectedUrl = `${config.protocol}://${config.host}:${config.port}/health`;
|
||||
expect(expectedUrl).toBe('https://secure.example.com:443/health');
|
||||
const expectedUrl = `${config.protocol}://${config.host}:${config.port}/v1/models`;
|
||||
expect(expectedUrl).toBe('https://secure.example.com:443/v1/models');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
+36
-33
@@ -1322,7 +1322,8 @@ function ProxyContent({
|
||||
const defaultLocal = { port: 8317, auto_start: true };
|
||||
|
||||
// Helper to get default port based on protocol
|
||||
const getDefaultPort = (protocol: 'http' | 'https') => (protocol === 'https' ? 443 : 80);
|
||||
// HTTP defaults to 8317 (CLIProxyAPI default), HTTPS to 443 (standard SSL)
|
||||
const getDefaultPort = (protocol: 'http' | 'https') => (protocol === 'https' ? 443 : 8317);
|
||||
|
||||
// Sync local state with config (using refs to avoid lint warnings)
|
||||
const hostInput = config?.remote.host ?? '';
|
||||
@@ -1650,42 +1651,44 @@ function ProxyContent({
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Local Proxy Settings */}
|
||||
<div className="space-y-3">
|
||||
<h3 className="text-base font-medium">Local Proxy</h3>
|
||||
<div className="space-y-3 p-4 rounded-lg border bg-muted/30">
|
||||
{/* Port */}
|
||||
<div className="space-y-1">
|
||||
<label className="text-sm text-muted-foreground">Port</label>
|
||||
<Input
|
||||
type="number"
|
||||
value={displayLocalPort}
|
||||
onChange={(e) => setEditedLocalPort(e.target.value)}
|
||||
onBlur={saveLocalPort}
|
||||
placeholder="8317"
|
||||
className="font-mono max-w-32"
|
||||
disabled={saving}
|
||||
/>
|
||||
</div>
|
||||
{/* Local Proxy Settings - Only show in Local mode */}
|
||||
{!isRemoteMode && (
|
||||
<div className="space-y-3">
|
||||
<h3 className="text-base font-medium">Local Proxy</h3>
|
||||
<div className="space-y-3 p-4 rounded-lg border bg-muted/30">
|
||||
{/* Port */}
|
||||
<div className="space-y-1">
|
||||
<label className="text-sm text-muted-foreground">Port</label>
|
||||
<Input
|
||||
type="number"
|
||||
value={displayLocalPort}
|
||||
onChange={(e) => setEditedLocalPort(e.target.value)}
|
||||
onBlur={saveLocalPort}
|
||||
placeholder="8317"
|
||||
className="font-mono max-w-32"
|
||||
disabled={saving}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Auto-start */}
|
||||
<div className="flex items-center justify-between">
|
||||
<div>
|
||||
<p className="font-medium text-sm">Auto-start</p>
|
||||
<p className="text-xs text-muted-foreground">
|
||||
Start local proxy automatically when needed
|
||||
</p>
|
||||
{/* Auto-start */}
|
||||
<div className="flex items-center justify-between">
|
||||
<div>
|
||||
<p className="font-medium text-sm">Auto-start</p>
|
||||
<p className="text-xs text-muted-foreground">
|
||||
Start local proxy automatically when needed
|
||||
</p>
|
||||
</div>
|
||||
<Switch
|
||||
checked={config?.local.auto_start ?? true}
|
||||
onCheckedChange={(checked) =>
|
||||
saveCliproxyServerConfig({ local: { ...localConfig, auto_start: checked } })
|
||||
}
|
||||
disabled={saving}
|
||||
/>
|
||||
</div>
|
||||
<Switch
|
||||
checked={config?.local.auto_start ?? true}
|
||||
onCheckedChange={(checked) =>
|
||||
saveCliproxyServerConfig({ local: { ...localConfig, auto_start: checked } })
|
||||
}
|
||||
disabled={saving}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</ScrollArea>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user