summaryrefslogtreecommitdiffhomepage
path: root/src/ollama-client.ts
diff options
context:
space:
mode:
authorAdam Malczewski <[email protected]>2026-03-24 13:18:50 +0900
committerAdam Malczewski <[email protected]>2026-03-24 13:18:50 +0900
commitbb543c3f7840f2a3fa1b7a1fb32245fa87a30f7b (patch)
treed2a9db2741dfd9822c5f76dca278562220e9b064 /src/ollama-client.ts
parente5583b836d4fe2f7f9806ed85a190254a6ea3990 (diff)
downloadai-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.ts97
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.");
+ }
+}