tools

package
v0.4.0-alpha Latest Latest
Warning

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

Go to latest
Published: Mar 8, 2026 License: MIT Imports: 10 Imported by: 1

Documentation

Overview

Package tools provides tool definitions, toolset aggregation, validation, and the tool execution loop (ToolLoop, StreamWithToolHandling) for multi-round tool calling with the LLM runtime.

Index

Constants

View Source
const (
	DefaultMaxRounds    = 8                // default tool loop iterations before giving up
	DefaultToolTimeout  = 30 * time.Second // per-tool execution timeout
	DefaultStreamBuffer = 16               // channel buffer for tool loop output stream
)

Variables

This section is empty.

Functions

func GenerateInputStream

func GenerateInputStream(ctx context.Context, p niro.Provider, req *niro.Request, input *niro.Stream, opts InputStreamOptions) (*niro.Stream, error)

GenerateInputStream calls provider-native input streaming when supported. Otherwise it degrades gracefully by collecting text frames from input and sending them as one message in a standard Generate request.

func IsToolDenied

func IsToolDenied(err error) bool

IsToolDenied reports whether err (or any error in its chain) is an ErrToolDenied.

func SetToolSchemaValidator

func SetToolSchemaValidator(v ToolSchemaValidator)

SetToolSchemaValidator sets the global schema validator. Nil resets to default.

Types

type ErrToolDenied

type ErrToolDenied struct {
	CallName string
	Reason   string
}

ErrToolDenied is returned by ExecuteCall when a ToolApprover rejects a call. The Reason is returned to the model as the tool result content so the model can explain to the user why the action was blocked.

func (*ErrToolDenied) Error

func (e *ErrToolDenied) Error() string

type HandoffSignal

type HandoffSignal struct {
	Target string // Agent or workflow name to hand off to
}

HandoffSignal is returned by a tool handler to signal handoff to another agent or workflow. Handoff is a tool like any other: the model calls the handoff tool with a target; the handler returns HandoffSignal{Target: "name"}; the tool loop emits a KindCustom handoff frame and exits without adding a tool result. The runner (e.g. DSL RunHandoff) then runs the target. Use this instead of encoding handoff in result content.

func (HandoffSignal) Error

func (HandoffSignal) Error() string

type InputStreamOptions

type InputStreamOptions struct {
	// Role used when converting streamed input to a single message.
	// Defaults to niro.RoleUser.
	Role niro.Role
}

InputStreamOptions controls behavior when falling back to non-native providers.

func DefaultInputStreamOptions

func DefaultInputStreamOptions() InputStreamOptions

DefaultInputStreamOptions returns safe defaults.

type InputStreamingProvider

type InputStreamingProvider interface {
	GenerateInputStream(ctx context.Context, req *niro.Request, input *niro.Stream) (*niro.Stream, error)
}

InputStreamingProvider is an optional provider extension for native input streaming (duplex-style) where user input arrives incrementally.

Providers that support realtime/duplex APIs may implement this directly. Core helpers will automatically prefer this path when available.

type StreamWithToolHandling

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

StreamWithToolHandling wraps a Provider and executes tool calls automatically.

func NewStreamWithToolHandling

func NewStreamWithToolHandling(p niro.Provider, executor ToolExecutor, maxRounds int) *StreamWithToolHandling

NewStreamWithToolHandling creates a provider that automatically executes tools.

func NewStreamWithToolHandlingOptions

func NewStreamWithToolHandlingOptions(p niro.Provider, executor ToolExecutor, opts ToolStreamOptions) *StreamWithToolHandling

NewStreamWithToolHandlingOptions creates a provider wrapper with full options.

func (*StreamWithToolHandling) Generate

func (swth *StreamWithToolHandling) Generate(ctx context.Context, req *niro.Request) (*niro.Stream, error)

Generate implements niro.Provider and preserves streaming while handling tools.

type ToolApproval

type ToolApproval struct {
	// Approved must be true for the tool call to proceed.
	Approved bool
	// Reason is fed back to the LLM as the tool result when Approved is false.
	// Provide a clear human-readable message — the model will use it to explain
	// to the user why the action was blocked.
	Reason string
}

ToolApproval is the outcome of an approval decision.

type ToolApprover

type ToolApprover interface {
	Approve(ctx context.Context, call niro.ToolCall) (ToolApproval, error)
}

ToolApprover intercepts tool calls before execution for human or policy-based review. Implementations block until a decision is made. The context carries the deadline — if no decision arrives in time, context cancellation is the timeout mechanism.

Example — channel-based human approval:

type ChannelApprover struct { Requests chan ApprovalRequest }
func (a *ChannelApprover) Approve(ctx context.Context, call niro.ToolCall) (ToolApproval, error) {
	req := ApprovalRequest{Call: call, Reply: make(chan ToolApproval, 1)}
	select {
	case a.Requests <- req:
	case <-ctx.Done(): return ToolApproval{}, ctx.Err()
	}
	select {
	case dec := <-req.Reply: return dec, nil
	case <-ctx.Done():       return ToolApproval{}, ctx.Err()
	}
}

func ApproveAll

func ApproveAll() ToolApprover

ApproveAll returns a ToolApprover that approves every call unconditionally. Use as a no-op placeholder or in tests.

func DenyAll

func DenyAll(reason string) ToolApprover

DenyAll returns a ToolApprover that denies every call with the given reason. Useful for blocking all tool execution pending a review or during maintenance.

type ToolApproverFunc

type ToolApproverFunc func(ctx context.Context, call niro.ToolCall) (ToolApproval, error)

ToolApproverFunc adapts a function to the ToolApprover interface.

func (ToolApproverFunc) Approve

type ToolDefinition

type ToolDefinition struct {
	Name        string
	Description string
	Schema      json.RawMessage
	Handler     ToolHandler
}

ToolDefinition is a high-level tool abstraction. It maps to niro.Request.Tools for providers and supports runtime execution.

func NewToolDefinition

func NewToolDefinition(name, description string, schema json.RawMessage, handler ToolHandler) (ToolDefinition, error)

NewToolDefinition creates a tool from raw JSON schema bytes.

func NewToolDefinitionAny

func NewToolDefinitionAny(name, description string, schema any, handler ToolHandler) (ToolDefinition, error)

NewToolDefinitionAny creates a tool using the configured JSON backend.

func (ToolDefinition) ToTool

func (d ToolDefinition) ToTool() niro.Tool

ToTool converts definition to provider-facing niro.Tool.

func (ToolDefinition) Validate

func (d ToolDefinition) Validate() error

Validate validates tool definition shape and schema. It delegates name format, description, and schema checks to niro.Tool.Validate so that the same cross-provider rules are enforced in one place.

type ToolExecutionInfo

type ToolExecutionInfo struct {
	Name   string
	CallID string
	Args   json.RawMessage
	Result niro.ToolResult
	Err    error
}

ToolExecutionInfo contains execution event data.

type ToolExecutor

type ToolExecutor interface {
	// Execute runs the named tool with the given arguments and returns the result.
	// The executor should handle errors appropriately (e.g. tool not found, execution failure)
	Execute(ctx context.Context, name string, args json.RawMessage) (string, error)
}

ToolExecutor defines how to execute a tool call.

type ToolExecutorFunc

type ToolExecutorFunc func(ctx context.Context, name string, args json.RawMessage) (string, error)

ToolExecutorFunc adapts a function to ToolExecutor interface.

func (ToolExecutorFunc) Execute

func (f ToolExecutorFunc) Execute(ctx context.Context, name string, args json.RawMessage) (string, error)

type ToolHandler

type ToolHandler func(ctx context.Context, args json.RawMessage) (any, error)

ToolHandler executes a tool with raw JSON args and returns any JSON-serializable value. Return string to emit plain text content directly.

type ToolLoop

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

ToolLoop manages automatic tool calling loops. It reads tool call frames from a stream, executes them, and returns a new stream with the results integrated.

func NewToolLoop

func NewToolLoop(executor ToolExecutor, maxRounds int) *ToolLoop

NewToolLoop creates a ToolLoop with defaults + maxRounds override.

func NewToolLoopWithOptions

func NewToolLoopWithOptions(executor ToolExecutor, opts ToolStreamOptions) *ToolLoop

NewToolLoopWithOptions creates a ToolLoop with explicit options.

func (*ToolLoop) GenerateWithTools

func (tl *ToolLoop) GenerateWithTools(ctx context.Context, provider niro.Provider, req *niro.Request) (*niro.Stream, error)

GenerateWithTools executes tool loops and preserves streaming output.

type ToolRuntimeHook

type ToolRuntimeHook interface {
	OnToolValidate(ctx context.Context, info ToolValidationInfo)
	OnToolExecuteStart(ctx context.Context, call niro.ToolCall)
	OnToolExecuteEnd(ctx context.Context, info ToolExecutionInfo)
}

ToolRuntimeHook receives tool validation/execution lifecycle events.

type ToolSchemaValidator

type ToolSchemaValidator interface {
	Validate(schema json.RawMessage, args json.RawMessage) error
}

ToolSchemaValidator validates tool call args against schema.

func CurrentToolSchemaValidator

func CurrentToolSchemaValidator() ToolSchemaValidator

CurrentToolSchemaValidator returns active validator. The global is always initialised by init(), so this never returns nil.

type ToolStreamOptions

type ToolStreamOptions struct {
	MaxRounds       int
	Parallel        bool
	EmitToolResults bool
	ToolTimeout     time.Duration
	StreamBuffer    int
	// Approver is an optional human-in-the-loop gate.
	// When set, every tool call is passed to Approver.Approve before execution.
	// A nil Approver means all calls proceed without review.
	Approver ToolApprover
}

ToolStreamOptions controls automatic tool execution behavior.

func DefaultToolStreamOptions

func DefaultToolStreamOptions() ToolStreamOptions

DefaultToolStreamOptions returns low-latency defaults.

type ToolValidationInfo

type ToolValidationInfo struct {
	Name string
	Args json.RawMessage
	Err  error
}

ToolValidationInfo contains validation event data.

type ToolingProvider

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

ToolingProvider is a smart provider wrapper that applies declared tools and executes tool loops with validation + hooks.

func NewToolingProvider

func NewToolingProvider(base niro.Provider, set *Toolset, opts ToolStreamOptions) *ToolingProvider

NewToolingProvider creates a provider wrapper that uses a Toolset.

func (*ToolingProvider) Generate

func (p *ToolingProvider) Generate(ctx context.Context, req *niro.Request) (*niro.Stream, error)

Generate applies tool definitions and executes tool loop.

type Toolset

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

Toolset provides a Genkit-like abstraction over tool declaration, provider wiring, validation, hooks, and execution.

func NewToolset

func NewToolset() *Toolset

NewToolset creates an empty toolset.

func (*Toolset) Apply

func (ts *Toolset) Apply(req *niro.Request) *niro.Request

Apply returns a shallow copy of req with toolset tools attached.

func (*Toolset) Execute

func (ts *Toolset) Execute(ctx context.Context, name string, args json.RawMessage) (string, error)

Execute implements ToolExecutor.

func (*Toolset) ExecuteCall

func (ts *Toolset) ExecuteCall(ctx context.Context, call niro.ToolCall) (niro.ToolResult, error)

ExecuteCall validates args, invokes handler, and returns niro.ToolResult.

func (*Toolset) Get

func (ts *Toolset) Get(name string) (ToolDefinition, bool)

Get returns the ToolDefinition registered under name.

func (*Toolset) Len

func (ts *Toolset) Len() int

Len returns the number of registered tools.

func (*Toolset) MustRegister

func (ts *Toolset) MustRegister(def ToolDefinition) *Toolset

MustRegister panics if registration fails.

func (*Toolset) Names

func (ts *Toolset) Names() []string

Names returns all registered tool names in sorted order.

func (*Toolset) Register

func (ts *Toolset) Register(def ToolDefinition) error

Register adds or replaces a tool definition.

func (*Toolset) Remove

func (ts *Toolset) Remove(name string) bool

Remove unregisters a tool by name. Returns true if the tool existed.

func (*Toolset) Tools

func (ts *Toolset) Tools() []niro.Tool

Tools returns provider-facing tool list sorted by name for deterministic ordering.

func (*Toolset) WithApprover

func (ts *Toolset) WithApprover(a ToolApprover) *Toolset

WithApprover sets a human-in-the-loop approval gate for this toolset. The approver is consulted before every tool handler execution. A nil approver removes any previously set approver. Stored atomically — safe to call concurrently with ExecuteCall.

func (*Toolset) WithHook

func (ts *Toolset) WithHook(h ToolRuntimeHook) *Toolset

WithHook appends a runtime hook.

func (*Toolset) WithValidator

func (ts *Toolset) WithValidator(v ToolSchemaValidator) *Toolset

WithValidator overrides schema validator for this toolset.

Jump to

Keyboard shortcuts

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