Documentation
¶
Overview ¶
Package tool provides functionality for defining and executing tools within the opsy application.
A tool is a unit of functionality that can be executed by the agent to perform specific tasks. Each tool has a definition that describes its capabilities, inputs, and behavior.
Tool Definition ¶
Tools are defined using the Definition struct, which includes:
- DisplayName: Human-readable name shown in the UI
- Description: Detailed description of the tool's purpose
- Rules: Additional rules the tool must follow
- Inputs: Map of input parameters the tool accepts
- Executable: Optional path to an executable the tool uses
Input Schema ¶
Tools can define their input requirements using the Input struct:
- Type: Data type of the input (e.g., "string", "number")
- Description: Human-readable description of the input
- Default: Default value if none is provided
- Examples: List of example values
- Optional: Whether the input is required
Every tool automatically includes common inputs:
- task: The task to be executed (required)
- working_directory: Directory to execute in (optional, defaults to ".")
- context: Additional context parameters (optional)
Tool Interface ¶
The Tool interface defines the methods a tool must implement:
- GetName: Returns the tool's identifier
- GetDisplayName: Returns the human-readable name
- GetDescription: Returns the tool's description
- GetInputSchema: Returns the JSON schema for inputs
- Execute: Executes the tool with given inputs
Tool Types ¶
The package includes two main types of tools:
1. Regular tools (tool): Base implementation that can be extended 2. Exec tools (execTool): Special tools that execute shell commands
The exec tool has specific features:
- Command execution with configurable timeouts
- Working directory resolution (absolute, relative, and ./ paths)
- Command output and exit code capture
- Timestamp tracking for command execution
- Process group management for proper cleanup
Example Usage ¶
Creating a new tool:
def := tool.Definition{ DisplayName: "My Tool", Description: "Does something useful", Rules: []string{"Follow these rules"}, Inputs: map[string]tool.Input{ "param": { Type: "string", Description: "A parameter", Optional: false, }, }, } myTool := tool.New("my-tool", def, logger, cfg, runner)
Creating an exec tool:
execTool := tool.NewExecTool(logger, cfg)
Using the exec tool:
output, err := execTool.Execute(map[string]any{ "command": "ls -la", "working_directory": "./mydir", }, ctx)
Error Handling ¶
The package defines several error types for validation:
- ErrToolMissingDisplayName: Tool definition lacks a display name
- ErrToolMissingDescription: Tool definition lacks a description
- ErrToolInputMissingType: Input definition lacks a type
- ErrToolInputMissingDescription: Input definition lacks a description
- ErrToolExecutableNotFound: Specified executable not found
- ErrInvalidToolInputType: Input value has wrong type
Thread Safety ¶
Tools are designed to be thread-safe and can be executed concurrently. Each execution:
- Gets its own context and timeout based on configuration
- Has isolated working directory resolution
- Maintains independent command state and output
- Uses process groups for clean termination
Index ¶
- Constants
- func New(n string, def Definition, logger *slog.Logger, cfg *config.ToolsConfiguration, ...) *tool
- func NewExecTool(logger *slog.Logger, cfg *config.ToolsConfiguration) *execTool
- func ValidateDefinition(def *Definition) error
- type Command
- type Definition
- type Input
- type Output
- type RunOptions
- type Runner
- type Tool
Constants ¶
const ( // ErrInvalidInputType is the error returned when an input parameter has an invalid type. ErrInvalidToolInputType = "invalid input type" // ErrToolMissingDisplayName is the error returned when a tool is missing a display name. ErrToolMissingDisplayName = "missing tool display name" // ErrToolMissingDescription is the error returned when a tool is missing a description. ErrToolMissingDescription = "missing tool description" // ErrToolInputMissingType is the error returned when a tool input is missing a type. ErrToolInputMissingType = "missing tool input type" // ErrToolInputMissingDescription is the error returned when a tool input is missing a description. ErrToolInputMissingDescription = "missing tool input description" // ErrToolExecutableNotFound is the error returned when a tool executable is not found. ErrToolExecutableNotFound = "tool executable not found" // ErrToolMarshalingInputs is the error returned when a tool inputs cannot be marshaled. ErrToolMarshalingInputs = "tool inputs cannot be marshaled" // ErrToolInvalidSystemPrompt is the error returned when a tool has an invalid system prompt. ErrToolInvalidSystemPrompt = "invalid system prompt" )
const ExecToolName = "exec"
ExecToolName is the name of the exec tool.
Variables ¶
This section is empty.
Functions ¶
func New ¶
func New(n string, def Definition, logger *slog.Logger, cfg *config.ToolsConfiguration, agent Runner) *tool
New creates a new tool.
func NewExecTool ¶
func NewExecTool(logger *slog.Logger, cfg *config.ToolsConfiguration) *execTool
NewExecTool creates a new exec tool.
func ValidateDefinition ¶
func ValidateDefinition(def *Definition) error
ValidateDefinition validates a tool definition.
Types ¶
type Command ¶
type Command struct { // Command is the command that was executed. Command string // WorkingDirectory is the working directory of the command. WorkingDirectory string // ExitCode is the exit code of the command. ExitCode int // Output is the output of the command. Output string // StartedAt is the time the command started. StartedAt time.Time // CompletedAt is the time the command completed. CompletedAt time.Time }
Command is the command that was executed.
type Definition ¶
type Definition struct { // DisplayName is the name of the tool as it will be displayed in the UI. DisplayName string `yaml:"display_name"` // Description is the description of the tool as it will be displayed in the UI. Description string `yaml:"description"` // Rules is additional rules the tool must follow. Rules []string `yaml:"rules"` // Inputs is the inputs for the tool. Inputs map[string]Input `yaml:"inputs"` // Executable is the executable to use to execute the tool. Executable string `yaml:"executable,omitempty"` }
Definition is the definition of a tool.
type Input ¶
type Input struct { // Type is the type of the input. Type string `yaml:"type"` // Description is the description of the input. Description string `yaml:"description"` // Default is the default value for the input. Default string `yaml:"default"` // Examples are examples of the input. Examples []any `yaml:"examples"` // Optional is whether the input is optional. Optional bool `yaml:"optional"` }
Input is the definition of an input for a tool.
type Output ¶
type Output struct { // Tool is the name of the tool that executed the task. Tool string `json:"tool"` // Result is the result from the tool execution. Result string `json:"result,omitempty"` // IsError indicates if the tool execution resulted in an error. IsError bool `json:"is_error"` // ExecutedCommand is the command that was executed. ExecutedCommand *Command `json:"executed_command,omitempty"` }
Output is the output of a tool.
type RunOptions ¶
type RunOptions struct { // Task is the task to be executed. Task string // Prompt is an optional prompt to be used for the agent instead of the default one. Prompt string // Caller is an optional tool that is calling the agent. Caller string // Tools is an optional list of tools to be used by the agent. Tools map[string]Tool }
RunOptions is a struct that contains the options for runner run.
type Runner ¶
type Runner interface {
Run(opts *RunOptions, ctx context.Context) ([]Output, error)
}
Runner is an interface that defines the methods for an agent.
type Tool ¶
type Tool interface { // GetName returns the name of the tool. GetName() string // GetDisplayName returns the display name of the tool. GetDisplayName() string // GetDescription returns the description of the tool. GetDescription() string // GetInputSchema returns the input schema of the tool. GetInputSchema() *jsonschema.Schema // Execute executes the tool. Execute(inputs map[string]any, ctx context.Context) (*Output, error) }
Tool is the interface for a tool.