Skip to content

Conversation

nonprofittechy
Copy link
Member

Fix #145

This resolves the last bunch of changes mentioned in #145. It's a big one, but it wasn't easy to break into smaller PRs.

  1. Use LLM for all normalization
  2. Move all prompts to standalone .txt files; we could do individual benchmarking more easily now with Promptfoo, although I haven't implemented benchmarks for everything
  3. Remove all scipy/nltk usage
  4. Integrate the PDF context branch which vastly improves the performance of the field renaming. This now works amazingly well out of the box even with gpt-5-nano.
  5. Upgrade all of the LLMs to the new-ish ChatCompletion API; use gpt-5-nano as the default model for all tasks.
  6. Added integration tests for the new functionality as I went - that's a lot of the line count, as well as the CSV for prompt evaluation
  7. Cleaned up some old files, including python notebook and joblib files that are now obsolete

BryceStevenWilley and others added 15 commits June 16, 2024 22:04
Harder than anticipated, for a few reasons:

* can't get things in order. I guess that's the point of PDFminer, but...
* PDF miner doesn't give you AcroForms at all. It has a completley hardcoded
  way of getting them, outside the context of the page.
* We can do these two things:
    * kinda put all of the fields back in the original text (see replace_original_text).
      Doesn't work too well though, lots of duplicate pieces of text that put many of the fields
      in the same place, when they should be in a different place.
        * could gather fields with the same adjacent text, and get all parts of that text in the PDF.
          Not guaranteed to be in order tho.
    * for each field, get all of the surrounding context. Is okay! But consistently gets too much text for GPT4.
      Even if we make it smaller, sometimes the surrounding context isn't the full sentence, or gets too much from other
      fields (will have too much shared / confusing the two fields).

TBH next goal is to try the PDFPageAndFieldInterpreter approach, notes in there.
@nonprofittechy
Copy link
Member Author

Going to look at the test failure which is for typing problems.

@nonprofittechy nonprofittechy requested a review from Copilot October 9, 2025 18:32
Copy link

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This pull request completes the migration to LLM-based processing by removing NLTK/scipy dependencies and integrating PDF context for enhanced field renaming. It upgrades all LLM calls to use the ChatCompletion API with gpt-5-nano as the default model, moves prompts to standalone .txt files for easier benchmarking, and adds comprehensive integration tests.

  • Removes all NLTK, scikit-learn, networkx, and joblib dependencies
  • Implements LLM-powered field renaming with full PDF context analysis
  • Migrates all functions to use external prompt files and modern OpenAI API

Reviewed Changes

Copilot reviewed 26 out of 32 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
setup.py Removes deprecated ML/NLP dependencies (nltk, scikit-learn, networkx, joblib)
pyproject.toml Removes mypy overrides for removed dependencies
promptfoo-real-system.yaml Adds comprehensive prompt evaluation framework with 10 test PDFs
promptfoo-quality.yaml Adds field renaming quality assessment with snake_case validation
formfyxer/tests/test_passive_voice_detection.py Updates tests to work with new ChatCompletion message format
formfyxer/tests/pdf_grouped_dataset.csv Adds test dataset for PDF field grouping evaluation
formfyxer/tests/field_renaming_dataset.csv Adds comprehensive field renaming test dataset (310 entries)
formfyxer/tests/cluster_test.py Simplifies tests to avoid hardcoded expectations, focuses on validation
formfyxer/requirements.txt Removes obsolete ML dependencies
formfyxer/prompts/*.txt Adds 6 external prompt files for modular LLM interactions
formfyxer/pdf_wrangling.py Adds PDF text extraction with field markers and improved type safety
formfyxer/passive_voice_detection.py Updates to use ChatCompletion API with proper message structure
formfyxer/lit_explorer.py Major refactor: removes ML dependencies, adds LLM-based field processing
formfyxer/integration_tests/*.py Adds 4 comprehensive integration tests for new LLM functionality
formfyxer/docx_wrangling.py Updates to use ChatCompletion API and improves type annotations
MANIFEST.in Removes joblib files from distribution

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

Copy link
Contributor

@BryceStevenWilley BryceStevenWilley left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, mostly nits and questions although I haven't had enough time to verify deeply myself.

Comment on lines +1709 to +1739
# Fallback to traditional approach
length = len(field_names)
last = "null"
new_names = []
new_names_conf = []
for i, field_name in enumerate(field_names):
new_name, new_confidence = normalize_name(
jur or "",
cat or "",
i,
i / length,
last,
field_name,
tools_token=tools_token,
)
new_names.append(new_name)
new_names_conf.append(new_confidence)
last = field_name
new_names = [
v + "__" + str(new_names[:i].count(v) + 1) if new_names.count(v) > 1 else v
for i, v in enumerate(new_names)
]
else:
# Traditional approach when no OpenAI credentials available
length = len(field_names)
last = "null"
new_names = []
new_names_conf = []
for i, field_name in enumerate(field_names):
new_name, new_confidence = normalize_name(
jur or "",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a big enough chunk that it shouldn't be duplicated in the else directly below it

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.

2 participants