tools

package
v0.0.0-...-d8a54d3 Latest Latest
Warning

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

Go to latest
Published: Feb 21, 2026 License: MIT Imports: 27 Imported by: 0

Documentation

Overview

Package tools provides AI agent tools for file, system, network, and knowledge operations.

Overview

This package implements tools that allow AI agents to interact with the system. All tools include built-in security validations and return structured results for consistent LLM handling.

Architecture

Tools are organized into four categories:

  • File: File operations (read, write, list, delete, info)
  • System: System operations (time, command execution, environment)
  • Network: Network operations (web search, web fetch)
  • Knowledge: Knowledge base operations (semantic search)

Each tool struct is created with a constructor, then registered with Genkit.

Available Tools

File tools (File):

  • read_file: Read file contents (max 10MB)
  • write_file: Write or create files
  • list_files: List directory contents
  • delete_file: Delete a file
  • get_file_info: Get file metadata

System tools (System):

  • current_time: Get current system time
  • execute_command: Execute shell commands (whitelist enforced)
  • get_env: Read environment variables (secrets protected)

Network tools (Network):

  • web_search: Search via SearXNG
  • web_fetch: Fetch web content with SSRF protection

Knowledge tools (Knowledge):

  • search_history: Search conversation history
  • search_documents: Search indexed documents
  • search_system_knowledge: Search system knowledge base
  • knowledge_store: Store knowledge documents (when DocStore is available)

Security

All tools integrate security validators from the security package:

  • Path validation prevents directory traversal attacks (CWE-22)
  • Command validation blocks dangerous commands like rm -rf (CWE-78)
  • SSRF protection blocks private IPs and cloud metadata endpoints
  • Environment variable protection blocks *KEY*, *SECRET*, *TOKEN* patterns

Result Type

File, System, and Knowledge tools return the unified Result type. Network tools (Search, Fetch) use typed output structs (SearchOutput, FetchOutput) with an Error string field for LLM-facing business errors.

type Result struct {
    Status  Status  // StatusSuccess or StatusError
    Data    any     // Tool output data
    Error   *Error  // Structured error (nil on success)
}

Results are constructed using struct literals directly:

// Success
return Result{Status: StatusSuccess, Data: map[string]any{"path": path}}, nil

// Error
return Result{Status: StatusError, Error: &Error{Code: ErrCodeSecurity, Message: "blocked"}}, nil

Error Handling

Tools distinguish between business errors and infrastructure errors:

Business errors are returned in Result.Error with err = nil:

  • Security validation failures (blocked path, dangerous command)
  • Resource not found
  • Permission denied
  • Invalid input

Infrastructure errors are returned as Go errors:

  • Context cancellation
  • System failures

This allows the LLM to handle expected error conditions gracefully.

Event Emission

Tools support lifecycle events for SSE streaming via the WithEvents wrapper:

wrapped := WithEvents("tool_name", handler)

Events emitted:

  • OnToolStart: Before tool execution begins
  • OnToolComplete: After successful execution
  • OnToolError: After execution returns Go error

Usage Example

// Create tools with security validators
pathVal, _ := security.NewPath([]string{"/allowed/path"}, nil)
fileTools, err := tools.NewFile(pathVal, logger)
if err != nil {
    return err
}

// Register with Genkit
fileToolList, _ := tools.RegisterFile(g, fileTools)

Index

Constants

View Source
const (
	// ReadFileName is the Genkit tool name for reading file contents.
	ReadFileName = "read_file"
	// WriteFileName is the Genkit tool name for writing file contents.
	WriteFileName = "write_file"
	// ListFilesName is the Genkit tool name for listing directory contents.
	ListFilesName = "list_files"
	// DeleteFileName is the Genkit tool name for deleting files.
	DeleteFileName = "delete_file"
	// FileInfoName is the Genkit tool name for retrieving file metadata.
	FileInfoName = "get_file_info"
)

Tool name constants for file operations registered with Genkit.

View Source
const (
	// SearchHistoryName is the Genkit tool name for searching conversation history.
	SearchHistoryName = "search_history"
	// SearchDocumentsName is the Genkit tool name for searching indexed documents.
	SearchDocumentsName = "search_documents"
	// SearchSystemKnowledgeName is the Genkit tool name for searching system knowledge.
	SearchSystemKnowledgeName = "search_system_knowledge"
	// StoreKnowledgeName is the Genkit tool name for storing new knowledge documents.
	StoreKnowledgeName = "knowledge_store"
)

Tool name constants for knowledge operations registered with Genkit.

View Source
const (
	DefaultHistoryTopK         = 3
	DefaultDocumentsTopK       = 5
	DefaultSystemKnowledgeTopK = 3
	MaxKnowledgeTopK           = 10
)

Default TopK values for knowledge searches.

View Source
const (
	// WebSearchName is the Genkit tool name for performing web searches.
	WebSearchName = "web_search"
	// WebFetchName is the Genkit tool name for fetching web page content.
	WebFetchName = "web_fetch"
)

Tool name constants for network operations registered with Genkit.

View Source
const (
	// MaxURLsPerRequest is the maximum number of URLs allowed per web_fetch request.
	MaxURLsPerRequest = 10
	// MaxContentLength is the maximum content length per URL (50KB).
	MaxContentLength = 50000
	// MaxSearchResults is the maximum number of search results allowed.
	MaxSearchResults = 50
	// DefaultSearchResults is the default number of search results.
	DefaultSearchResults = 10
	// MaxRedirects is the maximum number of HTTP redirects to follow.
	MaxRedirects = 5
	// MaxSearchQueryLength is the maximum allowed search query length in bytes.
	// Prevents abuse via extremely long queries that could DoS search backends.
	MaxSearchQueryLength = 1000
	// MaxSelectorLength is the maximum CSS selector length in bytes.
	MaxSelectorLength = 500
	// MaxURLLength is the maximum URL length in bytes per individual URL.
	MaxURLLength = 2048
)

Content limits.

View Source
const (
	// CurrentTimeName is the Genkit tool name for retrieving the current time.
	CurrentTimeName = "current_time"
	// ExecuteCommandName is the Genkit tool name for executing shell commands.
	ExecuteCommandName = "execute_command"
	// GetEnvName is the Genkit tool name for reading environment variables.
	GetEnvName = "get_env"
)

Tool name constants for system operations registered with Genkit.

View Source
const MaxCommandArgLength = 10000

MaxCommandArgLength is the maximum total length of command + args in bytes. Prevents abuse via extremely long command strings.

View Source
const MaxDocsPerUser = 1000

MaxDocsPerUser is the maximum number of user-created documents per owner. Prevents resource exhaustion via unbounded document ingestion.

View Source
const MaxEnvKeyLength = 256

MaxEnvKeyLength is the maximum allowed environment variable name length (256 bytes).

View Source
const MaxKnowledgeContentSize = 10_000

MaxKnowledgeContentSize is the maximum allowed content size for knowledge_store (10KB). Prevents DoS via large document ingestion and embedding computation.

View Source
const MaxKnowledgeQueryLength = 1000

MaxKnowledgeQueryLength is the maximum allowed search query length (1000 bytes). Prevents DoS via extremely long queries that waste embedding computation.

View Source
const MaxKnowledgeTitleLength = 500

MaxKnowledgeTitleLength is the maximum allowed title length for knowledge_store.

View Source
const MaxPathLength = 4096

MaxPathLength is the maximum allowed file path length (4096 bytes). Matches Linux PATH_MAX. Prevents DoS via extremely long paths.

View Source
const MaxReadFileSize = 10 * 1024 * 1024

MaxReadFileSize is the maximum file size allowed for ReadFile (10 MB). This prevents OOM when reading large files into memory.

View Source
const MaxWriteContentSize = 1 * 1024 * 1024

MaxWriteContentSize is the maximum content size for WriteFile (1 MB). Prevents OOM and disk abuse from extremely large write payloads.

Variables

This section is empty.

Functions

func ContextWithEmitter

func ContextWithEmitter(ctx context.Context, emitter Emitter) context.Context

ContextWithEmitter stores Emitter in context for per-request binding.

func ContextWithOwnerID

func ContextWithOwnerID(ctx context.Context, ownerID string) context.Context

ContextWithOwnerID stores the owner identity in context. The API layer injects the authenticated user ID; knowledge tools read it for per-user document isolation (RAG poisoning prevention).

func OwnerIDFromContext

func OwnerIDFromContext(ctx context.Context) string

OwnerIDFromContext retrieves the owner identity from context. Returns empty string if not set. Used by knowledge tools to tag and filter documents by owner.

func RegisterFile

func RegisterFile(g *genkit.Genkit, ft *File) ([]ai.Tool, error)

RegisterFile registers all file operation tools with Genkit.

func RegisterKnowledge

func RegisterKnowledge(g *genkit.Genkit, kt *Knowledge) ([]ai.Tool, error)

RegisterKnowledge registers all knowledge search tools with Genkit. Tools are registered with event emission wrappers for streaming support.

func RegisterNetwork

func RegisterNetwork(g *genkit.Genkit, nt *Network) ([]ai.Tool, error)

RegisterNetwork registers all network operation tools with Genkit. Tools are registered with event emission wrappers for streaming support.

func RegisterSystem

func RegisterSystem(g *genkit.Genkit, st *System) ([]ai.Tool, error)

RegisterSystem registers all system operation tools with Genkit. Tools are registered with event emission wrappers for streaming support.

func WithEvents

func WithEvents[In, Out any](name string, fn func(*ai.ToolContext, In) (Out, error)) func(*ai.ToolContext, In) (Out, error)

WithEvents wraps a typed tool handler to emit lifecycle events. This generic version works directly with genkit.DefineTool().

The wrapper:

  1. Retrieves emitter from context (may be nil for non-streaming calls)
  2. Emits OnToolStart before execution
  3. Calls the original handler function
  4. Emits OnToolComplete or OnToolError after execution

If no emitter is in context, the wrapper simply passes through to the original function. This allows graceful degradation for non-streaming code paths.

Types

type CurrentTimeInput

type CurrentTimeInput struct{}

CurrentTimeInput defines input for current_time tool (no input needed).

type DeleteFileInput

type DeleteFileInput struct {
	Path string `json:"path" jsonschema_description:"The file path to delete"`
}

DeleteFileInput defines input for delete_file tool.

type Emitter

type Emitter interface {
	// OnToolStart signals that a tool has started execution.
	// name: tool name (e.g., "web_search")
	// UI presentation (messages, icons) handled by web layer.
	OnToolStart(name string)

	// OnToolComplete signals that a tool completed successfully.
	// name: tool name
	OnToolComplete(name string)

	// OnToolError signals that a tool execution failed.
	// name: tool name
	// UI error messages handled by web layer.
	OnToolError(name string)
}

Emitter receives tool lifecycle events. Interface is minimal - only tool name, no UI concerns. UI presentation logic is handled by the SSE/API layer.

Usage:

  1. Handler creates emitter bound to SSE writer
  2. Handler stores emitter in context via ContextWithEmitter()
  3. Wrapped tool retrieves emitter via EmitterFromContext()
  4. Tool calls OnToolStart/Complete/Error during execution

func EmitterFromContext

func EmitterFromContext(ctx context.Context) Emitter

EmitterFromContext retrieves Emitter from context. Returns nil if not set, allowing graceful degradation (no events emitted).

type EnvInput

type EnvInput struct {
	Key string `json:"key" jsonschema_description:"The environment variable name"`
}

EnvInput defines input for get_env tool.

type Error

type Error struct {
	Code    ErrorCode `json:"code" jsonschema_description:"Error code"`
	Message string    `json:"message" jsonschema_description:"Detailed error message"`
	Details any       `json:"details,omitempty" jsonschema_description:"Additional error context"`
}

Error provides structured error information for JSON responses.

type ErrorCode

type ErrorCode string

ErrorCode represents standardized error codes for LLM-facing JSON responses. These are kept for backward compatibility and structured LLM responses.

const (
	ErrCodeSecurity   ErrorCode = "SecurityError"
	ErrCodeNotFound   ErrorCode = "NotFound"
	ErrCodePermission ErrorCode = "PermissionDenied"
	ErrCodeIO         ErrorCode = "IOError"
	ErrCodeExecution  ErrorCode = "ExecutionError"
	ErrCodeTimeout    ErrorCode = "TimeoutError"
	ErrCodeNetwork    ErrorCode = "NetworkError"
	ErrCodeValidation ErrorCode = "ValidationError"
)

Standardized error codes for tool responses.

type ExecuteCommandInput

type ExecuteCommandInput struct {
	Command string   `json:"command" jsonschema_description:"The command to execute (e.g., 'ls', 'git')"`
	Args    []string `json:"args,omitempty" jsonschema_description:"Command arguments as separate array elements"`
}

ExecuteCommandInput defines input for execute_command tool.

type FailedURL

type FailedURL struct {
	URL        string `json:"url"`
	Reason     string `json:"reason"`
	StatusCode int    `json:"status_code,omitempty"` // HTTP status code if available
}

FailedURL represents a URL that failed to fetch.

type FetchInput

type FetchInput struct {
	// URLs is one or more URLs to fetch. Required, max 10.
	URLs []string `json:"urls" jsonschema_description:"One or more URLs to fetch (required, max 10)"`

	// Selector is an optional CSS selector to extract specific content.
	// If empty, attempts to extract main content automatically using Readability.
	Selector string `` /* 128-byte string literal not displayed */
}

FetchInput defines the input for web_fetch tool.

type FetchOutput

type FetchOutput struct {
	// Results contains the fetched content for each URL.
	Results []FetchResult `json:"results"`

	// FailedURLs lists URLs that failed to fetch with reasons.
	FailedURLs []FailedURL `json:"failed_urls,omitempty"`

	// Error contains validation error for LLM to understand.
	Error string `json:"error,omitempty"`
}

FetchOutput defines the output for web_fetch tool.

type FetchResult

type FetchResult struct {
	URL         string `json:"url"`
	Title       string `json:"title"`
	Content     string `json:"content"`
	ContentType string `json:"content_type"` // e.g., "text/html", "application/json", "text/plain"
}

FetchResult represents successfully fetched content from a single URL.

type File

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

File provides file operation handlers. Use NewFile to create an instance, then either: - Call methods directly (for MCP) - Use RegisterFile to register with Genkit

func NewFile

func NewFile(pathVal *security.Path, logger *slog.Logger) (*File, error)

NewFile creates a File instance.

func (*File) DeleteFile

func (f *File) DeleteFile(_ *ai.ToolContext, input DeleteFileInput) (Result, error)

DeleteFile permanently deletes a file with security validation.

func (*File) FileInfo

func (f *File) FileInfo(_ *ai.ToolContext, input FileInfoInput) (Result, error)

FileInfo gets file metadata.

func (*File) ListFiles

func (f *File) ListFiles(_ *ai.ToolContext, input ListFilesInput) (Result, error)

ListFiles lists files in a directory.

func (*File) ReadFile

func (f *File) ReadFile(_ *ai.ToolContext, input ReadFileInput) (Result, error)

ReadFile reads and returns the complete content of a file with security validation.

func (*File) WriteFile

func (f *File) WriteFile(_ *ai.ToolContext, input WriteFileInput) (Result, error)

WriteFile writes content to a file with security validation.

type FileEntry

type FileEntry struct {
	Name string `json:"name"`
	Type string `json:"type"` // "file" or "directory"
}

FileEntry represents a single file or directory entry in ListFiles output.

type FileInfoInput

type FileInfoInput struct {
	Path string `json:"path" jsonschema_description:"The file path to get info for"`
}

FileInfoInput defines input for get_file_info tool.

type Knowledge

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

Knowledge holds dependencies for knowledge operation handlers.

func NewKnowledge

func NewKnowledge(retriever ai.Retriever, docStore *postgresql.DocStore, pool *pgxpool.Pool, logger *slog.Logger) (*Knowledge, error)

NewKnowledge creates a Knowledge instance. docStore and pool are optional: when nil, the knowledge_store tool is not registered and per-user document limits are not enforced, respectively.

func (*Knowledge) HasDocStore

func (k *Knowledge) HasDocStore() bool

HasDocStore reports whether the document store is available. Used by MCP server to conditionally register the knowledge_store tool.

func (*Knowledge) SearchDocuments

func (k *Knowledge) SearchDocuments(ctx *ai.ToolContext, input KnowledgeSearchInput) (Result, error)

SearchDocuments searches indexed documents using semantic similarity.

func (*Knowledge) SearchHistory

func (k *Knowledge) SearchHistory(ctx *ai.ToolContext, input KnowledgeSearchInput) (Result, error)

SearchHistory searches conversation history using semantic similarity.

func (*Knowledge) SearchSystemKnowledge

func (k *Knowledge) SearchSystemKnowledge(ctx *ai.ToolContext, input KnowledgeSearchInput) (Result, error)

SearchSystemKnowledge searches system knowledge base using semantic similarity.

func (*Knowledge) StoreKnowledge

func (k *Knowledge) StoreKnowledge(ctx *ai.ToolContext, input KnowledgeStoreInput) (Result, error)

StoreKnowledge stores a new knowledge document for later retrieval. Content is validated for secrets, prompt injection patterns, and injection markers. Per-user document count is enforced when pool and owner ID are available.

type KnowledgeSearchInput

type KnowledgeSearchInput struct {
	Query string `json:"query" jsonschema_description:"The search query string"`
	TopK  int    `json:"topK,omitempty" jsonschema_description:"Maximum results to return (1-10)"`
}

KnowledgeSearchInput defines input for all knowledge search tools. The default TopK varies by tool: history=3, documents=5, system=3.

type KnowledgeStoreInput

type KnowledgeStoreInput struct {
	Title   string `json:"title" jsonschema_description:"Short title for the knowledge entry"`
	Content string `json:"content" jsonschema_description:"The knowledge content to store"`
}

KnowledgeStoreInput defines input for the knowledge_store tool.

type ListFilesInput

type ListFilesInput struct {
	Path string `json:"path" jsonschema_description:"The directory path to list"`
}

ListFilesInput defines input for list_files tool.

type NetConfig

type NetConfig struct {
	SearchBaseURL    string
	FetchParallelism int
	FetchDelay       time.Duration
	FetchTimeout     time.Duration
}

NetConfig holds configuration for network tools.

type Network

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

Network holds dependencies for network operation handlers. Use NewNetwork to create an instance, then either: - Call methods directly (for MCP) - Use RegisterNetwork to register with Genkit

func NewNetwork

func NewNetwork(cfg NetConfig, logger *slog.Logger) (*Network, error)

NewNetwork creates a Network instance.

func (*Network) Fetch

func (n *Network) Fetch(ctx *ai.ToolContext, input FetchInput) (FetchOutput, error)

Fetch retrieves and extracts content from one or more URLs. Includes SSRF protection to block private IPs and cloud metadata endpoints.

func (*Network) Search

func (n *Network) Search(ctx *ai.ToolContext, input SearchInput) (SearchOutput, error)

Search performs web search via SearXNG.

type ReadFileInput

type ReadFileInput struct {
	Path string `json:"path" jsonschema_description:"The file path to read (absolute or relative)"`
}

ReadFileInput defines input for read_file tool.

type Result

type Result struct {
	Status Status `json:"status" jsonschema_description:"The execution status"`
	Data   any    `json:"data,omitempty" jsonschema_description:"The tool's output data"`
	Error  *Error `json:"error,omitempty" jsonschema_description:"Error information if failed"`
}

Result is the standard return format for all tools.

type SearchInput

type SearchInput struct {
	// Query is the search query string. Required.
	Query string `json:"query" jsonschema_description:"The search query (required)"`

	// Categories filters results by type. Optional.
	Categories []string `json:"categories,omitempty" jsonschema_description:"Search categories: general, news, images, videos, science"`

	// Language specifies the preferred language. Optional.
	Language string `json:"language,omitempty" jsonschema_description:"Language code (e.g. en, zh-TW, ja)"`

	// MaxResults limits the number of results. Optional, default 10, max 50.
	MaxResults int `json:"max_results,omitempty" jsonschema_description:"Maximum results to return (default 10, max 50)"`
}

SearchInput defines the input for web_search tool.

type SearchOutput

type SearchOutput struct {
	Results []SearchResult `json:"results,omitempty"`
	Query   string         `json:"query"`
	Error   string         `json:"error,omitempty"` // Business error for LLM
}

SearchOutput defines the output for web_search tool.

type SearchResult

type SearchResult struct {
	Title       string `json:"title"`
	URL         string `json:"url"`
	Content     string `json:"content"`
	Engine      string `json:"engine,omitempty"`
	PublishedAt string `json:"published_at,omitempty"`
}

SearchResult represents a single search result.

type Status

type Status string

Status represents the execution status of a tool.

const (
	StatusSuccess Status = "success" // Tool completed successfully
	StatusError   Status = "error"   // Tool failed with an error
)

Tool execution status constants.

type System

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

System holds dependencies for system operation handlers. Use NewSystem to create an instance, then either: - Call methods directly (for MCP) - Use RegisterSystem to register with Genkit

func NewSystem

func NewSystem(cmdVal *security.Command, envVal *security.Env, logger *slog.Logger) (*System, error)

NewSystem creates a System instance.

func (*System) CurrentTime

func (s *System) CurrentTime(_ *ai.ToolContext, _ CurrentTimeInput) (Result, error)

CurrentTime returns the current system date and time in multiple formats.

func (*System) Env

func (s *System) Env(_ *ai.ToolContext, input EnvInput) (Result, error)

Env reads an environment variable value with security protection. Sensitive variables containing KEY, SECRET, or TOKEN in the name are blocked. Business errors (sensitive variable blocked) are returned in Result.Error.

func (*System) ExecuteCommand

func (s *System) ExecuteCommand(ctx *ai.ToolContext, input ExecuteCommandInput) (Result, error)

ExecuteCommand executes a system shell command with security validation. Dangerous commands like rm -rf, sudo, and shutdown are blocked. Business errors (blocked commands, execution failures) are returned in Result.Error. Only context cancellation returns a Go error.

type WriteFileInput

type WriteFileInput struct {
	Path    string `json:"path" jsonschema_description:"The file path to write"`
	Content string `json:"content" jsonschema_description:"The content to write to the file"`
}

WriteFileInput defines input for write_file tool.

Jump to

Keyboard shortcuts

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