Script for easily configuring, using, switching and comparing local offline coding models
at main 71 lines 1.8 kB view raw
1import { OLLAMA_URL } from "../config.js"; 2import { getActiveChatModel } from "../runtime-config.js"; 3import { err } from "../log.js"; 4import { ensureOllama } from "./server.js"; 5 6export async function runAsk(question: string): Promise<void> { 7 await ensureOllama(); 8 const model = getActiveChatModel(); 9 10 const body = JSON.stringify({ 11 model: model.ollamaTag, 12 messages: [ 13 { 14 role: "system", 15 content: 16 "You are an expert programmer. Give concise, practical answers. Include code examples when helpful.", 17 }, 18 { role: "user", content: question }, 19 ], 20 stream: true, 21 }); 22 23 let res: Response; 24 try { 25 res = await fetch(`${OLLAMA_URL}/v1/chat/completions`, { 26 method: "POST", 27 headers: { "Content-Type": "application/json" }, 28 body, 29 }); 30 } catch { 31 err("Ollama not running. Start it with: localcode start"); 32 } 33 34 if (!res!.ok) { 35 err(`Server returned ${res!.status}`); 36 } 37 38 // Stream the response 39 const reader = res!.body?.getReader(); 40 if (!reader) { 41 err("No response body"); 42 } 43 44 const decoder = new TextDecoder(); 45 let buffer = ""; 46 47 while (true) { 48 const { done, value } = await reader.read(); 49 if (done) break; 50 51 buffer += decoder.decode(value, { stream: true }); 52 const lines = buffer.split("\n"); 53 buffer = lines.pop()!; 54 55 for (const line of lines) { 56 if (!line.startsWith("data: ")) continue; 57 const data = line.slice(6); 58 if (data === "[DONE]") continue; 59 try { 60 const json = JSON.parse(data) as { 61 choices?: { delta?: { content?: string } }[]; 62 }; 63 const content = json.choices?.[0]?.delta?.content; 64 if (content) process.stdout.write(content); 65 } catch { 66 // skip malformed chunks 67 } 68 } 69 } 70 process.stdout.write("\n"); 71}