tool

package
v0.28.0 Latest Latest
Warning

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

Go to latest
Published: Mar 25, 2026 License: MIT Imports: 7 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrNoHandler = fmt.Errorf("no handler for tool")
)

Functions

func SafeCall

func SafeCall(fn func(), errPtr *error)

func SafeHandle

func SafeHandle(ctx context.Context, h Handler, call Call) (output any, err error)

SafeHandle calls h.Handle inside a panic-recovery wrapper. Panics are recovered and returned as an error result instead of propagating.

Types

type Args

type Args = map[string]any

type AsyncDispatcher

type AsyncDispatcher struct {
	Handlers Handlers
}

func (*AsyncDispatcher) Dispatch

func (d *AsyncDispatcher) Dispatch(ctx context.Context, toolCalls ...Call) ([]Result, error)

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

func (b *BoundToolSpec[In, Out]) Handle(ctx context.Context, call Call) (any, error)

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

func NewToolCall(id, name string, args Args) Call

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 Exchange

type Exchange interface {
	Call
	Result
}

type Handler

type Handler interface {
	Handle(ctx context.Context, call Call) (any, error)
}

type Handlers

type Handlers map[string]Handler

func NewHandlers

func NewHandlers(handlers ...NamedHandler) Handlers

func (Handlers) Append

func (m Handlers) Append(handlers ...NamedHandler)

func (Handlers) Handle

func (m Handlers) Handle(ctx context.Context, call Call) (res any, err error)

type NamedHandler

type NamedHandler interface {
	Handler
	ToolName() string
}

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

type ParsedToolCall interface {
	ToolName() string
	ToolCallID() string
}

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 Result interface {
	ToolCallID() string

	ToolOutput() any
	IsError() bool

	MarshalJSON() ([]byte, error)
	UnmarshalJSON([]byte) error
}

func NewResult

func NewResult(id string, output any, isError bool) 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

func NewSpec[T any](name, description string) *Spec[T]

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.

Jump to

Keyboard shortcuts

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