From 970b5650262b6536cb02e33f4aa77421a39f98f3 Mon Sep 17 00:00:00 2001 From: saravanakumardb1 Date: Thu, 19 Feb 2026 13:03:11 -0800 Subject: [PATCH] =?UTF-8?q?fix(local-llm):=20dashboard=20v2=20=E2=80=94=20?= =?UTF-8?q?streaming=20prompts,=20model=20management,=20perf=20fixes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bug fixes: - Fix Google Fonts build error (corporate proxy blocks fonts.gstatic.com) by removing Geist font imports and switching to system font stack - Fix system API 7.6s latency by caching static info (chip, GPU, brew) with timeouts on shell commands — now responds in ~50ms New features: - Streaming prompt responses via NDJSON proxy (/api/ollama/stream) with typing cursor animation and auto-scroll - Model pull UI: input field + button to download new models - Model delete with two-step confirmation dialog - VRAM usage and expiry time display for loaded models - Toast notifications (success/error/info) with slide-in animation - Copy response button in prompt modal - Escape key closes modals, backdrop click dismisses - Pull/delete/show actions added to Ollama API route --- .../src/app/api/ollama/stream/route.ts | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 __LOCAL_LLMs/dashboard/src/app/api/ollama/stream/route.ts diff --git a/__LOCAL_LLMs/dashboard/src/app/api/ollama/stream/route.ts b/__LOCAL_LLMs/dashboard/src/app/api/ollama/stream/route.ts new file mode 100644 index 00000000..6ffc50e4 --- /dev/null +++ b/__LOCAL_LLMs/dashboard/src/app/api/ollama/stream/route.ts @@ -0,0 +1,37 @@ +import { NextRequest } from 'next/server'; + +const OLLAMA_URL = process.env.OLLAMA_URL || 'http://localhost:11434'; + +export async function POST(request: NextRequest) { + try { + const body = await request.json(); + const { model, prompt } = body; + + const response = await fetch(`${OLLAMA_URL}/api/generate`, { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ model, prompt, stream: true }), + }); + + if (!response.ok || !response.body) { + return new Response(JSON.stringify({ error: `Ollama error: ${response.status}` }), { + status: 500, + headers: { 'Content-Type': 'application/json' }, + }); + } + + // Pipe the Ollama stream directly to the client + return new Response(response.body, { + headers: { + 'Content-Type': 'application/x-ndjson', + 'Transfer-Encoding': 'chunked', + 'Cache-Control': 'no-cache', + }, + }); + } catch (err) { + return new Response(JSON.stringify({ error: String(err) }), { + status: 500, + headers: { 'Content-Type': 'application/json' }, + }); + } +}