This repository has no description
0

Configure Feed

Select the types of activity you want to include in your feed.

superconfig / tools / pi / ollama.ts
2.1 kB 73 lines
1/** 2 * Ollama provider — auto-discover models from a remote Ollama server. 3 * 4 * Queries the Ollama `/api/tags` endpoint at startup and registers every 5 * model it returns under a single provider, talking via Ollama's OpenAI 6 * compatibility layer (`/v1/chat/completions`). 7 */ 8 9import type { ExtensionAPI } from "@mariozechner/pi-coding-agent"; 10 11const ENDPOINTS: { name: string; host: string }[] = [ 12 { name: "c-base", host: "http://neoprism.r:11434" }, 13]; 14 15const DISCOVERY_TIMEOUT_MS = 3000; 16 17interface OllamaTag { 18 name: string; 19 model: string; 20 details?: { 21 parameter_size?: string; 22 family?: string; 23 }; 24} 25 26async function fetchTags(host: string): Promise<OllamaTag[]> { 27 const ctl = new AbortController(); 28 const timer = setTimeout(() => ctl.abort(), DISCOVERY_TIMEOUT_MS); 29 try { 30 const res = await fetch(`${host}/api/tags`, { signal: ctl.signal }); 31 if (!res.ok) throw new Error(`HTTP ${res.status}`); 32 const body = (await res.json()) as { models?: OllamaTag[] }; 33 return body.models ?? []; 34 } finally { 35 clearTimeout(timer); 36 } 37} 38 39export default async function ollama(pi: ExtensionAPI) { 40 for (const { name, host } of ENDPOINTS) { 41 let tags: OllamaTag[]; 42 try { 43 tags = await fetchTags(host); 44 } catch (err) { 45 console.error( 46 `[ollama] discovery failed for ${host}: ${err instanceof Error ? err.message : err}`, 47 ); 48 continue; 49 } 50 51 if (tags.length === 0) continue; 52 53 const providerName = ENDPOINTS.length === 1 ? "ollama" : `ollama-${name}`; 54 55 pi.registerProvider(providerName, { 56 name: `Ollama (${name})`, 57 baseUrl: `${host}/v1`, 58 apiKey: "ollama", 59 api: "openai-completions", 60 models: tags.map((t) => ({ 61 id: t.model, 62 name: t.details?.parameter_size 63 ? `${t.model} (${t.details.parameter_size})` 64 : t.model, 65 reasoning: false, 66 input: ["text"], 67 cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, 68 contextWindow: 32768, 69 maxTokens: 8192, 70 })), 71 }); 72 } 73}