ElicitationSchema round-trips through ElicitationSchemaWire, which had no
field for the top-level `$schema` keyword. A dialect declared on an incoming
requestedSchema (allowed since protocol revision 2025-11-25) was therefore
accepted but silently dropped on re-serialization.
Add a `schema` field to both the public struct and the wire bridge, thread it
through the two `From` conversions, and expose a `with_schema` setter. The
field is `skip_serializing_if = "Option::is_none"`, so schemas without a
dialect serialize unchanged.
Refs #1168
What
ElicitationSchema (de)serializes through an internal ElicitationSchemaWire
bridge. The bridge had no field for the top-level $schema keyword, so a
dialect declared on an incoming requestedSchema was accepted but silently
dropped when the schema was re-serialized.
The 2025-11-25 protocol revision allows a requestedSchema to carry a
$schema dialect identifier, and ElicitationSchema::from_type already emits
one (schemars draft-07), so the value was being lost on any round-trip.
Change
to both ElicitationSchema and the ElicitationSchemaWire bridge.
with_description builders. The struct is #[non_exhaustive], so an
external caller needs a setter to populate the field.
The field uses skip_serializing_if = "Option::is_none", so a schema without a
dialect serializes exactly as before. Adding a field to a #[non_exhaustive]
struct is semver compatible.
Tests
Three unit tests in elicitation_schema.rs:
Scope
This handles the $schema half of #1168. The other half (preserving unknown
property-level keywords) needs a data-model decision on where arbitrary
keywords should live, so I left it out of this change and kept the issue open
for it.
Refs #1168