mirror of
https://github.com/tiennm99/ccs.git
synced 2026-10-14 00:16:38 +00:00
feat(profiles): add local runtime readiness checks
This commit is contained in:
1 parent
29ef0c8e04
commit
63b67f1c1c
6 files changed
+307
No files matched your search
@@ -64,6 +64,12 @@ export {
|
||||
// OpenRouter catalog and picker
|
||||
export { isOpenRouterUrl, fetchOpenRouterModels, type OpenRouterModel } from './openrouter-catalog';
|
||||
export { pickOpenRouterModel, type OpenRouterSelection } from './openrouter-picker';
|
||||
export {
|
||||
getLocalRuntimeReadiness,
|
||||
type LocalRuntimeId,
|
||||
type LocalRuntimeReadiness,
|
||||
type LocalRuntimeStatus,
|
||||
} from './local-runtime-readiness';
|
||||
|
||||
// Provider presets for CLI
|
||||
export {
|
||||
|
||||
@@ -0,0 +1,121 @@
|
||||
export type LocalRuntimeId = 'ollama' | 'llamacpp';
|
||||
export type LocalRuntimeStatus = 'ready' | 'missing-model' | 'offline';
|
||||
|
||||
export interface LocalRuntimeReadiness {
|
||||
id: LocalRuntimeId;
|
||||
name: string;
|
||||
endpoint: string;
|
||||
status: LocalRuntimeStatus;
|
||||
commandHint: string;
|
||||
recommendedModel: string | null;
|
||||
recommendedModelInstalled: boolean;
|
||||
detectedModelCount: number;
|
||||
}
|
||||
|
||||
interface LocalRuntimeDefinition {
|
||||
id: LocalRuntimeId;
|
||||
name: string;
|
||||
endpoint: string;
|
||||
modelsUrl: string;
|
||||
commandHint: string;
|
||||
recommendedModel: string | null;
|
||||
parseModelIds: (payload: unknown) => string[];
|
||||
}
|
||||
|
||||
const LOCAL_RUNTIME_DEFINITIONS: LocalRuntimeDefinition[] = [
|
||||
{
|
||||
id: 'ollama',
|
||||
name: 'Ollama',
|
||||
endpoint: 'http://127.0.0.1:11434',
|
||||
modelsUrl: 'http://127.0.0.1:11434/api/tags',
|
||||
commandHint: 'ollama serve',
|
||||
recommendedModel: 'gemma4:e4b',
|
||||
parseModelIds: (payload) => {
|
||||
const models = (payload as { models?: Array<{ name?: string }> })?.models;
|
||||
return Array.isArray(models)
|
||||
? models
|
||||
.map((model) => (typeof model?.name === 'string' ? model.name.trim() : ''))
|
||||
.filter(Boolean)
|
||||
: [];
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'llamacpp',
|
||||
name: 'llama.cpp',
|
||||
endpoint: 'http://127.0.0.1:8080',
|
||||
modelsUrl: 'http://127.0.0.1:8080/v1/models',
|
||||
commandHint: './server --host 0.0.0.0 --port 8080 -m model.gguf',
|
||||
recommendedModel: null,
|
||||
parseModelIds: (payload) => {
|
||||
const models = (payload as { data?: Array<{ id?: string }> })?.data;
|
||||
return Array.isArray(models)
|
||||
? models
|
||||
.map((model) => (typeof model?.id === 'string' ? model.id.trim() : ''))
|
||||
.filter(Boolean)
|
||||
: [];
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
async function fetchModelIds(definition: LocalRuntimeDefinition): Promise<string[]> {
|
||||
const response = await fetch(definition.modelsUrl, {
|
||||
signal: AbortSignal.timeout(1500),
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`${definition.id} readiness probe failed (${response.status})`);
|
||||
}
|
||||
|
||||
return definition.parseModelIds(await response.json());
|
||||
}
|
||||
|
||||
function toReadiness(
|
||||
definition: LocalRuntimeDefinition,
|
||||
modelIds: string[]
|
||||
): LocalRuntimeReadiness {
|
||||
const recommendedModelInstalled = definition.recommendedModel
|
||||
? modelIds.some((modelId) => modelId === definition.recommendedModel)
|
||||
: modelIds.length > 0;
|
||||
|
||||
const status: LocalRuntimeStatus =
|
||||
modelIds.length === 0 || !recommendedModelInstalled ? 'missing-model' : 'ready';
|
||||
|
||||
return {
|
||||
id: definition.id,
|
||||
name: definition.name,
|
||||
endpoint: definition.endpoint,
|
||||
status,
|
||||
commandHint:
|
||||
status === 'missing-model' && definition.recommendedModel
|
||||
? `ollama pull ${definition.recommendedModel}`
|
||||
: definition.commandHint,
|
||||
recommendedModel: definition.recommendedModel,
|
||||
recommendedModelInstalled,
|
||||
detectedModelCount: modelIds.length,
|
||||
};
|
||||
}
|
||||
|
||||
function toOffline(definition: LocalRuntimeDefinition): LocalRuntimeReadiness {
|
||||
return {
|
||||
id: definition.id,
|
||||
name: definition.name,
|
||||
endpoint: definition.endpoint,
|
||||
status: 'offline',
|
||||
commandHint: definition.commandHint,
|
||||
recommendedModel: definition.recommendedModel,
|
||||
recommendedModelInstalled: false,
|
||||
detectedModelCount: 0,
|
||||
};
|
||||
}
|
||||
|
||||
export async function getLocalRuntimeReadiness(): Promise<LocalRuntimeReadiness[]> {
|
||||
return Promise.all(
|
||||
LOCAL_RUNTIME_DEFINITIONS.map(async (definition) => {
|
||||
try {
|
||||
return toReadiness(definition, await fetchModelIds(definition));
|
||||
} catch {
|
||||
return toOffline(definition);
|
||||
}
|
||||
})
|
||||
);
|
||||
}
|
||||
Reference in new issue
Block a user