49 lines
1.7 KiB
TypeScript
49 lines
1.7 KiB
TypeScript
import { LLM_CONFIG } from "../config/llm.js";
|
|
|
|
/**
|
|
* Pings the local llama.cpp server to ensure it's up, running, and has a model loaded.
|
|
* If the server is offline or still loading, it terminates the pipeline gracefully.
|
|
* Skipped entirely when using a cloud provider.
|
|
*/
|
|
export async function checkLlmServer(
|
|
url = "http://127.0.0.1:8080/health",
|
|
): Promise<void> {
|
|
if (LLM_CONFIG.provider !== "local") {
|
|
console.log("🌐 Using cloud provider — skipping local health check.");
|
|
return;
|
|
}
|
|
|
|
try {
|
|
const response = await fetch(url);
|
|
|
|
// llama.cpp returns a 503 status if the server is up but the model weights are still loading
|
|
if (response.status === 503) {
|
|
throw new Error(
|
|
"Local AI engine is starting up, but the model is still loading into memory. " +
|
|
"Please wait a minute for the weights to load, then run the pipeline again.",
|
|
);
|
|
}
|
|
|
|
// Parse the JSON health response (expected: { status: "ok" })
|
|
const data = (await response.json()) as { status?: string };
|
|
|
|
if (response.ok && data.status === "ok") {
|
|
console.log("🟢 Local AI engine is connected and ready for inference!");
|
|
return;
|
|
}
|
|
|
|
// Catch-all for unexpected active server responses
|
|
throw new Error(
|
|
`Unknown response from local AI engine health check (Status: ${response.status}).`,
|
|
);
|
|
} catch (error: unknown) {
|
|
if (error instanceof Error && error.message.includes("Local AI engine")) {
|
|
throw error; // Re-throw our own errors
|
|
}
|
|
throw new Error(
|
|
`Could not connect to the local AI engine at ${url}. ` +
|
|
"Make sure your './llama-server' command is actively running in another terminal tab.",
|
|
{ cause: error },
|
|
);
|
|
}
|
|
}
|