Documentation
¶
Overview ¶
Package tools provides HITL (Human-in-the-Loop) tool support.
Package tools provides typed tool handlers and utilities for SDK v2.
This package extends the basic tool registration provided by [sdk.Conversation.OnTool] with additional capabilities:
- Type-safe handlers using Go generics
- Handler adapters for the runtime tool registry
- HTTP tool executors
- Pending tool management for HITL workflows
Most users will only need [sdk.Conversation.OnTool] from the main sdk package. This sub-package is for advanced use cases.
Typed Handlers ¶
For type safety, use OnTyped with struct arguments:
type GetWeatherArgs struct {
City string `map:"city"`
Country string `map:"country"`
}
tools.OnTyped(conv, "get_weather", func(args GetWeatherArgs) (any, error) {
return weatherAPI.GetForecast(args.City, args.Country)
})
The struct fields are populated from the args map using the "map" struct tag (or the field name in lowercase if no tag is specified).
Index ¶
- Constants
- Variables
- func OnTyped[T any](conv ToolRegistrar, name string, handler TypedHandler[T])
- type AsyncToolHandler
- type HTTPExecutor
- func (e *HTTPExecutor) AggregateResponseSize() int64
- func (e *HTTPExecutor) Execute(ctx context.Context, descriptor *tools.ToolDescriptor, args json.RawMessage) (json.RawMessage, error)
- func (e *HTTPExecutor) ExecuteWithContext(ctx context.Context, descriptor *tools.ToolDescriptor, args json.RawMessage) (json.RawMessage, error)
- func (e *HTTPExecutor) Name() string
- func (e *HTTPExecutor) ResetAggregateSize()
- type HTTPToolConfig
- type HTTPToolOption
- func WithHeader(key, value string) HTTPToolOption
- func WithHeaderFromEnv(headerEnv string) HTTPToolOption
- func WithMethod(method string) HTTPToolOption
- func WithPostProcess(fn func(resp []byte) ([]byte, error)) HTTPToolOption
- func WithPreRequest(fn func(req *http.Request) error) HTTPToolOption
- func WithRedact(fields ...string) HTTPToolOption
- func WithTimeout(ms int) HTTPToolOption
- func WithTransform(transform func(args map[string]any) (map[string]any, error)) HTTPToolOption
- type HandlerAdapter
- type PendingResult
- type PendingStore
- func (s *PendingStore) Add(call *PendingToolCall) error
- func (s *PendingStore) Clear()
- func (s *PendingStore) Close()
- func (s *PendingStore) Get(id string) (*PendingToolCall, bool)
- func (s *PendingStore) Len() int
- func (s *PendingStore) List() []*PendingToolCall
- func (s *PendingStore) Reject(id, reason string) (*ToolResolution, error)
- func (s *PendingStore) Remove(id string)
- func (s *PendingStore) Resolve(id string) (*ToolResolution, error)
- type PendingStoreOption
- type PendingToolCall
- type ResolvedStore
- type ToolHandler
- type ToolRegistrar
- type ToolResolution
- type TypedHandler
Constants ¶
const ( // DefaultPendingTTL is the default time-to-live for pending tool calls. // Entries older than this are automatically removed by the cleanup goroutine. DefaultPendingTTL = 5 * time.Minute // DefaultMaxPending is the default maximum number of pending tool calls // that can be stored simultaneously. New adds are rejected when full. DefaultMaxPending = 1000 )
const (
DefaultMaxAggregateSize = 50 * 1024 * 1024 // 50MB cumulative across all responses
)
Default configuration values
Variables ¶
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.
var ErrPendingStoreFull = errors.New("pending store is full")
ErrPendingStoreFull is returned when the store has reached its maximum capacity.
Functions ¶
func OnTyped ¶
func OnTyped[T any](conv ToolRegistrar, name string, handler TypedHandler[T])
OnTyped registers a typed handler for a tool.
The type parameter T must be a struct type. Field values are populated from the args map using:
- The "map" struct tag value, or
- The lowercase field name if no tag is present
Example:
type SearchArgs struct {
Query string `map:"query"`
MaxResults int `map:"max_results"`
}
tools.OnTyped(conv, "search", func(args SearchArgs) (any, error) {
return search(args.Query, args.MaxResults)
})
Types ¶
type AsyncToolHandler ¶
type AsyncToolHandler func(args map[string]any) PendingResult
AsyncToolHandler is a function that may require approval before execution. Return a non-empty PendingResult to indicate approval is needed. Return an empty PendingResult{} to proceed immediately.
type HTTPExecutor ¶
type HTTPExecutor struct {
// 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.
func NewHTTPExecutor ¶
func NewHTTPExecutor() *HTTPExecutor
NewHTTPExecutor creates a new HTTP executor with the default HTTP client and default aggregate response size limit.
func NewHTTPExecutorWithClient ¶
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.10
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.10
func (e *HTTPExecutor) AggregateResponseSize() int64
AggregateResponseSize returns the cumulative response size consumed so far.
func (*HTTPExecutor) Execute ¶
func (e *HTTPExecutor) Execute( ctx context.Context, descriptor *tools.ToolDescriptor, args json.RawMessage, ) (json.RawMessage, error)
Execute performs an HTTP request based on the tool descriptor's HTTPConfig. The args are serialized to JSON and sent as the request body.
func (*HTTPExecutor) ExecuteWithContext ¶
func (e *HTTPExecutor) ExecuteWithContext( ctx context.Context, descriptor *tools.ToolDescriptor, args json.RawMessage, ) (json.RawMessage, error)
ExecuteWithContext performs an HTTP request with context support for cancellation.
func (*HTTPExecutor) Name ¶
func (e *HTTPExecutor) Name() string
Name returns the executor name used for registration.
func (*HTTPExecutor) ResetAggregateSize ¶ added in v1.3.10
func (e *HTTPExecutor) ResetAggregateSize()
ResetAggregateSize resets the cumulative response size counter to zero.
type HTTPToolConfig ¶
type HTTPToolConfig struct {
// contains filtered or unexported fields
}
HTTPToolConfig provides a builder pattern for configuring HTTP tool handlers. This is used with OnToolHTTP to register HTTP-based tools programmatically.
func NewHTTPToolConfig ¶
func NewHTTPToolConfig(url string, opts ...HTTPToolOption) *HTTPToolConfig
NewHTTPToolConfig creates a new HTTP tool configuration.
func (*HTTPToolConfig) Handler ¶
func (c *HTTPToolConfig) Handler() func(args map[string]any) (any, error)
Handler returns a tool handler function that makes the HTTP request. This is used with OnTool to register an HTTP-based tool.
func (*HTTPToolConfig) HandlerCtx ¶ added in v1.3.6
HandlerCtx returns a context-aware tool handler function that makes the HTTP request. The context is propagated to the underlying HTTP executor for tracing and cancellation.
func (*HTTPToolConfig) ToDescriptorConfig ¶
func (c *HTTPToolConfig) ToDescriptorConfig() *tools.HTTPConfig
ToDescriptorConfig converts the HTTPToolConfig to a runtime HTTPConfig that can be used with a tool descriptor.
type HTTPToolOption ¶
type HTTPToolOption func(*HTTPToolConfig)
HTTPToolOption configures an HTTPToolConfig.
func WithHeader ¶
func WithHeader(key, value string) HTTPToolOption
WithHeader adds a static header.
func WithHeaderFromEnv ¶
func WithHeaderFromEnv(headerEnv string) HTTPToolOption
WithHeaderFromEnv adds a header that reads its value from an environment variable. Format: "Header-Name=ENV_VAR_NAME"
func WithPostProcess ¶
func WithPostProcess(fn func(resp []byte) ([]byte, error)) HTTPToolOption
WithPostProcess adds a function to process the response after receiving.
func WithPreRequest ¶
func WithPreRequest(fn func(req *http.Request) error) HTTPToolOption
WithPreRequest adds a function to modify the request before sending.
func WithRedact ¶
func WithRedact(fields ...string) HTTPToolOption
WithRedact specifies fields to redact from the response.
func WithTimeout ¶
func WithTimeout(ms int) HTTPToolOption
WithTimeout sets the request timeout in milliseconds.
func WithTransform ¶
WithTransform adds a function to transform arguments before the request.
type HandlerAdapter ¶
type HandlerAdapter struct {
// contains filtered or unexported fields
}
HandlerAdapter adapts an SDK handler to the runtime's tools.Executor interface.
func NewHandlerAdapter ¶
NewHandlerAdapter creates a new adapter for the given handler.
func (*HandlerAdapter) Execute ¶
func (a *HandlerAdapter) Execute( _ context.Context, _ *tools.ToolDescriptor, args json.RawMessage, ) (json.RawMessage, error)
Execute runs the handler with the given arguments.
type PendingResult ¶
type PendingResult struct {
// Reason is a machine-readable code for why approval is needed.
// Examples: "high_value", "sensitive_action", "rate_limited"
Reason string
// Message is a human-readable explanation for the approval requirement.
// This should be suitable for display to an approver.
Message string
}
PendingResult is returned by async tool handlers to indicate that the tool execution requires external approval.
Example:
conv.OnToolAsync("process_refund", func(args map[string]any) PendingResult {
amount := args["amount"].(float64)
if amount > 1000 {
return PendingResult{
Reason: "high_value_refund",
Message: fmt.Sprintf("Refund of $%.2f requires approval", amount),
}
}
// Return empty to proceed immediately
return PendingResult{}
})
func (PendingResult) IsPending ¶
func (p PendingResult) IsPending() bool
IsPending returns true if this result requires approval.
type PendingStore ¶
type PendingStore struct {
// contains filtered or unexported fields
}
PendingStore manages pending tool calls for a conversation.
func NewPendingStore ¶
func NewPendingStore(opts ...PendingStoreOption) *PendingStore
NewPendingStore creates a new pending tool store with TTL-based cleanup. Call Close() when the store is no longer needed to stop the cleanup goroutine.
func (*PendingStore) Add ¶
func (s *PendingStore) Add(call *PendingToolCall) error
Add stores a pending tool call. Returns ErrPendingStoreFull if the store has reached its maximum capacity.
func (*PendingStore) Close ¶ added in v1.3.10
func (s *PendingStore) Close()
Close stops the background cleanup goroutine and waits for it to finish.
func (*PendingStore) Get ¶
func (s *PendingStore) Get(id string) (*PendingToolCall, bool)
Get retrieves a pending tool call by ID.
func (*PendingStore) Len ¶
func (s *PendingStore) Len() int
Len returns the number of pending calls.
func (*PendingStore) List ¶
func (s *PendingStore) List() []*PendingToolCall
List returns all pending tool calls.
func (*PendingStore) Reject ¶
func (s *PendingStore) Reject(id, reason string) (*ToolResolution, error)
Reject marks a pending tool call as rejected.
func (*PendingStore) Remove ¶
func (s *PendingStore) Remove(id string)
Remove deletes a pending tool call.
func (*PendingStore) Resolve ¶
func (s *PendingStore) Resolve(id string) (*ToolResolution, error)
Resolve executes an approved pending tool call.
type PendingStoreOption ¶ added in v1.3.10
type PendingStoreOption func(*PendingStore)
PendingStoreOption configures a PendingStore during construction.
func WithMaxPending ¶ added in v1.3.10
func WithMaxPending(limit int) PendingStoreOption
WithMaxPending sets the maximum number of pending tool calls allowed.
func WithPendingTTL ¶ added in v1.3.10
func WithPendingTTL(ttl time.Duration) PendingStoreOption
WithPendingTTL sets the time-to-live for pending tool calls. Entries older than this are removed during periodic cleanup.
type PendingToolCall ¶
type PendingToolCall struct {
// Unique identifier for this pending call
ID string `json:"id"`
// Tool name
Name string `json:"name"`
// Arguments passed to the tool
Arguments map[string]any `json:"arguments"`
// Reason the tool requires approval (from PendingResult)
Reason string `json:"reason"`
// Human-readable message (from PendingResult)
Message string `json:"message"`
// contains filtered or unexported fields
}
PendingToolCall represents a tool call awaiting approval.
func (*PendingToolCall) SetHandler ¶ added in v1.1.9
func (p *PendingToolCall) SetHandler(h func(args map[string]any) (any, error))
SetHandler sets the execution handler for this pending call. This is called by the SDK when creating a pending tool call.
type ResolvedStore ¶ added in v1.1.9
type ResolvedStore struct {
// contains filtered or unexported fields
}
ResolvedStore tracks tool call resolutions that haven't been processed by Continue(). This allows the Continue() method to send proper tool result messages to the LLM.
func NewResolvedStore ¶ added in v1.1.9
func NewResolvedStore() *ResolvedStore
NewResolvedStore creates a new resolved tool store.
func (*ResolvedStore) Add ¶ added in v1.1.9
func (s *ResolvedStore) Add(resolution *ToolResolution)
Add stores a resolved tool call.
func (*ResolvedStore) Len ¶ added in v1.1.9
func (s *ResolvedStore) Len() int
Len returns the number of stored resolutions.
func (*ResolvedStore) PopAll ¶ added in v1.1.9
func (s *ResolvedStore) PopAll() []*ToolResolution
PopAll returns all resolutions and clears the store. Used by Continue() to get all pending tool results.
type ToolHandler ¶
ToolHandler is a function type for tool handlers. This mirrors the definition in the main sdk package.
type ToolRegistrar ¶
type ToolRegistrar interface {
OnTool(name string, handler ToolHandler)
}
ToolRegistrar is the interface for registering tool handlers. This is implemented by [sdk.Conversation].
type ToolResolution ¶
type ToolResolution struct {
// The resolved tool call ID
ID string
// Result if approved and executed
Result any
// ResultJSON is the JSON-encoded result
ResultJSON json.RawMessage
// Parts contains multimodal content parts for the tool result.
// When set, these are used directly as MessageToolResult.Parts,
// taking precedence over ResultJSON.
Parts []types.ContentPart
// Error if execution failed
Error error
// Rejected is true if the tool was rejected
Rejected bool
// RejectionReason explains why the tool was rejected
RejectionReason string
}
ToolResolution represents the result of resolving a pending tool.
type TypedHandler ¶
TypedHandler is a function that executes a tool call with typed arguments. T must be a struct type with fields tagged with `map:"fieldname"`.