tools

package
v1.3.11 Latest Latest
Warning

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

Go to latest
Published: Mar 9, 2026 License: Apache-2.0 Imports: 29 Imported by: 4

Documentation

Overview

Package tools provides tool/function calling infrastructure for LLM testing.

This package implements a flexible tool execution system with:

  • Tool descriptor registry with JSON Schema validation
  • Mock executors for testing (static and template-based)
  • HTTP executor for live API calls
  • Type coercion and result validation
  • Adapter for prompt registry integration

Tools can be loaded from YAML/JSON files and executed with argument validation, result schema checking, and automatic type coercion for common mismatches.

Index

Constants

View Source
const (

	// DefaultToolTimeout is the default execution timeout applied to tools
	// that don't specify their own TimeoutMs. 30 seconds accommodates HTTP-calling
	// tools and other network-dependent operations.
	DefaultToolTimeout = 30000

	// DefaultMaxToolResultSize is the maximum allowed size (in bytes) of a
	// JSON-marshaled tool result. Results exceeding this limit are truncated.
	DefaultMaxToolResultSize = 1 * 1024 * 1024 // 1 MB
)
View Source
const (
	DeclineStrategyFallback = "fallback"
	DeclineStrategyError    = "error"
	DeclineStrategyRetry    = "retry"
)

Decline strategy constants for ConsentConfig.DeclineStrategy.

View Source
const (
	DefaultMaxAggregateSize = 50 * 1024 * 1024 // 50MB cumulative across all responses

)

Default configuration values for HTTP tool execution.

View Source
const DefaultMaxSchemaCacheSize = 128

DefaultMaxSchemaCacheSize is the maximum number of compiled JSON schemas held in the validator cache. When full the least-recently-used entry is evicted.

View Source
const NamespaceSep = "__"

NamespaceSep is the separator used in qualified tool names. Example: "a2a__weather_agent__get_forecast"

Variables

View Source
var (
	// ErrToolNotFound is returned when a requested tool is not found in the registry.
	ErrToolNotFound = errors.New("tool not found")

	// ErrToolNameRequired is returned when registering a tool without a name.
	ErrToolNameRequired = errors.New("tool name is required")

	// ErrToolDescriptionRequired is returned when registering a tool without a description.
	ErrToolDescriptionRequired = errors.New("tool description is required")

	// ErrInputSchemaRequired is returned when registering a tool without an input schema.
	ErrInputSchemaRequired = errors.New("input schema is required")

	// ErrOutputSchemaRequired is returned when registering a tool without an output schema.
	ErrOutputSchemaRequired = errors.New("output schema is required")

	// ErrInvalidToolMode is returned when a tool has an invalid mode.
	ErrInvalidToolMode = errors.New("mode must be 'mock', 'live', 'mcp', 'client', or a registered executor name")

	// ErrMockExecutorOnly is returned when a non-mock tool is passed to a mock executor.
	ErrMockExecutorOnly = errors.New("executor can only execute mock tools")

	// ErrMCPExecutorOnly is returned when a non-mcp tool is passed to an MCP executor.
	ErrMCPExecutorOnly = errors.New("MCP executor can only execute mcp tools")

	// ErrToolTimeout is returned when a tool execution exceeds its configured timeout.
	ErrToolTimeout = errors.New("tool execution timed out")
)

Sentinel errors for tool operations.

View Source
var ErrAggregateResponseSizeExceeded = fmt.Errorf("aggregate HTTP response size limit exceeded")

ErrAggregateResponseSizeExceeded is returned when the cumulative response size across all HTTP tool calls exceeds the configured maximum.

Functions

func ContentTypeToMediaType added in v1.3.11

func ContentTypeToMediaType(contentType string) string

ContentTypeToMediaType maps an HTTP Content-Type to a types.ContentPart Type string.

func IsBinaryContentType added in v1.3.11

func IsBinaryContentType(contentType string, acceptTypes []string) bool

IsBinaryContentType returns true if the Content-Type indicates a binary response that should be handled as multimodal content rather than JSON. If acceptTypes is non-empty, only those specific types match. Otherwise, common image/audio/video prefixes are checked.

func IsSystemTool added in v1.3.1

func IsSystemTool(name string) bool

IsSystemTool returns true if name belongs to a known system namespace.

func ParseToolName added in v1.3.1

func ParseToolName(name string) (namespace, localName string)

ParseToolName splits a qualified tool name on the first NamespaceSep. "a2a__weather__forecast" → ("a2a", "weather__forecast") "get_weather" → ("", "get_weather") "" → ("", "")

func QualifyToolName added in v1.3.1

func QualifyToolName(namespace, localName string) string

QualifyToolName joins a namespace and local name with NamespaceSep. ("mcp", "fs__read") → "mcp__fs__read" ("", "get_weather") → "get_weather"

func ReadMultimodalResponse added in v1.3.11

func ReadMultimodalResponse(
	resp *http.Response,
	aggregateSize *atomic.Int64,
	maxAggregateSize int64,
) (json.RawMessage, []types.ContentPart, error)

ReadMultimodalResponse reads a binary HTTP response and returns it as a ContentPart with base64-encoded data. It enforces per-response and aggregate size limits.

func RedactFields added in v1.3.11

func RedactFields(data []byte, fields []string) []byte

RedactFields removes or masks sensitive fields from a JSON response.

func ResolveMockParts added in v1.3.10

func ResolveMockParts(parts []types.ContentPart) ([]types.ContentPart, error)

ResolveMockParts processes a slice of ContentPart, resolving any file_path references in MediaContent to base64-encoded data. URL references and already-encoded data are passed through unchanged.

Types

type A2AAuthConfig added in v1.3.11

type A2AAuthConfig struct {
	Scheme   string `json:"scheme" yaml:"scheme"`                           // e.g. "Bearer", "Basic"
	Token    string `json:"token,omitempty" yaml:"token,omitempty"`         // Static token value
	TokenEnv string `json:"token_env,omitempty" yaml:"token_env,omitempty"` // Env var containing the token
}

A2AAuthConfig defines authentication for an A2A agent connection.

type A2AConfig added in v1.1.11

type A2AConfig struct {
	AgentURL       string            `json:"agent_url" yaml:"agent_url"`
	SkillID        string            `json:"skill_id" yaml:"skill_id"`
	TimeoutMs      int               `json:"timeout_ms,omitempty" yaml:"timeout_ms,omitempty"`
	Headers        map[string]string `json:"headers,omitempty" yaml:"headers,omitempty"`
	HeadersFromEnv []string          `json:"headers_from_env,omitempty" yaml:"headers_from_env,omitempty"`
	Auth           *A2AAuthConfig    `json:"auth,omitempty" yaml:"auth,omitempty"`
	RetryPolicy    *A2ARetryConfig   `json:"retry,omitempty" yaml:"retry,omitempty"`
	SkillFilter    *A2ASkillFilter   `json:"skill_filter,omitempty" yaml:"skill_filter,omitempty"`
}

A2AConfig defines configuration for A2A agent tool execution

type A2ARetryConfig added in v1.3.11

type A2ARetryConfig struct {
	MaxRetries     int `json:"max_retries,omitempty" yaml:"max_retries,omitempty"`
	InitialDelayMs int `json:"initial_delay_ms,omitempty" yaml:"initial_delay_ms,omitempty"`
	MaxDelayMs     int `json:"max_delay_ms,omitempty" yaml:"max_delay_ms,omitempty"`
}

A2ARetryConfig defines per-agent retry policy overrides.

type A2ASkillFilter added in v1.3.11

type A2ASkillFilter struct {
	Allowlist []string `json:"allowlist,omitempty" yaml:"allowlist,omitempty"`
	Blocklist []string `json:"blocklist,omitempty" yaml:"blocklist,omitempty"`
}

A2ASkillFilter controls which skills from an A2A agent are exposed to the LLM.

func (*A2ASkillFilter) IncludesSkill added in v1.3.11

func (f *A2ASkillFilter) IncludesSkill(skillID string) bool

IncludesSkill returns true if the given skill ID passes the filter.

type AsyncToolExecutor

type AsyncToolExecutor interface {
	Executor // Still implements the basic Executor interface

	// ExecuteAsync may return immediately with a pending status
	ExecuteAsync(ctx context.Context, descriptor *ToolDescriptor, args json.RawMessage) (*ToolExecutionResult, error)
}

AsyncToolExecutor is a tool that can return pending status instead of blocking. Tools that require human approval or external async operations should implement this.

type ClientConfig added in v1.3.8

type ClientConfig struct {
	Consent        *ConsentConfig `json:"consent,omitempty" yaml:"consent,omitempty"`
	TimeoutMs      int            `json:"timeout_ms,omitempty" yaml:"timeout_ms,omitempty"`
	Categories     []string       `json:"categories,omitempty" yaml:"categories,omitempty"`
	ValidateOutput bool           `json:"validate_output,omitempty" yaml:"validate_output,omitempty"`
}

ClientConfig defines configuration for client-side tool execution. Tools with mode "client" are fulfilled by the SDK caller's device (e.g., GPS, camera, contacts, biometrics).

type Coercion

type Coercion struct {
	Path string `json:"path"`
	From any    `json:"from"`
	To   any    `json:"to"`
}

Coercion represents a type coercion that was performed.

type ConsentConfig added in v1.3.8

type ConsentConfig struct {
	Required bool   `json:"required" yaml:"required"`
	Message  string `json:"message,omitempty" yaml:"message,omitempty"`
	// DeclineStrategy: "fallback" | "error" | "retry"
	DeclineStrategy string `json:"decline_strategy,omitempty" yaml:"decline_strategy,omitempty"`
}

ConsentConfig defines consent requirements for client-side tools.

type DefaultRequestMapper added in v1.3.11

type DefaultRequestMapper struct{}

DefaultRequestMapper is the built-in implementation of RequestMapper. It uses text/template for URL/header interpolation and JMESPath for body reshaping.

func (*DefaultRequestMapper) BuildBody added in v1.3.11

func (m *DefaultRequestMapper) BuildBody(bodyArgs map[string]any, jmespathExpr string) (json.RawMessage, error)

BuildBody produces the JSON body from args, optionally reshaped via JMESPath.

func (*DefaultRequestMapper) PartitionArgs added in v1.3.11

func (m *DefaultRequestMapper) PartitionArgs(
	args map[string]any, cfg *RequestMapping, urlTemplate string,
) (query, header, body map[string]any)

PartitionArgs splits tool arguments into three buckets: query parameters, header values, and body fields. Arguments consumed by URL templates and header templates are automatically excluded from the body.

func (*DefaultRequestMapper) RenderHeaders added in v1.3.11

func (m *DefaultRequestMapper) RenderHeaders(
	templates map[string]string, args map[string]any,
) (map[string]string, error)

RenderHeaders applies text/template substitution to header value templates.

func (*DefaultRequestMapper) RenderURL added in v1.3.11

func (m *DefaultRequestMapper) RenderURL(urlTemplate string, args map[string]any) (string, error)

RenderURL applies Go text/template substitution to a URL string. Template variables like {{.user_id}} are replaced with values from args.

type DefaultResponseMapper added in v1.3.11

type DefaultResponseMapper struct{}

DefaultResponseMapper is the built-in implementation of ResponseMapper. It uses JMESPath for response extraction and reshaping.

func (*DefaultResponseMapper) MapResponse added in v1.3.11

func (m *DefaultResponseMapper) MapResponse(
	response json.RawMessage, jmespathExpr string,
) (json.RawMessage, error)

MapResponse applies a JMESPath expression to extract or reshape a JSON response.

type ErrToolsPending added in v1.3.8

type ErrToolsPending struct {
	Pending []PendingToolExecution
}

ErrToolsPending is returned by executeToolCalls when one or more tool calls returned ToolStatusPending. The pipeline should suspend: completed tool results are still returned alongside this error so they can be appended to the message history.

func IsErrToolsPending added in v1.3.8

func IsErrToolsPending(err error) (*ErrToolsPending, bool)

IsErrToolsPending checks whether err is or wraps an *ErrToolsPending.

func (*ErrToolsPending) Error added in v1.3.8

func (e *ErrToolsPending) Error() string

type Executor

type Executor interface {
	Execute(ctx context.Context, descriptor *ToolDescriptor, args json.RawMessage) (json.RawMessage, error)
	Name() string
}

Executor interface defines how tools are executed

type FileToolResponseRepository added in v1.1.0

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

FileToolResponseRepository implements ToolResponseRepository using the provider's MockConfig YAML structure. This allows Arena scenarios to define tool responses alongside LLM responses.

func NewFileToolResponseRepository added in v1.1.0

func NewFileToolResponseRepository(
	scenarioID string, toolResponses map[string][]MockToolResponseConfig,
) *FileToolResponseRepository

NewFileToolResponseRepository creates a repository from scenario tool responses. This is typically used by Arena to provide tool mocking from YAML scenarios.

func (*FileToolResponseRepository) GetToolResponse added in v1.1.0

func (r *FileToolResponseRepository) GetToolResponse(
	toolName string, args map[string]any, contextKey string,
) (*ToolResponseData, error)

GetToolResponse implements ToolResponseRepository. It finds the first matching response based on argument comparison.

type HTTPConfig

type HTTPConfig struct {
	URL            string            `json:"url" yaml:"url"`
	Method         string            `json:"method" yaml:"method"`
	HeadersFromEnv []string          `json:"headers_from_env,omitempty" yaml:"headers_from_env,omitempty"`
	TimeoutMs      int               `json:"timeout_ms" yaml:"timeout_ms"`
	Redact         []string          `json:"redact,omitempty" yaml:"redact,omitempty"`
	Headers        map[string]string `json:"headers,omitempty" yaml:"headers,omitempty"`

	// Request/response mapping configuration
	Request  *RequestMapping  `json:"request,omitempty" yaml:"request,omitempty"`
	Response *ResponseMapping `json:"response,omitempty" yaml:"response,omitempty"`

	// Multimodal response handling
	Multimodal *MultimodalConfig `json:"multimodal,omitempty" yaml:"multimodal,omitempty"`
}

HTTPConfig defines configuration for live HTTP tool execution

type HTTPExecutor added in v1.3.11

type HTTPExecutor struct {

	// RequestMapper customizes how tool args map to HTTP requests.
	// If nil, DefaultRequestMapper is used.
	RequestMapper RequestMapper

	// ResponseMapper customizes how HTTP responses map to tool results.
	// If nil, DefaultResponseMapper is used.
	ResponseMapper ResponseMapper
	// contains filtered or unexported fields
}

HTTPExecutor executes tools that make HTTP calls based on pack configuration. It reads the HTTPConfig from the tool descriptor and makes the appropriate HTTP request. It tracks cumulative response sizes and rejects calls once the aggregate limit is reached.

For GET/HEAD/DELETE requests, tool arguments are encoded as URL query parameters. For POST/PUT/PATCH requests, tool arguments are sent as a JSON request body.

Custom RequestMapper and ResponseMapper implementations can be injected to override URL templating, argument partitioning, body building, header rendering, and response reshaping.

func NewHTTPExecutor added in v1.3.11

func NewHTTPExecutor() *HTTPExecutor

NewHTTPExecutor creates a new HTTP executor with the default HTTP client and default aggregate response size limit.

func NewHTTPExecutorWithClient added in v1.3.11

func NewHTTPExecutorWithClient(client *http.Client) *HTTPExecutor

NewHTTPExecutorWithClient creates a new HTTP executor with a custom HTTP client. This is useful for testing or when custom transport configuration is needed.

func NewHTTPExecutorWithMaxAggregate added in v1.3.11

func NewHTTPExecutorWithMaxAggregate(maxAggregate int64) *HTTPExecutor

NewHTTPExecutorWithMaxAggregate creates a new HTTP executor with a custom aggregate response size limit. Use 0 or a negative value to disable.

func (*HTTPExecutor) AggregateResponseSize added in v1.3.11

func (e *HTTPExecutor) AggregateResponseSize() int64

AggregateResponseSize returns the cumulative response size consumed so far.

func (*HTTPExecutor) Execute added in v1.3.11

func (e *HTTPExecutor) Execute(
	ctx context.Context,
	descriptor *ToolDescriptor,
	args json.RawMessage,
) (json.RawMessage, error)

Execute performs an HTTP request based on the tool descriptor's HTTPConfig.

func (*HTTPExecutor) ExecuteMultimodal added in v1.3.11

func (e *HTTPExecutor) ExecuteMultimodal(
	ctx context.Context,
	descriptor *ToolDescriptor,
	args json.RawMessage,
) (json.RawMessage, []types.ContentPart, error)

ExecuteMultimodal performs an HTTP request and returns multimodal content parts when the response is a binary type (image, audio, video). For JSON responses, it falls back to the standard Execute path with no content parts.

func (*HTTPExecutor) Name added in v1.3.11

func (e *HTTPExecutor) Name() string

Name returns the executor name used for registration.

func (*HTTPExecutor) ResetAggregateSize added in v1.3.11

func (e *HTTPExecutor) ResetAggregateSize()

ResetAggregateSize resets the cumulative response size counter to zero.

type InMemoryToolResponseRepository added in v1.1.0

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

InMemoryToolResponseRepository implements ToolResponseRepository using in-memory storage. This is useful for SDK unit tests and programmatic configuration of tool responses.

func NewInMemoryToolResponseRepository added in v1.1.0

func NewInMemoryToolResponseRepository() *InMemoryToolResponseRepository

NewInMemoryToolResponseRepository creates a new in-memory tool response repository.

func (*InMemoryToolResponseRepository) AddResponse added in v1.1.0

func (r *InMemoryToolResponseRepository) AddResponse(contextKey, toolName string, response *ToolResponseData)

AddResponse adds a tool response for a specific context and tool name. This method supports simple responses where argument matching is not needed.

func (*InMemoryToolResponseRepository) GetToolResponse added in v1.1.0

func (r *InMemoryToolResponseRepository) GetToolResponse(
	toolName string, args map[string]any, contextKey string,
) (*ToolResponseData, error)

GetToolResponse implements ToolResponseRepository. For simplicity, this implementation only matches by tool name and context, not by arguments. For argument-based matching, use FileToolResponseRepository or implement a custom repository.

type MCPExecutor

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

MCPExecutor executes tools using MCP (Model Context Protocol) servers

func NewMCPExecutor

func NewMCPExecutor(registry mcp.Registry) *MCPExecutor

NewMCPExecutor creates a new MCP executor

func (*MCPExecutor) Execute

func (e *MCPExecutor) Execute(
	ctx context.Context, descriptor *ToolDescriptor, args json.RawMessage,
) (json.RawMessage, error)

Execute executes a tool using an MCP server

func (*MCPExecutor) Name

func (e *MCPExecutor) Name() string

Name returns the executor name

type MockScriptedExecutor

type MockScriptedExecutor struct{}

MockScriptedExecutor executes tools using templated mock data

func NewMockScriptedExecutor

func NewMockScriptedExecutor() *MockScriptedExecutor

NewMockScriptedExecutor creates a new scripted mock executor

func (*MockScriptedExecutor) Execute

func (e *MockScriptedExecutor) Execute(
	_ context.Context, descriptor *ToolDescriptor, args json.RawMessage,
) (json.RawMessage, error)

Execute executes a tool using templated mock data

func (*MockScriptedExecutor) ExecuteMultimodal added in v1.3.10

func (e *MockScriptedExecutor) ExecuteMultimodal(
	ctx context.Context, descriptor *ToolDescriptor, args json.RawMessage,
) (json.RawMessage, []types.ContentPart, error)

ExecuteMultimodal executes a scripted mock tool and returns both JSON result and content parts. The JSON result is rendered via Go templates; MockParts (if present) are resolved identically to MockStaticExecutor (file_path → base64, URLs passed through).

func (*MockScriptedExecutor) Name

func (e *MockScriptedExecutor) Name() string

Name returns the executor name

type MockStaticExecutor

type MockStaticExecutor struct{}

MockStaticExecutor executes tools using static mock data

func NewMockStaticExecutor

func NewMockStaticExecutor() *MockStaticExecutor

NewMockStaticExecutor creates a new static mock executor

func (*MockStaticExecutor) Execute

func (e *MockStaticExecutor) Execute(
	_ context.Context, descriptor *ToolDescriptor, _ json.RawMessage,
) (json.RawMessage, error)

Execute executes a tool using static mock data

func (*MockStaticExecutor) ExecuteMultimodal added in v1.3.10

func (e *MockStaticExecutor) ExecuteMultimodal(
	ctx context.Context, descriptor *ToolDescriptor, args json.RawMessage,
) (json.RawMessage, []types.ContentPart, error)

ExecuteMultimodal executes a tool and returns both JSON result and content parts. When MockParts are configured on the descriptor, file_path references in media content are resolved to base64 data, and URL references are passed through as-is.

func (*MockStaticExecutor) Name

func (e *MockStaticExecutor) Name() string

Name returns the executor name

type MockToolErrorConfig added in v1.1.0

type MockToolErrorConfig struct {
	Type    string `yaml:"type"`
	Message string `yaml:"message"`
}

MockToolErrorConfig represents an error configuration.

type MockToolResponseConfig added in v1.1.0

type MockToolResponseConfig struct {
	CallArgs map[string]any       `yaml:"call_args"`
	Result   any                  `yaml:"result,omitempty"`
	Error    *MockToolErrorConfig `yaml:"error,omitempty"`
}

MockToolResponseConfig represents a single tool response configuration.

type MultimodalConfig added in v1.3.11

type MultimodalConfig struct {
	// Enabled activates Content-Type-based detection of binary responses.
	Enabled bool `json:"enabled" yaml:"enabled"`

	// AcceptTypes lists the MIME types the tool may return (e.g. "image/png", "audio/wav").
	// If empty, common image/audio/video types are auto-detected.
	AcceptTypes []string `json:"accept_types,omitempty" yaml:"accept_types,omitempty"`
}

MultimodalConfig configures multimodal response handling for HTTP tools.

type MultimodalExecutor added in v1.3.10

type MultimodalExecutor interface {
	Executor

	// ExecuteMultimodal returns both the JSON result and optional content parts.
	ExecuteMultimodal(
		ctx context.Context, descriptor *ToolDescriptor, args json.RawMessage,
	) (json.RawMessage, []types.ContentPart, error)
}

MultimodalExecutor extends Executor with support for returning multimodal content parts. Executors that can return images, audio, or other non-text content should implement this.

type PendingToolExecution added in v1.3.8

type PendingToolExecution struct {
	CallID      string                  `json:"call_id"`
	ToolName    string                  `json:"tool_name"`
	Args        map[string]any          `json:"args"`
	PendingInfo *PendingToolInfo        `json:"pending_info,omitempty"`
	ToolResult  types.MessageToolResult `json:"tool_result"`
}

PendingToolExecution captures a single tool call that returned ToolStatusPending.

type PendingToolInfo

type PendingToolInfo struct {
	// Reason for pending (e.g., "requires_approval", "waiting_external_api")
	Reason string `json:"reason"`

	// Human-readable description
	Message string `json:"message"`

	// Tool details (for middleware to use in notifications)
	ToolName string          `json:"tool_name"`
	Args     json.RawMessage `json:"args"`

	// Optional: expiration, callback URL, etc.
	ExpiresAt   *time.Time `json:"expires_at,omitempty"`
	CallbackURL string     `json:"callback_url,omitempty"`

	// Arbitrary metadata for custom middleware
	Metadata map[string]any `json:"metadata,omitempty"`
}

PendingToolInfo provides context for middleware (email templates, notifications)

type PredictMessage added in v1.1.0

type PredictMessage struct {
	Role               string     `json:"role"`
	Content            string     `json:"content"`
	ToolCalls          []ToolCall `json:"tool_calls,omitempty"`
	ToolCallResponseID string     `json:"tool_call_id,omitempty"` // For tool result messages
}

PredictMessage represents a predict message (simplified version for tool context)

type PredictionRequest added in v1.1.0

type PredictionRequest struct {
	System      string           `json:"system"`
	Messages    []PredictMessage `json:"messages"`
	Temperature float32          `json:"temperature"`
	TopP        float32          `json:"top_p"`
	MaxTokens   int              `json:"max_tokens"`
	Seed        *int             `json:"seed,omitempty"`
}

PredictionRequest represents a predict request (extending existing type)

type PredictionResponse added in v1.1.0

type PredictionResponse struct {
	Content   string        `json:"content"`
	TokensIn  int           `json:"tokens_in"`
	TokensOut int           `json:"tokens_out"`
	Latency   time.Duration `json:"latency"`
	Raw       []byte        `json:"raw,omitempty"`
	ToolCalls []ToolCall    `json:"tool_calls,omitempty"` // Tools called in this response
}

PredictionResponse represents a predict response (extending existing type)

type Registry

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

Registry manages tool descriptors and provides access to executors. All map access is protected by mu (RWMutex) for safe concurrent use.

func NewRegistry

func NewRegistry(opts ...RegistryOption) *Registry

NewRegistry creates a new tool registry without a repository backend (legacy mode)

func NewRegistryWithRepository

func NewRegistryWithRepository(repo ToolRepository, opts ...RegistryOption) *Registry

NewRegistryWithRepository creates a new tool registry with a repository backend

func (*Registry) Execute

func (r *Registry) Execute(
	ctx context.Context, toolName string, args json.RawMessage,
) (*ToolResult, error)

Execute executes a tool with the given arguments

func (*Registry) ExecuteAsync

func (r *Registry) ExecuteAsync(
	ctx context.Context, toolName string, args json.RawMessage,
) (*ToolExecutionResult, error)

ExecuteAsync executes a tool with async support, checking if it implements AsyncToolExecutor. Returns ToolExecutionResult with status (complete/pending/failed).

func (*Registry) Get

func (r *Registry) Get(name string) *ToolDescriptor

Get retrieves a tool descriptor by name with repository fallback.

func (*Registry) GetByNamespace added in v1.3.1

func (r *Registry) GetByNamespace(ns string) []*ToolDescriptor

GetByNamespace returns all tool descriptors in the given namespace.

func (*Registry) GetTool

func (r *Registry) GetTool(name string) (*ToolDescriptor, error)

GetTool retrieves a tool descriptor by name.

func (*Registry) GetTools

func (r *Registry) GetTools() map[string]*ToolDescriptor

GetTools returns all loaded tool descriptors. The returned map is a shallow copy (safe to iterate/delete keys), but the *ToolDescriptor pointers are shared with the registry. Callers MUST NOT mutate the returned descriptors.

func (*Registry) GetToolsByNames

func (r *Registry) GetToolsByNames(names []string) ([]*ToolDescriptor, error)

GetToolsByNames returns tool descriptors for the specified names

func (*Registry) IterateTools added in v1.3.10

func (r *Registry) IterateTools(fn func(name string, tool *ToolDescriptor))

IterateTools calls fn for each loaded tool descriptor while holding the read lock. This avoids the map copy that GetTools performs, which matters when the registry is large and the caller only needs to inspect each tool once (e.g. building a provider tool list). The callback MUST NOT call back into the Registry (deadlock).

func (*Registry) List

func (r *Registry) List() []string

List returns all tool names from repository or cache.

func (*Registry) LoadToolFromBytes

func (r *Registry) LoadToolFromBytes(filename string, data []byte) error

LoadToolFromBytes loads a tool descriptor from raw bytes data. This is useful when tool data has already been read from a file or received from another source, avoiding redundant file I/O. The filename parameter is used only for error reporting.

func (*Registry) MaxToolResultSize added in v1.3.10

func (r *Registry) MaxToolResultSize() int

MaxToolResultSize returns the configured maximum tool result size in bytes.

func (*Registry) Register

func (r *Registry) Register(descriptor *ToolDescriptor) error

Register adds a tool descriptor to the registry with validation.

func (*Registry) RegisterExecutor

func (r *Registry) RegisterExecutor(executor Executor)

RegisterExecutor registers a tool executor.

type RegistryOption added in v1.3.10

type RegistryOption func(*Registry)

RegistryOption configures a Registry during construction.

func WithDefaultTimeout added in v1.3.10

func WithDefaultTimeout(ms int) RegistryOption

WithDefaultTimeout sets the default timeout (in milliseconds) applied to tools that don't declare their own TimeoutMs. Pass 0 to disable timeouts by default.

func WithMaxToolResultSize added in v1.3.10

func WithMaxToolResultSize(bytes int) RegistryOption

WithMaxToolResultSize sets the maximum allowed size (in bytes) of a JSON-marshaled tool result. Pass 0 to disable size checking.

type RepositoryToolExecutor added in v1.1.0

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

RepositoryToolExecutor wraps existing tool executors to provide repository-backed mock responses with fallback to real execution. This enables deterministic tool testing while maintaining the ability to fall back to real tool execution when needed.

func NewRepositoryToolExecutor added in v1.1.0

func NewRepositoryToolExecutor(
	baseExecutor Executor, repo ToolResponseRepository, contextKey string,
) *RepositoryToolExecutor

NewRepositoryToolExecutor creates a new repository-backed tool executor. The executor will first check the repository for configured responses, and fall back to the base executor if no match is found.

func (*RepositoryToolExecutor) Execute added in v1.1.0

func (e *RepositoryToolExecutor) Execute(
	ctx context.Context, descriptor *ToolDescriptor, args json.RawMessage,
) (json.RawMessage, error)

Execute executes a tool, first checking the repository for mock responses. If a matching response is found in the repository, it returns that response. Otherwise, it falls back to the base executor for real execution.

func (*RepositoryToolExecutor) Name added in v1.1.0

func (e *RepositoryToolExecutor) Name() string

Name returns the executor name with repository suffix.

type RequestMapper added in v1.3.11

type RequestMapper interface {
	// RenderURL applies path parameter substitution to the URL template.
	RenderURL(urlTemplate string, args map[string]any) (string, error)

	// PartitionArgs splits tool arguments into query, header, and body buckets
	// based on the mapping configuration.
	PartitionArgs(args map[string]any, cfg *RequestMapping, urlTemplate string) (query, header, body map[string]any)

	// BuildBody produces the JSON request body from the body arguments.
	// If a JMESPath body_mapping is configured, it reshapes the args.
	BuildBody(bodyArgs map[string]any, jmespathExpr string) (json.RawMessage, error)

	// RenderHeaders applies template interpolation to header values.
	RenderHeaders(templates map[string]string, args map[string]any) (map[string]string, error)
}

RequestMapper maps tool arguments to HTTP request components. Implementations can customize URL templating, argument partitioning, and body building.

type RequestMapping added in v1.3.11

type RequestMapping struct {
	// QueryParams lists argument keys to route as URL query parameters.
	QueryParams []string `json:"query_params,omitempty" yaml:"query_params,omitempty"`

	// HeaderParams maps HTTP header names to Go text/template strings
	// that interpolate tool arguments. E.g. {"Authorization": "Bearer {{.token}}"}.
	HeaderParams map[string]string `json:"header_params,omitempty" yaml:"header_params,omitempty"`

	// BodyMapping is a JMESPath expression to reshape the body arguments
	// before sending. Only applies to POST/PUT/PATCH requests.
	BodyMapping string `json:"body_mapping,omitempty" yaml:"body_mapping,omitempty"`

	// Exclude lists argument keys to omit from the request entirely.
	// Keys consumed by URL path templates and header templates are
	// automatically excluded from the body.
	Exclude []string `json:"exclude,omitempty" yaml:"exclude,omitempty"`

	// StaticQuery injects fixed query parameters into every request.
	// These are not part of the LLM's input schema — they control
	// API behavior (e.g. result count, language, format).
	StaticQuery map[string]string `json:"static_query,omitempty" yaml:"static_query,omitempty"`

	// StaticHeaders injects fixed headers into every request.
	// Unlike header_params, these are literal values, not templates.
	StaticHeaders map[string]string `json:"static_headers,omitempty" yaml:"static_headers,omitempty"`

	// StaticBody injects fixed fields into the JSON request body.
	// Only applies to POST/PUT/PATCH. Merged with LLM-provided body fields.
	StaticBody map[string]any `json:"static_body,omitempty" yaml:"static_body,omitempty"`
}

RequestMapping configures how LLM tool arguments are mapped to HTTP request components.

type ResponseMapper added in v1.3.11

type ResponseMapper interface {
	// MapResponse applies a JMESPath expression to reshape the response JSON.
	MapResponse(response json.RawMessage, jmespathExpr string) (json.RawMessage, error)
}

ResponseMapper maps HTTP response bodies to tool results. Implementations can customize response extraction and reshaping.

type ResponseMapping added in v1.3.11

type ResponseMapping struct {
	// BodyMapping is a JMESPath expression to extract or reshape the response JSON.
	BodyMapping string `json:"body_mapping,omitempty" yaml:"body_mapping,omitempty"`
}

ResponseMapping configures how HTTP response bodies are mapped to tool results.

type SchemaValidator

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

SchemaValidator handles JSON schema validation for tool inputs and outputs. It maintains an LRU cache of compiled schemas bounded by maxCacheSize.

func NewSchemaValidator

func NewSchemaValidator() *SchemaValidator

NewSchemaValidator creates a new schema validator with the default cache size.

func NewSchemaValidatorWithSize added in v1.3.10

func NewSchemaValidatorWithSize(maxSize int) *SchemaValidator

NewSchemaValidatorWithSize creates a new schema validator with the given maximum cache size. If maxSize <= 0 it defaults to DefaultMaxSchemaCacheSize.

func (*SchemaValidator) CacheLen added in v1.3.10

func (sv *SchemaValidator) CacheLen() int

CacheLen returns the number of entries currently in the schema cache. Exported for testing and monitoring.

func (*SchemaValidator) CoerceResult

func (sv *SchemaValidator) CoerceResult(
	descriptor *ToolDescriptor, result json.RawMessage,
) (json.RawMessage, []Coercion, error)

CoerceResult attempts to coerce simple type mismatches in tool results.

Currently this is a pass-through: if the result validates, it is returned as-is; otherwise validation is re-attempted after a round-trip through JSON (which normalises whitespace/encoding). Actual type coercion (e.g., string↔number) is not yet implemented — the Coercion slice is always empty.

func (*SchemaValidator) ValidateArgs

func (sv *SchemaValidator) ValidateArgs(descriptor *ToolDescriptor, args json.RawMessage) error

ValidateArgs validates tool arguments against the input schema

func (*SchemaValidator) ValidateResult

func (sv *SchemaValidator) ValidateResult(descriptor *ToolDescriptor, result json.RawMessage) error

ValidateResult validates tool result against the output schema

type ToolCall

type ToolCall struct {
	Name string          `json:"name"`
	Args json.RawMessage `json:"args"`
	ID   string          `json:"id"` // Provider-specific call ID
}

ToolCall represents a tool invocation request

type ToolConfig

type ToolConfig struct {
	APIVersion string            `json:"apiVersion" yaml:"apiVersion"`
	Kind       string            `json:"kind" yaml:"kind"`
	Metadata   metav1.ObjectMeta `json:"metadata,omitempty" yaml:"metadata,omitempty"`
	Spec       ToolDescriptor    `json:"spec" yaml:"spec"`
}

ToolConfig represents a K8s-style tool configuration manifest

type ToolDescriptor

type ToolDescriptor struct {
	Name         string          `json:"name" yaml:"name"`
	Namespace    string          `json:"namespace,omitempty" yaml:"namespace,omitempty"`
	Description  string          `json:"description" yaml:"description"`
	InputSchema  json.RawMessage `json:"input_schema" yaml:"input_schema"`   // JSON Schema Draft-07
	OutputSchema json.RawMessage `json:"output_schema" yaml:"output_schema"` // JSON Schema Draft-07
	Mode         string          `json:"mode" yaml:"mode"`                   // "mock" | "live"
	TimeoutMs    int             `json:"timeout_ms" yaml:"timeout_ms"`

	// Static mock data (in-memory)
	MockResult json.RawMessage `json:"mock_result,omitempty" yaml:"mock_result,omitempty"`
	// Multimodal mock parts (text, image, audio, etc.)
	MockParts []types.ContentPart `json:"mock_parts,omitempty" yaml:"mock_parts,omitempty"`
	// Template for dynamic mocks (inline or file)
	MockTemplate     string `json:"mock_template,omitempty" yaml:"mock_template,omitempty"`
	MockResultFile   string `json:"mock_result_file,omitempty" yaml:"mock_result_file,omitempty"`
	MockTemplateFile string `json:"mock_template_file,omitempty" yaml:"mock_template_file,omitempty"`

	HTTPConfig   *HTTPConfig   `json:"http,omitempty" yaml:"http,omitempty"`     // Live HTTP configuration
	A2AConfig    *A2AConfig    `json:"a2a,omitempty" yaml:"a2a,omitempty"`       // A2A agent configuration
	ClientConfig *ClientConfig `json:"client,omitempty" yaml:"client,omitempty"` // Client-side execution configuration
}

ToolDescriptor represents a normalized tool definition

type ToolErrorData added in v1.1.0

type ToolErrorData struct {
	Type    string `json:"type"`    // Error type/category
	Message string `json:"message"` // Error message
}

ToolErrorData represents an error response for tool execution.

type ToolExecutionResult

type ToolExecutionResult struct {
	Status  ToolExecutionStatus `json:"status"`
	Content json.RawMessage     `json:"content,omitempty"`
	Parts   []types.ContentPart `json:"parts,omitempty"`
	Error   string              `json:"error,omitempty"`

	// Present when Status == ToolStatusPending
	PendingInfo *PendingToolInfo `json:"pending_info,omitempty"`
}

ToolExecutionResult includes status and optional pending information

type ToolExecutionStatus

type ToolExecutionStatus string

ToolExecutionStatus represents whether a tool completed or needs external input

const (
	// ToolStatusComplete indicates the tool finished executing
	ToolStatusComplete ToolExecutionStatus = "complete"
	// ToolStatusPending indicates the tool is waiting for external input (e.g., human approval)
	ToolStatusPending ToolExecutionStatus = "pending"
	// ToolStatusFailed indicates the tool execution failed
	ToolStatusFailed ToolExecutionStatus = "failed"
)

type ToolGuidance

type ToolGuidance struct {
	Support   string `json:"support,omitempty"`
	Assistant string `json:"assistant,omitempty"`
	Generic   string `json:"generic,omitempty"`
}

ToolGuidance provides hints for different interaction modes This is a flexible structure that can be extended with task-specific guidance

type ToolPolicy

type ToolPolicy struct {
	ToolChoice          string   `json:"tool_choice"` // "auto" | "required" | "none"
	MaxToolCallsPerTurn int      `json:"max_tool_calls_per_turn"`
	MaxTotalToolCalls   int      `json:"max_total_tool_calls"`
	Blocklist           []string `json:"blocklist,omitempty"`
}

ToolPolicy defines constraints for tool usage in scenarios

type ToolRepository

type ToolRepository interface {
	LoadTool(name string) (*ToolDescriptor, error)
	ListTools() ([]string, error)
	SaveTool(descriptor *ToolDescriptor) error
}

ToolRepository provides abstract access to tool descriptors (local interface to avoid import cycles)

type ToolResponseData added in v1.1.0

type ToolResponseData struct {
	Result any            `json:"result,omitempty"` // Successful response data
	Error  *ToolErrorData `json:"error,omitempty"`  // Error response
}

ToolResponseData represents a configured tool response with optional error.

type ToolResponseRepository added in v1.1.0

type ToolResponseRepository interface {
	// GetToolResponse retrieves a mock response for a tool execution.
	// Returns nil if no matching response is configured (not an error).
	GetToolResponse(toolName string, args map[string]any, contextKey string) (*ToolResponseData, error)
}

ToolResponseRepository defines the interface for repositories that can provide mock tool responses based on tool name, arguments, and context.

type ToolResult

type ToolResult struct {
	Name      string              `json:"name"`
	ID        string              `json:"id"` // Matches ToolCall.ID
	Result    json.RawMessage     `json:"result"`
	Parts     []types.ContentPart `json:"parts,omitempty"`
	LatencyMs int64               `json:"latency_ms"`
	Error     string              `json:"error,omitempty"`
}

ToolResult represents the result of a tool execution

type ValidationError

type ValidationError struct {
	Type   string `json:"type"` // "args_invalid" | "result_invalid" | "policy_violation"
	Tool   string `json:"tool"`
	Detail string `json:"detail"`
	Path   string `json:"path,omitempty"`
}

ValidationError represents a tool validation failure

func (*ValidationError) Error

func (e *ValidationError) Error() string

Error implements the error interface

Jump to

Keyboard shortcuts

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