Skip to content

Commit 9d6ab25

Browse files
committed
garotm - fix the default ollama port expectation.
1 parent 5cd8078 commit 9d6ab25

6 files changed

Lines changed: 68 additions & 25 deletions

File tree

backend/src/__tests__/app.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ describe("createApp HTTP API", () => {
2828
const app = createApp(db);
2929
const res = await request(app).get("/api/settings").expect(200);
3030
expect(res.body.watch_folder).toBeNull();
31-
expect(res.body.llm_base_url).toContain("8080");
31+
expect(res.body.llm_base_url).toContain("11434");
3232
expect(res.body.llm_model).toBeTruthy();
3333
});
3434

backend/src/app.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import type { Database } from "better-sqlite3";
44
import { z } from "zod";
55
import { getSetting, setSetting } from "./db";
66
import { ingestFile } from "./ingest";
7+
import { DEFAULT_LLM_BASE_URL, DEFAULT_LLM_MODEL } from "./llmDefaults";
78

89
export function createApp(db: Database) {
910
const app = express();
@@ -24,8 +25,8 @@ export function createApp(db: Database) {
2425
app.get("/api/settings", (_req, res) => {
2526
const rawWatch = getSetting(db, "watch_folder");
2627
const watch_folder = rawWatch && rawWatch.length > 0 ? rawWatch : null;
27-
const llm_base_url = getSetting(db, "llm_base_url") ?? "http://127.0.0.1:8080/v1";
28-
const llm_model = getSetting(db, "llm_model") ?? "local-model";
28+
const llm_base_url = getSetting(db, "llm_base_url") ?? DEFAULT_LLM_BASE_URL;
29+
const llm_model = getSetting(db, "llm_model") ?? DEFAULT_LLM_MODEL;
2930
res.json({
3031
watch_folder,
3132
llm_base_url,
@@ -47,8 +48,8 @@ export function createApp(db: Database) {
4748
const watch_folder = wf && wf.length > 0 ? wf : null;
4849
res.json({
4950
watch_folder,
50-
llm_base_url: getSetting(db, "llm_base_url") ?? "http://127.0.0.1:8080/v1",
51-
llm_model: getSetting(db, "llm_model") ?? "local-model",
51+
llm_base_url: getSetting(db, "llm_base_url") ?? DEFAULT_LLM_BASE_URL,
52+
llm_model: getSetting(db, "llm_model") ?? DEFAULT_LLM_MODEL,
5253
});
5354
});
5455

backend/src/ingest.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { extractFromHl7, looksLikeHl7 } from "./pipelines/hl7";
77
import { extractTextFromPdf } from "./pipelines/pdf";
88
import { getSetting } from "./db";
99
import { heuristicSummary, synthesizeClinical } from "./llm";
10+
import { DEFAULT_LLM_BASE_URL, DEFAULT_LLM_MODEL } from "./llmDefaults";
1011

1112
export type IngestResult = {
1213
documentId: string;
@@ -91,9 +92,8 @@ export async function ingestFile(db: Database.Database, filePath: string): Promi
9192
const kind = ext === ".pdf" ? "pdf" : detectKind(normalized, rawText);
9293
const ctx = await buildContext(kind, normalized, rawText);
9394

94-
const llmBase =
95-
getSetting(db, "llm_base_url") ?? process.env.SIFT_LLM_BASE_URL ?? "http://127.0.0.1:8080/v1";
96-
const llmModel = getSetting(db, "llm_model") ?? process.env.SIFT_LLM_MODEL ?? "gpt-oss-20b";
95+
const llmBase = getSetting(db, "llm_base_url") ?? process.env.SIFT_LLM_BASE_URL ?? DEFAULT_LLM_BASE_URL;
96+
const llmModel = getSetting(db, "llm_model") ?? process.env.SIFT_LLM_MODEL ?? DEFAULT_LLM_MODEL;
9797

9898
let summary: string;
9999
let confidence = ctx.baseConfidence;

backend/src/llmDefaults.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
/** Defaults aligned with Ollama’s OpenAI-compatible API (`/v1/chat/completions` on port 11434). */
2+
export const DEFAULT_LLM_BASE_URL = "http://127.0.0.1:11434/v1";
3+
/** Common tag; change in Settings to match `ollama list` (e.g. `llama3.2`, `mistral`, `qwen2.5:14b`). */
4+
export const DEFAULT_LLM_MODEL = "llama3.2";

docs/CONFIGURATION.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ These are exposed via `GET/POST /api/settings` and the UI:
4040
| `llm_base_url` | Base URL for chat completions (often ends with `/v1`) |
4141
| `llm_model` | Model name passed to the LLM API |
4242

43-
Defaults in code if unset: see `backend/src/index.ts` for current defaults.
43+
Defaults if unset (also used by the UI): **`http://127.0.0.1:11434/v1`** and **`llama3.2`** — aligned with **Ollama**’s OpenAI-compatible API on port **11434** (not 8080). See `backend/src/llmDefaults.ts`. Adjust the model to match `ollama list` on your machine (for example `mistral`, `qwen2.5:14b`).
4444

4545
## LLM endpoint shape
4646

frontend/src/App.tsx

Lines changed: 54 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
import { useCallback, useEffect, useState } from "react";
2+
3+
const OLLAMA_DEFAULT_BASE = "http://127.0.0.1:11434/v1";
4+
const OLLAMA_DEFAULT_MODEL = "llama3.2";
25
import { invoke } from "@tauri-apps/api/core";
36
import { open } from "@tauri-apps/plugin-dialog";
47
import { api, type DocumentDetail, type DocumentRow, type Health, type Settings } from "./api";
@@ -267,6 +270,12 @@ function SettingsForm(props: {
267270
}) {
268271
const [url, setUrl] = useState(props.settings.llm_base_url);
269272
const [model, setModel] = useState(props.settings.llm_model);
273+
274+
useEffect(() => {
275+
setUrl(props.settings.llm_base_url);
276+
setModel(props.settings.llm_model);
277+
}, [props.settings.llm_base_url, props.settings.llm_model]);
278+
270279
return (
271280
<section className="max-w-xl space-y-6 print:hidden">
272281
<h2 className="text-lg font-semibold text-white">Settings</h2>
@@ -289,30 +298,59 @@ function SettingsForm(props: {
289298
</div>
290299
</div>
291300
<div className="rounded-xl border border-slate-800 bg-slate-900/40 p-5 space-y-3">
292-
<label className="block text-sm font-medium text-slate-300">Local LLM (OpenAI-compatible)</label>
293-
<p className="text-xs text-slate-500">
294-
Point to <code className="text-clinical-teal">llama-server</code>, Ollama, LM Studio, or any
295-
OpenAI-compatible URL on this machine.
301+
<label className="block text-sm font-medium text-slate-300">Local LLM (OpenAI-compatible API)</label>
302+
<p className="text-xs text-slate-500 leading-relaxed">
303+
The app does not bundle model weights. It calls your local server using the same shape as OpenAI chat
304+
completions (<code className="text-clinical-teal">/v1/chat/completions</code>).{" "}
305+
<strong className="text-slate-400">Ollama</strong> listens on{" "}
306+
<code className="text-clinical-teal">127.0.0.1:11434</code> by default (not 8080). Use the base URL
307+
below and a model name from <code className="text-clinical-teal">ollama list</code>.
296308
</p>
297-
<input
298-
className="w-full rounded-lg bg-slate-950 border border-slate-700 px-3 py-2 text-sm"
299-
value={url}
300-
onChange={(e) => setUrl(e.target.value)}
301-
placeholder="http://127.0.0.1:8080/v1"
302-
/>
303-
<input
304-
className="w-full rounded-lg bg-slate-950 border border-slate-700 px-3 py-2 text-sm"
305-
value={model}
306-
onChange={(e) => setModel(e.target.value)}
307-
placeholder="model id"
308-
/>
309+
<div className="flex flex-wrap gap-2">
310+
<button
311+
type="button"
312+
className="rounded-md border border-slate-600 px-3 py-1.5 text-xs text-slate-300 hover:bg-slate-800"
313+
onClick={() => {
314+
setUrl(OLLAMA_DEFAULT_BASE);
315+
setModel(OLLAMA_DEFAULT_MODEL);
316+
}}
317+
>
318+
Use Ollama defaults
319+
</button>
320+
</div>
321+
<div>
322+
<span className="text-xs text-slate-500">Base URL</span>
323+
<input
324+
className="mt-1 w-full rounded-lg bg-slate-950 border border-slate-700 px-3 py-2 text-sm font-mono"
325+
value={url}
326+
onChange={(e) => setUrl(e.target.value)}
327+
placeholder={OLLAMA_DEFAULT_BASE}
328+
autoComplete="off"
329+
spellCheck={false}
330+
/>
331+
</div>
332+
<div>
333+
<span className="text-xs text-slate-500">Model id</span>
334+
<input
335+
className="mt-1 w-full rounded-lg bg-slate-950 border border-slate-700 px-3 py-2 text-sm font-mono"
336+
value={model}
337+
onChange={(e) => setModel(e.target.value)}
338+
placeholder={OLLAMA_DEFAULT_MODEL}
339+
autoComplete="off"
340+
spellCheck={false}
341+
/>
342+
</div>
309343
<button
310344
type="button"
311345
onClick={() => props.onSaveLlm(url, model)}
312346
className="rounded-lg bg-slate-100 text-slate-900 px-4 py-2 text-sm font-semibold hover:bg-white"
313347
>
314348
Save LLM settings
315349
</button>
350+
<p className="text-xs text-slate-600">
351+
After saving, drop a new file or re-copy an existing file into the watch folder to regenerate a summary
352+
with the LLM. Existing rows keep their stored text until re-ingested.
353+
</p>
316354
</div>
317355
</section>
318356
);

0 commit comments

Comments
 (0)