PI-MONO
This commit is contained in:
@@ -1,54 +1,44 @@
|
||||
import { Hono } from 'hono';
|
||||
import type { HonoVariables } from '@@/create-router';
|
||||
import { readApiKeys } from '@@/api/server-settings/pi-mono';
|
||||
|
||||
export const piMonoModelsRouter = new Hono<{ Variables: HonoVariables }>();
|
||||
|
||||
// Hardcoded fallback models — pi supports many providers but these are the most common
|
||||
const FALLBACK_MODELS = [
|
||||
{ id: 'claude-sonnet-4-5-20250514', name: 'Claude Sonnet 4.5', provider: 'anthropic', providerId: 'anthropic' },
|
||||
{ id: 'claude-opus-4-20250918', name: 'Claude Opus 4', provider: 'anthropic', providerId: 'anthropic' },
|
||||
{ id: 'gpt-4.1', name: 'GPT-4.1', provider: 'openai', providerId: 'openai' },
|
||||
{ id: 'o3', name: 'o3', provider: 'openai', providerId: 'openai' },
|
||||
{ id: 'gemini-2.5-pro', name: 'Gemini 2.5 Pro', provider: 'google', providerId: 'google' },
|
||||
{ id: 'gemini-2.5-flash', name: 'Gemini 2.5 Flash', provider: 'google', providerId: 'google' },
|
||||
];
|
||||
|
||||
piMonoModelsRouter.get('/pi-mono/models', async (ctx) => {
|
||||
// Spawn a short-lived pi process to query available models
|
||||
try {
|
||||
const proc = Bun.spawn(['pi', '--list-models', '--mode', 'json'], {
|
||||
const storedKeys = await readApiKeys();
|
||||
const proc = Bun.spawn(['pi', '--list-models'], {
|
||||
stdout: 'pipe',
|
||||
stderr: 'pipe',
|
||||
env: { ...process.env },
|
||||
env: { ...process.env, ...storedKeys },
|
||||
});
|
||||
|
||||
const output = await new Response(proc.stdout).text();
|
||||
await proc.exited;
|
||||
|
||||
if (proc.exitCode !== 0) return ctx.json(FALLBACK_MODELS);
|
||||
if (proc.exitCode !== 0) return ctx.json([]);
|
||||
|
||||
// Parse the output — pi --list-models outputs model info
|
||||
// Parse the whitespace-separated table output:
|
||||
// provider model context max-out thinking images
|
||||
// anthropic claude-sonnet-4-6 200K 128K yes yes
|
||||
const lines = output.trim().split('\n').filter(Boolean);
|
||||
const models: { id: string; name: string; provider: string; providerId: string }[] = [];
|
||||
|
||||
for (const line of lines) {
|
||||
try {
|
||||
const data = JSON.parse(line);
|
||||
if (data.id && data.provider) {
|
||||
models.push({
|
||||
id: data.id,
|
||||
name: data.name ?? data.id,
|
||||
provider: data.provider,
|
||||
providerId: data.provider,
|
||||
});
|
||||
}
|
||||
} catch {
|
||||
// skip non-JSON lines
|
||||
}
|
||||
// Skip header line (first line)
|
||||
for (let i = 1; i < lines.length; i++) {
|
||||
const cols = lines[i]!.trim().split(/\s+/);
|
||||
if (cols.length < 2) continue;
|
||||
const [provider, model] = cols;
|
||||
models.push({
|
||||
id: `${provider}/${model}`,
|
||||
name: model!,
|
||||
provider: provider!,
|
||||
providerId: provider!,
|
||||
});
|
||||
}
|
||||
|
||||
return ctx.json(models.length > 0 ? models : FALLBACK_MODELS);
|
||||
return ctx.json(models);
|
||||
} catch {
|
||||
return ctx.json(FALLBACK_MODELS);
|
||||
return ctx.json([]);
|
||||
}
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user