Commit graph

703 commits

Author SHA1 Message Date
Luis Novo
d28bff4888
feat: add French (fr-FR) language support (#581)
- Add fr-FR locale with French translations (875 keys)
- Register fr-FR in locale index, LanguageToggle, and date-locale
- Add common.french key to all existing locale files
- Sync fr-FR key structure to match current en-US after cleanup

Based on #514, rebased and adapted to the current locale structure.

Closes #481

Co-authored-by: saikrishna-prathapaneni <saiprathapaneni23@gmail.com>
2026-02-14 20:34:41 -03:00
Luis Novo
fb21f5e777
feat: add CI test workflow and improve i18n validation (#580)
- Add GitHub Actions workflow to run backend (pytest) and frontend
  (vitest) tests on PRs and pushes to main
- Replace hardcoded locale parity tests with dynamic discovery from
  the resources registry, so new languages are tested automatically
- Add unused key detection test that scans source files for i18n
  key references, with optional chaining normalization
- Remove 149 genuinely unused translation keys from all 7 locale files
- Add missing keys to it-IT (7) and ru-RU (5) with English fallback
2026-02-14 20:14:08 -03:00
Luis Novo
9b507f111c
fix: update esperanto to fix ElevenLabs TTS credential passthrough (#578)
Esperanto's AIFactory.create_text_to_speech() did not accept a config
dict like the other factory methods, so credentials configured via the
UI were not passed through. Fixed upstream in esperanto 2.9.2.

Refs #571
2026-02-14 19:12:49 -03:00
Luis Novo
9811c58d15
docs: fix docker container names in local setup guides (#577)
Docker Compose v2 derives container names from the directory name using
dashes. Since the docs instruct users to create an `open-notebook-local`
folder, the correct container name is `open-notebook-local-ollama-1`,
not `open_notebook-ollama-1`.

Fixes #575
2026-02-14 18:38:32 -03:00
Richard Solomou
7efac77503
feat: expose embed command_id in note API responses (#545)
* feat: expose embed command_id in note API responses

Note.save() already returns the command_id from the embed_note
background job, but the API routes discarded it. This surfaces
the command_id in NoteResponse for both POST and PUT endpoints,
enabling callers to poll GET /api/commands/jobs/{command_id} to
know when embedding has completed.

* Add tests for note API command_id response
2026-02-14 18:11:23 -03:00
dependabot[bot]
db094da10a
chore(deps): bump langchain-core from 1.2.7 to 1.2.11 (#564)
Bumps [langchain-core](https://github.com/langchain-ai/langchain) from 1.2.7 to 1.2.11.
- [Release notes](https://github.com/langchain-ai/langchain/releases)
- [Commits](https://github.com/langchain-ai/langchain/compare/langchain-core==1.2.7...langchain-core==1.2.11)

---
updated-dependencies:
- dependency-name: langchain-core
  dependency-version: 1.2.11
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-02-14 18:10:43 -03:00
dependabot[bot]
1049b39449
chore(deps): bump cryptography from 46.0.3 to 46.0.5 (#563)
Bumps [cryptography](https://github.com/pyca/cryptography) from 46.0.3 to 46.0.5.
- [Changelog](https://github.com/pyca/cryptography/blob/main/CHANGELOG.rst)
- [Commits](https://github.com/pyca/cryptography/compare/46.0.3...46.0.5)

---
updated-dependencies:
- dependency-name: cryptography
  dependency-version: 46.0.5
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-02-14 18:10:27 -03:00
Luis Novo
26d5349750
fix: handle empty/whitespace source content without retry loop (#576)
Source.vectorize() wrapped its own ValueError in DatabaseOperationError,
bypassing the stop_on=[ValueError] retry guard in process_source_command.
This caused up to 15 retries when processing files with no extractable
text, blocking sync API requests indefinitely.

- Re-raise ValueError directly in Source.vectorize() instead of wrapping
- Add .strip() check to catch whitespace-only content
- Skip vectorization gracefully in save_source() when content is empty
- Add unit tests for vectorize error handling

Fixes #560
2026-02-14 18:09:07 -03:00
Luis Novo
877c303b02
fix: update esperanto dep and increase transformation max_tokens (#568)
* fix: increase transformation max_tokens from 5055 to 8192

Closes #565

* chore: update esperanto dep to fix api keys passing via config - fixes: #567
2026-02-12 07:33:27 -03:00
Luis Novo
98dadd151a
fix: turn the embedding field into optional (#557)
* fix: turn the embedding field into optional

* enable migration 13 - fixes: #556
2026-02-10 11:24:17 -03:00
Luis Novo
97b7fc6e0d
docs: update CHANGELOG for v1.7.0 release (#555)
* chore: bump version to 1.7.0

* docs: update CHANGELOG for v1.7.0 release
2026-02-10 08:48:25 -03:00
Luis Novo
3cb8c73cf1
chore: bump version to 1.7.0 (#554) 2026-02-10 08:36:32 -03:00
dependabot[bot]
0268a1e6a3
chore(deps): bump axios from 1.12.0 to 1.13.5 in /frontend (#553)
Bumps [axios](https://github.com/axios/axios) from 1.12.0 to 1.13.5.
- [Release notes](https://github.com/axios/axios/releases)
- [Changelog](https://github.com/axios/axios/blob/v1.x/CHANGELOG.md)
- [Commits](https://github.com/axios/axios/compare/v1.12.0...v1.13.5)

---
updated-dependencies:
- dependency-name: axios
  dependency-version: 1.13.5
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-02-10 08:34:58 -03:00
dependabot[bot]
827cf55d25
chore(deps): bump pip from 25.3 to 26.0 (#532)
Bumps [pip](https://github.com/pypa/pip) from 25.3 to 26.0.
- [Changelog](https://github.com/pypa/pip/blob/main/NEWS.rst)
- [Commits](https://github.com/pypa/pip/compare/25.3...26.0)

---
updated-dependencies:
- dependency-name: pip
  dependency-version: '26.0'
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-02-10 08:34:37 -03:00
Luis Novo
3f352cfcce
feat: credential-based API key management (#477) (#540)
* feat: replace provider config with credential-based system (#477)

Introduce a new credential management system replacing the old
ProviderConfig singleton and standalone Models page. Each credential
stores encrypted API keys and provider-specific configuration with
full CRUD support via a unified settings UI.

Backend:
- Add Credential domain model with encrypted API key storage
- Add credentials API router (CRUD, discovery, registration, testing)
- Add encryption utilities for secure key storage
- Add key_provider for DB-first env-var fallback provisioning
- Add connection tester and model discovery services
- Integrate ModelManager with credential-based config
- Add provider name normalization for Esperanto compatibility
- Add database migrations 11-12 for credential schema

Frontend:
- Rewrite settings/api-keys page with credential management UI
- Add model discovery dialog with search and custom model support
- Add compact default model assignments (primary/advanced layout)
- Add inline model testing and credential connection testing
- Add env-var migration banner
- Update navigation to unified settings page
- Remove standalone models page and old settings components

i18n:
- Update all 7 locale files with credential and model management keys

Closes #477

Co-Authored-By: JFMD <git@jfmd.us>
Co-Authored-By: OraCatQAQ <570768706@qq.com>

* fix: address PR #540 review comments

- Fix docs referencing removed Models page
- Fix error-handler returning raw messages instead of i18n keys
- Fix auth.py misleading docstring and missing no-password guard
- Fix connection_tester using wrong env var for openai_compatible
- Add provision_provider_keys before model discovery/sync
- Update CLAUDE.md to reflect credential-based system
- Fix missing closing brace in api-keys page useEffect

* fix: add logging to credential migration and surface errors in UI

- Add comprehensive logging to migrate-from-env and
  migrate-from-provider-config endpoints (start, per-provider
  progress, success/failure with stack traces, final summary)
- Fix frontend migration hooks ignoring errors array from response
- Show error toast when migration fails instead of "nothing to migrate"
- Invalidate status/envStatus queries after migration so banner updates

* docs: update CLAUDE.md files for credential system

Replace stale ProviderConfig and /api-keys/ references across 8 CLAUDE.md
files to reflect the new Credential-based system from PR #540.

* docs: update user documentation for credential-based system

Replace env var API key instructions with Settings UI credential
workflow across all user-facing documentation. The new flow is:
set OPEN_NOTEBOOK_ENCRYPTION_KEY → start services → add credential
in Settings UI → test → discover models → register.

- Rewrite ai-providers.md, api-configuration.md, environment-reference.md
- Update all quick-start guides and installation docs
- Update ollama.md, openai-compatible.md, local-tts/stt networking sections
- Update reverse-proxy.md, development-setup.md, security.md
- Fix broken links to non-existent docs/deployment/ paths
- Add credentials endpoints to api-reference.md
- Move all API key env vars to deprecated/legacy sections

* chore: bump version to 1.7.0-rc1

Release candidate for credential-based provider management system.

* fix: initialize provider before try block in test_credential

Prevents UnboundLocalError when Credential.get() throws (e.g.,
invalid credential_id) before provider is assigned.

* fix: reorder down migration to drop index before table

Removes duplicate REMOVE FIELD statement and reorders so the index
is dropped before the table, preventing rollback failures.

* refactor: simplify encryption key to always derive via SHA-256

Remove the dual code path in _ensure_fernet_key() that detected native
Fernet keys. Since the credential system is new, always deriving via
SHA-256 removes unnecessary complexity. Also removes the generate_key()
function and Fernet.generate_key() references from docs.

* fix: correct mock patch targets in embedding tests and URL validation

Fix embedding tests patching wrong module path for model_manager
(was targeting open_notebook.utils.embedding.model_manager but it's
imported locally from open_notebook.ai.models). Also fix URL validation
to allow unresolvable hostnames since they may be valid in the
deployment environment (e.g., Azure endpoints, internal DNS).

* feat: add global setup banner for encryption and migration status

Show a persistent banner in AppShell when encryption key is missing
(red) or env var API keys can be migrated (amber), so users see
these prompts on every page instead of only on Settings > API Keys.

Includes a docs link for the encryption banner and i18n support
across all 7 locales.

* docs: several improvements to docker-compose e env examples

* Update README.md

Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>

* docs: fix env var format in README and update model setup instructions

Align the encryption key snippet in README Step 2 with the list
format used in the compose file. Replace deprecated "Settings →
Models" instructions with credential-based Discover Models flow.

* fix: address credential system review issues

- Fix SSRF bypass via IPv4-mapped IPv6 addresses (::ffff:169.254.x.x)
- Fix TTS connection test missing config parameter
- Add Azure-specific model discovery using api-key auth header
- Add Vertex static model list for credential-based discovery
- Fix PROVIDER_DISCOVERY_FUNCTIONS incorrect azure/vertex mapping
- Extract business logic to api/credentials_service.py (service layer)
- Move credential Pydantic schemas to api/models.py
- Update tests to use new service imports and ValueError assertions

* fix: sanitize error responses and migrate key_provider to Credential

- Replace raw exception messages in all credential router 500 responses
  with generic error strings (internal details logged server-side only)
- Refactor key_provider.py to use Credential.get_by_provider() instead
  of deprecated ProviderConfig.get_instance()
- Remove unused functions (get_provider_configs, get_default_api_key,
  get_provider_config) that were dead code

---------

Co-authored-by: JFMD <git@jfmd.us>
Co-authored-by: OraCatQAQ <570768706@qq.com>
2026-02-10 08:30:22 -03:00
danrush777
1a6fe4723b fix: handle structured content format in LLM response parsing
Some LLM providers (notably Gemini, DeepSeek via OpenAI-compatible
proxies) return ai_message.content as a list of content parts:
[{'type': 'text', 'text': '...', 'extras': {...}}]

The current code uses str() on non-string content, which produces the
Python repr of the entire list — not valid JSON. This breaks
PydanticOutputParser.parse() with OutputParserException.

This adds extract_text_content() to properly unwrap text from both
string and structured content formats, applied in ask.py, chat.py,
and prompt.py.

Fixes #329
2026-02-08 22:29:45 +01:00
Kevin Colten
b1d7a18ce8
Add solo-speaker mode to podcast transcript prompt (#530)
Introduce conditional handling for solo podcasts in prompts/podcast/transcript.jinja. Changes add tailored final-segment wording, strict solo-speaker formatting and guidelines (force use of the single speaker name, require minimum turns, enforce not inventing other speakers), and additional transcript-generation reminders (flow, root "transcript" key, transitions). Multi-speaker behavior and existing format instructions are preserved.
2026-02-08 08:15:26 -03:00
Nikita
eae429b3bd
fix: complete SqliteSaver async compatibility in chat routers (#525)
* fix: use sync get_state() for SqliteSaver in chat routers

Replace async aget_state() calls with sync get_state() wrapped in
asyncio.to_thread() to fix SqliteSaver compatibility issues.

SqliteSaver does not support async methods, so we need to run
the sync version in a separate thread.

This is a follow-up to #519 which fixed the same issue in
graph_utils.py but missed four locations:
- chat.py: get_session() and execute_chat()
- source_chat.py: get_source_chat_session() and stream_source_chat_response()

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* chore: translate comments to English

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: Luis Novo <lfnovo@gmail.com>
2026-02-06 15:55:05 -03:00
Luiza
36ac10d5f6
[Bug]: execute_command_sync receives 300 (int) as context instead of timeout. #537 (#538)
Happened when requested to include a file using the api.

Tests Done:
. Requested again to include the same file, and it did not throw any
error.
. After, I requested the include of lots of other files, and had no
issue.

Co-authored-by: Luiza Carneiro <luiza.carneiro@cloudera.com>
2026-02-06 15:54:32 -03:00
Nikita
2137758103
docs: add local STT setup guide (#521)
Add comprehensive documentation for setting up local speech-to-text
using Speaches with faster-whisper. Includes model recommendations,
GPU acceleration, Docker networking, and troubleshooting.

Also updates related docs with cross-references to the new guide.

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 18:54:49 -03:00
Nikita
d0816caab1
feat(i18n): add Russian (ru-RU) language support (#524)
Add complete Russian language support to Open Notebook following the
established i18n patterns from ja-JP and pt-BR implementations.

Changes:
- Create ru-RU locale file with all translation keys
- Register ru-RU in locales/index.ts resources and languages array
- Add ru-RU key integrity test
- Add Russian date-fns locale mapping
- Add Russian option to LanguageToggle dropdown
- Add `russian: "Русский"` key to all existing locales
- Update README.md supported languages list
- Update locales CLAUDE.md documentation

Fixes #523

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: Luis Novo <lfnovo@gmail.com>
2026-02-01 18:48:54 -03:00
Emiliano Morello
0f76c93b00
Add Italian language support (#508)
* Create new file index.ts

* Content added

* updated words

* Add Italian language support to locales

* Fix typos in Italian localization strings

* Fix typo in Italian locale for defaultAssignments
2026-02-01 18:43:38 -03:00
Luis Novo
2861439ca0
fix: prevent note editor from expanding beyond dialog bounds (#528)
Add max-height and overflow constraints to MarkdownEditor component
to prevent the textbox from expanding indefinitely when typing.
The editor now scrolls internally instead of pushing the save
button out of view.

- Added max-h-[500px] to limit editor height
- Added overflow-hidden to container
- Made internal editor content scrollable with overflow-y-auto
2026-02-01 16:54:09 -03:00
Luis Novo
4f33b854dd
feat: add environment variables for chunk size configuration (#520)
Adds OPEN_NOTEBOOK_CHUNK_SIZE and OPEN_NOTEBOOK_CHUNK_OVERLAP environment
variables to allow users to configure chunking behavior for different
embedding models with varying context window limits.

Key changes:
- CHUNK_SIZE is now configurable via OPEN_NOTEBOOK_CHUNK_SIZE (default: 1200)
- CHUNK_OVERLAP is configurable via OPEN_NOTEBOOK_CHUNK_OVERLAP (default: 15%)
- Validation with warnings for invalid or out-of-range values
- Updated documentation with configuration examples

This enables users of models like mxbai-embed-large with limited context
windows to reduce chunk size accordingly.

Closes #510
2026-01-31 19:30:56 -03:00
Luis Novo
98eb6ed202
fix: use sync get_state() for SqliteSaver compatibility (#519)
SqliteSaver does not support async methods like aget_state().
Use asyncio.to_thread() to run the sync get_state() call from
async context, maintaining compatibility with the existing
sync graph invocations.

Closes #509
2026-01-31 19:25:11 -03:00
Luis Novo
c4ed1b18ec
chore: bump surreal-commands to 1.3.1 (#517)
* chore: bump surreal-commands to 1.3.1

Required for improved retry logging with command_id in error messages.

Ref #513

* chore: update uv.lock for surreal-commands 1.3.1
2026-01-31 19:00:15 -03:00
Luis Novo
5b2c97cab7
Fix re-embedding issues and improve retry strategy (#515)
* fix: filter empty content in rebuild embeddings queries

Update collect_items_for_rebuild() to properly filter out items with
empty or whitespace-only content before submitting embedding jobs.

Changes:
- Sources: add string::trim(full_text) != '' filter
- Notes: add string::trim(content) != '' filter
- Insights: add content != none AND string::trim(content) != '' filter
  (previously had no content filter at all)

This prevents unnecessary job submissions that would fail validation
in the individual embed commands.

Ref #513

* feat: add command_id to embedding error logs

Add get_command_id() helper to extract command_id from execution context.
Include command_id in error logs for all embedding commands:
- embed_note_command
- embed_insight_command
- embed_source_command
- create_insight_command

This makes it easier to trace failed embedding jobs back to specific
command records in the database.

Ref #513

* fix: improve logging for embedding commands

Log improvements:
- Add command_id to all embedding error logs for traceability
- Transaction conflicts in repo_insert now log at DEBUG (not ERROR)
- Embedding API errors log at DEBUG, only ERROR when retries exhausted
- Friendlier retry messages: "This will be retried automatically"
- Include model name and command_id in generate_embeddings errors

Files changed:
- commands/embedding_commands.py: command_id in logs, friendlier messages
- open_notebook/database/repository.py: DEBUG for transaction conflicts
- open_notebook/utils/embedding.py: DEBUG logging, pass-through command_id

Ref #513

* fix: correct field names in rebuild embeddings status endpoint

The API status endpoint was looking for wrong field names:
- sources_processed → sources_submitted
- notes_processed → notes_submitted
- insights_processed → insights_submitted
- processed_items → jobs_submitted
- failed_items → failed_submissions

The command outputs "_submitted" because embedding happens async
(we count jobs submitted, not items processed).

Ref #513

* fix: update rebuild UI text to reflect async job submission

Changed terminology from "Completed/processed" to "Jobs Submitted"
since the rebuild command submits embedding jobs for async processing,
not completing them synchronously.

Updated in all locales: en-US, pt-BR, zh-CN, zh-TW, ja-JP

Ref #513

* refactor: migrate retry strategy from allowlist to blocklist

- Change from `retry_on: [RuntimeError, ...]` to `stop_on: [ValueError]`
- This is more resilient: new exception types auto-retry by default
- Simplified exception handling: ValueError = permanent, else = retry
- Transient errors logged at DEBUG (surreal-commands logs final failure)
- Permanent errors (ValueError) logged at ERROR

Ref #513
2026-01-31 18:55:01 -03:00
Luis Novo
301dd4e20a
fix: async insight creation to prevent transaction conflicts (#512)
Migrate insight creation to the command system with automatic retry logic
to prevent SurrealDB transaction conflicts during batch imports.

Changes:
- Add create_insight_command with retry logic for transaction conflicts
- Add run_transformation_command for async transformation execution
- Make Source.add_insight() fire-and-forget (returns command_id)
- Update POST /sources/{id}/insights to return 202 Accepted immediately
- Frontend polls command status until complete, then refreshes
- Auto-update notebook page icon when source gains insights
- Add i18n keys for insight generation feedback

Related to #489
2026-01-31 15:51:27 -03:00
Luis Novo
303ffacfa5
docs: add reverse proxy timeout configuration (#501)
* chore: force env file on api

* docs: add reverse proxy timeout configuration for all proxies

- Add timeout configuration to Caddy examples (read_timeout, write_timeout)
- Add Traefik serversTransport timeout configuration
- Increase nginx timeout from 300s to 600s to match frontend
- Expand timeout troubleshooting section with symptoms and solutions
- Reference API_CLIENT_TIMEOUT and ESPERANTO_LLM_TIMEOUT env vars

Fixes #447
2026-01-30 00:02:03 -03:00
Luis Novo
b1d4c5cd34
fix: Docker networking and permissions documentation (#500)
* chore: force env file on api

* fix: Docker networking and permissions documentation

- Add HOSTNAME=0.0.0.0 as default in Dockerfiles for reverse proxy compatibility
- Document Linux extra_hosts requirement for host.docker.internal
- Add user: root to SurrealDB examples for bind mount permissions on Linux
- Update environment reference and reverse proxy docs

Fixes #483, fixes #485, fixes #409
2026-01-29 23:54:17 -03:00
Luis Novo
03f9edfec2
feat: use standard HTTP_PROXY/HTTPS_PROXY environment variables (#499)
Update proxy configuration to use industry-standard environment variables
(HTTP_PROXY, HTTPS_PROXY, NO_PROXY) instead of custom variables.

The underlying libraries (esperanto, content-core, podcast-creator)
now automatically detect proxy settings from these standard variables.

- Bump content-core>=1.14.1 (fixes #494)
- Bump esperanto>=2.18
- Bump podcast-creator>=0.9
- Update documentation with new proxy configuration
2026-01-29 23:31:02 -03:00
Fauzira Alpiandi
9adf70d18d
feat: message counting for chat sessions (#430) 2026-01-29 23:00:22 -03:00
POWERFULMOVES
5621066123
fix(api): initialize file_path before try block (#497)
This PR fixes a potential UnboundLocalError in the API router
by ensuring file_path is initialized before the try block.

## Issue

In the create_source endpoint, file_path was initialized inside the
try block. If an exception occurred before this initialization,
exception handlers that reference file_path would crash with
UnboundLocalError.

## Fix

- Initialize file_path = None before the try block (line 289)
- Add explanatory comment for future maintainers
- Remove duplicate initialization inside the try block

This ensures exception handlers on line 415 can safely reference
file_path without causing runtime errors.

## Testing

- Verified exception handler path no longer crashes
- Confirmed file cleanup works correctly in error cases

Co-authored-by: POWERFULMOVES <POWERFULMOVES@users.noreply.github.com>
Co-authored-by: Claude Code <noreply@anthropic.com>
2026-01-29 22:55:59 -03:00
dependabot[bot]
bddc82ac66
chore(deps): bump python-multipart from 0.0.21 to 0.0.22 (#479)
Bumps [python-multipart](https://github.com/Kludex/python-multipart) from 0.0.21 to 0.0.22.
- [Release notes](https://github.com/Kludex/python-multipart/releases)
- [Changelog](https://github.com/Kludex/python-multipart/blob/master/CHANGELOG.md)
- [Commits](https://github.com/Kludex/python-multipart/compare/0.0.21...0.0.22)

---
updated-dependencies:
- dependency-name: python-multipart
  dependency-version: 0.0.22
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-01-29 22:44:32 -03:00
dependabot[bot]
cb4301ab6e
chore(deps): bump next from 16.1.1 to 16.1.5 in /frontend (#482)
Bumps [next](https://github.com/vercel/next.js) from 16.1.1 to 16.1.5.
- [Release notes](https://github.com/vercel/next.js/releases)
- [Changelog](https://github.com/vercel/next.js/blob/canary/release.js)
- [Commits](https://github.com/vercel/next.js/compare/v16.1.1...v16.1.5)

---
updated-dependencies:
- dependency-name: next
  dependency-version: 16.1.5
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-01-29 22:43:54 -03:00
dependabot[bot]
0b5197f2fa
chore(deps-dev): bump tar from 7.5.6 to 7.5.7 in /frontend (#495)
Bumps [tar](https://github.com/isaacs/node-tar) from 7.5.6 to 7.5.7.
- [Release notes](https://github.com/isaacs/node-tar/releases)
- [Changelog](https://github.com/isaacs/node-tar/blob/main/CHANGELOG.md)
- [Commits](https://github.com/isaacs/node-tar/compare/v7.5.6...v7.5.7)

---
updated-dependencies:
- dependency-name: tar
  dependency-version: 7.5.7
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-01-29 22:43:23 -03:00
Luis Novo
2ec64c0440
chore: publish v1-dev Docker tags on merge to main (#476)
Update build-dev workflow to:
- Push v1-dev and v1-dev-single tags on merge to main
- Build both regular and single-container images
- Push to both GHCR and Docker Hub
- Keep test-only builds for PRs (no push)

This enables users to test unreleased features via:
- docker pull ghcr.io/lfnovo/open-notebook:v1-dev
- docker pull lfnovo/open_notebook:v1-dev
2026-01-26 07:44:04 -03:00
Luis Novo
6dc9a3db50
feat: detect HTML content in clipboard for text sources (#475)
* chore: bump content-core to support html to markdown

* feat: detect HTML content in clipboard for text sources

- Add paste handler to detect text/html format in clipboard
- Use HTML content instead of plain text when available
- Display info message when HTML is detected
- Add translations for all supported languages (en-US, pt-BR, ja-JP, zh-CN, zh-TW)

* fix: reset HTML detection banner on plain text paste

Clear the hasHtmlContent flag when pasting plain text (no HTML in
clipboard) so the banner doesn't persist incorrectly after replacing
HTML content with plain text.
2026-01-25 21:36:58 -03:00
Luis Novo
a329806a33
fix: improve error handling in repo_create and repo_insert (#474)
* fix: improve error handling in repo_create and repo_insert

When SurrealDB encounters an error (e.g., schema validation failure),
it may return a string error message instead of the expected record.
Previously, this caused a confusing "'str' object has no attribute
'items'" error in base.py:save().

This change adds error string detection to repo_create() and repo_insert(),
raising a RuntimeError with the actual SurrealDB error message. This helps
debug issues like #469 by showing the underlying database error.

Related to #469

* fix: preserve error details in repo_insert RuntimeError handling

The RuntimeError with SurrealDB error message was being caught by
the broad 'except Exception' block and replaced with a generic
'Failed to create record' message.

Now RuntimeError is caught separately and re-raised, preserving
the actual error details for debugging.
2026-01-25 15:11:51 -03:00
Luis Novo
4e411e0488
feat: add cascade deletion for notebooks with delete preview (#471)
* feat: decrease chunking size for maximum ollama compatibility

* docs: improve i18n info on Claude.md

* feat: add cascade deletion for notebooks with delete preview

- Add Notebook.get_delete_preview() to show counts of affected items
- Add Notebook.delete(delete_exclusive_sources) for cascade deletion
- Always delete notes when notebook is deleted
- Allow user to choose: delete or keep exclusive sources
- Shared sources are always unlinked but never deleted
- Add NotebookDeleteDialog component with radio button options
- Add delete-preview API endpoint
- Update delete endpoint with delete_exclusive_sources param
- Add i18n support for all 5 locales

Closes #77

* docs: remove harcoded config settings
2026-01-25 14:56:14 -03:00
Luis Novo
f14020d385
fix: run execute_command_sync in thread pool to avoid event loop conflict (#468)
When async_processing=False, the sync path calls execute_command_sync()
which internally uses asyncio.run(). This fails when called from FastAPI's
already-running event loop with 'asyncio.run() cannot be called from a
running event loop'.

Wrapping the call in asyncio.to_thread() runs it in a thread pool executor,
avoiding the event loop conflict while preserving the synchronous behavior
from the API consumer's perspective.

Fixes #453
2026-01-24 18:19:02 -03:00
Luis Novo
28936d3944
fix: connection error with llama.cpp and OpenAI-compatible providers (#466)
* docs: update CHANGELOG for v1.6.0 release

* fix: connection error with llama.cpp and OpenAI-compatible providers

Bump Esperanto to 2.17.2 which fixes LangChain connection errors
caused by garbage collection closing shared HTTP clients.

Closes #465
2026-01-24 09:39:38 -03:00
Luis Novo
47c513edfd
fix: improve error logging for chat model configuration issues (#458)
* docs: update CHANGELOG for v1.6.0 release

* fix: improve error logging for chat model configuration issues (#358)

- Add detailed error logging in provision.py when model lookup fails
- Add warning logging in models.py when default model is not configured
- Add traceback logging in chat router exception handler
- Update Ollama docs with model name configuration guidance
- Update troubleshooting docs with "Failed to send message" solutions
- Bump version to 1.6.1

* chore: uvlock
2026-01-23 16:45:13 -03:00
dependabot[bot]
09a0f786aa
chore(deps-dev): bump tar from 7.5.3 to 7.5.6 in /frontend (#454)
Bumps [tar](https://github.com/isaacs/node-tar) from 7.5.3 to 7.5.6.
- [Release notes](https://github.com/isaacs/node-tar/releases)
- [Changelog](https://github.com/isaacs/node-tar/blob/main/CHANGELOG.md)
- [Commits](https://github.com/isaacs/node-tar/compare/v7.5.3...v7.5.6)

---
updated-dependencies:
- dependency-name: tar
  dependency-version: 7.5.6
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-01-21 23:50:02 -03:00
Jun Endo
0436a851da
feat(i18n): add Japanese (ja-JP) language support (#450) 2026-01-21 23:49:44 -03:00
Luis Novo
d8006ff5cb
feat: content-type aware chunking and unified embedding (#444)
* feat: content-type aware chunking and unified embedding

- Add chunking.py with HTML, Markdown, and plain text detection
- Add embedding.py with mean pooling for large content
- Create dedicated commands: embed_note, embed_insight, embed_source
- Use fire-and-forget pattern for embedding via submit_command()
- Refactor rebuild_embeddings_command to delegate to individual commands
- Remove legacy commands and needs_embedding() methods
- Reduce chunk size to 1500 chars for Ollama compatibility
- Update CLAUDE.md documentation for new architecture

Fixes #350, #142

* fix: address code review issues

- Note.save() now returns command_id for tracking embedding jobs
- Add length check after generate_embeddings() to fail fast on mismatch
- Add numpy as explicit dependency (was transitive)
- Remove hardcoded chunk sizes from docstrings

* docs: address code review comments

- Rename "SYNC PATH" to "DOMAIN MODEL PATH" in embedding router
- Add test_chunking.py and test_embedding.py to Testing Strategy
- Clarify auto-embedding behavior for each domain model

* fix: clean thinking tags from prompt graph output

Adds clean_thinking_content() to prompt.py to handle extended thinking
models that return <think>...</think> tags. This fixes empty titles
when saving notes from chat.

* chore: remove local docker-compose from git

* fix(frontend): handle null parent_id in search results

Add defensive check for null parent_id in search results to prevent
"Cannot read properties of null (reading 'split')" error. This can
happen with orphaned records in the database.

* fix: cascade delete embeddings and insights when source is deleted

When deleting a Source, now also deletes associated:
- source_embedding records
- source_insight records

This prevents orphaned records that cause null parent_id errors
in vector search results.

* fix: add cleanup for orphan embedding/insight records in migration 10

Deletes source_embedding and source_insight records where the
linked source no longer exists (source.id = NONE).

* chore: bump esperanto to 2.16

Increases ctx_num for Ollama models to accommodate larger notebook
context windows. See: https://github.com/lfnovo/esperanto/pull/69
2026-01-21 23:49:08 -03:00
dependabot[bot]
78b9024ad3
chore(deps): bump pyasn1 from 0.6.1 to 0.6.2 (#443)
Bumps [pyasn1](https://github.com/pyasn1/pyasn1) from 0.6.1 to 0.6.2.
- [Release notes](https://github.com/pyasn1/pyasn1/releases)
- [Changelog](https://github.com/pyasn1/pyasn1/blob/main/CHANGES.rst)
- [Commits](https://github.com/pyasn1/pyasn1/compare/v0.6.1...v0.6.2)

---
updated-dependencies:
- dependency-name: pyasn1
  dependency-version: 0.6.2
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-01-18 16:50:59 -03:00
dependabot[bot]
9b0b7e80b3
chore(deps-dev): bump tar from 7.4.3 to 7.5.3 in /frontend (#445)
Bumps [tar](https://github.com/isaacs/node-tar) from 7.4.3 to 7.5.3.
- [Release notes](https://github.com/isaacs/node-tar/releases)
- [Changelog](https://github.com/isaacs/node-tar/blob/main/CHANGELOG.md)
- [Commits](https://github.com/isaacs/node-tar/compare/v7.4.3...v7.5.3)

---
updated-dependencies:
- dependency-name: tar
  dependency-version: 7.5.3
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-01-18 16:50:39 -03:00
nanshaws
9c61ffef9a
docs: add conda installation instructions to README (#446)
* docs: add conda installation instructions to README

docs: add conda installation instructions to README

* docs: add conda environment setup as an alternative to uv

docs: add conda environment setup as an alternative to uv
2026-01-18 16:50:19 -03:00
Luis Novo
809a1d0741
fix(api): correct embedded flag check in source listing (#439)
Change embedded check from `!= NONE` to `!= []` because SurrealDB's
SELECT VALUE returns an empty array [] when no results found, not NONE.
The comparison `[] != NONE` evaluates to true, causing all sources to
incorrectly show as embedded.

Fixes #397
2026-01-16 09:33:01 -03:00