mirror of
https://github.com/lfnovo/open-notebook.git
synced 2026-09-10 18:16:41 +00:00
* feat(search): scope Search and Ask to selected notebooks Search and Ask always ran against the whole knowledge base; `notebook_id` was accepted by POST /api/search and silently ignored because the request model never declared it. Both endpoints now take an optional notebook scope and the Search/Ask page gets a shared notebook selector. - Migration 24: fn::text_search / fn::vector_search gain an optional trailing `$notebook_ids: option<array<record<notebook>>>` parameter. NONE/empty keeps the unfiltered path; otherwise sources are limited via the `reference` edge and notes via the `artifact` edge (chunks and insights follow their parent source). The 4-/5-arg call shapes still work, so existing callers are unaffected; `24_down` restores the previous definitions. - API: SearchRequest / AskRequest accept `notebook_ids` (list) and `notebook_id` (single, the shape clients already send); ids are validated (400 for non-notebook ids, 404 for unknown notebooks) before reaching the query so a typo never masquerades as "no matches". - Domain: text_search / vector_search take `notebook_ids`; the highlight overflow fallback preserves the scope. - Ask graph: scope travels in the thread state and reaches every fan-out vector search. - Frontend: NotebookScopeSelector (collapsible checkbox list, "All notebooks" by default, Clear action) shared by the Ask and Search tabs; strings in all 14 locales. - Docs: user guide section on scoping; API reference note. Closes #574 Closes #87 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01U53d3BNjGghLsf6tufRTKX * fix(search): harden notebook scope validation after review - Raise typed InvalidInputError / NotFoundError instead of bare HTTPException, per the API error convention. - Check notebook existence with a single query for the whole scope; a database failure now surfaces as 500 instead of a misleading 404. - Bound notebook_ids to 50 entries; keep empty ids so they are rejected (400) rather than silently widening the scope to everything. - Replace the pluralized "N notebooks selected" string with a neutral "N selected" form: the locale parity test forbids per-language extra keys, so _few/_many forms for ru/pl were not an option. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01U53d3BNjGghLsf6tufRTKX * refactor(search): move scope resolution to the domain, add ADR-008 - resolve_notebook_scope() now lives in open_notebook/domain/notebook.py next to text_search / vector_search; the router only calls it. - Reject malformed ids such as "notebook:" (empty key) and anything RecordID.parse cannot handle with InvalidInputError instead of letting them surface as 500. - ADR-008 records the notebook-scope semantics, the compatibility choice (notebook_id + notebook_ids, optional trailing SurrealQL parameter) and how it relates to the #1315 retrieval contract. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01U53d3BNjGghLsf6tufRTKX * test(search): cover migration 24, validate Ask scope before model lookups - Ask endpoints resolve the notebook scope first, so a malformed or unknown scope returns 400/404 before any model or embedding lookup. - Registration and content tests for 24.surrealql / 24_down.surrealql, following the existing migration test pattern. - ADR-008 context trimmed to the template's sentence budget. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01U53d3BNjGghLsf6tufRTKX * fix(search): surface a typed error when scope resolution hits the database resolve_notebook_scope() now logs the raw driver error and raises DatabaseOperationError with a fixed message, matching text_search / vector_search, so connection details never reach the 500 response body. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01U53d3BNjGghLsf6tufRTKX * fix(search): compare notebook scope ids as strings The driver returns `id` as RecordID objects, which are unhashable and never equal to the request strings, so every real scoped request raised TypeError before reaching the search. Normalize to str before comparing and add a regression test that mocks RecordID rows. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014kRBoPiBD1NKeKHCo6EyrE --------- Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com> |
||
|---|---|---|
| .. | ||
| public | ||
| src | ||
| test-results | ||
| .gitignore | ||
| AGENTS.md | ||
| CLAUDE.md | ||
| components.json | ||
| eslint.config.mjs | ||
| next.config.ts | ||
| package-lock.json | ||
| package.json | ||
| postcss.config.mjs | ||
| start-server.js | ||
| tsconfig.json | ||
| vitest.config.ts | ||