● Zion Boggan
repos/Zion Pm/app/api/fleet/ping/route.ts
zionboggan.com ↗
47 lines · typescript
History for this file →
1
import { NextRequest, NextResponse } from 'next/server';
2
import { generateText } from 'ai';
3
import { glmModel } from '@/lib/glm';
4
import { runSSH } from '@/lib/workers/ssh';
5
import { setCap } from '@/lib/db';
6
 
7
export const runtime = 'nodejs';
8
export const dynamic = 'force-dynamic';
9
export const maxDuration = 120;
10
 
11
const OLLAMA = process.env.ZPM_OLLAMA_URL || 'http://REDACTED-IP:11434';
12
 
13
async function pingModel(model: string): Promise<{ ok: boolean; latencyMs: number; detail: string }> {
14
  const start = Date.now();
15
  try {
16
    if (model === 'glm') {
17
      const r = await generateText({ model: glmModel, prompt: 'Reply with exactly: OK' });
18
      return { ok: /ok/i.test(r.text), latencyMs: Date.now() - start, detail: r.text.trim().slice(0, 40) };
19
    }
20
    if (model === 'claude') {
21
      const r = await runSSH('REDACTED-IP', 'zion', 'echo ok', 15_000);
22
      return { ok: r.stdout.trim() === 'ok', latencyMs: Date.now() - start, detail: 'CT215 reachable' };
23
    }
24
    if (model === 'codex') {
25
      const r = await runSSH('REDACTED-IP', 'zion', 'echo ok', 15_000);
26
      return { ok: r.stdout.trim() === 'ok', latencyMs: Date.now() - start, detail: 'CT241 reachable' };
27
    }
28
    if (model === 'ollama') {
29
      const ctrl = new AbortController();
30
      const t = setTimeout(() => ctrl.abort(), 10_000);
31
      const res = await fetch(`${OLLAMA}/api/tags`, { signal: ctrl.signal });
32
      clearTimeout(t);
33
      return { ok: res.ok, latencyMs: Date.now() - start, detail: res.ok ? '3060 ollama up' : `http ${res.status}` };
34
    }
35
    return { ok: false, latencyMs: 0, detail: 'unknown model' };
36
  } catch (e) {
37
    return { ok: false, latencyMs: Date.now() - start, detail: (e as Error).message.slice(0, 80) };
38
  }
39
}
40
 
41
export async function POST(req: NextRequest) {
42
  const { model } = await req.json();
43
  if (!model) return NextResponse.json({ error: 'model required' }, { status: 400 });
44
  const res = await pingModel(model);
45
  if (model !== 'glm') setCap(model, res.ok ? 1 : 0, res.ok ? 'ping ok' : `ping fail: ${res.detail}`);
46
  return NextResponse.json({ model, ...res });
47
}