Docker compatibility:
- Discovery endpoints now read from OLLAMA_URL, LLAMACPP_URL, LMSTUDIO_URL env vars
- docker-compose.yml sets backends to host.docker.internal for container access
- justfile updated with --host 0.0.0.0 for llama-server
Vision support:
- OpenAI adapter now converts images to content parts array format
- Enables vision models with llama.cpp and LM Studio
Bumps version to 0.7.1
- Update tagline to 'local LLMs' instead of 'Ollama'
- Add LLM Backends section with Ollama, llama.cpp, LM Studio
- Update Prerequisites to list all supported backends
- Add LLM Backends to documentation table
- Update Roadmap with multi-backend as completed
- Update Non-Goals to clarify cloud providers not supported
TypeScript error fixes:
- Fix UUID mock type in chunker.test.ts
- Remove invalid timestamp property from Message types in tests
- Fix mockFetch type in client.test.ts
- Add missing parameters property to tool definition in test
Accessibility fixes (109 → 40 warnings, remaining are CSS @apply):
- Add aria-labels to all toggle switches and icon-only buttons
- Add tabindex="-1" to all dialog elements with role="dialog"
- Add onkeydown handlers to modal backdrops for keyboard accessibility
- Fix form labels: change decorative labels to spans, use fieldset/legend for groups
- Convert fileInput variables to $state() for proper reactivity
- Fix closure captures in ThinkingBlock and HtmlPreview with $derived()
- Add role="region" to drag-and-drop zones
- Restore keyboard navigation to BranchNavigator
All 547 tests pass.
Add unified backend abstraction layer supporting multiple LLM providers:
Backend (Go):
- New backends package with interface, registry, and adapters
- Ollama adapter wrapping existing functionality
- OpenAI-compatible adapter for llama.cpp and LM Studio
- Unified API routes under /api/v1/ai/*
- SSE to NDJSON streaming conversion for OpenAI backends
- Auto-discovery of backends on default ports
Frontend (Svelte 5):
- New backendsState store for backend management
- Unified LLM client routing through backend API
- AI Providers tab combining Backends and Models sub-tabs
- Backend-aware chat streaming (uses appropriate client)
- Model name display for non-Ollama backends in top nav
- Persist and restore last selected backend
Key features:
- Switch between backends without restart
- Conditional UI based on backend capabilities
- Models tab only visible when Ollama active
- llama.cpp/LM Studio show loaded model name
- Add AboutTab.svelte with app branding, version display, update checking
- Show update status and download link when new version available
- Include links to GitHub repo and issue tracker
- Display tech stack badges and license info
- Remove About section from GeneralTab (now separate tab)
Also improves development configuration:
- justfile now reads PORT, DEV_PORT, LLAMA_PORT, OLLAMA_PORT from .env
- docker-compose.dev.yml uses env var substitution
- Add dev-build and dev-rebuild recipes for Docker
- Update .env.example with all configurable variables
- Backend runs on port 9090 (matches vite proxy default)
- Adds health check command for all services
- Includes llama.cpp server commands
- Adds test and build commands
- Add SyncStatusIndicator component showing connection status in TopNav
- Add SyncWarningBanner that appears after 30s of backend disconnection
- Green dot when synced, amber pulsing when syncing, red when error/offline
- Warning banner is dismissible but reappears on next failure
Closes #11
- Fix pin icons in ConversationItem to use bookmark style matching TopNav
- Make pin() and archive() methods async with IndexedDB persistence
- Use optimistic updates with rollback on failure
- Queue changes for backend sync via markForSync()
Install script improvements:
- Show release notes after --update completes
- Detect installed version from backend/cmd/server/main.go
- Fetch releases from GitHub API and display changes between versions
- Graceful fallback when jq not installed (shows link only)
Embedding model detection:
- Add EMBEDDING_MODEL_PATTERNS for detecting embedding models
- Add embeddingModels and hasEmbeddingModel derived properties
- KnowledgeTab shows embedding model status conditionally
- MemoryTab shows model installation status with three states
- Add dedicated /search page with semantic, titles, and messages tabs
- Add embedding model selector in Settings > Memory Management
- Add background migration service to index existing conversations
- Fix sidebar search to navigate on Enter only (local filtering while typing)
- Fix search page input race condition with isTyping flag
- Update chat-indexer to use configured embedding model
- Add embedding-based chat indexing for project conversations
- Chunk long messages (1500 chars with 200 overlap) for better coverage
- Index messages when leaving a conversation (background)
- Search indexed chat history with semantic similarity
- Show other project conversations with message count and summary status
- Include relevant chat snippets in project context for LLM
- Fix chunker infinite loop bug near end of text
- Fix curl encoding error with explicit Accept-Encoding header
- Add document previews to project knowledge base context
- Lower RAG threshold to 0.2 and increase topK to 10 for better recall
- Add embedding model dropdown to project file upload
- Create addDocumentAsync that stores immediately, embeds in background
- Add embeddingStatus field to track pending/processing/ready/failed
- Show status indicator and text for each document
- Upload no longer blocks the UI - files appear immediately
- Background embedding shows toast notifications on completion/error
- Add 30 second timeout to generateEmbedding and generateEmbeddings
- Abort controller cancels request if it takes too long
- Clear error message when embedding model isn't available
- Add null check for projectId before file upload
- Wrap loadProjectData in try-catch after upload
- Show detailed error messages on upload failure
- Fix document filter to use strict equality
- Add /projects/[id] route with project header, stats, and tabbed UI
- Add "New chat in [Project]" input that creates chats inside project
- Add project conversation search and filtering
- Add file upload with drag-and-drop for project documents
- Update ProjectFolder to navigate to project page on click
- Add initialMessage prop to ChatWindow for auto-sending first message
- Support ?firstMessage= query param in chat page for project chats
- Add projectId support to vector-store for document association
Add ChatGPT-style projects with cross-chat context sharing:
- Database schema v6 with projects, projectLinks, chatChunks tables
- Project CRUD operations and storage layer
- ProjectsState store with Svelte 5 runes
- Cross-chat context services (summaries, chat indexing, context assembly)
- Project context injection into ChatWindow system prompt
- ProjectFolder collapsible component in sidebar
- ProjectModal for create/edit with Settings, Instructions, Links tabs
- MoveToProjectModal for moving conversations between projects
- "New Project" button in sidebar
- "Move to Project" action on conversation items
Conversations in a project share awareness through:
- Project instructions injected into system prompt
- Summaries of other project conversations
- RAG search across project chat history (stub)
- Reference links
Tool descriptions now explicitly state when models should use them:
- Memory Store: 'Use when user asks to remember, recall, list memories'
- Task Manager: 'Use when user mentions tasks, todos, things to do'
- Structured Thinking: 'Use for complex questions requiring analysis'
- Decision Matrix: 'Use when comparing options or recommendations'
- Project Planner: 'Use for planning, roadmaps, breaking work into phases'
This helps smaller models understand WHEN to call these tools instead of
just responding with text claiming they don't have memory/capabilities.
When the model calls recall without key or category (e.g., 'what memories
do you have?'), it now returns all memories across all categories instead
of an error. This provides better UX since models often use recall instead
of list for memory queries.
- Add validation for missing key/value in store action
- Return formatted entries in recall (category only) - consistent with list
- Check if category exists before reporting success in forget
- Include value in store response for confirmation
- Include entriesRemoved count when forgetting a category
The list action was only returning keys and counts, not the actual
stored values. Now it returns full entries with key, value, and
stored timestamp for all memories.
Models like ministral output tool calls as plain text (e.g., tool_name[ARGS]{json})
instead of using Ollama's native tool_calls format. This adds a parser that:
- Detects text-based tool call patterns in model output
- Converts them to OllamaToolCall format for execution
- Cleans the raw tool call text from the message
- Shows proper ToolCallDisplay UI with styled output
Supports three formats:
- tool_name[ARGS]{json}
- <tool_call>{"name": "...", "arguments": {...}}</tool_call>
- {"tool_calls": [...]} JSON blobs