refactor(themefinder): migrate LLM layer to Pydantic AI - #1428
refactor(themefinder): migrate LLM layer to Pydantic AI#1428jjuritzno10 wants to merge 6 commits into
Conversation
126a158 to
bcf500a
Compare
7c1f5ee to
d7ec478
Compare
|
Claude finished @Nazehs's task in 2m 9s —— View job PR Review: refactor(themefinder): migrate LLM layer to Pydantic AI
Clean refactor — replaces the bespoke Two things worth addressing: 🔵 CONSIDER ( ⚪️ NIT ( |
c60c805 to
4917ff4
Compare
|
Claude finished @Nazehs's task in 1m 1s —— View job
PR Review: refactor(themefinder): migrate LLM layer to Pydantic AIClean migration. The Two carry-forwards from the previous review and one new one: 🔵 CONSIDER ( ⚪️ NIT ( ⚪️ NIT ( |
|
Claude finished @Nazehs's task in 48s —— View job
PR Review: refactor(themefinder): migrate LLM layer to Pydantic AINITs from prior rounds are resolved. Only one carry-forward remains: 🔵 CONSIDER ( |
|
Claude finished @Nazehs's task in 48s —— View job
PR Review: refactor(themefinder): migrate LLM layer to Pydantic AIClean and minimal. All prior NITs resolved. 🔵 CONSIDER ( |
|
Claude finished @Nazehs's task in 50s —— View job
PR Review: refactor(themefinder): migrate LLM layer to Pydantic AIClean and minimal — prior NITs resolved. One carry-forward: 🔵 CONSIDER ( |
|
Claude finished @Nazehs's task in 29s —— View job
PR Review: refactor(themefinder): migrate LLM layer to Pydantic AIClean and minimal — prior NITs all resolved. 🔵 CONSIDER ( 🔵 CONSIDER ( |
|
Claude finished @Nazehs's task in 39s —— View job
PR Review: refactor(themefinder): migrate LLM layer to Pydantic AIClean migration with all prior NITs resolved. Two carry-forwards remain as future-PR material: 🔵 CONSIDER ( 🔵 CONSIDER ( |
|
Claude finished @Nazehs's task in 34s —— View job
PR Review: refactor(themefinder): migrate LLM layer to Pydantic AIClean and minimal — all prior NITs resolved, 🔵 CONSIDER ( |
Replace the OpenAI-specific OpenAILLM with a single Pydantic AI-backed LLM class that supports provider-prefixed models (openai:/anthropic:/google:) and OpenAI-compatible gateway routing via base_url/api_key. Wire per-stage model routing through tasks.py and the batch processor. Add pydantic-ai-slim (openai/anthropic/google extras) as a themefinder dependency. _resolve_model narrows on str first, so a ready-made Model instance is always used as-is regardless of gateway args (avoids re-wrapping it in OpenAIChatModel). Batch-processor signatures use PEP 604 str | None throughout.
d8954ef to
8f40062
Compare
|
Claude finished @Nazehs's task in 43s —— View job
PR Review: refactor(themefinder): migrate LLM layer to Pydantic AIClean and merge-ready. All prior NITs resolved. ⚪️ NIT ( 🔵 CONSIDER ( |
Add unit tests for the new LLM wrapper (gateway vs direct-provider resolution, Model-instance passthrough incl. with gateway args, structured-output modes) and live-inference tests gated on gateway credentials. Extend task and batch-processor tests for the Pydantic AI code path.
…AILLM Point benchmark, metrics, and the four eval scripts at the new LLM class, and update the sign-off/mapping pipeline scripts to match. benchmark.py gains --dataset/--provider/--models/--runs for multi-model, multi-repeat runs. Also fix pre-existing eval breakage the revived Pydantic AI path exposed: - align Azure deployment names with the gateway catalog (gpt-4.1, gpt-4o-sweden) instead of stale dated names that 400 as 'Invalid model name'; - reuse the resolved task LLM for generation metrics in the local fallback rather than building a judge from the AUTO_EVAL_4_1_SWEDEN_DEPLOYMENT secret; - parse the prompt's ternary decision format (STRONG/PARTIAL/NO) via evaluators._parse_evaluation_response instead of treating dicts as scores.
…val fallback The eval's local-data path reads inputs/question_part_*/question.json and outputs/mapping/2025-07-22/question_part_*/themes.json, but a blanket *.json ignore rule (for GCP creds) hid every .json under the dataset, so only the .jsonl files were tracked. When Langfuse is unavailable the eval falls back to local data and failed with FileNotFoundError in CI. Re-include the reference dataset's .json via a targeted .gitignore negation and commit the four missing files, copied verbatim from upstream themefinder (commit 09918eb2, per ADR-0009; sibling .jsonl verified byte-identical).
Expose a 'runs' workflow input and pass it through to benchmark.py as --runs, raise the job timeout to 180m to accommodate repeated runs.
Exclude themefinder dev-only directories (evals, docs, tests, caches) and sql.log from Docker build context; regenerate uv.lock to resolve pydantic-ai-slim and its transitive dependencies.
8f40062 to
6a9eae9
Compare
|
Claude finished @Nazehs's task in 37s —— View job
PR Review: refactor(themefinder): migrate LLM layer to Pydantic AIClean migration — all prior NITs resolved. Two items remain: ⚪️ NIT ( 🔵 CONSIDER ( |
Context
Every themefinder LLM call went through a single OpenAI-SDK class (
OpenAILLM), making provider switching hard. This replaces it with one Pydantic AI-backedLLMwhere the model is a single configurable value —LLM("openai:gpt-4o")vsLLM("anthropic:claude-..."), or the LiteLLM gateway viabase_url+api_key.Changes proposed in this pull request
llm.py:OpenAILLM→ Pydantic AILLM(sameainvoke/invokeinterface). Direct mode (provider-prefixed string), gateway mode (OpenAIChatModel+OpenAIProvider), or aModelinstance. Structured output kept on OpenAI-native behaviour viaNativeOutput.llm_batch_processor.py: provider-agnostic error handling (ModelHTTPError/UnexpectedModelBehavior);tiktokenfallback for non-OpenAI model names.tasks.py: optionalstage_llmsonfind_themesfor per-stage models (backward compatible).LLM(...).FunctionModel/TestModel) + live gateway tests ongambling_XSdata (skip without creds).pydantic-ai-slim[openai,anthropic,google].Guidance to review
make test(themefinder) for unit tests. Live tests run automatically whenLLM_GATEWAY_URL/LITELLM_CONSULT_OPENAI_API_KEYare set — currently 8 pass.Outstanding (future PRs)
Things to check
.env.testfiles in the repo🤖 Generated with Claude Code