wire_schema

Function wire_schema 

Source
pub fn wire_schema<T: JsonSchema + ?Sized>() -> Value
Expand description

Derive a JSON Schema in the shape the Gemini API will actually enforce.

This is the one way a Rust type becomes a schema on the wire: #[tool] parameters, TypedTool arguments, typed agent output and turn extraction all go through it. Derive JsonSchema on the type (doc comments on fields become descriptions) and call this instead of schemars::schema_for!, whose output the API misreads in the ways below.

use gemini_adk_rs::tool::wire_schema;

#[derive(schemars::JsonSchema)]
#[allow(dead_code)]
struct Lookup {
    /// The city to look up.
    city: String,
    units: Option<String>,
}

let schema = wire_schema::<Lookup>();
assert_eq!(schema["properties"]["city"]["description"], "The city to look up.");
assert_eq!(schema["properties"]["units"]["type"], "string"); // not ["string", "null"]
assert_eq!(schema["required"], serde_json::json!(["city"]));

schemars::schema_for! hoists every nested type into definitions and points at it with $ref. The API does not resolve those references — it ignores them, silently. A declaration carrying $ref therefore degrades to “send some JSON”: enum constraints stop applying and the model invents variants the type cannot deserialize. On the Live endpoint the failure is harsher still — the server closes the connection during setup rather than accepting the declaration.

So subschemas are inlined and $schema/definitions are stripped, leaving nothing that points outside the document. A schema that is ignored is worse than one that is absent: it reads as a constraint and behaves like free-form generation.

The result is then narrowed to the API’s schema subset, which draft-07 is broader than in ways that matter: a nullable union collapses to its one type, and a oneOf over single-variant enums flattens into one enum.