fix(conversations): align create and update request contracts - #625
fix(conversations): align create and update request contracts#625leseb wants to merge 6 commits into
Conversation
praxis-bot
left a comment
There was a problem hiding this comment.
PR Review
Correct alignment of create and update contracts with verified OpenAI behavior. The MetadataUpdate enum removal, optional nullable items, and empty-body handling are all internally consistent. The macro syntax change ([none], [required ...], [optional ...]) cleanly disambiguates request body semantics. Conformance documentation with the verification date is a good addition.
CI passes. Two medium findings below on test coverage gaps for the new schema and deserialization paths.
aef5501 to
63291ca
Compare
praxis-bot
left a comment
There was a problem hiding this comment.
PR Review
Clean alignment of create and update contracts with verified OpenAI behavior. The MetadataUpdate enum removal, nullable optional items, empty-body handling, and macro syntax disambiguation are all internally consistent. Good conformance documentation and test coverage for the new update-requires-metadata invariant.
CI passes. One medium finding on incorrect error messages.
| Severity | File | Finding |
|---|---|---|
| Medium | handlers.rs |
classify_update_error hardcodes "got null" for all non-object metadata types |
praxis-bot
left a comment
There was a problem hiding this comment.
PR Review
Correct alignment of create and update contracts with verified OpenAI behavior. The MetadataUpdate enum removal, nullable optional items, empty-body defaulting, and macro syntax disambiguation ([none], [required ...], [optional ...]) are all clean and internally consistent. Good conformance documentation with verification dates.
CI passes. Two medium findings on error response consistency.
| Severity | File | Finding |
|---|---|---|
| Medium | handlers.rs:856 |
invalid_input_response now adds "code": null, "param": null to all 400 responses |
| Medium | handlers.rs:178 |
validate_metadata errors all use "invalid_type" error code |
63291ca to
ffe1315
Compare
|
@aslakknutsen ptal again :) |
praxis-bot
left a comment
There was a problem hiding this comment.
PR Review (Round 4)
CI passes. Two new medium findings on conformance gap and schema test coverage.
| Severity | File | Finding |
|---|---|---|
| Medium | handlers.rs:169 |
Empty-body update produces generic 400, not missing_required_parameter per conformance README |
| Medium | openapi.rs:156 |
generated_create_request_contract_matches_runtime does not verify maxItems survived schema restructuring |
praxis-bot
left a comment
There was a problem hiding this comment.
PR Review (Round 5)
Good conformance alignment. The MetadataUpdate enum removal, nullable optional items, empty-body create handling, and macro syntax disambiguation ([none], [required ...], [optional ...]) are clean and internally consistent. Prior round findings about classify_update_error message accuracy and blanket invalid_type usage have been addressed.
CI passes. One medium finding on error classification robustness.
| Severity | File | Finding |
|---|---|---|
| Medium | handlers.rs:176 |
validate_metadata error gate relies on fragile string matching |
Align the locally owned Conversation create and update request bodies with confirmed OpenAI behavior. Create requests accept an absent body and nullable optional fields, while update requests require a non-null metadata object. Generate the matching OpenAPI schemas from the shared runtime contracts, retain the 20-item limit, cover absent, null, empty, valid, and invalid body shapes, and document the verified live behavior where it contradicts the pinned upstream specification. Closes praxis-proxy#566 Signed-off-by: Sébastien Han <seb@redhat.com>
Signed-off-by: Sébastien Han <seb@redhat.com>
Signed-off-by: Sébastien Han <seb@redhat.com>
Map update-conversation parse and validation errors to the OpenAI error contract with code (missing_required_parameter, invalid_type) and param fields. Add inner anyOf assertions for the two-layer nullable metadata schema and an array-type rejection test. Signed-off-by: Sébastien Han <seb@redhat.com>
- Remove hardcoded "but got null" from classify_update_error message since the error applies to all non-object types, not just null - Restore invalid_input_response to not include code/param fields, keeping those only for update-specific errors via invalid_input_response_with - Use invalid_type code only for actual type violations from validate_metadata, not for constraint violations (key/value length, key count) Signed-off-by: Sébastien Han <seb@redhat.com>
- Replace string-matching heuristic (msg.contains("must be")) with
MetadataError enum that structurally distinguishes type errors from
constraint violations
- Add maxItems assertion to OpenAPI schema test ensuring the 20-item
bound is preserved in the generated document
- Handle empty update body with missing_required_parameter error code
matching the {} case, as documented in conformance README
Signed-off-by: Sébastien Han <seb@redhat.com>
ffe1315 to
9767694
Compare
Problem
The Conversations create and update request contracts diverged from verified
OpenAI live behavior: create treated
itemsas a requiredVecinstead ofa nullable optional array, and update accepted absent or null
metadataviaa three-variant
MetadataUpdateenum instead of requiring a metadata object.Changes
CreateConversationRequest.itemsanOption<Vec<ConversationItem>>with a nullable bounded-array OpenAPI schema matching upstream
MetadataUpdateenum with a requiredMetadatafield using acustom deserializer that rejects null, matching verified
400behaviornullable_metadata_schemaandnullable_initial_items_schemaforprecise OpenAPI generation
update operations)
Validation
make lint(clippy, fmt, deps, docs, examples all clean)cargo test -p praxis-ai-apis -- conversationscargo xtask openai-conformance --area conversations(3/8 exact, 12 exceptions)git diff --check origin/main...HEADCloses #566