Fully migrate off Gemini: shared Ollama client (gemma4:26b @ shadow-death), health reports llm backend, drop @google/genai
This commit is contained in:
38
src/server/llmClient.ts
Normal file
38
src/server/llmClient.ts
Normal file
@@ -0,0 +1,38 @@
|
||||
// Shared local-LLM client — Ollama on shadow-death (.128).
|
||||
// Single source of truth for host/model across the whole app.
|
||||
export const OLLAMA_HOST = process.env.OLLAMA_HOST || 'http://10.30.20.128:11434';
|
||||
export const OLLAMA_MODEL = process.env.OLLAMA_MODEL || 'gemma4:26b';
|
||||
|
||||
export interface LocalModelOptions {
|
||||
formatJson?: boolean;
|
||||
numPredict?: number;
|
||||
temperature?: number;
|
||||
}
|
||||
|
||||
export async function callLocalModel(prompt: string, opts: LocalModelOptions = {}): Promise<string> {
|
||||
const body: Record<string, any> = {
|
||||
model: OLLAMA_MODEL,
|
||||
messages: [{ role: 'user', content: prompt }],
|
||||
stream: false,
|
||||
keep_alive: '30m',
|
||||
options: {
|
||||
num_predict: opts.numPredict ?? 4096,
|
||||
temperature: opts.temperature ?? 0.2,
|
||||
},
|
||||
};
|
||||
if (opts.formatJson) body.format = 'json';
|
||||
|
||||
const res = await fetch(`${OLLAMA_HOST}/api/chat`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(body),
|
||||
signal: AbortSignal.timeout(180000),
|
||||
});
|
||||
if (!res.ok) {
|
||||
throw new Error(`Ollama HTTP ${res.status} (${res.statusText})`);
|
||||
}
|
||||
const data = await res.json();
|
||||
let content = data?.message?.content || '';
|
||||
if (!content) content = data?.message?.thinking || '';
|
||||
return (content || '').trim();
|
||||
}
|
||||
Reference in New Issue
Block a user