41 lines
1.3 KiB
TypeScript
41 lines
1.3 KiB
TypeScript
// 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 || 'qwen3.8:latest';
|
|
|
|
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,
|
|
think: false,
|
|
num_ctx: 8192,
|
|
},
|
|
};
|
|
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();
|
|
}
|