Allow users to specify a Tesseract language string (e.g. jpn+jpn_vert)
on a per-extraction basis, overriding the global OCR language setting.
- Add payload column to ai_jobs table (migration) to carry per-call data
- Thread ocrLanguages payload through enqueueJob → processNextJob → extractItemText
- New GET /api/ai-settings/ocr endpoint (requireAuth) returns { ocrMode, ocrLanguages }
- ImageLightbox fetches OCR settings and shows a language input next to the
Extract Text button when mode is hybrid or tesseract (hidden for llm-only)
- MixedView fetches OCR settings and passes them down to EntryTile; kebab
Extract Text on images shows an inline language prompt before dispatching the job
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Poll /api/ai-tagging/fields every 2s after any 202 (queued) response in
ImageLightbox and DoomScrollView so extraction, translation, and description
results appear automatically without a page refresh
- DoomScrollView extract button now turns accent-coloured while a job is
queued instead of flashing red; red is reserved for genuine errors
- Kebab menu "Translate" option is now gated on entry.hasExtractedText
(populated via a batch DB query in the browse API) so it only appears
when there is text to translate
- Tag panel redesigned: toolbar collapses to just the filename when open;
panel header holds hide (›), AI Tagger (✨), and Close (✕) buttons;
sections ordered Description → Text Extraction → Tags; description
state and generate handler moved from TagSelector into ImageLightbox
- VideoPlayerModal receives the same toolbar/panel restructure
- TagSelector gains hideDescription prop so the parent can own description
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Allows users to configure the max_tokens sent to the AI endpoint for
each activity (tagging, description, extraction, translation) individually,
with per-library overrides following the same pattern as model overrides.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Extracted text in the tag panel is now an editable textarea; a Save
button appears when the content is dirty and persists edits to the DB
- Source language input added next to Re-translate button; when filled,
the translation prompt uses "translate from X to Y" for more accurate
results
- New updateExtractedText() helper and PATCH /api/ai-tagging/fields
endpoint to support saving edited text
- translateItemText/translateText accept optional sourceLanguage param
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Show an extract-text button (document icon) in the bottom bar when the
current image has no extracted text yet. Clicking it calls the extract-text
API, shows a spinner while in progress, and on success replaces itself with
the text-lines display button and auto-opens the overlay. Error state briefly
turns the button red. Resets on every item navigation alongside the other
text state. Hidden for videos and items without an itemKey.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add getAiImagePath() to thumbnails.ts (1920px wide, quality 90, no
upscaling) cached separately from display thumbnails via an _ai suffix.
Swap all four image-to-AI code paths in ai-tagger.ts (extract text,
describe, batch tagging x2) to use the new high-res image instead of
the 400px display thumbnail, improving OCR accuracy on dense text.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- move play/pause to clicking the video directly; remove dedicated button
- replace emoji mute icons with flat minimal SVGs
- add view-in-library button in doom scroll that navigates to the file's
directory and opens it in the regular viewer
- add display text overlay button in doom scroll and image lightbox;
shows extracted text (translated by default when available) in a
semi-transparent box at the bottom; toggle between translated/original
- hide tag panel by default in image lightbox and video player modal
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
When generating an item description, any already-applied tags are
appended to the system prompt as a source of truth, so the model
can produce a more accurate description aligned with existing tags.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Applied tags are now pinned to the front of each category's tag list,
with unapplied tags continuing in usage order behind them. Both
partitions preserve the existing usage-sort from the API.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
When no filters are selected, doom scroll now recursively fetches only
items under the current directory instead of the entire library root.
Navigating to a new directory invalidates the cached listing. Filter-
based doom scroll (search or tags) continues to search library-wide.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add library_ai_settings table with migration for per-library overrides
- Extend AiConfig with editable prompt parts for description, tagging,
extraction, and translation steps; defaults match previous hardcoded values
- Add getEffectiveAiConfig(libraryId) that merges global settings with
library-level overrides (empty override falls through to global)
- Update all ai-tagger functions to use getEffectiveAiConfig and build
prompts from configurable parts
- Add GET/PUT /api/ai-settings/library/[id] for per-library overrides
- Update /api/ai-settings GET/PUT to include prompt fields
- Add Prompts section and Library Overrides section to admin UI
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>