Skip to content

Latest commit

 

History

History
357 lines (267 loc) · 15.1 KB

File metadata and controls

357 lines (267 loc) · 15.1 KB

ecoextract 0.1.27

Documentation

  • get_ocr_pages() is listed in the pkgdown reference index, which the site build requires for every exported function.

ecoextract 0.1.26

New features

  • New get_ocr_pages() returns a document's OCR markdown one page at a time, with each page's stored images embedded as <img> tags. Viewers such as ecoreview can call it instead of re-implementing the image lookup (#159).

Bug fixes

  • OCR images are matched to their placeholders by the image's stored id, within each page. embed_images_in_markdown() matched by position, so with Mistral's document-wide image numbering most images were left as placeholders or showed the wrong image, in get_ocr_html_preview() too. It is replaced by the internal embed_page_images(). Placeholders with no stored image become their alt text (#159, #160).
  • get_ocr_html_preview() no longer fails on single-line markdown, which markdown::mark_html() treated as a file path.
  • HTTP 500-504 server errors are retried on the same model, like malformed output. ellmer already retries 429, 503, and 529, but not 500, 502, or 504, so a transient server error marked the document failed (#158).

ecoextract 0.1.25

New features

  • New coalesce_metadata argument to process_documents() and process_single_document() sets how metadata results are saved. NULL (default) replaces the stored metadata on a forced re-run (force_reprocess_metadata), including clearing fields the new result leaves empty, and otherwise only fills fields that are still empty. TRUE or FALSE overrides this in either direction (#156).
  • Reviewer edits to document metadata are protected. save_document() logs each metadata field whose value changes in a new document_edits table, and later metadata runs never overwrite those fields, whatever coalesce_metadata says. Existing databases gain the table on their next run (#156).

Bug fixes

  • A forced metadata re-run now clears fields whose new result is empty. Previously every field was saved as COALESCE(new, old), so an empty result kept the old value, and a clean re-run could keep an old metadata_log (#155).
  • save_metadata_to_db() no longer has an overwrite mode that deleted the document and its records before updating them (#155).

ecoextract 0.1.24

New features

  • New reasoning_effort argument to process_documents() and process_single_document() controls model thinking for every LLM step (metadata, extraction, refinement, and LLM deduplication). Set an effort level such as "low", "medium", or "high" to turn thinking on (#153).

Breaking changes

  • Thinking is off by default. Since 0.1.23 (ellmer 0.5.0), Claude Sonnet 5 ran adaptive thinking at high effort on every call, which multiplied output tokens and run time. Claude now gets thinking: disabled unless reasoning_effort is set, and Gemini keeps reasoning_tokens = 0. Other providers use their model default (#153).

ecoextract 0.1.23

Bug fixes

  • ecoextract now requires ellmer 0.5.0 or later. ellmer 0.4.x did not recognize Claude 5 models as supporting native structured output, so their output came back as a JSON string that failed to parse when the model's text contained unescaped quotes, backslashes, or control characters. On 0.5.0 the API returns a parsed object (#151).
  • The retry for malformed structured output also covers jsonlite's "lexical error" messages (e.g. an unescaped quote inside a string), not only "parse error" (#151).

ecoextract 0.1.22

New features

  • Token usage is recorded for every LLM call, read from the API reply through ellmer. The documents table gains <step>_input_tokens, <step>_output_tokens, and <step>_cached_input_tokens columns for the metadata, extraction, and refinement steps. Totals include retries, failed attempts, extraction reps, and LLM deduplication. Each attempt in the *_log audit trail carries its own usage. Existing databases gain the columns on their next run; earlier rows stay NULL (#147).
  • The metadata schema's metadata object can have any name, not just publication_metadata (#148).

Breaking changes

  • Metadata columns in the documents table come only from the metadata schema in use. A database created with a custom metadata schema no longer gets the thirteen bibliographic columns (title, authors, journal, ...). The default schema still creates them, and existing databases keep their columns (#148).
  • export_db() exports the metadata schema's fields as document columns (the default schema adds language), and simple = TRUE keeps document_id, file_name, and the schema's x-record-id-fields. It gains a metadata_schema_file argument (#148).

Bug fixes

  • export_db() keeps documents with no records, as one row with empty record columns. It previously used an inner join, so documents where extraction found nothing were missing from the export (#149).

  • LLM calls whose structured output cannot be parsed (for example, stray markup after the JSON object) are retried on the same model before falling back to the next one. Content refusals are still not retried.

  • process_documents(document_id = ...) finds documents from any subdirectory of the project. Stored file paths are relative to the project root but were resolved against the working directory, so reprocessing by ID from elsewhere reported "file not found".

  • refine_records() no longer reports "Refinement failed: object 'error_log' not found" when every record in a document is human-edited or deleted. The step is now marked skipped.

ecoextract 0.1.21

New features

  • Projects can supply their own metadata schema and prompt, via ecoextract/metadata_schema.json and ecoextract/metadata_prompt.md or the new metadata_schema_file and metadata_prompt_file arguments to process_documents(). Fields not already in the documents table are added as columns (#138).
  • New run_metadata argument to process_documents() skips the metadata step (#138).
  • Record IDs are built from the fields named in the metadata schema's x-record-id-fields (metadata fields, document_id, or file_name) instead of hardcoded author and year. The default schema keeps first_author_lastname and publication_year, so default IDs are unchanged (Smith_2020_1_r1) (#138).

Breaking changes

  • The default model is now anthropic/claude-sonnet-5 (was anthropic/claude-sonnet-4-5) for all steps (#142).
  • A document's metadata now counts as present if any metadata schema field is populated. Previously title, first author, and year were all required, so documents missing one re-ran metadata on every pass.
  • Missing record ID values become Unknown (previously a missing year became the current year).

Bug fixes

  • Schemas sent to Anthropic and OpenAI now have "additionalProperties": false on every object instead of having it stripped, which Claude Sonnet 4.6 rejected with HTTP 400. Gemini schemas still have it removed (#140).
  • The default metadata schema lists every field in required (with nullable types), so it stays within the structured-output limits of older models such as Claude Sonnet 4.6 and Haiku 4.5 (#142).
  • When every model fails, the error message links to the README's new Troubleshooting section (#142).
  • Refinement now declares record_id in the schema it sends, so models return it for each refined record. It was previously an undeclared extra field, which "additionalProperties": false disallows (#145).

Documentation

  • README and configuration guide cover custom metadata schemas and troubleshooting unexplained schema errors, including measured model limits (#142).

ecoextract 0.1.20

Minor improvements

  • Parallel worker completion messages now include document_id.

ecoextract 0.1.19

New features

  • process_documents() now accepts db_conn alone — omitting both pdf_path and document_id processes all documents already in the database. Useful for re-running extraction on a database that was split from a larger one.

ecoextract 0.1.18

Bug fixes

  • process_documents() with workers > 1 now passes a unique seed to each parallel worker via crew's seed argument. Previously, workers spawned simultaneously could inherit identical RNG state and generate colliding UUIDs, causing UNIQUE constraint failures on records.id.

ecoextract 0.1.17

Bug fixes

  • process_documents() with force_reprocess_extraction now deletes existing unedited records for the document before re-extracting, instead of relying on dedup to filter them out. This prevents record accumulation across multiple force runs and eliminates the risk of UNIQUE constraint failures on records.id. Human-edited records (those with entries in record_edits) are preserved.

ecoextract 0.1.16

Bug fixes

  • save_document() now correctly includes id (UUID) when inserting into record_edits. Since 0.1.13 the column is TEXT PRIMARY KEY (NOT NULL), so omitting it caused every cell edit followed by Verify to fail with a NOT NULL constraint error and roll back the entire save (#133).

  • Extraction write failures are no longer silently swallowed. When save_records_to_db() throws, the error message is now written into extraction_status (e.g. "Extraction failed: ...") rather than leaving the document marked "completed" with 0 records extracted (#134).

ecoextract 0.1.15

Bug fixes

  • get_document_content() no longer throws "missing value where TRUE/FALSE needed" when document_content is NULL in the database (returned as NA in R). The is.null() check did not catch NA, causing NA == "" to evaluate to NA and if(NA) to error. Fixed by extracting the value first and checking with is.na() / nzchar().

ecoextract 0.1.14

Bug fixes

  • migrate_ecoextract_database() now correctly upgrades databases whose records table was created by dbWriteTable rather than init_ecoextract_database(). The previous approach patched the DDL string from sqlite_master, which silently failed when column names were backtick-quoted or AUTOINCREMENT was absent. The migration now builds the new DDL from PRAGMA table_info and uses ALTER TABLE ... RENAME TO / CREATE TABLE / dbAppendTable / DROP TABLE instead of DROP + CREATE + dbWriteTable, so the schema change is guaranteed regardless of how the original table was created.

  • Records with NULL id (possible when the original table was created without AUTOINCREMENT) now receive a fresh UUID during migration instead of remaining NULL.

  • Schema migration warning is now issued from get_records() (as a message, printed immediately) and save_document() (as a hard error) rather than from init_ecoextract_database(), which is only called when creating new databases. Old-schema databases opened for reading or writing are now always surfaced correctly.

ecoextract 0.1.13

Improvements

  • records.id is now TEXT PRIMARY KEY (UUID v4) instead of INTEGER PRIMARY KEY AUTOINCREMENT. UUIDs are generated in R using base functions only (no new dependency). This makes records collision-free when merging databases from independent researchers.

  • Added migrate_ecoextract_database() to upgrade existing databases created before 0.1.13. The function recreates records and record_edits with TEXT ids, backfills UUIDs from a per-session integer-to-UUID map, and runs the entire operation in a single transaction. Safe to re-run.

  • init_ecoextract_database() now warns when it detects the old integer-id schema, prompting the user to run migrate_ecoextract_database().

  • All record insert paths (bulk extraction via save_records_to_db() and single-row user additions via save_document()) now generate UUIDs for rows that do not already have an id.

ecoextract 0.1.12

Bug fixes

  • save_document() now assigns id after inserting a user-added row, fixing infinite duplication on repeated verify clicks in databases created with the old schema where id was a plain INTEGER rather than INTEGER PRIMARY KEY. After each insert, UPDATE records SET id = last_insert_rowid() WHERE rowid = last_insert_rowid() is executed; this is a no-op on new-schema databases where id is already set by autoincrement.

ecoextract 0.1.11

Bug fixes

  • save_document() no longer silently drops user-added rows when the document has zero LLM-extracted records. Previously the diff/insert block was guarded by nrow(original_df) > 0, which skipped the insert path when original_df was an empty tibble. The nrow() guard is removed; diff_records() already handles a 0-row original_df correctly. Passing original_df = NULL still skips record changes as documented.

ecoextract 0.1.10

Bug fixes

  • Fixed document_id <- NA clobber in ocr_document() that caused reprocessing via document_id to create a duplicate documents row when the file hash had changed (e.g. after opening and re-saving the PDF).

  • process_documents(document_id = X, force_reprocess_ocr = TRUE) now returns a clear "file not found" status and leaves the database untouched when the stored file path no longer exists, instead of nullifying ocr_status and failing mid-pipeline. A subsequent run without force_reprocess_ocr will use the stored OCR content.

Improvements

  • PDF file paths are now stored relative to the project root (found by walking up from the PDF file's directory until a .git, .Rproj, DESCRIPTION, or .here marker is found). This makes paths portable across machines and when the project folder is moved. If no project root marker is found the absolute path is stored as a fallback — this is machine-specific and will break if the database is shared or the project folder is moved.

  • When a document is identified by hash match but the file has moved to a new path, file_path in the database is immediately updated to reflect the current location.

ecoextract 0.1.9

Bug fixes

  • process_documents(document_id = ...) now correctly reprocesses the specified document in-place instead of creating a duplicate row when the file's hash has changed since initial processing (e.g. after opening and re-saving the PDF). The original document_id is passed through to process_single_document() and used directly, bypassing the hash lookup.

ecoextract 0.1.8

Improvements

  • Extraction now uses a two-turn LLM conversation: turn 1 produces structured reasoning (capturing document analysis, organism identifiability decisions, and extraction choices), turn 2 uses that reasoning as context to extract structured records. This ensures reasoning causally precedes extraction rather than being a sibling field in the same structured output call, fixing divergence between stated reasoning and extracted records.

  • reasoning removed from the extraction JSON schema — it is now always captured via the two-turn structure and stored in the database regardless of schema configuration.

  • Content refusals on turn 1 are now correctly detected and logged as refusals rather than retried as stochastic empty-reasoning failures.

ecoextract 0.1.7

  • Initial release.