Documentation
¶
Overview ¶
Package schema provides JSON schema generation utilities for AI agent tool definitions.
Use NewGenerator or the package-level Reflect and ReflectType helpers to derive JSON schemas from Go types. The generator is pre-configured with defaults suitable for tool input schemas.
Index ¶
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Reflect ¶
func Reflect(v any) *jsonschema.Schema
Reflect derives the JSON schema for the provided value using a default generator.
func ReflectType ¶
func ReflectType[T any]() *jsonschema.Schema
ReflectType allocates a zero value of T and reflects it to a schema.
Example ¶
ExampleReflectType demonstrates generating a JSON schema from a Go type.
package main
import (
"encoding/json"
"fmt"
"chainguard.dev/driftlessaf/agents/schema"
)
func main() {
type Input struct {
Path string `json:"path" jsonschema:"required,description=File path to read"`
Offset int `json:"offset,omitempty" jsonschema:"description=Byte offset"`
}
s := schema.ReflectType[Input]()
data, err := json.Marshal(s)
if err != nil {
panic(err)
}
var m map[string]any
if err := json.Unmarshal(data, &m); err != nil {
panic(err)
}
fmt.Println("type:", m["type"])
}
Output: type: object
func ResultValidator ¶ added in v0.7.60
func ResultValidator[Response any]() callbacks.ResultValidator[Response]
ResultValidator returns the schema-conformance validator that the executors install as the base of every submit tool's validator chain: it checks a submitted response against the JSON schema reflected from the Response type — the same schema (modulo cosmetic descriptions) that the submit tool advertises to the model — and returns one finding per violation, rejecting the submission back to the model until it conforms.
This is the enforcement half of declaring constraints in jsonschema struct tags (enum, minimum/maximum, minLength/maxLength, pattern, minItems, ...): the tags shape what the model is asked for, and this validator makes the asked-for shape binding. Prefer expressing a constraint as a tag over hand-rolling a validator for it; reserve hand-rolled validators for cross-field and semantic rules a schema cannot state.
The validator sees the parsed response, not the raw payload, so it validates the response's canonical JSON encoding. Required-property checks are skipped: after parsing, an omitted field is indistinguishable from its zero value (and omitempty fields drop back out), so requiredness cannot be checked faithfully here — declare minLength=1 or an enum on fields whose zero value is unacceptable.
Example ¶
ExampleResultValidator demonstrates the schema-conformance validator the executors install as the base of every submit tool's validator chain.
package main
import (
"context"
"fmt"
"chainguard.dev/driftlessaf/agents/schema"
)
func main() {
type Verdict struct {
Label string `json:"label" jsonschema:"required,enum=benign,enum=malicious"`
Confidence float64 `json:"confidence" jsonschema:"minimum=0,maximum=1"`
}
validate := schema.ResultValidator[*Verdict]()
findings, _ := validate(context.Background(), &Verdict{Label: "unsure", Confidence: 0.5}, "reasoning")
for _, f := range findings {
fmt.Println(f.Identifier)
}
}
Output: schema:label
Types ¶
type Generator ¶
type Generator struct {
// contains filtered or unexported fields
}
Generator wraps jsonschema.Reflector with project defaults.
func NewGenerator ¶
func NewGenerator() *Generator
NewGenerator constructs a generator wired with the defaults we need for tool schemas.
Example ¶
ExampleNewGenerator demonstrates creating a generator and reflecting a value.
package main
import (
"encoding/json"
"fmt"
"chainguard.dev/driftlessaf/agents/schema"
)
func main() {
type Params struct {
Query string `json:"query" jsonschema:"required"`
}
g := schema.NewGenerator()
s := g.Reflect(&Params{})
data, _ := json.Marshal(s)
var m map[string]any
_ = json.Unmarshal(data, &m)
fmt.Println("type:", m["type"])
}
Output: type: object
type Options ¶ added in v0.7.60
type Options struct {
// IgnoreRequired skips the required-property checks. A document produced
// by round-tripping a parsed Go value (rather than taken verbatim from
// the model) no longer distinguishes an omitted field from its zero
// value — a field with a json omitempty tag drops back out at zero — so
// required checks against such a document report false positives.
IgnoreRequired bool
}
Options adjusts Validate's behavior for callers whose documents cannot carry certain constraints faithfully.
type Violation ¶ added in v0.7.60
type Violation struct {
// Path locates the failing value within the document, e.g.
// "failures[2].severity". Empty means the document root.
Path string
// Message states the violated constraint, e.g.
// `value "warn" is not one of the allowed values ["error","warning","info"]`.
Message string
}
Violation describes one way a decoded JSON value fails to conform to a schema. Its message is written for the model that produced the value: it names the failing path and states the constraint so the value can be corrected and resubmitted.
func Validate ¶ added in v0.7.60
func Validate(s *jsonschema.Schema, value any, opts ...Options) []Violation
Validate checks a decoded JSON document (map[string]any, []any, string, float64, json.Number, bool, or nil — the shapes encoding/json produces) against a schema produced by this package's Generator and returns every violation found. An empty return means the document conforms.
It enforces the subset of JSON Schema the generator emits from struct tags: type, enum, const, numeric bounds (minimum, maximum, exclusiveMinimum, exclusiveMaximum), string bounds (minLength, maxLength, pattern), array bounds (minItems, maxItems, uniqueItems), object requirements (required, properties), items, and the combinators (anyOf, oneOf, allOf). Annotation-only keywords (format, description, default, examples) and keywords the generator never emits are not enforced.
A null value for a property that is not required is treated as absent and skipped: encoding/json decodes it to the field's zero value, which is the same outcome as omitting the key. A null for a required property is a violation — the requirement exists because a meaningful value is expected.
An invalid pattern in the schema is a schema-authoring bug, not a document bug; the pattern constraint is skipped rather than blaming the document.
Example ¶
ExampleValidate demonstrates checking a decoded JSON document against a reflected schema.
package main
import (
"encoding/json"
"fmt"
"chainguard.dev/driftlessaf/agents/schema"
)
func main() {
type Verdict struct {
Label string `json:"label" jsonschema:"required,enum=benign,enum=malicious"`
Confidence float64 `json:"confidence" jsonschema:"minimum=0,maximum=1"`
}
var doc any
_ = json.Unmarshal([]byte(`{"label":"unsure","confidence":1.5}`), &doc)
for _, v := range schema.Validate(schema.ReflectType[Verdict](), doc) {
fmt.Println(v)
}
}
Output: label: value "unsure" is not one of the allowed values ["benign", "malicious"] confidence: value 1.5 exceeds the maximum 1
Directories
¶
| Path | Synopsis |
|---|---|
|
Package schematest provides test helpers for comparing JSON schemas.
|
Package schematest provides test helpers for comparing JSON schemas. |