Merge pull request 'fix: per-provider health checks in status display' (#44) from fix/per-provider-health-check into main
This commit is contained in:
@@ -17,6 +17,7 @@ const CLEAR_LINE = '\x1b[2K\r';
|
||||
interface ProvidersInfo {
|
||||
providers: string[];
|
||||
tiers: { fast: string[]; heavy: string[] };
|
||||
health: Record<string, boolean>;
|
||||
}
|
||||
|
||||
export interface StatusCommandDeps {
|
||||
@@ -234,13 +235,17 @@ export function createStatusCommand(deps?: Partial<StatusCommandDeps>): Command
|
||||
clearInterval(interval);
|
||||
|
||||
if (providersInfo && (providersInfo.tiers.fast.length > 0 || providersInfo.tiers.heavy.length > 0)) {
|
||||
// Tiered display
|
||||
// Tiered display with per-provider health
|
||||
write(`${CLEAR_LINE}`);
|
||||
if (providersInfo.tiers.fast.length > 0) {
|
||||
log(`LLM (fast): ${providersInfo.tiers.fast.join(', ')} ${GREEN}✓${RESET}`);
|
||||
}
|
||||
if (providersInfo.tiers.heavy.length > 0) {
|
||||
log(`LLM (heavy): ${providersInfo.tiers.heavy.join(', ')} ${GREEN}✓${RESET}`);
|
||||
for (const tier of ['fast', 'heavy'] as const) {
|
||||
const names = providersInfo.tiers[tier];
|
||||
if (names.length === 0) continue;
|
||||
const label = tier === 'fast' ? 'LLM (fast): ' : 'LLM (heavy):';
|
||||
const parts = names.map((n) => {
|
||||
const ok = providersInfo.health[n];
|
||||
return ok ? `${n} ${GREEN}✓${RESET}` : `${n} ${RED}✗${RESET}`;
|
||||
});
|
||||
log(`${label} ${parts.join(', ')}`);
|
||||
}
|
||||
} else {
|
||||
// Legacy single provider display
|
||||
@@ -258,11 +263,15 @@ export function createStatusCommand(deps?: Partial<StatusCommandDeps>): Command
|
||||
const [llmStatus, models, providersInfo] = await Promise.all([llmPromise, modelsPromise, providersPromise]);
|
||||
|
||||
if (providersInfo && (providersInfo.tiers.fast.length > 0 || providersInfo.tiers.heavy.length > 0)) {
|
||||
if (providersInfo.tiers.fast.length > 0) {
|
||||
log(`LLM (fast): ${providersInfo.tiers.fast.join(', ')}`);
|
||||
}
|
||||
if (providersInfo.tiers.heavy.length > 0) {
|
||||
log(`LLM (heavy): ${providersInfo.tiers.heavy.join(', ')}`);
|
||||
for (const tier of ['fast', 'heavy'] as const) {
|
||||
const names = providersInfo.tiers[tier];
|
||||
if (names.length === 0) continue;
|
||||
const label = tier === 'fast' ? 'LLM (fast): ' : 'LLM (heavy):';
|
||||
const parts = names.map((n) => {
|
||||
const ok = providersInfo.health[n];
|
||||
return ok ? `${n} ✓` : `${n} ✗`;
|
||||
});
|
||||
log(`${label} ${parts.join(', ')}`);
|
||||
}
|
||||
} else {
|
||||
if (llmStatus === 'ok' || llmStatus === 'ok (key stored)') {
|
||||
|
||||
@@ -140,19 +140,40 @@ export async function createHttpServer(
|
||||
}
|
||||
});
|
||||
|
||||
// LLM providers — list all registered providers with tier assignments
|
||||
// LLM providers — list all registered providers with tier assignments and health
|
||||
app.get('/llm/providers', async (_request, reply) => {
|
||||
const registry = deps.providerRegistry;
|
||||
if (!registry) {
|
||||
reply.code(200).send({ providers: [], tiers: { fast: [], heavy: [] } });
|
||||
reply.code(200).send({ providers: [], tiers: { fast: [], heavy: [] }, health: {} });
|
||||
return;
|
||||
}
|
||||
|
||||
// Run isAvailable() on all providers in parallel (lightweight, no tokens burned)
|
||||
const names = registry.list();
|
||||
const healthChecks = await Promise.all(
|
||||
names.map(async (name) => {
|
||||
const provider = registry.get(name);
|
||||
if (!provider) return { name, available: false };
|
||||
try {
|
||||
const available = await provider.isAvailable();
|
||||
return { name, available };
|
||||
} catch {
|
||||
return { name, available: false };
|
||||
}
|
||||
}),
|
||||
);
|
||||
const health: Record<string, boolean> = {};
|
||||
for (const check of healthChecks) {
|
||||
health[check.name] = check.available;
|
||||
}
|
||||
|
||||
reply.code(200).send({
|
||||
providers: registry.list(),
|
||||
providers: names,
|
||||
tiers: {
|
||||
fast: registry.getTierProviders('fast'),
|
||||
heavy: registry.getTierProviders('heavy'),
|
||||
},
|
||||
health,
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user