fix(data_contract): enrich in bounded units so wide schemas and wide tables don't truncate#8
Merged
Merged
Conversation
…tables don't truncate
The enricher drafted ALL assets in a single ForcedToolCaller call capped at max_tokens,
so a wide schema's combined enrichment exceeded the cap and WP3's max_tokens guard raised
LLMCallError — the full messy_insurance `run` could never complete end-to-end.
DataContractAgent.run now enriches in BOUNDED units, scaling in both dimensions:
* one asset per call — a wide *schema* (many tables) never overflows; and
* a table wider than _FIELDS_PER_CALL (40) is split by field into ceil(cols/40) calls —
a wide *table* (many columns, routine in legacy insurance/banking sources, e.g. 256
attributes) never overflows either. _merge_enrichment folds an asset's chunks back
together (merging fields, keeping the first doc).
The system prompt (carrying the full declared schema) is byte-identical across calls, so
WP3 prompt caching makes the extra calls cheap on input tokens; the per-call output budget
is raised to 8192 (output tokens billed per generation, so headroom is free).
Verified live: (a) 5-table / 38-column messy_insurance — 5/5 contracts, all 38 fields
typed, 0 undetermined-type flags; (b) a real 256-column table — 7 bounded calls
(ceil(256/40)), all 256 fields contracted, no truncation. Both previously LLMCallError.
Keyless tests: test_enrichment_is_batched_one_asset_per_call (one call per asset),
test_wide_table_is_chunked_and_fully_enriched (256 cols → chunked, every field covered).
331 tests green, ruff clean, mypy strict clean (32 files).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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.
Summary
Fixes the pre-existing
data_contracttruncation blocker flagged in the WP9 milestone: the enricher drafted all assets in oneForcedToolCallercall capped atmax_tokens, so a wide schema's combined enrichment exceeded the cap and WP3'smax_tokensguard raisedLLMCallError— the fullmessy_insurancerun could never complete end-to-end.DataContractAgent.runnow enriches in bounded units, scaling in both dimensions:_FIELDS_PER_CALL(40) is split by field intoceil(cols/40)calls → a wide table (many columns — routine in legacy insurance/banking sources, e.g. 256 attributes) never overflows either._merge_enrichmentfolds an asset's chunks back together (merging fields, keeping the first doc).The system prompt (carrying the full declared schema) is byte-identical across calls, so WP3 prompt caching makes the extra calls cheap on input tokens; the per-call output budget is raised to 8192 (output tokens are billed per generation, so headroom is free).
Verification
Live (real Anthropic API):
messy_insurance— 5/5 contracts, all 38 fields typed, 0 undetermined-type flags.ceil(256/40)), all 256 fields contracted, no truncation.Both cases previously raised
LLMCallError.Keyless (CI, no API key):
test_enrichment_is_batched_one_asset_per_call— one bounded call per asset.test_wide_table_is_chunked_and_fully_enriched— 256 cols → chunked, every field covered.331 tests green,
ruff check .clean,uv run mypyclean (32 files).Notes
data_contractagent was the specific blocker to a fullmessy_insurancerun; this closes it. A full end-to-endvault-agent runon messy (all LLM agents, token-heavy) was not run here.🤖 Generated with Claude Code