Commit graph

71 commits

Author SHA1 Message Date
LLLin000
508ef78d51 feat(#81, #82): Release N+1/2 cutover — remove setup_complete, auto_update, legacy migration, deprecated build-state JSON writer
#81 (N+1) remaining:
- settings.ts: _resolveRuntimeCommand fail-closed (no getCachedPython fallback)
- managed-runtime.ts: PYTHON_310_DEPRECATED warning removed, single 3.11+ gate
- Python backend: checker/setup_wizard/status → 3.11 minimum
- i18n: 3.10 → 3.11 user-facing strings

#82 (N+2) deletions:
- constants.ts: removed setup_complete, auto_update, auto_update_on_startup, selected_skill_platform
- main.ts: removed _autoUpdate, _firstLaunchSnapshotMigration, credential migration
- modals.ts: removed setup_complete write
- settings.ts: removed categorizeMaintenanceRow dead import
- build_state.py: removed deprecated get_vector_build_state_path

Build: 261.4KB | Tests: 384/384 passed | Typecheck: clean
2026-07-19 14:54:19 +08:00
LLLin000
b4ac277438 Merge branch 'feat/retrieval-recovery'
# Conflicts:
#	paperforge/commands/embed.py
2026-07-11 01:26:37 +08:00
LLLin000
1eb4d80f8d fix: create vec0 companion meta tables unconditionally in ensure_schema 2026-07-11 00:16:38 +08:00
LLLin000
aa9f1de278 fix: add missing CREATE_VEC_FULLTEXT_META to vec0 schema
The vec_fulltext_meta table DDL was referenced by ensure_schema()
but never defined. ADD the missing CREATE_VEC_FULLTEXT_META variable
so the meta table is created alongside vec_body_meta and vec_objects_meta.
2026-07-10 23:55:11 +08:00
LLLin000
66c2db427e fix: add missing vec_fulltext_meta DDL and embed lifecycle tests
schema.py: CREATE_VEC_FULLTEXT_META was referenced at line 328 but
never defined. Adds the missing DDL constant so the v5 schema migration
does not raise NameError on fresh databases.

tests: add embedding test suite with four tests covering vec0 resume
detection, empty-table fallback, force drop, and delete-then-write
ordering verification.
2026-07-10 23:39:10 +08:00
LLLin000
55e0c4c33c fix(schema): create vec0 tables unconditionally, support dynamic dim
- CREATE VIRTUAL TABLE IF NOT EXISTS runs unconditionally, not gated
  on schema version migration. Fixes case where vec0 tables were never
  created when sqlite-vec wasn't available during v5 migration.
- Add VEC_EMBEDDING_DIM and _vec_table_ddl() to support runtime
  dimension detection instead of hardcoded 1536.
2026-07-10 02:48:11 +08:00
LLLin000
745c3dd1e1 fix(db): use sqlite_vec.load(conn) instead of loadable_path()
loadable_path() returns a path without .dll extension on Windows,
causing vec0 extension loading to fail. Use sqlite_vec.load(conn)
which handles platform-specific paths correctly.
2026-07-10 02:47:58 +08:00
LLLin000
d24c78c5dc feat(#27 #28 #29 #30 #32): migrate write/read/status/build_state from ChromaDB to sqlite-vec
#27: write_encoded_payload and delete_paper_vectors use sqlite-vec
  - builder.py: writes to vec0 tables + companion meta tables
  - _chroma.py: delete_paper_vectors deletes from vec0 + meta by paper_id
  - Stores body_units_hash, object_units_hash, retrieval_policy_version in meta tables

#28: merge_retrieve and retrieve_chunks use vec0 k-NN search
  - search.py: vec0 k-NN queries with companion meta JOINs
  - Same dedup/per-paper-cap logic, same result shapes

#29: build_state migrated from JSON file to SQLite build_state table

#30: E2E embed+retrieve test with sqlite-vec + FixedProvider
  - 3 tests: body roundtrip, source correctness, per-paper cap

#32: E2E OCR pipeline test with fixture PDFs

Additional changes:
- schema.py: bump to v6, add hash/policy columns to vec companion meta tables
- embed.py: _assert_collections_healthy uses sqlite-vec; resume hash checks read from meta tables
- status.py: chunk counts from SQL COUNT on companion tables
- Removed unused get_collection/embed_paper imports from embed.py
- All tests updated: 76 pass (was 72, +4 new E2E tests, +4 for migration)
- FixedFixedProvider to generate 1536-dim vectors (matching vec0 schema)
- Fixed health check tests for sqlite-vec path
2026-07-09 17:52:45 +08:00
LLLin000
49f84a1aad feat(#31): OpenAICompatibleProvider uses openai SDK with requests fallback
Rewrite embedding provider to use openai.OpenAI client instead of
raw requests.post. Old code preserved in requests_fallback.py,
selectable via VECTOR_DB_PROVIDER_TYPE env/setting.

Changes:
- paperforge/embedding/providers/openai_compatible.py: rewrite to SDK
- paperforge/embedding/providers/requests_fallback.py: NEW old impl
- paperforge/embedding/_config.py: add get_provider_type()
- tests/test_openai_compatible.py: 6 new tests (encode, timeout,
  provider_type switch, no-key error, custom base url)

feat(#33): E2E test fixtures — 3 synthetic PDFs + expected outputs

3 synthetic papers generated with PyMuPDF, each 3 pages:
- paper_a: The Effect of Machine Learning on Clinical Outcomes
- paper_b: A Randomized Trial of Remimazolam vs Propofol (with tables)
- paper_c: Deep Learning for Medical Image Segmentation (with figures)

Changes:
- tests/fixtures/papers/: 3 PDFs
- tests/fixtures/expected_outputs/: expected blocks + body units
- tests/conftest.py: e2e_fixture_dir + synthetic_paper_paths fixtures

feat(#26): sqlite-vec schema — vec0 virtual tables + build_state

Schema version bumped 4→5. Adds:
- 3 vec0 virtual tables: vec_fulltext, vec_body, vec_objects (1536-dim)
- 3 companion metadata tables: vec_*_meta (paper_id, chunk_index, text)
- build_state table (key/value/updated_at)
- ensure_vec_extension() in db.py for extension loading

Changes:
- paperforge/memory/schema.py: schema v5, new tables in ensure_schema()
- paperforge/memory/db.py: ensure_vec_extension() helper
- tests/test_vector_schema.py: 5 new tests (tables, virtual, idempotent, v5)
2026-07-09 17:15:19 +08:00
LLLin000
0dfbf2a68d feat: PR 8 — Object Vector Retrieval (paperforge_objects collection)
New paperforge_objects collection in ChromaDB for figure/table caption
vector search, completing the memory layer retrieval triad:

  paperforge_fulltext → legacy_chunk
  paperforge_body     → body_unit
  paperforge_objects  → object_unit (NEW)

Changes:
- manifest.py: compute_object_units_hash(), manifest records both hashes
- _chroma.py: _COLLECTION_NAMES includes paperforge_objects
- builder.py: get_object_units_for_embedding() + embed_object_units()
- status.py: object_chunk_count, total_chunks
- state_snapshot.py: write_vector_runtime() extended with new fields
- search.py: 3rd collection, dict-based source mapping, object_kind/label
- __init__.py: exports for new functions
- commands/embed.py: _has_object_units_in_db, body+object structured
  path routing with dual-hash resume, extended counters
- Test fix: test_build_paper_manifest data complete for hash functions

Verification: 20 object vectors embedded, all per-paper counts match,
status total consistent (58266 = 57435 + 811 + 20),
object caption queries return object_unit results via merge_retrieve.
Unit tests: 153 pass, 1 skip.
2026-07-06 19:58:46 +08:00
LLLin000
897afdaecb fix: token cap recursive split + policy version check + test plan update
- _split_if_oversized: recursive _halve_text until every part <= 1000 tokens
- _incremental_units_only: also checks retrieval_policy_version match
- _rebuild_paper_units: use RETRIEVAL_POLICY_VERSION constant
- Functional test plan: Layer A (artifact) + Layer B (API), all 8 review
  fixes incorporated (persisted artifacts, no jump-assertion, stronger
  object/backmatter/abstract tests, proper embed flow)
2026-07-06 17:05:13 +08:00
LLLin000
9f79ac3482 fix: hardening — FTS per-paper, object_units keys, unit_id collision, resume hash
P0-1: FTS per-paper insert — move SELECT INTO body_units_fts inside the
per-paper loop with WHERE paper_id = ? to avoid re-inserting other papers'
rows during full rebuild. Fix sqlite3.DatabaseError on empty FTS table.

P0-2: object_units real role_index keys — read from 'captions'/'tables'
(what build_role_indexes actually outputs) with fallback to old key names.

P1-1: unit_id collision for mixed body/backmatter — include unit_kind
suffix (:backmatter_body) in unit_id. Also fix duplicate tree node_ids
(block_id reused on different pages) by appending order{emitted_order}.

P1-2: Embed resume body_units_hash — add compute_body_units_hash() to
manifest.py, write hash + retrieval_policy_version to Chroma metadata,
resume compares both before skipping.
2026-07-06 16:56:33 +08:00
LLLin000
8dca070b75 feat: PR 2 — Memory Builder incremental update
- Replace _read_result_hash with _resolve_ocr_result_hash (3-level fallback:
  result-hash.txt → SHA-256 of structured artifacts → meta.json derived_version)
- Change fast-path to incremental mode: hash-match calls _incremental_units_only
  instead of early return
- _incremental_units_only: per-paper OCR hash comparison, rebuild only changed
- _rebuild_paper_units: DELETE + rebuild + insert + FTS refresh
- _upsert_body_units updated with schema v4 columns
2026-07-06 16:42:28 +08:00
LLLin000
288829bb5b feat: PR 1 — nested structure tree + body_units correctness
- RenderOutput dataclass with heading_events/emitted_block_events tracking
- Stack-algorithm structure tree with own/subtree block IDs
- Recursive body_units builder with role helper + token cap splitting
- Schema v4: section_path_json, section_level, section_title, part_ordinal
- Phase 4/5 reorder in ocr_rebuild.py and ocr.py
- 12 new test cases for tree nesting, own_block_ids, rendered-order intervals
2026-07-06 16:42:08 +08:00
LLLin000
c534e481c7 fix: close 4 review gaps — registry, body/object-unit schemas, compat vector arm
Changes:
- Add paper-lookup, content-discovery, scoped-fetch to command registry
- Add unit_kind column to body_units schema (DEFAULT 'body')
- Replace object_units schema: object_role -> object_kind, object_label,
  caption_text, nearby_body_text; drop unit_text, drop object_role
- Bump schema version to 3 with deterministic drop/recreate migration for
  derived tables (body_units, body_units_fts, object_units)
- Update _upsert_body_units / _upsert_object_units for new columns
- Update build_object_units to emit object_kind, object_label, caption_text,
  nearby_body_text fields
- Add vector secondary arm to _run_compat_content_discovery: runs paper_fts
  primary, conditionally adds vector_retrieve secondary when vector is healthy
- Add/fix tests for schema columns, builder output, registry, and compat
  content-discovery vector-secondary path
2026-07-05 15:13:43 +08:00
LLLin000
2ab3aa4219 fix: deduplicate object unit_id and wire units persistence in builder
Fix 1 (units.py): object unit_id now includes the entry's block_id
instead of the node's block_span, fixing PRIMARY KEY collisions when
a section has multiple objects (e.g. two figure_captions).

Fix 2 (builder.py): retrieval units are now persisted during
build_from_index(). Scans each paper's OCR output directory for
structure-tree.json, builds body+object units and manifest, then
upserts into the DB tables and meta. Also clears body_units and
object_units at rebuild start alongside the other tables.
2026-07-05 14:28:43 +08:00
LLLin000
9d332980f0 feat: add body units, manifest, and body-unit FTS 2026-07-05 14:21:27 +08:00
LLLin000
9d5a008df1 feat: make paper lookup decomposed and coverage-scored 2026-07-05 14:14:03 +08:00
LLLin000
f8d928d6ed docs: design Layer 4 retrieval substrate 2026-07-05 02:05:27 +08:00
Research Assistant
03ad9ce64f feat: stabilize paperforge query planning 2026-05-27 21:20:15 +08:00
Research Assistant
f68f45f3a2 fix: improve search accuracy with multi-token LIKE and guided agent search queries
- _like_query: split multi-token queries into per-field AND matching
- lookup_paper: same multi-token AND for title lookup
- read-known-paper.md: restructure Step 1 by known-info type (zotero_key,
  DOI, author+year, title keyword, fuzzy)
- discover-papers.md Arm 2: note on author+year search pattern
- retrieval-routing.md Arm 2: same author+year search guidance
2026-05-25 16:42:11 +08:00
Research Assistant
19c28a8b91 chore: commit session work before hotfix switch 2026-05-18 22:47:30 +08:00
Research Assistant
885f20879e feat(memory): show (fast) in sync output when hash matches 2026-05-18 22:29:53 +08:00
Research Assistant
baa6c758f5 fix(vector): get_collection no longer silently deletes collection on error; memory builder skips full rebuild when index hash matches 2026-05-18 22:18:23 +08:00
Research Assistant
add220d93c feat(discussion): remove JSON output and markdown escaping 2026-05-18 21:09:54 +08:00
Research Assistant
a599cd930b Merge branch 'paperforge-stabilization'
# Conflicts:
#	paperforge/memory/vector_db.py
2026-05-18 18:47:07 +08:00
Research Assistant
98417b5245 refactor: update worker/asset_index.py and memory/runtime_health.py imports to embedding package 2026-05-18 17:21:43 +08:00
Research Assistant
f90327bfa3 refactor(memory): convert vector_db.py to deprecated forwarding shim 2026-05-18 17:18:53 +08:00
Research Assistant
2b552be9e6 feat: runtime contract hardening + skill/command truth alignment (Package A+B)
Atomic snapshots, canonical index mutation serialization, sync post-clean truth,
plugin path config-awareness, embed stop signal honesty, full snapshot bootstrap,
pf_ prefix unification, workflow command/lifecycle/path corrections,
mechanical/cognitive route separation with unknown-command guard.
2026-05-16 22:38:43 +08:00
Research Assistant
6bfb247549 feat: Python writes canonical runtime snapshot files for JS reads 2026-05-15 23:06:13 +08:00
Research Assistant
7b567af7c8 fix: add missing chunker module; restore deleted vector_db.py 2026-05-15 21:27:22 +08:00
Research Assistant
67199beae5 fix: reorder table drops to respect FK constraints; add rebuild logging 2026-05-15 17:42:10 +08:00
Research Assistant
fe33470303 feat: add layered runtime health computation 2026-05-15 01:15:39 +08:00
Research Assistant
64ee50a080 feat: add persistent vector build state helpers 2026-05-15 01:13:12 +08:00
Research Assistant
560be86b83 fix: refresh_paper FTS delete-before-upsert, import error checking 2026-05-14 22:47:48 +08:00
Research Assistant
e68d931134 fix: import_reading_log to JSONL, correction JSONL-first, events.py wrapper 2026-05-14 22:37:55 +08:00
Research Assistant
59ef9d9344 fix: dedupe correction import on rebuild, clean FTS row on refresh 2026-05-14 22:35:35 +08:00
Research Assistant
19d17797d1 feat: safe FTS search with token-quote and LIKE fallback 2026-05-14 21:50:29 +08:00
Research Assistant
0d3ff8dcdd feat: permanent correction-log.jsonl, fix original_id field alignment 2026-05-14 21:48:21 +08:00
Research Assistant
9dd1cbe893 refactor: unify reading-log reads to JSONL, deprecate paper_events writes 2026-05-14 21:44:05 +08:00
Research Assistant
750e8ade17 feat: import JSONL into DB on memory build 2026-05-14 17:48:23 +08:00
Research Assistant
6ccce87272 feat: upgrade reading-log to JSONL with context/tags/project fields and auto-render 2026-05-14 17:31:32 +08:00
Research Assistant
60c524b012 fix: align JSONL field names with spec (type/title, add verified) 2026-05-14 17:20:29 +08:00
Research Assistant
47904da95e feat: add permanent JSONL storage layer for reading-log and project-log 2026-05-14 17:08:10 +08:00
Research Assistant
c1001bcc78 feat: add reading_log and project_log tables to memory schema 2026-05-14 16:51:14 +08:00
Research Assistant
bfc4e9ffab fix: get_embed_status reads API model; defer display() after async status refresh 2026-05-14 00:18:03 +08:00
Research Assistant
7ad1d2405d debug: log API base_url to check env var passthrough 2026-05-13 22:25:20 +08:00
Research Assistant
110889da73 fix: pass API key/base/model as env vars to avoid saveSettings race 2026-05-13 22:22:37 +08:00
Research Assistant
58bd70ace7 feat: API model as text field (custom any name) + fix Python duplicate 2026-05-13 21:55:09 +08:00
Research Assistant
4113af1c99 feat: urllib-based model download bypasses HF hub + HF_TOKEN field 2026-05-13 21:33:09 +08:00