- Remove curl --max-filesize to avoid hard failures on large pages
- Add Truncated/OriginalSize fields to FetchResult for all fetch methods
- Return truncation info in proxy response (truncated, originalSize, returnedSize)
- Add timeout parameter to fetch_url tool (default 30s, max 120s)
- Increase default maxLength from 5KB to 50KB, allow up to 2MB
- Include _hint in response guiding LLM to retry with larger maxLength
Instead of failing when content exceeds limits, the tool now returns
truncated content with guidance for the LLM to request more if needed.
Auto-scroll now stops when the top of the assistant's response
reaches the top of the viewport, allowing users to read from
the beginning while more content streams below.
The SvelteKit hooks proxy was only forwarding pathname without
the query string (event.url.search), causing filters and pagination
to be silently dropped in production builds.
Fixes "COMPOSE_CMD: unbound variable" error when running
--uninstall or --update flags. Previously the variable was only
set during check_prerequisites(), which runs after flag handling.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Ollama must listen on 0.0.0.0 for Docker containers to connect.
Added instructions for both systemd and manual configuration.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Simplify setup by requiring local Ollama installation:
- docker-compose.yml now connects to host Ollama via host.docker.internal
- Remove ollama service from compose (no longer included)
- install.sh now requires Ollama to be installed
- Update README with clear prerequisites
- Add Docker Ollama support to roadmap for future
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Remove depends_on from docker-compose.yml (services handle reconnection)
- This allows the override to disable ollama without errors
- Fix prompt display when running via curl | bash (print to stderr)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
When disabling the ollama service, we also need to clear
depends_on references to avoid "undefined service" errors.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
SvelteKit production build needs server-side request handling
since Vite's dev proxy isn't available. The hooks.server.ts file
proxies:
- /api/v1/* -> backend service
- /api/* -> Ollama service
- /health -> backend health check
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
When running via `curl | bash`, stdin is not a terminal.
Read from /dev/tty to allow interactive prompts.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add install.sh for one-line installation (Linux/macOS)
- Detects local Ollama and lets user choose system vs Docker
- Generates docker-compose.override.yml for system Ollama mode
- Supports --update and --uninstall flags
- Fix backend not reading OLLAMA_URL from environment variable
- Add getEnvOrDefault() helper for PORT, DB_PATH, OLLAMA_URL
- Update Dockerfile to use env vars instead of hardcoded flags
- Update README with new Quick Start instructions
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add GPL-3.0 license with copyright notice (2026 VikingOwl)
- Update license badge from MIT to GPL-3.0
- Add copyright to license section
- Remove completed roadmap items (system prompts, search, shortcuts, export)
- Add Hugging Face integration to roadmap
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add project documentation including:
- Feature overview (chat, tools, model management)
- Screenshots showcasing UI (dark/light mode, code generation, web search)
- Quick start with Docker Compose
- Installation instructions (Docker and manual)
- Configuration and environment variables
- Architecture overview and tech stack
- API reference and development guide
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Parse search results into structured data with SearchResultItem type
- Render expanded results as clickable cards with:
- Numbered rank badges
- Linked titles (open in new tab)
- Truncated URLs
- Snippets when available
- Fallback to raw text for non-search results
- Proper light/dark mode styling
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Detect BusyBox wget (limited options) vs GNU wget
- Use compatible flags for BusyBox: -q -O -T -U only
- Add curl to Docker image for better reliability
- curl is now preferred and will be used over BusyBox wget
BusyBox wget doesn't support --max-redirect, --header, or
long-form options which caused web search to fail.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- MessageContent: Make prose-invert conditional (dark:prose-invert)
and use !important on inline code colors to override Typography
- ToolCallDisplay: Replace theme variables with explicit Tailwind
dark/light classes for reliable styling
- ToolResultDisplay: Same treatment - explicit slate colors for
both light and dark modes
All components now properly respect light/dark mode toggle.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- CodeBlock: Use consistent dark styling (github-dark theme colors)
regardless of light/dark app theme to match Shiki output
- MessageContent: Detect JSON tool call objects in message content
and render them as formatted code blocks instead of prose
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Use border-theme-subtle for softer border in dark mode
- Use bg-theme-tertiary/50 for better dark mode background
- Update text colors for proper contrast
- Change focus color from emerald to violet (branding)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Update package.json name to "vessel"
- Update storage keys (vessel-settings, vessel IndexedDB)
- Update Go module to vessel-backend with new imports
- Update database path to vessel.db
- Add new Vessel "V" icon (favicon + app icons)
- Update all user-facing branding (titles, sidebar, settings)
- Update docker-compose files with vessel naming and network
- Change accent color from emerald to violet
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Increase light mode text contrast in app.css (slate.600→700, slate.500→600)
- Add light/dark mode prose styles in MessageContent.svelte for proper markdown rendering
- Convert hardcoded slate-* classes to theme utilities across 37 components
- Fix code block copy button and scrollbar theming for both modes
- Update all route pages (models, tools, knowledge, prompts) with theme classes
- Ensure consistent theming in modals, dialogs, and form inputs
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add CSS custom properties for theme colors (:root and .dark)
- Create utility classes: bg-theme-*, text-theme-*, border-theme-*
- Update +layout.svelte main containers
- Update Sidenav with theme-aware navigation links
- Update TopNav header and action buttons
- Update ChatWindow main area and input section
- Update ChatInput with themed input container
- Update MessageItem with theme-aware message bubbles
- Update EmptyState with themed welcome cards
Theme colors automatically switch between light and dark mode
when clicking the theme toggle button in the top navigation.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add onSelect callback to SystemPromptSelector for 'new' mode
- Track selected prompt locally (newChatPromptId) before conversation exists
- Show selector in both 'new' and 'conversation' modes
- Apply newChatPromptId when streaming in new conversation
Note: Theme toggle mechanism works but CSS lacks light mode styles
(app uses hardcoded dark colors, would need CSS refactoring)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Context Window Management:
- Add ContextFullModal with recovery options (summarize, new chat, dismiss)
- Show toast notifications at 85% and 95% context thresholds
- Block sending when context exceeds 100% until user takes action
Conversation Summarization:
- Add isSummarized/isSummary flags to Message type
- Implement markAsSummarized() and insertSummaryMessage() in ChatState
- Add messagesForContext derived state (excludes summarized, includes summaries)
- Complete handleSummarize flow with LLM summary generation
- Add amber-styled summary message UI with archive icon
Auto-scroll Fixes:
- Fix Svelte 5 reactivity issues by using plain variables instead of $state
- Add continuous scroll during streaming via streamBuffer tracking
- Properly handle user scroll override (re-enable at bottom)
Drag & Drop Improvements:
- Add full-screen drag overlay with document-level event listeners
- Use dragCounter pattern for reliable nested element detection
- Add hideDropZone prop to FileUpload/ImageUpload components
Additional Features:
- Add SystemPromptSelector for per-conversation prompts
- Add SearchModal for full-text message search
- Add ShortcutsModal for keyboard shortcuts help
- Add theme toggle to TopNav
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Implement four major features for the Ollama WebUI:
1. Streaming Stats - Real-time performance metrics display
- Tokens per second, time to first token, total tokens
- Fade-out display after stream completion
- New streaming-metrics.svelte.ts store and StreamingStats component
2. Settings Panel - Model parameter configuration
- Temperature, top_k, top_p, num_ctx sliders
- localStorage persistence for global defaults
- Collapsible panel in chat window with gear icon toggle
3. Model Management - Pull/delete models from UI
- Add pullModel() and deleteModel() methods to Ollama client
- Progress tracking with speed and ETA calculations
- PullModelDialog component and model-operations store
4. Export/Import - Full conversation backup/restore
- JSON export with full fidelity, Markdown for readability
- Import validation with error/warning display
- Export button in conversation items, import in sidebar header
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Fix memory leaks in ui.svelte.ts and sync-manager.svelte.ts by storing
bound function references for proper addEventListener/removeEventListener
- Make conversation action buttons visible on mobile (opacity-100 when isMobile)
- Replace silent console.error calls with toast notifications for user feedback
- Remove ~35 debug console.log statements from production code
Files: ui.svelte.ts, sync-manager.svelte.ts, ConversationItem.svelte,
ChatWindow.svelte, CodeBlock.svelte, MessageActions.svelte,
MessageContent.svelte, +page.svelte, builtin.ts
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Testing:
- Add vitest with jsdom environment for unit testing
- Create 61 comprehensive tests for keyboard shortcuts
- Add test helpers for platform switching and key simulation
- Mock SvelteKit $app modules for testing
Fix:
- Change Windows/Linux shortcuts from Ctrl to Alt to avoid
browser shortcut conflicts (Ctrl+N opens new browser window)
- Mac shortcuts remain Cmd+N/K/B (unaffected)
New shortcuts on Windows/Linux:
- Alt+N: New chat
- Alt+K: Search conversations
- Alt+B: Toggle sidebar
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Backend:
- Add local models API with filter, sort, and pagination
- Add grouped chats endpoint for date-based display
- Support search, family filtering, and multi-field sorting
Frontend:
- Add model registry store with backend-powered operations
- Add server conversations store for future backend queries
- Fix sidenav to use local state for immediate updates on
conversation create/delete (offline-first architecture)
- Fix date display in conversation items (remove duplicate
Date constructor call)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add model registry backend that scrapes ollama.com library page
- Extract capabilities (vision, tools, thinking, embedding, cloud) from HTML
- Store models in SQLite with search, filter by type and capabilities
- Add tag sizes fetching from individual model pages
- Create Model Browser UI with search, filters, and pagination
- Implement streaming model pull with progress bar
- Auto-refresh model selector and select new model after pull
- Add cloud capability detection (uses different HTML pattern)
- Update Go version to 1.24 in Dockerfile
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add github.com/ollama/ollama/api dependency (v0.13.5)
- Create OllamaService wrapper with typed handlers for all endpoints
- Implement streaming support for chat, generate, and pull operations
- Add dedicated handlers: ListModels, ShowModel, Chat, Generate, Embed,
PullModel, DeleteModel, CopyModel, Version, Heartbeat
- Keep fallback proxy for any unhandled endpoints
- Update routes to use new typed API endpoints
- Upgrade Go version to 1.24.1
Benefits:
- Type-safe request/response handling
- Built-in NDJSON streaming with 512KB buffer
- Proper tool call types (ToolCall, ToolCallFunction)
- Thinking mode support (ThinkValue)
- Future compatibility with Ollama updates
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Backend:
- Add unified URL fetcher with fallback chain: curl → wget → native Go → headless Chrome
- Implement JS-rendered page detection for sites like docs.rs
- Add chromedp dependency for headless browser support
- Log fetch method on server startup
Frontend:
- Store tool results in structured ToolCall.result field instead of message content
- Show tool results collapsed by default in ToolCallDisplay
- Add expandable results section with truncation for large outputs
- Add Message.hidden flag for internal messages (tool context)
- Separate visibleMessages (UI) from allMessages (API) to fix infinite loop
- Fix tool result messages not being sent to model
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add <svelte:head> to set browser tab title on both new chat and conversation pages
- Update tab title dynamically when smart title is generated
- Add debug logging to trace title generation flow
- Make title generation more robust:
- Fall back to user message if assistant content is only thinking
- Strip thinking blocks from title generation response
- Remove common prefixes like "Title:"
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Thinking mode:
- Add native Ollama `think: true` API parameter support
- Create ThinkingBlock component with collapsible UI and streaming indicator
- Allow expanding/collapsing thinking blocks during streaming
- Pass showThinking prop through component chain to hide when disabled
- Auto-generate smart chat titles using LLM after first response
File uploads:
- Add FileUpload component supporting images, text files, and PDFs
- Create FilePreview component for non-image attachments
- Add file-processor utility for text extraction and PDF parsing
- Text/PDF content injected as context for all models
Model capabilities:
- Add ModelCapabilityIcons component showing vision/tools/code badges
- Detect model capabilities from name patterns in models store
- Display capability icons in model selector dropdown
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Textarea no longer disabled during streaming (only sending is blocked)
- User can prepare their next message while LLM is responding
- Focus maintained on input after sending a message
- Image upload also enabled during streaming
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- ConversationItem now navigates to / when deleting the currently active chat
- Added text selection styling (violet highlight) for better visibility in dark theme
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Modernize chat UI with dark slate palette and subtle styling
- Add interactive quick-start prompt cards that set system prompts
- Clear temporary prompt when starting new chat
- Fix scroll jumping during streaming by skipping Shiki highlighting
- Improve code block styling with CSS containment
- Fix doubled newlines in code blocks (Shiki .line display: inline)
- Simplify success badge in execution output
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Tool messages get emerald/teal avatar with wrench icon
- Tool message bubbles have emerald left border and darker bg
- Normal assistant messages keep purple robot avatar
- Clear visual hierarchy: user (blue) / assistant (purple) / tool (green)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Hide tool result messages (role: user) from chat display
They're internal API messages, not actual user input
- Improve pattern matching to catch all tool result formats
- Clean up "Tool execution results:" and "Called tool:" text
- Detect and hide HTML garbage from failed fetch attempts
- Add fetch result type with proper styling
- Improve text visibility in fallback displays
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
ToolCallDisplay improvements:
- Tool-specific icons and gradient colors (location, search, fetch, time, calc)
- Human-readable argument formatting instead of raw JSON
- Collapsible details with expand/collapse animation
- Contextual summaries (e.g., "Searching: query")
New ToolResultDisplay component:
- Beautiful location results with city/country display
- Web search results as clickable cards with ranks
- Error states with distinct red styling
- Automatic JSON detection and formatting
MessageContent improvements:
- Detect and parse tool results in message content
- Hide redundant "Called tool:" text (shown via ToolCallDisplay)
- Clean separation of text, code, and tool results
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add /api/v1/location endpoint using ip-api.com for IP geolocation
- Update get_location tool to try browser GPS first, then IP fallback
- Make tool description directive to trigger automatic usage
- Handle private IPs by letting ip-api.com auto-detect
The tool chain now works: get_location → web_search → fetch_url
Browser geolocation often fails on desktop Linux; IP fallback
provides city-level accuracy which is sufficient for weather queries.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Simplify and clarify all tool descriptions for better model understanding
- Enable recursive tool calling - model can now chain multiple tools
- Pass tools on follow-up calls so model can call more tools after seeing results
- Update tool result message to encourage calling additional tools if needed
- Include suggestion in error messages so model knows what to do on failure
- Fix StreamingIndicator visibility with explicit colors
🤖 Generated with [Claude Code](https://claude.ai/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add web_search built-in tool that searches via DuckDuckGo
- Add get_location tool to get user's geographic location
- Create backend search proxy endpoint (/api/v1/proxy/search)
- DuckDuckGo HTML scraping with title, URL, and snippet extraction
- Geolocation with OpenStreetMap reverse geocoding for city/country
- Fix StreamingIndicator visibility in dark mode
- Improve tool descriptions to encourage proper tool usage
- Better error messages with suggestions when location fails
🤖 Generated with [Claude Code](https://claude.ai/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Complete Ollama Web UI implementation featuring:
Frontend (SvelteKit + Svelte 5 + Tailwind CSS + Skeleton UI):
- Chat interface with streaming responses and markdown rendering
- Message tree with branching support (edit creates branches)
- Vision model support with image upload/paste
- Code syntax highlighting with Shiki
- Built-in tools: get_current_time, calculate, fetch_url
- Function model middleware (functiongemma) for tool routing
- IndexedDB storage with Dexie.js
- Context window tracking with token estimation
- Knowledge base with embeddings (RAG support)
- Keyboard shortcuts and responsive design
- Export conversations as Markdown/JSON
Backend (Go + Gin + SQLite):
- RESTful API for conversations and messages
- SQLite persistence with branching message tree
- Sync endpoints for IndexedDB ↔ SQLite synchronization
- URL proxy endpoint for CORS-bypassed web fetching
- Health check endpoint
- Docker support with host network mode
Infrastructure:
- Docker Compose for development and production
- Vite proxy configuration for Ollama and backend APIs
- Hot reload development setup
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>