Repository navigation
Conversation
Rebuilt on origin/main (6a9c878) from the 2026-09-28 model-pin audit's salvaged lane work (refs/salvage/model-pins-2026-09-28/PolicyEngine__policyengine.py, 8fa112335). - No build-lane report survived for this edit; it is re-verified from scratch in this branch. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Name the changelog fragment after issue #580, as the repository's PR guide requires. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Validate effective LiteLLM AnthropicConfig before synchronous and asynchronous requests for both supported model spellings without mutating shared settings. Add 24 regression cases, preserve custom-model behavior and compatible token defaults, and update the issue #580 changelog fragment. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #580
Optional derivation narration defaults to an outdated Sonnet model and sends temperature with a tight token budget. Update it to Sonnet 5.5 with explicit low effort and compatible requests. Rebuilt from the 2026-09-28 model-pin audit against current main, including its approved DECIDE-to-FIX override for opt-in narration text.
src/policyengine/derivations/narrate.pyclaude-sonnet-4-6→claude-sonnet-5-5tests/test_derivations.pyPin LiteLLM 1.103.0 in the optional
narrationand development extras. Regenerateuv.lockfrom main: 27 new packages belong to LiteLLM's dependency closure, and its requirement upgradespydantic-settingsfrom 2.10.1 to 2.15.0. Preserve main's project and country-package versions: policyengine 6.2.6, core 3.33.0, UK 2.125.1, US 2.2.1, and SPM calculator 1.0.0.Both supported Sonnet routes use explicit Anthropic routing, native
output_config.effort=low, and a 4,096-token default budget for the short narrative, including thinking. They omit thinking so adaptive thinking applies. No request on these routes sends temperature, top_p, top_k, legacy thinking settings, forced tool choice, or assistant prefill. Explicit temperature is rejected for these routes. LiteLLM joins response blocks by type; narration rejects refusal and empty text. Because this pinned wrapper silently discards effort when parameter dropping is enabled, narration fails before requesting in that configuration. Real sync/async SDK calls through HTTPX MockTransport verify the final JSON, both model spellings, multiple text blocks, and refusal handling. The provider-prefix convention follows LiteLLM's Anthropic routing documentation.No environment variable selects the model default; callers can override it with
model=. Explicit custom-model temperature and token arguments remain supported. KeepLITELLM_DROP_PARAMSunset or false andlitellm.drop_paramsfalse.ANTHROPIC_API_BASEandANTHROPIC_BASE_URLcan change the endpoint, not the explicit model ID. Arbitrary custom-model overrides remain caller-controlled.Validation used uv 0.12.14, a locked Python 3.13.9 development environment, and at most four pytest workers. Caches and fixtures were kept under scratch and removed afterward.
POLICYENGINE_SKIP_COUNTRY_IMPORTS=1 PYTEST_ADDOPTS='-n 0 -o cache_dir=.lane-scratch/derivations-cache --basetemp=.lane-scratch/derivations-temp' uv run --no-sync pytest --noconftest tests/test_derivations.py -v: 36 passed.POLICYENGINE_SKIP_COUNTRY_IMPORTS=1 uv run --no-sync pytest --noconftest tests/test_derivations.py -k narrat -v: 30 passed on Python 3.13.9 with four workers..lane-scratch/compat-current/py3.11/bin/python -m pytest --noconftest tests/test_derivations.py -k narrat -v -o cache_dir=.lane-scratch/compat-current/pytest-cache-py3.11 --basetemp=.lane-scratch/compat-current/pytest-tmp-py3.11: 30 passed, 6 deselected..lane-scratch/compat-current/py3.12/bin/python -m pytest --noconftest tests/test_derivations.py -k narrat -v -o cache_dir=.lane-scratch/compat-current/pytest-cache-py3.12 --basetemp=.lane-scratch/compat-current/pytest-tmp-py3.12: 30 passed, 6 deselected..lane-scratch/compat-current/py3.14/bin/python -m pytest --noconftest tests/test_derivations.py -k narrat -v -o cache_dir=.lane-scratch/compat-current/pytest-cache-py3.14 --basetemp=.lane-scratch/compat-current/pytest-tmp-py3.14: 30 passed, 6 deselected. These three runs disabled country imports, enabled the local cost map, and removed provider credentials.PYTEST_ADDOPTS='-n 4 -o cache_dir=.lane-scratch/pytest-cache --basetemp=.lane-scratch/pytest-temp' PYTHONUNBUFFERED=1 make test: 1,306 passed, 9 skipped, 1 failed, 89% coverage. The sole failure is a Git-tag fixture discovering parent-checkout tags through its scratch directory; origin/main's files reproduce it.GIT_CEILING_DIRECTORIES="$PWD/.lane-scratch/bump-fixed-temp" POLICYENGINE_SKIP_COUNTRY_IMPORTS=1 PYTEST_ADDOPTS='-n 0 -o cache_dir=.lane-scratch/bump-cache --basetemp=.lane-scratch/bump-fixed-temp' uv run --no-sync pytest --noconftest tests/test_bump_version.py -v: 8 passed, resolving that environment-only failure.make formatandPATH="$PWD/.lane-scratch/ruff-cli/bin:$PATH" make lint: passed with CI's Ruff 0.16.10. Locked Ruff 0.12.11 reports 11 pre-existing UP038 findings in unchanged files.uv run --no-sync mypy src/policyengine: 118 pre-existing errors versus 120 with main's narration file; no new errors. CI treats this check as informational.uv lock --check,.github/check-changelog.sh,python scripts/release_lock.py, anduv pip check: passed.POLICYENGINE_SKIP_COUNTRY_IMPORTS=1 uv run --no-sync policyengine bundle verify --country us --country uk --packages-only --json: all 5 package versions matched.python -c "import policyengine; from policyengine.core import Dataset, Policy, Simulation; from policyengine.outputs import aggregate, poverty, inequality; print('import OK')": base-only installs and smoke imports passed on Python 3.11, 3.12, and 3.14; package/narration imports also passed on 3.13.env QUARTO_DENO="$PWD/.lane-scratch/quarto-wrapper/deno-wrapper" DENO_DIR="$PWD/.lane-scratch/deno" XDG_CACHE_HOME="$PWD/.lane-scratch/xdg-cache" make docs: 30 pages built. The scratch-only wrapper resolves a macOS Quarto cache failure also reproduced on main.The initial standard derivation invocation was interrupted during unrelated country startup; the complete test file and full suite subsequently finished. The nine suite skips concern unavailable Belgium source-stack integration and explicit SPM development-authentication setup. Credentialed
python scripts/check_release_credentials.pyandpython scripts/bundle.py check --published-spm --include-tros --strict-trosremain skipped withoutHUGGING_FACE_TOKENand must run in CI.Simulation code, country-model pins, UK region filtering, and public result models were deliberately left unchanged. No other outdated live model call site was found on current main. Replaced-ID searches find no matches in HEAD or the final working tree. No live model-provider call was made, and no provider credentials or metered usage were used.
After independent review
Independent review's global-sampling blocker was reproduced in all 12 mocked HTTP combinations. Narration now rejects effective LiteLLM AnthropicConfig temperature, top_p, and top_k before either completion function for both Sonnet spellings, without mutating shared configuration. Added 24 regression cases including zero values; custom-model overrides remain supported, and existing HTTPX tests verify compatible global token defaults remain unchanged.
Offline, serial Python 3.13.9 validation used locked LiteLLM 1.103.0, removed provider credentials, local cost data, disabled pytest plugin autoload, and blocked sockets.
.venv/bin/python -m pytest --noconftest tests/test_derivations.py -k narrat -v -o cache_dir=.lane-scratch/narration-cache --basetemp=.lane-scratch/narration-temp: 54 passed, 6 deselected..venv/bin/python -m pytest --noconftest tests/test_derivations.py -k 'not narrat and not derive_returns and not top_level_contributions' -v -o cache_dir=.lane-scratch/deterministic-cache --basetemp=.lane-scratch/deterministic-temp: 4 passed, 56 deselected. This verifies 58 tests. The full-file coverage run was interrupted after 1,428.34 seconds during unchanged US-model startup; origin/main's identical US fixture/tests also exceeded a 300-second limit, so no complete 60-test pass is claimed.make format,make lint, locked Ruff checks on both changed Python files,.github/check-changelog.sh,uv lock --check --python .venv/bin/python,python scripts/release_lock.py, anduv pip check --python .venv/bin/pythonpassed; dependency consistency checked 187 packages. Bundle verification matched all five pins. Clean base-only installs, dependency checks, and CI smoke imports passed on Python 3.11–3.14, with 24 packages per environment.env -u PYTHONPATH .venv/bin/python -m mypy src/policyengine --no-incremental --cache-dir .lane-scratch/mypy-cachereported 118 existing errors; substituting main's narration file reported 120, with zero new diagnostic lines. Complete current-main sources reported 134 errors. Credentialed release verification remains for CI without HUGGING_FACE_TOKEN; the full suite was excluded as instructed. Scratch was removed, fixes remain uncommitted, and no live provider calls or GitHub writes were made.Part of the 2026-09-28 cross-repo model-pin audit, rebuilt on today's
main(2026-10-11) after the audit's build lanes were cut off. Current models were re-checked against the provider's docs on 2026-10-03. Opened as a draft perdocs/engineering/skills/github-prs.md.🤖 Generated with Claude Code