Petr Polezhaev b94f222c96 Add per-request AI logging, DB batch queue, WS entity updates, and UI polish
- log_thread.py: thread-safe ContextVar bridge so executor threads can log
  individual LLM calls and archive searches back to the event loop
- ai_log.py: init_thread_logging(), notify_entity_update(); WS now pushes
  entity_update messages when book data changes after any plugin or batch run
- batch.py: replace batch_pending.json with batch_queue SQLite table;
  run_batch_consumer() reads queue dynamically so new books can be added
  while batch is running; add_to_queue() deduplicates
- migrate.py: fix _migrate_v1 (clear-on-startup bug); add _migrate_v2 for
  batch_queue table
- _client.py / archive.py / identification.py: wrap each LLM API call and
  archive search with log_thread start/finish entries
- api.py: POST /api/batch returns {already_running, added}; notify_entity_update
  after identify pipeline
- models.default.yaml: strengthen ai_identify confidence-scoring instructions;
  warn against placeholder data
- detail-render.js: book log entries show clickable ID + spine thumbnail;
  book spine/title images open full-screen popup
- events.js: batch-start handles already_running+added; open-img-popup action
- init.js: entity_update WS handler; image popup close listeners
- overlays.css / index.html: full-screen image popup overlay
- eslint.config.js: add new globals; fix no-redeclare/no-unused-vars for
  multi-file global architecture; all lint errors resolved

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-11 12:10:54 +03:00
2026-03-09 14:17:13 +03:00
2026-03-09 14:17:13 +03:00
2026-03-09 14:17:13 +03:00
2026-03-09 14:17:13 +03:00
2026-03-09 14:17:13 +03:00
2026-03-09 14:17:13 +03:00
2026-03-09 14:17:13 +03:00

Bookshelf

Photo-based book cataloger. Organizes books in a Room -> Cabinet -> Shelf -> Book hierarchy. Photographs shelf spines; AI plugins identify books and look up metadata in library archives.

Requirements

  • Python 3.11+, Poetry
  • An OpenAI-compatible API endpoint (OpenRouter recommended)

Setup

poetry install

Create config/credentials.user.yaml with your API key:

credentials:
  openrouter:
    api_key: "sk-or-your-key-here"

Start the server:

poetry run serve

Open http://localhost:8000 in a browser.

Configuration

Config is loaded from config/*.default.yaml merged with config/*.user.yaml overrides. User files take precedence; dicts merge recursively, lists replace entirely. User files are gitignored.

File Purpose
credentials.default.yaml API endpoints and keys
models.default.yaml Model selection and prompts per AI function
functions.default.yaml Plugin definitions (boundary detection, text recognition, identification, archive search)
ui.default.yaml UI display settings

To use a different model for a function, create config/models.user.yaml:

models:
  vl_recognize:
    credentials: openrouter
    model: "google/gemini-2.0-flash"

To add an alternative provider, add it to config/credentials.user.yaml and reference it in models.user.yaml.

Usage

  1. Add a room, then cabinets and shelves using the tree in the sidebar.
  2. Upload a photo of each cabinet or shelf.
  3. Drag boundary lines on the photo to segment shelves (or books within a shelf). The AI boundary detector can suggest splits automatically.
  4. Run the text recognizer on a book to extract spine text, then the book identifier to match it against library archives.
  5. Review and approve AI suggestions in the detail panel. Use the batch button to process all unidentified books at once.
  6. On mobile, use the photo queue button on a cabinet or shelf to photograph books one by one with automatic AI processing.

Development

poetry run presubmit   # black check + flake8 + pyright + pytest + JS tests
poetry run fmt         # auto-format Python with black
npm install            # install JS dev tools (ESLint, Prettier) — requires network
npm run lint           # ESLint
npm run fmt            # Prettier

Tests are in tests/ (Python) and tests/js/ (JavaScript).

Description
bookshelf scan and management program (ai-written)
Readme 301 KiB
Languages
Python 65.4%
JavaScript 29.4%
CSS 4%
HTML 1.2%