gbnf

package
v0.1.3 Latest Latest
Warning

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

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

Documentation

Overview

Package gbnf compiles a tool's JSON Schema into a GBNF grammar that a local inference runtime applies as a token mask during decoding, so a model cannot emit a structurally invalid tool call no matter how small or weak it is. The malformed-call failure class is removed by construction, independent of model size, because the runtime can only sample tokens the grammar permits.

The package is deliberately self-contained and has an in-process recognizer for the same grammar AST it renders. That recognizer is the executable meaning of a grammar: tests compile a schema, then check that the grammar accepts exactly the JSON values the schema admits, so the emitted text is proven correct here without needing a GPU or a running runtime in the loop. Rendering to GBNF text and recognizing against the AST share one representation, so what the tests verify is what ships to the runtime.

Only the subset of JSON Schema that tool argument schemas actually use is supported (objects with typed properties, required lists, enums, arrays, nested objects, closed or open). An unsupported construct is a compile error, never a silently wrong grammar: refusing is safe, guessing is not.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func WellFormed

func WellFormed(text, root string) error

WellFormed checks the rendered GBNF text on its own terms, independent of the AST it came from: every group and class and string literal is balanced, the start rule is defined, and every bareword reference resolves to a defined rule. It scans the text a runtime would actually parse, so a rendering bug is caught here rather than at the runtime. It returns the first problem found, or nil.

Types

type Grammar

type Grammar struct {
	// contains filtered or unexported fields
}

Grammar is a named set of rules with a distinguished root, renderable to GBNF text and recognizable in process against the same rules. The zero value is not usable; build one through a compile entry point such as Tool or Arguments.

func Arguments

func Arguments(schema json.RawMessage) (*Grammar, error)

Arguments compiles a tool's JSON Schema into a grammar whose root matches a single JSON object: the arguments of one call to that tool. A runtime applies it so the argument object is structurally valid and type-correct by construction.

The supported subset is what tool argument schemas use in practice: a top-level object with typed properties (string, integer, number, boolean, enum, array, and nested object), a required list, and either closed (additionalProperties false) or open extra properties. Anything outside the subset is a compile error so a runtime is never handed a grammar that quietly permits an invalid call.

func Tool

func Tool(schema json.RawMessage) (*Grammar, error)

Tool compiles a grammar for a single tool's argument object, the unit a runtime constrains once it has committed to calling that tool. It is ToolCall narrowed to one tool with no name envelope.

func ToolCall

func ToolCall(tools []ToolSchema) (*Grammar, error)

ToolCall compiles a grammar whose root matches a single tool-call object of the form {"name": <one of the tool names>, "arguments": <object matching that tool's schema>}. A runtime applies it so a local model can only ever name a real tool and can only ever emit arguments that satisfy that specific tool's schema. The tool name and its argument shape are bound together: a call naming one tool cannot borrow another's arguments.

The tool set must be non-empty and every tool's argument schema must compile; either failure is reported rather than producing a permissive grammar.

func ToolCallOrText

func ToolCallOrText(tools []ToolSchema) (*Grammar, error)

ToolCallOrText compiles a grammar whose root matches EITHER a structurally valid tool call (exactly as ToolCall) OR a free-text final answer that does not begin with "{". A constrained local model can therefore still end its turn with prose, while every tool call it does emit stays well-formed by construction. The two branches are told apart by the first character: an output that starts with "{" is a tool call and nothing else, so there is no ambiguity. This is the form used for an agent loop, where a turn is either a tool call or the model's final answer.

func (*Grammar) Accepts

func (g *Grammar) Accepts(input string) bool

Accepts reports whether the grammar matches the whole of input. It is the in-process meaning of the grammar: the same answer a runtime's token mask would converge to if it only ever sampled grammar-permitted tokens and the result were checked against the rules. Tests use it to prove a compiled grammar accepts exactly the JSON values its source schema admits.

The recognizer is a backtracking matcher over the rule AST. A node maps an input position to the set of positions it can advance to (more than one, because alternation and repetition branch), and the input is accepted when the root rule can advance from the start to the very end. Positions reached are memoized per (node, position) so shared subgrammars are not re-explored, which keeps the JSON grammars this package emits well within a fixed work budget. The budget counts matches attempted, including one per start position when advancing a set, so it bounds total work rather than node visits: an input that widens the position set pays for the width. It is a guard against a pathological grammar or input rather than a real limit for the inputs these grammars describe; exhausting it reports no match rather than looping or running long.

func (*Grammar) References

func (g *Grammar) References() []string

References returns the set of rule names referenced anywhere in the grammar, sorted. It backs the well-formedness check that every reference resolves.

func (*Grammar) Root

func (g *Grammar) Root() string

Root returns the name of the grammar's start rule.

func (*Grammar) String

func (g *Grammar) String() string

String renders the grammar as GBNF text, the form a runtime consumes. Rules are emitted root-first then in insertion order, so the output is deterministic and diff-stable.

type ToolSchema

type ToolSchema struct {
	Name   string
	Schema json.RawMessage
}

ToolSchema names a callable tool and the JSON Schema of its arguments. It is the input ToolCall constrains a model's output against.

Jump to

Keyboard shortcuts

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