diff options
| author | Adam Malczewski <[email protected]> | 2026-03-24 13:18:50 +0900 |
|---|---|---|
| committer | Adam Malczewski <[email protected]> | 2026-03-24 13:18:50 +0900 |
| commit | bb543c3f7840f2a3fa1b7a1fb32245fa87a30f7b (patch) | |
| tree | d2a9db2741dfd9822c5f76dca278562220e9b064 /src/ollama-client.ts | |
| parent | e5583b836d4fe2f7f9806ed85a190254a6ea3990 (diff) | |
| download | ai-pulse-obsidian-plugin-bb543c3f7840f2a3fa1b7a1fb32245fa87a30f7b.tar.gz ai-pulse-obsidian-plugin-bb543c3f7840f2a3fa1b7a1fb32245fa87a30f7b.zip | |
initial prototype
Diffstat (limited to 'src/ollama-client.ts')
| -rw-r--r-- | src/ollama-client.ts | 97 |
1 files changed, 97 insertions, 0 deletions
diff --git a/src/ollama-client.ts b/src/ollama-client.ts new file mode 100644 index 0000000..377d640 --- /dev/null +++ b/src/ollama-client.ts @@ -0,0 +1,97 @@ +import { requestUrl } from "obsidian"; + +export interface ChatMessage { + role: "system" | "user" | "assistant"; + content: string; +} + +export async function testConnection(ollamaUrl: string): Promise<string> { + try { + const response = await requestUrl({ + url: `${ollamaUrl}/api/version`, + method: "GET", + throw: false, + }); + + if (response.status === 200) { + const version = (response.json as Record<string, unknown>).version; + if (typeof version === "string") { + return version; + } + throw new Error("Unexpected response format: missing version field."); + } + + throw new Error(`Ollama returned status ${response.status}.`); + } catch (err: unknown) { + if (err instanceof Error) { + const msg = err.message.toLowerCase(); + if (msg.includes("net") || msg.includes("fetch") || msg.includes("failed to fetch")) { + throw new Error("Ollama is unreachable. Is the server running?"); + } + throw err; + } + throw new Error("Ollama is unreachable. Is the server running?"); + } +} + +export async function listModels(ollamaUrl: string): Promise<string[]> { + try { + const response = await requestUrl({ + url: `${ollamaUrl}/api/tags`, + method: "GET", + }); + + const models = (response.json as Record<string, unknown>).models; + if (!Array.isArray(models)) { + throw new Error("Unexpected response format: missing models array."); + } + + return models.map((m: unknown) => { + if (typeof m === "object" && m !== null && "name" in m) { + const name = (m as Record<string, unknown>).name; + if (typeof name === "string") { + return name; + } + return String(name); + } + return String(m); + }); + } catch (err: unknown) { + if (err instanceof Error) { + throw new Error(`Failed to list models: ${err.message}`); + } + throw new Error("Failed to list models: unknown error."); + } +} + +export async function sendChatMessage( + ollamaUrl: string, + model: string, + messages: ChatMessage[], +): Promise<string> { + try { + const response = await requestUrl({ + url: `${ollamaUrl}/api/chat`, + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ model, messages, stream: false }), + }); + + const message = (response.json as Record<string, unknown>).message; + if ( + typeof message === "object" && + message !== null && + "content" in message && + typeof (message as Record<string, unknown>).content === "string" + ) { + return (message as Record<string, unknown>).content as string; + } + + throw new Error("Unexpected response format: missing message content."); + } catch (err: unknown) { + if (err instanceof Error) { + throw new Error(`Chat request failed: ${err.message}`); + } + throw new Error("Chat request failed: unknown error."); + } +} |
