# Changelog All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## [Unreleased] ### Added - `OPEN_NOTEBOOK_EMBEDDING_BATCH_SIZE` environment variable to override the embedding batch size; default remains `50`. Helps with CPU-only local embedding and stricter OpenAI-compatible endpoints (#735) - `CORS_ORIGINS` environment variable to configure the API's allowed origins (comma-separated). Default remains `*` for backward compatibility; the API now logs a startup warning prompting users to set it for production deployments. Exception responses honor the configured origins when explicitly set (#585, #597, #730) ## [1.8.5] - 2026-04-14 ### Changed - Embedding chunking is now token-based instead of character-based, improving chunk sizing consistency for CJK and mixed-language content (#542, #749) - `OPEN_NOTEBOOK_CHUNK_SIZE` and `OPEN_NOTEBOOK_CHUNK_OVERLAP` semantics changed from characters to tokens; default reduced from 1200 characters to 400 tokens to stay safely below the 512-token ceiling of BERT-family embedders (e.g. mxbai-embed-large) after accounting for tokenizer mismatch and splitter overshoot. Existing stored embeddings are unaffected; only new ingestions use the new chunking. ### Fixed - Credentials endpoint no longer crashes (500) when encryption key doesn't match stored credentials (#740) - Broken credentials are now shown with a decryption warning and can still be deleted - DELETE endpoint for broken credentials supports model migration (`migrate_to` parameter) ## [1.8.4] - 2026-04-09 ### Security - Fix Remote Code Execution (RCE) via Jinja2 Server-Side Template Injection in transformations (CVSS 9.2 Critical) - Fix arbitrary file write via path traversal in file upload (CVSS 7.0 High) - Fix arbitrary file read via Local File Inclusion in source creation (CVSS 8.2 High) ### Dependencies - Bump ai-prompter to >=0.4.0 (uses Jinja2 SandboxedEnvironment to prevent SSTI) ## [1.8.3] - 2026-04-07 ### Security - Fix SurrealDB injection via unsanitized `order_by` query parameter in `GET /api/notebooks` (CVSS 8.7 High) - Add allowlist validation for sorting parameters in notebooks endpoint - Replace f-string query interpolation with parameterized `$variable` binding in source chat and migration queries - Add defensive validation in `get_all()` base method to prevent injection via `order_by` parameter ## [1.8.2] - 2026-04-06 ### Added - DashScope (Qwen) and MiniMax provider support via Esperanto v2.20.0 (#725) - Source list auto-refresh after adding a new source via URL, file upload, or text (#721) ### Fixed - Source asset persistence — failed sources now persist their asset (URL/file path), making them identifiable and retryable (#722) - Source title preservation — user-set custom titles are no longer overwritten after background processing (#722) - Credential cascade delete — deleting a credential now removes linked models instead of returning a 409 error (#722) - Podcast directory names — uses UUID for episode directories, fixing filesystem errors with special characters (#666) - Tiktoken offline handling — API no longer crashes in air-gapped environments (#622) - SurrealDB healthcheck — removed incompatible healthcheck from Docker Compose (#656) - Esperanto embedding fixes — base_url/api_key config issues across multiple embedding providers (#664, #665) ### Docs - Deprecated single-container Docker image in favor of Docker Compose (#723) ### Dependencies - Bump esperanto to >=2.20.0 ## [1.8.1] - 2026-03-10 ### Added - i18n support for Bengali (bn-IN) (#643) - Podcast language support via podcast-creator 0.12.0 (#645) - Upgrade default Azure API version for model testing and fetching (#638) ### Fixed - Tiktoken network errors in offline/air-gapped Docker deployments — pre-downloads encoding at build time (#264, #622) - SurrealDB getting stuck (#656) ### Dependencies - Bump esperanto to 2.19.5 (#657) - Bump langgraph from 1.0.6 to 1.0.10rc1 (#658) - Bump authlib from 1.6.6 to 1.6.7 (#649) - Bump lxml-html-clean from 0.4.3 to 0.4.4 (#646) - Bump rollup from 4.55.1 to 4.59.0 (#635) - Bump minimatch in frontend (#634) - Bump tar from 7.5.9 to 7.5.11 (#650, #659) ## [1.7.4] - 2026-02-18 ### Fixed - Embedding large documents (3MB+) fails with 413 Payload Too Large (#594) - `generate_embeddings()` now batches texts in groups of 50 with per-batch retry, preventing provider payload limits from being exceeded - 413 errors now classified with user-friendly message in error classifier - Misleading "Created 0 embedded chunks" log in `process_source_command` — embedding is fire-and-forget, so the count was always 0; now logs "embedding submitted" instead ## [1.7.3] - 2026-02-17 ### Added - Retry button for failed podcast episodes in the UI (#211, #218) - Error details displayed on failed podcast episodes (#185, #355) - `POST /podcasts/episodes/{id}/retry` API endpoint for re-submitting failed episodes - `error_message` field in podcast episode API responses ### Fixed - Podcast generation failures now correctly marked as "failed" instead of "completed" (#300, #335) - Disabled automatic retries for podcast generation to prevent duplicate episode records (#302) ### Dependencies - Bump podcast-creator to >= 0.11.2 - Bump esperanto to >= 2.19.4 ## [1.7.2] - 2026-02-16 ### Added - Error classification utility that maps LLM provider errors to user-friendly messages (#506) - Global exception handlers in FastAPI for all custom exception types with proper HTTP status codes - `getApiErrorMessage()` frontend helper that falls back to backend messages when no i18n mapping exists ### Fixed - LLM errors (invalid API key, wrong model, rate limits) now show descriptive messages instead of "An unexpected error occurred" (#590) - SSE streaming error events in source chat and ask hooks were swallowed by inner JSON parse catch blocks - Transformation execution errors were caught and re-wrapped as generic 500s instead of using proper status codes - Fail fast when source content extraction returns empty instead of retrying (#589) - Chat input and message overflow with long unbroken strings (#588) - Word-wrap overflow in source cards, note editor, inline edit, note titles, and dialog content (#588) - Translation proxy shadowing `name` keys (#588) - OpenAI-compatible provider name handling via Esperanto update (#583) ### Changed - `ValueError` replaced with `ConfigurationError` in model provisioning for proper error classification - `ConfigurationError` added to command retry `stop_on` lists to avoid retrying permanent config failures ### Dependencies - Bump esperanto to 2.19.3 (#583) - Bump podcast-creator to 0.9.1 ## [1.7.1] - 2026-02-14 ### Added - French (fr-FR) language support (#581) - CI test workflow and improved i18n validation (#580) - Expose embed `command_id` in note API responses (#545) ### Fixed - ElevenLabs TTS credential passthrough via Esperanto update (#578) - Handle empty/whitespace source content without retry loop (#576) - Increase transformation `max_tokens` and update Esperanto dep (#568) - Turn the embedding field into optional (#557) ### Docs - Fix docker container names in local setup guides (#577) ### Dependencies - Bump langchain-core from 1.2.7 to 1.2.11 (#564) - Bump cryptography from 46.0.3 to 46.0.5 (#563) ## [1.7.0] - 2026-02-10 ### Added - **Credential-Based Provider Management** (#477) - New Settings → API Keys page for managing AI provider credentials via the UI - Support for 14 providers: OpenAI, Anthropic, Google, Groq, Mistral, DeepSeek, xAI, OpenRouter, Voyage AI, ElevenLabs, Ollama, Azure OpenAI, OpenAI-Compatible, and Vertex AI - Secure storage of API keys in SurrealDB with field-level encryption (Fernet AES-128-CBC + HMAC-SHA256) - One-click connection testing, model discovery, and model registration per credential - Migration tool to import existing environment variable keys into the credential system - Azure OpenAI support with service-specific endpoints (LLM, Embedding, STT, TTS) - OpenAI-Compatible support with per-service URL configurations - Vertex AI support with project, location, and credentials path - Environment variable API keys deprecated in favor of Settings UI - **Security Enhancements** - Docker secrets support via `_FILE` suffix pattern (e.g., `OPEN_NOTEBOOK_PASSWORD_FILE`) - Default encryption key derived from "0p3n-N0t3b0ok" for easy setup (change in production!) - Default password "open-notebook-change-me" for out-of-box experience (change in production!) - URL validation for SSRF protection - blocks private IPs and localhost (except for Ollama which runs locally) - Security warnings logged when using default credentials - HTML clipboard detection for text sources (#426) - When pasting content, automatically detects HTML format (e.g., from Word, web pages) - Shows info message when HTML is detected, informing user it will be converted to Markdown - Preserves formatting that would be lost with plain text paste - Bump content-core to 0.11.0 for HTML to Markdown conversion support - **Improved Getting Started Experience** - Simplified docker-compose.yml in repository root (single official file) - Added examples/ folder with ready-made configurations: - `docker-compose-ollama.yml` - Local AI with Ollama - `docker-compose-speaches.yml` - Local TTS/STT with Speaches - `docker-compose-full-local.yml` - 100% local setup (Ollama + Speaches) - Inline quick start in README (no need to navigate to docs) - Cross-references between docker-compose examples and documentation - .env.example template with all configuration options ### Fixed - Azure form race condition: all configuration now saved in single atomic request - Migration API "error error" display: added proper MigrationResult model with message field - Connection tester for Ollama providers: improved error handling and URL validation - SqliteSaver async compatibility issues in chat system (#509, #525, #538) - Re-embedding failures with empty content (#513, #515) - Deletion cascade for notes and sources (#77) - YouTube content availability issues (#494) - Large document embedding errors (#489) ### Security - API keys are encrypted at rest using Fernet symmetric encryption - Keys are never returned to the frontend, only configuration status - SSRF protection prevents internal network access via URL validation ### Docs - Complete documentation update for credential-based system across 25 files - All quick-start, installation, and configuration guides now use Settings UI workflow - Environment variable API key instructions moved to deprecated/legacy sections - Fixed broken links in installation docs - Added comprehensive examples/ folder with documented docker-compose configurations - Updated local-tts.md and local-stt.md with links to ready-made examples ### Internationalization - Added Russian (ru-RU) language support (#524) - Added Italian (it-IT) language support (#508) ## [1.6.2] - 2026-01-24 ### Fixed - Connection error with llama.cpp and OpenAI-compatible providers (#465) - Bump Esperanto to 2.17.2 which fixes LangChain connection errors caused by garbage collection ## [1.6.1] - 2026-01-22 ### Fixed - "Failed to send message" error with unhelpful logs when chat model is not configured (#358) - Added detailed error logging with model selection context and full traceback - Improved error messages to guide users to Settings → Models - Added warnings when default models are not configured ### Docs - Ollama troubleshooting: Added "Model Name Configuration" section emphasizing exact model names from `ollama list` - Added troubleshooting entry for "Failed to send message" error with step-by-step solutions - Updated AI Chat Issues documentation with model configuration guidance ## [1.6.0] - 2026-01-21 ### Added - Content-type aware text chunking with automatic HTML, Markdown, and plain text detection (#350, #142) - Unified embedding generation with mean pooling for large content that exceeds model context limits - Dedicated embedding commands: `embed_note`, `embed_insight`, `embed_source` - New utility modules: `chunking.py` and `embedding.py` in `open_notebook/utils/` - Japanese (ja-JP) language support (#450) ### Changed - Embedding is now fire-and-forget: domain models submit embedding commands asynchronously after save - `rebuild_embeddings_command` now delegates to individual embed_* commands instead of inline processing - Chunk size reduced to 1500 characters for better compatibility with Ollama embedding models - Bump Esperanto to 2.16 for increased Ollama context window support ### Removed - Legacy embedding commands: `embed_single_item_command`, `embed_chunk_command`, `vectorize_source_command` - `needs_embedding()` and `get_embedding_content()` methods from domain models - `split_text()` function from text_utils (replaced by `chunk_text()` in chunking module) ### Fixed - Embedding failures when content exceeds model context limits (#350, #142) - Empty note titles when saving from chat (clean thinking tags from prompt graph output) - Orphaned embedding/insight records when deleting sources (cascade delete) - Search results crash with null parent_id (defensive frontend check) - Database migration 10 cleans up existing orphaned records ## [1.5.2] - 2026-01-15 ### Performance - Improved source listing speed by 20-30x (#436, closes #351) - Added database indexes on `source` field for `source_insight` and `source_embedding` tables - Use SurrealDB `FETCH` clause for command status instead of N async calls ## [1.5.1] - 2026-01-15 ### Fixed - Podcast dialog infinite loop error caused by excessive translation Proxy accesses in loops - Podcast dialog UI freezing when typing episode name or additional instructions - Removed incorrect translation keys for user-defined episode profiles (user content should not be translated) ## [1.5.0] - 2026-01-15 ### Added - Internationalization (i18n) support with Chinese (Simplified and Traditional) translations (#371, closes #344, #349, #360) - Frontend test infrastructure with Vitest (#371) - Language toggle component for switching UI language (#371) - Date localization using date-fns locales (#371) - Error message translation system (#371) ### Fixed - Accessibility improvements: added missing `id`, `name`, and `autoComplete` attributes to form inputs (#371) - Added `DialogDescription` to dialogs for Radix UI accessibility compliance (#371) - Fixed "Collapsible is changing from uncontrolled to controlled" warning in SettingsForm (#371) - Fixed lint command for Next.js 16 compatibility (`eslint` instead of `next lint`) ### Changed - Dockerfile optimizations: better layer caching, `--no-install-recommends` for smaller images (#371) - Dockerfile.single refactored into 3 separate build stages for better caching (#371) ## [1.4.0] - 2026-01-14 ### Added - CTA button to empty state notebook list for better onboarding (#408) - Offline deployment support for Docker containers (#414) ### Fixed - Large file uploads (>10MB) by upgrading to Next.js 16 (#423) - Orphaned uploaded files when sources are removed (#421) - Broken documentation links to ai-providers.md (#419) - ZIP support indication removed from UI (#418) - Duplicate Claude Code workflow runs on PRs (#417) - Claude Code review workflow now runs on PRs from forks (#416) ### Changed - Upgraded Next.js from 15.4.10 to 16.1.1 (#423) - Upgraded React from 19.1.0 to 19.2.3 (#423) - Renamed `middleware.ts` to `proxy.ts` for Next.js 16 compatibility (#423) ### Dependencies - next: 15.4.10 → 16.1.1 - react: 19.1.0 → 19.2.3 - react-dom: 19.1.0 → 19.2.3 ## [1.2.4] - 2025-12-14 ### Added - Infinite scroll for notebook sources - no more 50 source limit (#325) - Markdown table rendering in chat responses, search results, and insights (#325) ### Fixed - Timeout errors with Ollama and local LLMs - increased to 10 minutes (#325) - "Unable to Connect to API Server" on Docker startup - frontend now waits for API health check (#325, #315) - SSL issues with langchain (#274) - Query key consistency for source mutations to properly refresh infinite scroll (#325) - Docker compose start-all flow (#323) ### Changed - Timeout configuration now uses granular httpx.Timeout (short connect, long read) (#325) ### Dependencies - Updated next.js to 15.4.10 - Updated httpx to >=0.27.0 for SSL fix