schema

package
v0.9.10 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 18, 2026 License: Apache-2.0 Imports: 9 Imported by: 0

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

func (*Generator) Reflect

func (g *Generator) Reflect(v any) *jsonschema.Schema

Reflect returns the JSON schema for the provided value.

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

func (Violation) String added in v0.7.60

func (v Violation) String() string

String renders the violation as "<path>: <message>".

Directories

Path Synopsis
Package schematest provides test helpers for comparing JSON schemas.
Package schematest provides test helpers for comparing JSON schemas.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL