2.7.0
Quilltap v2.7.0 Release Notes
Highlights
File Storage Abstraction - Pluggable storage backends with mount points. Configure multiple storage locations, migrate files between them, and use S3 or local filesystem interchangeably.
Context Compression - Sliding window compression for long conversations using a cheap LLM. Keeps recent messages intact while summarizing older ones, dramatically reducing token costs.
Project-Based Organization - New Projects feature for organizing chats, files, and characters with optional instructions injected into system prompts.
MCP Integration - Model Context Protocol server connector plugin enables connecting to external MCP servers and exposing their tools to Claude.
Homepage Redesign - Three-column responsive layout with welcome section, quick actions, recent chats, projects, and favorite characters.
Major Features
File Storage Abstraction System
- New generic
FileStorageBackendinterface for pluggable storage providers - Built-in local filesystem backend (configurable via
QUILLTAP_FILE_STORAGE_PATH) - S3 backend moved to optional plugin (
qtap-plugin-storage-s3) - Mount point system for configuring multiple storage locations in Settings → File Storage
- Files can be stored on different backends per mount point
- Per-project mount point assignment with batch file migration when changing
- Encrypted secrets storage for backend credentials (AES-256-GCM)
- Orphan file recovery tool: scan backends for untracked files and adopt them
- First-class folder entities with database persistence (empty folders now survive)
- Project-based S3 key structure:
users/{userId}/{projectId}/{folderPath}/{fileId}_{filename}
Sliding Window Context Compression
- Compresses older messages using a cheap LLM while keeping last N messages (default 5) in full context
- Also compresses system prompts when compression is active (tool definitions never compressed)
- New
request_full_contexttool allows AI to reload full conversation if needed - Async pre-compression: starts immediately after receiving response, cached for next message
- Configurable window size (3–10 messages) and target token counts in Chat Settings
- Keep-alive pings during compression prevent proxy/ALB timeouts
Projects Feature
- Organize chats, files, and characters under Projects with optional instructions
- Project instructions injected into system prompts for all associated chats
- Character roster management with "allow any character" option
project_infoLLM tool for accessing project context (get_info, get_instructions, list_files, read_file, search_files)- Project detail page with expandable cards: Files, Characters, Settings
- Sidebar integration with collapsible projects showing nested chats
- Full backup/restore and sync support for projects
Homepage Redesign
- Three-column responsive layout (3 columns desktop, 2 tablet, 1 mobile)
- WelcomeSection with personalized greeting
- QuickActionsRow: Start Chat, Continue Last, New Project, Generate Image
- RecentChatsSection with avatars, message counts, and quick-hide filtering
- ProjectsSection showing 4 most recent active projects
- CharactersSection with 2×2 grid of favorites and quick chat buttons
- Standalone
/generate-imagepage for image generation outside chats
MCP Server Connector Plugin
- New built-in
qtap-plugin-mcpfor connecting to Model Context Protocol servers - Uses official
@modelcontextprotocol/sdkwith Streamable HTTP and SSE transports - Dynamically discovers and exposes tools from connected MCP servers
- Collision-aware naming: tools use original names, only prefixed on collision
- Supports multiple simultaneous server connections
- Authentication: Bearer tokens, API keys, and custom headers
- Auto-reconnection with configurable retry attempts
- Configuration via Settings → Tools with JSON array of server configs
Multi-Tool Plugin Support
- New
getToolDefinitions(config)andexecuteByName(toolName, input, context)pattern - All tool plugins standardized on multi-tool pattern for consistency
- Tool registry handles both static and dynamic (MCP) tools
- Dynamic tool discovery happens at request time, not startup
- Updated
@quilltap/plugin-typesto v1.9.0
API & Backend
V1 API Migration (Complete)
- All legacy
/api/*routes now return 410 Gone with redirect instructions - New
/api/v1/namespace with action dispatch pattern (?action=) - Consolidated endpoints for all entity types with consistent response formats
- Authentication routes:
/api/v1/auth/signup,/api/v1/auth/change-password,/api/v1/auth/delete-account,/api/v1/auth/2fa/*,/api/v1/auth/oauth/[provider]/* - System routes:
/api/v1/system/deployment,/api/v1/system/plugins/initialize,/api/v1/system/backup,/api/v1/system/restore,/api/v1/system/mount-points,/api/v1/system/tools - All frontend components updated to use v1 endpoints
Migration System Overhaul
- Migrations now run in
instrumentation.tsBEFORE server accepts requests - If migrations fail, process exits with code 1 (container won't start with incompatible data)
- Removed
qtap-plugin-upgradeplugin; migrations now inmigrations/directory - MigrationRunner class handles dependency sorting, state tracking, and execution
- Migration state stored in MongoDB
migrations_statecollection
Token Usage Tracking
- Added
promptTokens,completionTokensfields to messages - Added aggregate fields to chats:
totalPromptTokens,totalCompletionTokens,estimatedCostUSD - Added usage tracking to connection profiles:
totalTokens,messageCount - New SystemEvent type for tracking cheap LLM operations
- Cost estimation using OpenRouter pricing when available, with fallback
- Token display settings: per-message tokens/cost, chat totals, system events
- New UI components: TokenBadge, SystemEventMessage, ChatCostSummary
Chat Improvements
File Management LLM Tool
- New
file_managementtool for LLM access to project and general files - Operations: list, read, write, and organize files with folder support
- Write operations require user permission (per-project or general scope)
- Inline file write permission prompt in chat with quick approve/deny
- Deferred execution: tool pauses for approval, LLM sees "Waiting for user approval"
- Permission schema with SINGLE_FILE, PROJECT, GENERAL scopes
Enhanced First Message Context
- Characters receive relevant context when speaking first in new chats
- Includes recent and semantically-relevant memories about other participants (3–5 per participant)
- Project name, description, and instructions included if chat is in a project
- Generic greeting fallback when LLM content filter blocks auto-generation
Graceful Error Recovery
- When requests exceed LLM limits, system attempts to recover gracefully
- Sends simplified message to LLM explaining what happened with attachment details
- LLM provides in-character response suggesting alternatives
- Two-tier fallback: LLM-generated recovery, then static fallback
- Recovery messages saved with
recoveryTypemetadata field - Supports: token limits, PDF page limits (max 100), image/file size limits
Turn Manager Improvements
- Chat title moved to page toolbar header (updates automatically on rename)
- Manual chat rename with auto-rename toggle in tool palette
- Dynamic browser tab title shows chat name
- Improved continue mode error handling with better error extraction
File System Improvements
Redesigned File Browser
- Grid view with image thumbnails (on-demand generation with S3 caching)
- List view with sortable columns (Name, Associations, Type, Date)
- Preview modal for images, PDFs (via PDF.js), text/code files
- Syntax highlighting for code files using react-syntax-highlighter (30+ languages)
- Markdown files render with formatting, YAML frontmatter in "Document Info" section
- Wikilinks supported:
[[File]],[[File#Header]],[[File|Text]] - Copy button for text file preview
- Folder operations: create, rename, delete
- File operations: move to folder, rename, delete with association management
File Upload Improvements
- Removed file type restrictions; all types can now be uploaded
- Backend automatically detects plain text content by sampling bytes
- MIME type inferred from file extension when browser provides generic types
- Paste images directly into chat textarea (auto-uploaded and attached)
- Unicode filenames work correctly (Base64 encoding for S3 metadata)
- Automatic image resizing for provider size limits (Anthropic: 5MB, others: 20MB)
Enhanced File Deletion
- Files linked to chats/characters show detailed confirmation dialog before deletion
- Dialog lists all associated characters and chats using the file
- Deleting dissociates from linked entities; messages get deletion note appended
- Direct repository updates ensure memories are NOT regenerated from deletion notes
Provider & Tool Improvements
Tool Plugin Development
- New
TOOL_PROVIDERplugin capability for custom LLM tools - Tool plugins define schemas, validation, execution handlers, and result formatting
- Plugin configuration UI for per-user settings via
configSchema PluginConfigModaldynamically renders form fields- Configuration stored per-user in MongoDB
- Documented in
TOOL_PLUGIN_DEVELOPMENT.md
Curl Tool Plugin
- New
qtap-plugin-curlprovidescurltool for HTTP requests - Supports GET, POST, PUT, DELETE, PATCH, HEAD, OPTIONS
- Options:
--url,--request,--header,--data,--user-agent,--max-time,--location,--insecure,--render --renderconverts HTML responses to plain text- Configurable URL allowlist for security
- Blocks private/local IP addresses for SSRF protection
Provider Improvements
- Anthropic plugin fetches models from API instead of hardcoded list (v1.0.10)
- OpenRouter streaming token tracking fixed
- OpenAI-compatible streaming token tracking fixed
- GPT-5 reasoning models: increased max_completion_tokens to 4096
- OpenRouter public API used for cost estimation fallback
- Web search tool decoupled from native provider web search (
useNativeWebSearchfield)
Theming & CSS
New qt-* Utility Classes
- Alert CSS variables:
--qt-alert-success-*,--qt-alert-warning-*,--qt-alert-error-*,--qt-alert-info-* - Entity badge CSS variables: character, persona, chat, tag, memory
- Status badge CSS variables: enabled, disabled, related, manual, auto
- Plugin source badge CSS variables: included, npm, git, manual
- Warning button CSS variables:
--qt-button-warning-* - Search highlight class:
qt-highlightwith customizable styling - Filter chip classes:
qt-filter-chip,qt-filter-chip-active - File preview classes:
qt-file-preview-*,qt-wikilink,qt-wikilink-broken - Copy button classes:
qt-copy-button
Theme Updates
- Ocean v1.2.6: Copy button variables, file preview styling
- Earl Grey v1.2.2: Wikilink styling, file preview panels
- Rains v1.1.5: Wikilink styling, file preview panels
- theme-storybook v1.0.13: All new CSS variables and component classes
Testing
Comprehensive Unit Test Expansion
- Phase 1 (API Layer): 201 tests for responses, middleware, search service
- Phase 2 (Chat Services): 97 tests for streaming, tool execution, pseudo-tool parser, conversation builder
- Phase 3 (Data Infrastructure): 143 tests for import/export, theme system
- Phase 4 (Hooks & Auth): 242 tests for 9 React hooks, Arctic OAuth modules
- Phase 5 (Utilities & Services): 161 tests for utility functions, remaining services
- Grand Total: 844+ new tests across 40+ modules with 90%+ coverage on critical paths
- All 3438 tests now pass (164 test suites)
Feature-Specific Tests
- Context compression: 22 tests
- Compression cache service: 17 tests
- Text detection utility: 47 tests
- LLM error types: 47 tests
- Recovery service: 32 tests
- Tool registry: 28 tests
- Orphan recovery: 13 tests
- Folders repository: 28 tests
- First message context: 18 tests
- Memory processor inter-character tracking: 11 tests
Bug Fixes
Critical Fixes
- Sign out now properly clears session and resets UI (wrong cookie name)
- Startup state persists across Next.js module reloads (moved to global namespace)
- All authenticated API routes wait for server startup to complete
- Cloud backups appear in backup list after creation (missing metadata entries)
- Plugin toggle works with PUT handler for enable/disable
- Quick Chat dialog loads connection profiles correctly
- Sync push response format returns arrays instead of numbers
- MongoDB migrations work in hosted environments without admin access
Chat & Messaging Fixes
- Streaming reliability during long context compression operations
- Generic greeting fallback when LLM content filter blocks auto-generation
- OpenRouter streaming tool calls detected (camelCase handling)
- Memory extraction now properly links memories to user-controlled characters
- Template variables in user character descriptions properly substituted
- File write permission prompt appears correctly
UI Fixes
- Recent chats quick-hide filtering on homepage
- Character avatar setting from gallery (HTTP method mismatch)
- Image tagging in character photo gallery (correct API endpoints)
- Plugin source detection showing npm packages correctly
- Cancel button in form modals always enabled except during loading
- Settings UI data structure and API endpoint alignment
Refactoring
Route Decomposition
- Characters route: 821 → 428 lines (extracted character-wizard.service.ts)
- Chats/[id] route: 1,876 → 49 lines (extracted handlers/ and actions/ directories)
- Extracted 14 Zod validation schemas, helper functions, and type definitions
Service Extraction
handleInterCharacterMemory: Extracts memories one character learns about anotherhandleContextSummary: Updates running context summaries using cheap LLMhandleTitleUpdate: Evaluates and updates chat titles based on conversation
CSS Migration
- Converted Tailwind color classes to qt-* semantic classes throughout
RenameReplaceTab.tsx: Error alerts, info boxesplugins-tab.tsx: Plugin source badges
Security
Dependency Updates
- esbuild 0.19.0/0.20.0/0.24.0 → 0.27.0 across all 14 plugins (CVE-2024-23334)
Documentation
- Major README overhaul: repositioned as general-purpose AI chat platform
- Roadmap extracted to
features/ROADMAP.md - Provider plugin development guide:
docs/PROVIDER_PLUGIN_DEVELOPMENT.md - Testing guide:
docs/TESTING_GUIDE.md - File LLM access documentation:
docs/FILE_LLM_ACCESS.md - Updated CLAUDE.md documentation references