Documentation
¶
Index ¶
- Variables
- func SafeCall(fn func(), errPtr *error)
- func SafeHandle(ctx context.Context, h Handler, call Call) (output any, err error)
- type Args
- type AsyncDispatcher
- type BoundToolSpec
- type Call
- type Definition
- type DefinitionProvider
- type Dispatcher
- type DispatcherType
- type Exchange
- type Handler
- type Handlers
- type NamedHandler
- type ParsedToolCall
- type Result
- type Set
- type Spec
- type TypedToolCall
Constants ¶
This section is empty.
Variables ¶
var (
ErrNoHandler = fmt.Errorf("no handler for tool")
)
Functions ¶
Types ¶
type AsyncDispatcher ¶
type AsyncDispatcher struct {
Handlers Handlers
}
type BoundToolSpec ¶
type BoundToolSpec[In, Out any] struct { // contains filtered or unexported fields }
BoundToolSpec pairs a Spec[In] with a handler function, satisfying both Handler (for StreamProcessor.HandleTool) and toolRegistration (for NewToolSet). Create one with the package-level Handle function.
func Handle ¶
func Handle[In, Out any](spec *Spec[In], fn func(ctx context.Context, in In) (*Out, error)) *BoundToolSpec[In, Out]
Handle binds a handler function to a Spec, producing a *BoundToolSpec that satisfies both Handler and toolRegistration.
Because Go methods cannot introduce new type parameters, this is a package-level generic function rather than a method on Spec.
Example:
weatherSpec := llm.NewSpec[GetWeatherParams]("get_weather", "Get weather")
// Register with StreamProcessor:
llm.ProcessChan(ctx, ch).
HandleTool(llm.Handle(weatherSpec, func(ctx context.Context, in GetWeatherParams) (*GetWeatherResult, error) {
return &GetWeatherResult{Temp: 22}, nil
}))
// Or pass directly to NewToolSet — BoundToolSpec satisfies toolRegistration too:
tools := llm.NewToolSet(
llm.Handle(weatherSpec, weatherFn),
llm.Handle(searchSpec, searchFn),
)
func (*BoundToolSpec[In, Out]) Definition ¶
func (b *BoundToolSpec[In, Out]) Definition() Definition
Definition implements toolRegistration — delegates to the embedded spec.
func (*BoundToolSpec[In, Out]) Handle ¶
Handle implements Handler — validates, unmarshal, calls fn, marshals toolResult.
func (*BoundToolSpec[In, Out]) ToolName ¶
func (b *BoundToolSpec[In, Out]) ToolName() string
ToolName implements Handler — returns the spec's tool name.
type Call ¶
type Call interface {
ToolName() string
ToolCallID() string
ToolArgs() Args
MarshalJSON() ([]byte, error)
UnmarshalJSON([]byte) error
Validate() error
}
func NewToolCall ¶
type Definition ¶
type Definition struct {
Name string `json:"name"`
Description string `json:"description"`
Parameters map[string]any `json:"parameters"`
}
Definition describes a tool that the model can invoke. This is used when sending tools to a provider's API.
func DefinitionFor ¶
func DefinitionFor[T any](name, description string) Definition
DefinitionFor creates a Definition from a Go struct type using reflection. The struct's fields are converted to a JSON Schema that describes the tool's parameters.
Field tags:
- `json:"fieldName"` - Sets the parameter name (required)
- `jsonschema:"description=..."` - Describes the parameter
- `jsonschema:"required"` - Marks the parameter as required
- `jsonschema:"enum=val1,enum=val2"` - Restricts to specific values
Example:
type GetWeatherParams struct {
Location string `json:"location" jsonschema:"description=City name,required"`
Unit string `json:"unit" jsonschema:"description=Temperature unit,enum=celsius,enum=fahrenheit"`
}
tool := DefinitionFor[GetWeatherParams]("get_weather", "Get current weather")
func (Definition) Validate ¶
func (t Definition) Validate() error
Validate checks that the tool definition is valid.
type DefinitionProvider ¶
type DefinitionProvider interface {
ToolDefinitions() []Definition
}
type Dispatcher ¶
type Dispatcher interface {
Dispatch(ctx context.Context, toolCalls ...Call) (results []Result, err error)
}
func NewSyncDispatcher ¶
func NewSyncDispatcher(h Handler) Dispatcher
type DispatcherType ¶
type DispatcherType int
DispatcherType controls how tool calls are executed when multiple tools are emitted in a single response.
const ( // DispatchTypeSync executes tool handlers one at a time in emission order. // This is the default. DispatchTypeSync DispatcherType = iota // DispatchTypeAsync executes all tool handlers concurrently, one goroutine // per tool call. Results are collected in emission order. DispatchTypeAsync )
type Handlers ¶
func NewHandlers ¶
func NewHandlers(handlers ...NamedHandler) Handlers
func (Handlers) Append ¶
func (m Handlers) Append(handlers ...NamedHandler)
type NamedHandler ¶
func NewHandler ¶
func NewHandler[In, Out any](name string, fn func(ctx context.Context, in In) (*Out, error)) NamedHandler
NewHandler creates a named Handler from a strongly-typed function without requiring a Spec. Use this when you don't need schema validation or when the spec is defined elsewhere.
Example:
proc.HandleTool(llm.NewHandler("get_weather", func(ctx context.Context, in GetWeatherParams) (*GetWeatherResult, error) {
return &GetWeatherResult{Temp: 22}, nil
}))
type ParsedToolCall ¶
ParsedToolCall is the interface for parsed tool call results. Use a type switch on the concrete *TypedToolCall[T] to access typed params.
Example:
switch c := call.(type) {
case *TypedToolCall[GetWeatherParams]:
fmt.Println(c.Params.Location) // strongly typed
case *TypedToolCall[SearchParams]:
fmt.Println(c.Params.Query)
}
type Result ¶
type Set ¶
type Set struct {
// contains filtered or unexported fields
}
Set manages a collection of tool specifications. It provides tool definitions for sending to providers and parses raw tool calls into strongly-typed results with validation.
func NewToolSet ¶
func NewToolSet(tools ...toolRegistration) *Set
NewToolSet creates a Set from one or more tool specs.
Example:
tools := NewToolSet(
NewSpec[GetWeatherParams]("get_weather", "Get weather"),
NewSpec[SearchParams]("search", "Search the web"),
)
func (*Set) Definitions ¶
func (ts *Set) Definitions() []Definition
Definitions returns all tool definitions for sending to providers.
func (*Set) Parse ¶
func (ts *Set) Parse(calls []Call) ([]ParsedToolCall, error)
Parse converts raw ToolCalls (from eventPub events) into typed ParsedToolCalls. Each tool call's arguments are validated against its JSON Schema before parsing.
Successfully parsed calls are always returned. Errors from unknown tool names or validation/parse failures are collected and returned as a joined error. The error is non-fatal - you get all successfully parsed calls.
Example:
calls, err := tools.Parse(rawToolCalls)
if err != nil {
log.Printf("parse warnings: %v", err)
}
for _, call := range calls {
switch c := call.(type) {
case *TypedToolCall[GetWeatherParams]:
fmt.Println(c.Params.Location)
}
}
type Spec ¶
type Spec[T any] struct { // contains filtered or unexported fields }
Spec is a type-safe tool specification that pairs a tool name/description with a Go struct that defines the parameter schema. It includes a compiled JSON Schema for runtime validation.
func NewSpec ¶
NewSpec creates a typed tool specification from a parameter struct. The struct's fields define the JSON Schema for the tool's parameters. Field tags are the same as DefinitionFor: json, jsonschema.
Example:
type GetWeatherParams struct {
Location string `json:"location" jsonschema:"description=City name,required"`
}
spec := NewSpec[GetWeatherParams]("get_weather", "Get current weather")
func (*Spec[T]) Definition ¶
func (s *Spec[T]) Definition() Definition
Definition returns the Definition for sending to providers.
type TypedToolCall ¶
type TypedToolCall[T any] struct { ID string // Original tool call ID (for sending results back) Name string // Tool name Params T // Parsed, validated parameters }
TypedToolCall holds a parsed tool call with strongly-typed parameters.
func (*TypedToolCall[T]) ToolCallID ¶
func (c *TypedToolCall[T]) ToolCallID() string
ToolCallID returns the tool call ID.
func (*TypedToolCall[T]) ToolName ¶
func (c *TypedToolCall[T]) ToolName() string
ToolName returns the tool name.