Repository navigation
LCORE-3095: Fix schema constraint loss in json_schema_updater recursive_update() - #3096
fullsend-ai-coder[bot] wants to merge 3 commits into
Conversation
…ve_update()
Fix two bugs in recursive_update() that silently dropped schema constraints
when converting Pydantic JSON Schema to OpenAPI 3.0:
1. exclusiveMinimum conversion: Pydantic v2 emits {exclusiveMinimum: 0} for
PositiveInt (value > 0). The function incorrectly rewrote this to
{minimum: 0} (value >= 0), losing the exclusive semantics. Now correctly
emits {minimum: 0, exclusiveMinimum: true} per OpenAPI 3.0.
2. anyOf nullable handling: When converting anyOf: [{type, enum, ...},
{type: null}] to a nullable type, only the type was extracted while all
other constraints (enum, format, maxLength, items, etc.) were silently
discarded. Now preserves all additional properties from the first anyOf
item, with recursive processing for nested dict values.
Updated unit tests to assert the corrected behavior and added new tests for
enum preservation and nested items handling. Regenerated all documentation
schema artifacts.
Closes #3095
|
Important Review skippedBot user detected. To trigger a single review, invoke the
|
|
🤖 Finished Review · ✅ Success · Started 12:39 PM UTC · Completed 12:56 PM UTC Commit: Runtime: pi · Model: opus → claude-opus-4-6 · Effort: high · Cost: $5.25 |
|
<!-- fullsend:risk-assessment --> DetailsLow-moderate risk. The large line count (9192) is almost entirely regenerated JSON doc artifacts; actual code change is ~14 lines in one utility function plus ~96 lines of tests. No protected paths, no security-sensitive files, no CI/dependency changes. Bot author, low churn on source files. Issue scope aligns with PR. Signals unchanged from prior review. Previous run<!-- fullsend:risk-assessment --> DetailsLow-moderate risk. The large line count (9186) is almost entirely regenerated JSON doc artifacts; actual code change is ~10 lines in one utility function plus ~96 lines of tests. No protected paths, no security-sensitive files, no CI/dependency changes. Bot author, low churn on source files. Issue scope aligns with PR. Previous run (2)<!-- fullsend:risk-assessment --> DetailsLow-moderate risk. The large line count (9140) is almost entirely regenerated JSON doc artifacts; actual code change is ~80 lines in one utility function plus tests. No protected paths, no security-sensitive files, no CI/dependency changes. Bot author, low churn on source files. Issue scope aligns with PR. |
|
Looks good to me Earlier findings
Previous run<!-- fullsend:review-findings-v2:eyJ2ZXJzaW9uIjoyLCJhY3Rpb24iOiJyZXF1ZXN0LWNoYW5nZXMiLCJmaW5kaW5ncyI6W3sic2V2ZXJpdHkiOiJtZWRpdW0iLCJjYXRlZ29yeSI6ImluY29tcGxldGUtZG9jIiwiZmlsZSI6InNyYy91dGlscy9qc29uX3NjaGVtYV91cGRhdGVyLnB5IiwiaWQiOiJmXzEyNDIwNjAwM2VkYTU0ZWEiLCJsaW5lIjoxNCwiYWN0aW9uYWJsZSI6dHJ1ZX0seyJzZXZlcml0eSI6ImhpZ2giLCJjYXRlZ29yeSI6ImxvZ2ljLWVycm9yIiwiZmlsZSI6InNyYy91dGlscy9qc29uX3NjaGVtYV91cGRhdGVyLnB5IiwiaWQiOiJmXzEyYTIyOWIxNjBhMTY2OWUiLCJsaW5lIjo1MSwiYWN0aW9uYWJsZSI6dHJ1ZX0seyJzZXZlcml0eSI6Im1lZGl1bSIsImNhdGVnb3J5IjoibWlzc2luZy10ZXN0IiwiZmlsZSI6InRlc3RzL3VuaXQvdXRpbHMvdGVzdF9qc29uX3NjaGVtYV91cGRhdGVyLnB5IiwiaWQiOiJmXzMyOWNmZmI4MmIxZDhiNTUiLCJsaW5lIjo0NjgsImFjdGlvbmFibGUiOnRydWV9LHsic2V2ZXJpdHkiOiJtZWRpdW0iLCJjYXRlZ29yeSI6InN0YWxlLWRvYyIsImZpbGUiOiJzcmMvdXRpbHMvanNvbl9zY2hlbWFfdXBkYXRlci5weSIsImlkIjoiZl8yNWM2ODUxYzNlOTFmNjI2IiwibGluZSI6MTIsImFjdGlvbmFibGUiOnRydWV9XSwiZGlzcG9zaXRpb25zIjpbeyJpZCI6ImZfMTJhMjI5YjE2MGExNjY5ZSIsInN0YXR1cyI6InJlc29sdmVkX2J5X2NoYW5nZSJ9LHsiaWQiOiJmXzMyOWNmZmI4MmIxZDhiNTUiLCJzdGF0dXMiOiJyZXNvbHZlZF9ieV9jaGFuZ2UifSx7ImlkIjoiZl8yNWM2ODUxYzNlOTFmNjI2Iiwic3RhdHVzIjoicmVzb2x2ZWRfYnlfY2hhbmdlIn1dfQ== --> ReviewFindingsMedium
Earlier findings
Next steps:
Previous run (2)<!-- fullsend:review-findings-v2:eyJ2ZXJzaW9uIjoyLCJhY3Rpb24iOiJyZXF1ZXN0LWNoYW5nZXMiLCJmaW5kaW5ncyI6W3sic2V2ZXJpdHkiOiJoaWdoIiwiY2F0ZWdvcnkiOiJsb2dpYy1lcnJvciIsImZpbGUiOiJzcmMvdXRpbHMvanNvbl9zY2hlbWFfdXBkYXRlci5weSIsImlkIjoiZl8xMmEyMjliMTYwYTE2NjllIiwibGluZSI6NTEsImFjdGlvbmFibGUiOnRydWV9LHsic2V2ZXJpdHkiOiJtZWRpdW0iLCJjYXRlZ29yeSI6Im1pc3NpbmctdGVzdCIsImZpbGUiOiJ0ZXN0cy91bml0L3V0aWxzL3Rlc3RfanNvbl9zY2hlbWFfdXBkYXRlci5weSIsImlkIjoiZl8zMjljZmZiODJiMWQ4YjU1IiwibGluZSI6NDY4LCJhY3Rpb25hYmxlIjp0cnVlfSx7InNldmVyaXR5IjoibWVkaXVtIiwiY2F0ZWdvcnkiOiJzdGFsZS1kb2MiLCJmaWxlIjoic3JjL3V0aWxzL2pzb25fc2NoZW1hX3VwZGF0ZXIucHkiLCJpZCI6ImZfMjVjNjg1MWMzZTkxZjYyNiIsImxpbmUiOjEyLCJhY3Rpb25hYmxlIjp0cnVlfV19 --> ReviewFindingsHigh
Medium
Labels: Bug fix in schema generation utility with small review effort. Next steps:
|
|
🤖 Finished Fix · ✅ Success · Started 12:57 PM UTC · Completed 1:07 PM UTC Commit: Runtime: pi · Model: opus → claude-opus-4-6 · Effort: high · Cost: $2.40 |
When converting anyOf nullable types, properties from the first item (e.g., exclusiveMinimum) were copied verbatim instead of being processed through recursive_update. This produced invalid OpenAPI 3.0 output where exclusiveMinimum was an integer instead of a boolean. Changes: - Process first_item constraints through recursive_update so that exclusiveMinimum (and any other convertible keys) are properly handled - Update docstring to reflect that exclusiveMinimum is rewritten to minimum plus exclusiveMinimum: true (OpenAPI 3.0 boolean form) - Add test for Optional[PositiveInt] pattern (anyOf with top-level exclusiveMinimum in the first variant) - Regenerate affected doc schema artifacts Addresses #3096
🔧 Fix agent — iteration 1 (bot-triggered)All three review findings addressed with a single root-cause fix: the anyOf handler now processes first-item properties through recursive_update instead of copying them directly, ensuring exclusiveMinimum (and any other convertible keys) are properly converted to OpenAPI 3.0 form. Added a test for the Optional[PositiveInt] pattern, updated the docstring, and regenerated affected doc schema artifacts. Fixed (3):
Tests: passed CI inspections (12):
Conflict update: skipped; strategy Decision points
Next steps:
|
|
🤖 Finished Review · ✅ Success · Started 1:09 PM UTC · Completed 1:25 PM UTC Commit: Runtime: pi · Model: opus → claude-opus-4-6 · Effort: high · Cost: $5.67 |
|
🤖 Finished Fix · ✅ Success · Started 1:27 PM UTC · Completed 1:32 PM UTC Commit: Runtime: pi · Model: opus → claude-opus-4-6 · Effort: high · Cost: $1.16 |
Update the recursive_update() docstring to accurately describe the anyOf handling behavior: all additional constraints from the first variant are preserved and recursively processed through OpenAPI 3.0 conversion, not just the type field. Addresses #3096
🔧 Fix agent — iteration 2 (bot-triggered)Updated the recursive_update() docstring to accurately describe the anyOf nullable conversion behavior, including constraint preservation and recursive OpenAPI 3.0 processing Fixed (1):
Tests: passed CI inspections (17):
Next steps:
|
|
🤖 Finished Review · ✅ Success · Started 1:34 PM UTC · Completed 1:51 PM UTC Commit: Runtime: pi · Model: opus → claude-opus-4-6 · Effort: high · Cost: $5.37 |
Superseded by updated review
|
🤖 Finished Retro · ✅ Success · Started 8:07 AM UTC · Completed 8:17 AM UTC Commit: Runtime: pi · Model: opus → claude-opus-4-6 · Effort: high · Cost: $2.25 |
Retro: PR #3096 — Fix schema constraint loss in json_schema_updaterTimeline
Total cost: $22.78 · 2 review→fix rework cycles · Outcome: PR closed, issue #3095 remains open Review qualityThe review agent performed well. Its first-pass finding was a genuine logic error: the code agent's anyOf handler copied first-item properties verbatim instead of processing them through Rework analysisCycle 1 (code agent miss): The issue description explicitly provided a code snippet showing Cycle 2 (fix agent miss): Fix 1 changed the anyOf handler to use Evidence for existing issues
Autonomy readinessInconclusive. No human review was conducted — the human closed the PR without leaving any review comments or feedback. There is no meaningful delta between agent review and human review to analyze. Proposals filed
|
Description
Fix two bugs in
recursive_update()insrc/utils/json_schema_updater.pythat silently dropped schema constraints when converting Pydantic JSON Schema to OpenAPI 3.0:exclusiveMinimumconversion: Pydantic v2 emits{"exclusiveMinimum": 0}forPositiveInt(value > 0). The function incorrectly rewrote this to{"minimum": 0}(value ≥ 0), losing the exclusive semantics. Now correctly emits{"minimum": 0, "exclusiveMinimum": true}per OpenAPI 3.0.anyOfnullable handling: When convertinganyOf: [{type, enum, ...}, {type: null}]to a nullable type, onlytypewas extracted while all other constraints (enum,format,maxLength,items, etc.) were silently discarded. Now preserves all additional properties from the firstanyOfitem.Updated existing unit tests to assert correct behavior, added new tests for enum preservation and nested items handling, and regenerated all documentation schema artifacts.
Type of change
Tools used to create PR
Related Tickets & Documents
Checklist before requesting a review
Testing
test_json_schema_updater.pypass (including 2 new tests)docs/user_doc/config.jsonconfirms:streaming_output_check_interval_tokensnow shows"minimum": 0, "exclusiveMinimum": trueAllowedModel.model_typenow includes"enum": ["llm", "embedding", "rerank"]Closes #3095
Post-script verification
agent/3095-fix-schema-constraint-loss)7850c3ceb201ad75e889bead2e5bb41d1f216680..HEAD)