Skip to content

Phase 3: smarter grouping — EXIF/docx signals, structured outputs, model split, batched grouping - #17

Open
zackkitzmiller wants to merge 2 commits into
feat/phase2-detection-v2from
feat/phase3-smarter-grouping
Open

Phase 3: smarter grouping — EXIF/docx signals, structured outputs, model split, batched grouping#17
zackkitzmiller wants to merge 2 commits into
feat/phase2-detection-v2from
feat/phase3-smarter-grouping

Conversation

@zackkitzmiller

Copy link
Copy Markdown
Member

Why

Grouping quality was limited by its inputs and plumbing: EXIF was a declared dependency but never read (photo dates/cameras unused), docx/rtf fell back to filename-only descriptions, JSON came back via regex extraction, one giant prompt handled up to 500 files, every call ran on the most expensive model, and low-confidence placements silently joined folders.

Stacked on #16.

Changes

  • EXIF hints (analyze::exif_hint): capture date, camera model, GPS presence sent as metadata_hint for images; filesystem mtime as universal fallback for images and documents.
  • docx/rtf extraction: docx = zip → word/document.xml → tag-strip with paragraph preservation; rtf = control-word stripper. Both feed the normal text-describe path. .doc remains filename-only.
  • Structured outputs: describe and group requests carry output_config.format (json_schema for ContentDescription and the groups shape). extract_json stays as a fallback for proxies/models that ignore the parameter.
  • Model split: descriptions default to claude-haiku-4-5 (high-volume vision → 5x cheaper), grouping stays on [ai].model. New [ai].describe_model config; estimate_cost prices each stage at its own model.
  • Batched grouping: >120 files are grouped in topic-coherent chunks (sorted by suggested category); labels from earlier chunks feed later ones so folders get reused, and same-label groups merge.
  • Needs Review bucket: placements whose description confidence is < 0.6 are pulled into a visible Needs Review group.
  • Ledger in --dupes-only: already-organized files are skipped there too.

Test plan

  • cargo test — 374 passed (new: docx xml stripping + real docx structure, rtf control-word stripping, exif-none-for-plain-png, quarantine positive/noop, cross-chunk label merge at 2×batch+5 files, split-model pricing)
  • cargo clippy --all-targets — clean

…odel split, batched grouping, needs-review bucket

- images now send EXIF capture date / camera / GPS presence as a
  metadata hint (fs mtime as fallback); documents send mtime — dates
  are the strongest photo-grouping signal and were unused
- docx (zip -> word/document.xml) and rtf (control-word stripping) now
  yield real text excerpts instead of filename-only guesses
- describe/group API calls request structured outputs
  (output_config.format json_schema); regex JSON extraction remains as
  fallback for proxies that ignore it
- model split: per-file descriptions default to claude-haiku-4-5,
  grouping stays on the big model; configurable via [ai].describe_model;
  cost estimates price each stage at its own model
- grouping of >120 files runs in topic-coherent batches; labels from
  earlier batches feed later ones and same-label groups merge
- placements with description confidence < 0.6 land in a visible
  'Needs Review' group instead of silently joining a folder
- --dupes-only now respects the organized ledger
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant