Skip to main content

objectiveai_sdk/cli/command/
response_schema.rs

1//! [`ResponseSchema`] — newtype wrapper around [`schemars::Schema`]
2//! that delegates its `JsonSchema` impl to [`serde_json::Value`].
3//!
4//! Every cli `*-schema` leaf subcommand emits a JSON Schema document
5//! as its response. The wire shape is opaque JSON — any valid schema
6//! is acceptable. Typing the response as `schemars::Schema` directly
7//! makes that wire shape strongly typed, but `schemars::Schema`'s own
8//! JsonSchema impl emits `{"type": ["object", "boolean"]}` (because
9//! the JSON Schema spec says a (sub)schema can be either an object or
10//! a bare boolean). That type array trips the
11//! `no_type_arrays_outside_properties` builder property test.
12//!
13//! The orphan rule prevents us from `impl JsonSchema for schemars::Schema`
14//! directly. This wrapper provides the same in-process typing
15//! (a `schemars::Schema` inside) while overriding the JsonSchema impl
16//! to behave exactly like `serde_json::Value` (no constraints, no
17//! type array). Serialization is transparent — the wire shape is
18//! identical to `schemars::Schema`'s.
19
20use objectiveai_sdk_macros::schema_override;
21
22#[schema_override(Ref)]
23#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)]
24#[serde(transparent)]
25pub struct ResponseSchema(pub schemars::Schema);
26
27impl schemars::JsonSchema for ResponseSchema {
28    fn schema_name() -> std::borrow::Cow<'static, str> {
29        <serde_json::Value as schemars::JsonSchema>::schema_name()
30    }
31
32    fn json_schema(
33        generator: &mut schemars::SchemaGenerator,
34    ) -> schemars::Schema {
35        <serde_json::Value as schemars::JsonSchema>::json_schema(generator)
36    }
37
38    fn inline_schema() -> bool {
39        // ALWAYS inline. Bare `serde_json::Value` fields embed an
40        // inline `{}` (unconstrained) schema, and this wrapper must
41        // behave identically. Without this, schemars treats
42        // `ResponseSchema` as a referenceable named type and every
43        // `*-schema` response becomes a `$ref: "AnyValue"`, forcing
44        // `Value` itself to exist as a registered standalone title.
45        true
46    }
47}