mirror of
https://github.com/tiennm99/ccs.git
synced 2026-07-20 04:17:37 +00:00
- let applyDefaultPreset accept a caller-provided provider catalog - pass cached catalog data from cliproxy and quick-setup flows - add regression coverage for skipping the extra catalog fetch
105 lines
3.3 KiB
TypeScript
105 lines
3.3 KiB
TypeScript
/**
|
|
* Preset Utilities
|
|
* Shared functions for applying default presets to provider settings
|
|
*/
|
|
|
|
import type { CliproxyProviderCatalog } from './api-client';
|
|
import { MODEL_CATALOGS } from './model-catalogs';
|
|
import { buildUiCatalogs } from './model-catalogs';
|
|
import { CLIPROXY_DEFAULT_PORT } from './default-ports';
|
|
export { CLIPROXY_DEFAULT_PORT } from './default-ports';
|
|
|
|
/** Default fallback API key if fetch fails */
|
|
const DEFAULT_API_KEY = 'ccs-internal-managed';
|
|
|
|
/**
|
|
* Fetch effective API key from backend
|
|
* Falls back to default if fetch fails
|
|
*/
|
|
async function fetchEffectiveApiKey(): Promise<string> {
|
|
try {
|
|
const response = await fetch('/api/settings/auth/tokens/raw');
|
|
if (!response.ok) return DEFAULT_API_KEY;
|
|
const data = await response.json();
|
|
return data?.apiKey?.value ?? DEFAULT_API_KEY;
|
|
} catch {
|
|
return DEFAULT_API_KEY;
|
|
}
|
|
}
|
|
|
|
async function fetchProviderCatalog(provider: string, catalog?: CliproxyProviderCatalog) {
|
|
if (catalog) {
|
|
return catalog;
|
|
}
|
|
|
|
try {
|
|
const response = await fetch('/api/cliproxy/catalog');
|
|
if (!response.ok) {
|
|
return MODEL_CATALOGS[provider];
|
|
}
|
|
|
|
const data = (await response.json()) as {
|
|
catalogs?: Partial<Record<string, (typeof MODEL_CATALOGS)[string]>>;
|
|
};
|
|
return buildUiCatalogs(data.catalogs)[provider] ?? MODEL_CATALOGS[provider];
|
|
} catch {
|
|
return MODEL_CATALOGS[provider];
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Apply default preset for a provider to its settings
|
|
* Uses the catalog default model's preset mapping or falls back to using defaultModel for all tiers
|
|
*
|
|
* @param provider - The provider ID (e.g., 'gemini', 'codex', 'agy')
|
|
* @param port - Optional custom port (defaults to CLIPROXY_DEFAULT_PORT)
|
|
* @returns Object with success status and applied preset name
|
|
*/
|
|
export async function applyDefaultPreset(
|
|
provider: string,
|
|
port?: number,
|
|
catalog?: CliproxyProviderCatalog
|
|
): Promise<{ success: boolean; presetName?: string }> {
|
|
const resolvedCatalog = await fetchProviderCatalog(provider, catalog);
|
|
if (!resolvedCatalog) return { success: false };
|
|
|
|
const defaultModelEntry =
|
|
resolvedCatalog.models.find((model) => model.id === resolvedCatalog.defaultModel) ||
|
|
resolvedCatalog.models[0];
|
|
const mapping = defaultModelEntry?.presetMapping || {
|
|
default: resolvedCatalog.defaultModel,
|
|
opus: resolvedCatalog.defaultModel,
|
|
sonnet: resolvedCatalog.defaultModel,
|
|
haiku: resolvedCatalog.defaultModel,
|
|
};
|
|
|
|
// Fetch effective API key (respects user customization)
|
|
const effectiveApiKey = await fetchEffectiveApiKey();
|
|
|
|
const effectivePort = port ?? CLIPROXY_DEFAULT_PORT;
|
|
const settings = {
|
|
env: {
|
|
ANTHROPIC_BASE_URL: `http://127.0.0.1:${effectivePort}/api/provider/${provider}`,
|
|
ANTHROPIC_AUTH_TOKEN: effectiveApiKey,
|
|
ANTHROPIC_MODEL: mapping.default,
|
|
ANTHROPIC_DEFAULT_OPUS_MODEL: mapping.opus,
|
|
ANTHROPIC_DEFAULT_SONNET_MODEL: mapping.sonnet,
|
|
ANTHROPIC_DEFAULT_HAIKU_MODEL: mapping.haiku,
|
|
},
|
|
};
|
|
|
|
try {
|
|
const res = await fetch(`/api/settings/${provider}`, {
|
|
method: 'PUT',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify({ settings }),
|
|
});
|
|
return {
|
|
success: res.ok,
|
|
presetName: defaultModelEntry?.name || resolvedCatalog.defaultModel,
|
|
};
|
|
} catch {
|
|
return { success: false };
|
|
}
|
|
}
|