tools

package
v0.6.6 Latest Latest
Warning

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

Go to latest
Published: Aug 6, 2026 License: MIT Imports: 24 Imported by: 0

Documentation

Overview

Package tools implements the coding agent's built-in tools: file reading, editing, writing, and shell execution. Each tool is a definition-first Tool that carries both its executable body and the metadata it contributes to the system prompt, so the prompt is assembled from whichever tools are active.

Filesystem and command execution go through the FileOps and ExecOps seams rather than touching os/exec directly. LocalOps is the default, running against the local filesystem and shell; override the seams to sandbox, containerize, or drive a remote workspace.

Index

Constants

View Source
const (
	FailureNotRead   = "not_read"  // an existing file was not read before mutating
	FailureChanged   = "changed"   // the file changed on disk since it was read
	FailureNotFound  = "not_found" // old_string was not present in the file
	FailureAmbiguous = "ambiguous" // old_string matched multiple places
	FailureIO        = "io"        // an I/O or filesystem error
	FailureInput     = "input"     // invalid arguments
)

Failure reason codes for MutationFailure.Reason.

View Source
const (
	MinQuestions   = 1
	MaxQuestions   = 4
	MinOptions     = 2
	MaxOptions     = 4
	MaxHeaderRunes = 12
)

Question limits. The schema enforces the counts, so a model that exceeds them gets a validation error before the tool runs; Execute only checks what a schema cannot express.

View Source
const (
	DefaultMaxLines = 1000
	DefaultMaxBytes = 30000
)

Default output caps for tool results. Unbounded file reads or command output can fill the context window in a single turn, so results are capped and the model is told what was dropped.

View Source
const DefaultBashTimeout = 120 * time.Second

DefaultBashTimeout bounds a single command when the model does not set one.

View Source
const MaxBrowserInspectionTextRunes = 12_000
View Source
const ToolNameAskUserQuestion = "ask_user_question"

ToolNameAskUserQuestion is the advertised name of the question tool.

Variables

View Source
var (
	// ErrFileNotRead means a mutating tool was asked to change an existing file
	// that has not been observed by Read in this tool-set lifetime.
	ErrFileNotRead = errors.New("file has not been read")
	// ErrFileChanged means the file's current disk version no longer matches the
	// version most recently observed or produced by the tools.
	ErrFileChanged = errors.New("file has changed since it was read")
)
View Source
var ErrNoAsker = errors.New("no interactive surface is available to ask the user")

ErrNoAsker is returned when no product surface can reach the user.

View Source
var ErrTaskNotFound = errors.New("background task not found")

ErrTaskNotFound is returned when a task id is not owned by this manager.

Functions

func AgentTools

func AgentTools(tools []Tool) []agent.AgentTool

AgentTools extracts the executable agent.AgentTool from each Tool, for handing to the agent loop.

func CheckPreview

func CheckPreview(ctx context.Context, raw string) (string, error)

CheckPreview validates and probes a local preview URL before it is handed to a WebView. Both the agent tool and the Browser HTTP endpoint use this path.

func CoreToolsWithTasks

func CoreToolsWithTasks(root string, ops Ops) ([]Tool, *TaskManager)

CoreToolsWithTasks returns the filesystem and shell tools that make up the coding product's core capability. Browser tools are assembled separately so the engine can register them as an optional capability without coupling that distinction to the reusable agent package.

func InternalAccess

func InternalAccess(map[string]any) []permission.Access

InternalAccess describes a tool that only interacts with state already owned by the coding session, such as managed task state or loaded skill text.

func ResolvePreviewAsset

func ResolvePreviewAsset(root, path string) (string, string, error)

ResolvePreviewAsset validates one file requested by a workspace preview.

func ResolvePreviewDocument

func ResolvePreviewDocument(root, path string) (string, string, error)

ResolvePreviewDocument validates an HTML entry point and returns its canonical absolute path plus a workspace-relative URL path.

Types

type Answer

type Answer struct {
	Question string   `json:"question"`
	Values   []string `json:"values"`
}

Answer is the user's response to one Question. Values holds one entry for a single-select question and may hold several for a multi-select one; free text the user typed instead of picking an option arrives here unchanged.

type Asker

type Asker interface {
	Ask(context.Context, []Question) ([]Answer, error)
}

Asker puts questions to the user and blocks until they answer. Implementations must honor ctx cancellation, so aborting a run cannot leave a question waiting forever, and must not invent an answer the user did not give: a cancelled or abandoned question is an error, not an empty answer.

type BrowserControlCapability

type BrowserControlCapability string
const (
	BrowserControlRead     BrowserControlCapability = "read"
	BrowserControlNavigate BrowserControlCapability = "navigate"
	BrowserControlInteract BrowserControlCapability = "interact"
)

type BrowserControlledTab

type BrowserControlledTab struct {
	TabID        string                     `json:"tabID"`
	Capabilities []BrowserControlCapability `json:"capabilities"`
}

BrowserControlledTab describes temporary Agent attachment to an open tab. It intentionally does not record who originally created the tab.

type BrowserController

type BrowserController interface {
	OpenBrowser(context.Context, BrowserRequest) (BrowserResult, error)
}

BrowserController delivers a navigation command to the product shell and waits for its terminal acknowledgement.

type BrowserDisposition

type BrowserDisposition string

BrowserDisposition describes where a product shell should apply an agent navigation request. Reuse prefers the selected Agent-controlled tab and is the default; new tabs require an explicit user request surfaced by the model.

const (
	BrowserReuseAgentTab    BrowserDisposition = "reuse_agent_tab"
	BrowserNewForegroundTab BrowserDisposition = "new_foreground_tab"
	BrowserNewBackgroundTab BrowserDisposition = "new_background_tab"
)

type BrowserInspectionResult

type BrowserInspectionResult struct {
	ID          string
	Status      BrowserInspectionStatus
	URL         string
	Title       string
	PageStatus  BrowserPageStatus
	Revision    int
	VisibleText string
	Truncated   bool
	Error       string
}

BrowserInspectionResult is a bounded, read-only observation of one open tab in the requesting session. It intentionally contains no DOM, storage, cookies, form values, or executable page code.

type BrowserInspectionStatus

type BrowserInspectionStatus string
const (
	BrowserInspectionCompleted BrowserInspectionStatus = "completed"
	BrowserInspectionFailed    BrowserInspectionStatus = "failed"
	BrowserInspectionCancelled BrowserInspectionStatus = "cancelled"
	BrowserInspectionTimeout   BrowserInspectionStatus = "timeout"
)

type BrowserInspector

type BrowserInspector interface {
	InspectBrowser(context.Context, string) (BrowserInspectionResult, error)
}

type BrowserOpenTab

type BrowserOpenTab struct {
	TabID  string           `json:"tabID"`
	URL    string           `json:"url,omitempty"`
	Title  string           `json:"title,omitempty"`
	Status BrowserTabStatus `json:"status"`
}

BrowserOpenTab is bounded metadata for one tab in the requesting session's browser workspace. TabID is stable until that tab is closed.

type BrowserPageStatus

type BrowserPageStatus string
const (
	BrowserPageReady      BrowserPageStatus = "ready"
	BrowserPageNavigating BrowserPageStatus = "navigating"
	BrowserPageFailed     BrowserPageStatus = "failed"
)

type BrowserRequest

type BrowserRequest struct {
	Preview     PreviewRequest
	Disposition BrowserDisposition
}

BrowserRequest is the validated navigation intent handed to the product transport. It contains no Electron view or renderer state.

type BrowserResult

type BrowserResult struct {
	ID           string
	Status       BrowserResultStatus
	RequestedURL string
	CommittedURL string
	Title        string
	Error        string
	Preview      PreviewRequest
}

BrowserResult is the product shell's terminal acknowledgement. RequestedURL and CommittedURL remain separate so redirects are visible to the model.

type BrowserResultStatus

type BrowserResultStatus string

BrowserResultStatus is a terminal browser-command outcome. A controller must return exactly one terminal result for each accepted request.

const (
	BrowserCommitted BrowserResultStatus = "committed"
	BrowserFailed    BrowserResultStatus = "failed"
	BrowserCancelled BrowserResultStatus = "cancelled"
	BrowserTimeout   BrowserResultStatus = "timeout"
)

type BrowserTabStatus

type BrowserTabStatus string
const (
	BrowserTabIdle       BrowserTabStatus = "idle"
	BrowserTabNavigating BrowserTabStatus = "navigating"
	BrowserTabReady      BrowserTabStatus = "ready"
	BrowserTabFailed     BrowserTabStatus = "failed"
)

type BrowserTabsProvider

type BrowserTabsProvider interface {
	BrowserTabs(context.Context) (BrowserTabsResult, error)
}

type BrowserTabsResult

type BrowserTabsResult struct {
	ID             string
	Status         BrowserTabsStatus
	OpenTabs       []BrowserOpenTab
	ControlledTabs []BrowserControlledTab
	Selected       string
	Error          string
}

type BrowserTabsStatus

type BrowserTabsStatus string
const (
	BrowserTabsCompleted BrowserTabsStatus = "completed"
	BrowserTabsFailed    BrowserTabsStatus = "failed"
	BrowserTabsCancelled BrowserTabsStatus = "cancelled"
	BrowserTabsTimeout   BrowserTabsStatus = "timeout"
)

type ChangeKind

type ChangeKind string

ChangeKind reports whether a write created a new file or updated an existing one.

const (
	ChangeCreate ChangeKind = "create"
	ChangeUpdate ChangeKind = "update"
)

type ExecOps

type ExecOps interface {
	// Exec runs command in a shell within dir and returns its combined output.
	// A non-zero exit code is reported in ExecResult, not as an error; an error
	// is returned only when the command could not be started. Exec must honor ctx
	// cancellation (e.g. a timeout).
	Exec(ctx context.Context, command string, dir string) (ExecResult, error)
	// Start launches command in a shell within dir, writing its combined output
	// to out, and returns once the command is running. A background command
	// outlives the turn that started it, so it is bounded by its Process rather
	// than by a context.
	Start(command string, dir string, out io.Writer) (Process, error)
}

ExecOps abstracts shell command execution for the bash tool. Both the foreground and the background paths go through it, so a backend that sandboxes, containerizes, or forwards commands governs every command the session runs rather than only the ones the model waits on.

type ExecResult

type ExecResult struct {
	// Output is the combined stdout and stderr.
	Output string
	// ExitCode is the process exit status. Zero means success.
	ExitCode int
}

ExecResult is the outcome of one shell command.

type FileChange

type FileChange struct {
	// Path is the file path as the model supplied it (relative to the workspace
	// root when the input was relative), so it can be passed straight to read.
	Path string
	// Kind is create for a new file or update for an existing one.
	Kind ChangeKind
	// Additions and Deletions are the line counts of the change.
	Additions int
	Deletions int
	// Hunks is the diff. A newly created non-empty file is represented as a diff
	// from an empty file. Lines within a hunk are prefixed with " ", "+", or "-".
	Hunks []Hunk
	// Bytes is the size of the content written.
	Bytes int
}

FileChange is the structured result of a successful edit or write. It is the single source of truth: the tool's text Content is formatted from it, and UIs render it directly.

type FileOps

type FileOps interface {
	Open(ctx context.Context, path string) (io.ReadCloser, error)
	ReadFile(ctx context.Context, path string) ([]byte, error)
	// WriteFile replaces path without exposing a partially written destination
	// when the backend supports atomic replacement.
	WriteFile(ctx context.Context, path string, data []byte, perm os.FileMode) error
	MkdirAll(ctx context.Context, path string, perm os.FileMode) error
	Stat(ctx context.Context, path string) (os.FileInfo, error)
	ReadDir(ctx context.Context, path string) ([]os.DirEntry, error)
}

FileOps abstracts filesystem access for the file tools. Paths passed to it are already resolved to absolute form by the tool. Implementations must honor ctx cancellation where the underlying operation supports it.

type FileStateStore

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

FileStateStore tracks disk versions observed by one coding tool set. It is safe for concurrent reads while mutating tools execute sequentially.

func NewFileStateStore

func NewFileStateStore() *FileStateStore

func (*FileStateStore) Check

func (s *FileStateStore) Check(path string, info os.FileInfo) error

Check verifies that path was observed and still has the same disk version.

func (*FileStateStore) Delete

func (s *FileStateStore) Delete(path string)

Delete forgets path after an operation changed it but its new version could not be observed. The next mutation must Read it again.

func (*FileStateStore) Record

func (s *FileStateStore) Record(path string, info os.FileInfo)

Record marks path's current version as observed by the model or produced by a successful tool write.

type FileVersion

type FileVersion struct {
	ModTime time.Time
	Size    int64
}

FileVersion is the portable, inexpensive identity used for optimistic file concurrency checks. It deliberately avoids hashing the full file so a small range read of a large file remains a range read.

func (FileVersion) Equal

func (v FileVersion) Equal(other FileVersion) bool

type Hunk

type Hunk struct {
	OldStart int
	OldLines int
	NewStart int
	NewLines int
	// Lines carry a leading " ", "+", or "-" marking context, addition, or
	// deletion.
	Lines []string
}

Hunk is one contiguous region of a unified diff. Start lines are 1-based.

type LocalOps

type LocalOps struct{}

LocalOps runs against the local filesystem and a bash shell. It is the default backend and holds no state.

func (LocalOps) Exec

func (LocalOps) Exec(ctx context.Context, command string, dir string) (ExecResult, error)

Exec runs command with `bash -c` inside dir, returning combined output. A non-zero exit is returned in ExecResult with a nil error; only a failure to start the process is a Go error. ctx cancellation stops the command.

func (LocalOps) MkdirAll

func (LocalOps) MkdirAll(ctx context.Context, path string, perm os.FileMode) error

MkdirAll creates path and any missing parents.

func (LocalOps) Open

func (LocalOps) Open(ctx context.Context, path string) (io.ReadCloser, error)

Open opens path for streaming reads.

func (LocalOps) ReadDir

func (LocalOps) ReadDir(_ context.Context, path string) ([]os.DirEntry, error)

ReadDir lists the directory entries of path.

func (LocalOps) ReadFile

func (LocalOps) ReadFile(_ context.Context, path string) ([]byte, error)

ReadFile reads the file at path.

func (LocalOps) Start added in v0.6.2

func (LocalOps) Start(command string, dir string, out io.Writer) (Process, error)

Start launches command with `bash -c` inside dir and returns once it is running, with its combined output going to out. The command leads its own process group so the whole tree it spawns can be stopped later.

func (LocalOps) Stat

func (LocalOps) Stat(_ context.Context, path string) (os.FileInfo, error)

Stat returns file info for path.

func (LocalOps) WriteFile

func (LocalOps) WriteFile(ctx context.Context, path string, data []byte, perm os.FileMode) error

WriteFile writes through a same-directory temporary file and atomically renames it into place. Existing permissions and symlinks are preserved.

type MutationFailure

type MutationFailure struct {
	// Path is the file path the model supplied.
	Path string
	// Reason is a stable machine code for the failure class.
	Reason string
	// Detail is the human-facing explanation, matching the text summary.
	Detail string
}

MutationFailure is the structured result attached to a failed edit or write, so a shell can show why the write did not happen rather than only a text blob.

type Ops

type Ops interface {
	FileOps
	ExecOps
}

Ops is the full operation surface the built-in tools need. LocalOps satisfies it; a custom backend can compose its own value from a FileOps and an ExecOps.

type Option

type Option struct {
	Label string `json:"label" jsonschema:"description=Display text for this option. Keep it to a few words,minLength=1"`
	// Description explains what choosing this option means. It gives the user
	// the trade-off the model already knows but the label has no room for.
	Description string `json:"description" jsonschema:"description=What this option means or what happens if it is chosen. State the trade-off"`
}

Option is one selectable answer to a Question.

type PreviewRequest

type PreviewRequest struct {
	URL          string
	Path         string
	RelativePath string
	Title        string
	GrantID      string
	PreviewPath  string
}

PreviewRequest is the structured UI intent emitted by open_preview. Product shells act on it live, and ToolOutcome.Data retains it so a reopened conversation can offer the same preview again.

type Process added in v0.6.2

type Process interface {
	// Wait blocks until the command exits and reports its exit code. A command
	// that exits non-zero is not an error; a failure to wait on it is, and
	// reports exit code -1.
	Wait() (exitCode int, err error)
	// Stop asks the command to exit and returns without waiting for it.
	Stop() error
	// Kill terminates the command immediately.
	Kill() error
}

Process is one running background command. Implementations must terminate everything the command spawned, not just the shell that fronts it.

type Question

type Question struct {
	Question string `json:"question" jsonschema:"description=The complete question. Make it specific and end it with a question mark,minLength=1"`
	// Header labels the question in the product surface, where a full sentence
	// does not fit.
	Header      string   `` /* 134-byte string literal not displayed */
	Options     []Option `json:"options" jsonschema:"description=The available choices. Each must be distinct,minItems=2,maxItems=4"`
	MultiSelect bool     `` /* 151-byte string literal not displayed */
}

Question is one multiple-choice question put to the user. The same type is both the model-facing schema and the value handed to an Asker so the product shell renders exactly what the model asked.

type QuestionAnswers

type QuestionAnswers struct {
	Questions []Question `json:"questions"`
	Answers   []Answer   `json:"answers"`
}

QuestionAnswers is the structured result product shells render.

type ReadResult

type ReadResult struct {
	Path       string
	Content    string
	StartLine  int
	LineCount  int
	Limit      int
	HasMore    bool
	NextOffset int
}

ReadResult is the provider- and UI-independent result of a text range read. Content does not include line-number prefixes; those are added only when the result is serialized for the model.

type TaskInfo

type TaskInfo struct {
	ID          string
	Command     string
	Description string
	OutputPath  string
	StartedAt   time.Time
}

TaskInfo is returned immediately after a background task starts.

type TaskManager

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

TaskManager owns background processes and their output files for one coding session. Tasks run in separate process groups, survive across turns, and are stopped and removed when the session closes.

Commands are launched through the session's ExecOps, the same seam the foreground bash tool uses, so a backend cannot be bypassed by asking for a background task.

func NewTaskManager

func NewTaskManager(ops ExecOps) *TaskManager

NewTaskManager returns an empty session-scoped task manager that launches its commands through ops.

func (*TaskManager) Completed

func (m *TaskManager) Completed() []TaskState

Completed returns terminal task states in task creation order.

func (*TaskManager) OwnsOutputPath

func (m *TaskManager) OwnsOutputPath(path string) bool

OwnsOutputPath reports whether path is exactly one output file registered by this manager. It deliberately does not trust the containing directory.

func (*TaskManager) ReadOutput

func (m *TaskManager) ReadOutput(id string, maxBytes int64) (TaskOutput, error)

ReadOutput returns the latest bytes from a managed task's combined output.

func (*TaskManager) Shutdown

func (m *TaskManager) Shutdown()

Shutdown stops all running tasks and removes their managed output files.

func (*TaskManager) Snapshot

func (m *TaskManager) Snapshot() []TaskState

Snapshot returns every task's latest state in task creation order.

func (*TaskManager) Start

func (m *TaskManager) Start(command, description, dir string) (TaskInfo, error)

Start launches command in dir, redirects its combined output to a private managed file, and returns without waiting for the process to exit.

func (*TaskManager) Stop

func (m *TaskManager) Stop(id string) error

Stop terminates a running task's process group. It is a no-op for a task that has already finished.

func (*TaskManager) Subscribe

func (m *TaskManager) Subscribe(listener func(TaskState)) func()

Subscribe registers a lifecycle listener and returns its remover.

type TaskOutput

type TaskOutput struct {
	Content   string
	Truncated bool
}

TaskOutput is a bounded tail of one task's combined stdout and stderr.

type TaskState

type TaskState struct {
	TaskInfo
	Status      TaskStatus
	ExitCode    *int
	CompletedAt time.Time
}

TaskState is the latest state of one managed background task. CompletedAt is zero and ExitCode is nil while the task is running.

type TaskStatus

type TaskStatus string

TaskStatus is the lifecycle state of a background task.

const (
	TaskRunning   TaskStatus = "running"
	TaskSucceeded TaskStatus = "succeeded"
	TaskFailed    TaskStatus = "failed"
	TaskStopped   TaskStatus = "stopped"
)

type Tool

type Tool struct {
	agent.AgentTool

	// Guidelines are bullet points appended to the system prompt's guidelines
	// section while this tool is active. A tool's own description travels in its
	// schema; only rules that span tools belong here.
	Guidelines []string
	// AccessFor describes the effects of one validated call. A nil function is
	// treated as unknown access and therefore requires approval.
	AccessFor func(args map[string]any) []permission.Access
}

Tool is a coding-agent tool: the executable agent.AgentTool the model calls, plus the metadata the tool contributes to the system prompt. Keeping prompt contribution on the tool itself means the system prompt is assembled from whichever tools are active, rather than maintained as one central block.

func AskUserQuestion

func AskUserQuestion(asker Asker) Tool

AskUserQuestion returns the tool that puts a decision back to the user. It is only registered when a product surface can actually reach them; a session with nobody at the keyboard advertises no question tool rather than one that always fails.

func Bash

func Bash(root string, ops ExecOps, tasks *TaskManager) Tool

Bash returns a tool that runs a shell command in the workspace directory and returns its combined output and exit code. A non-zero exit is a failed tool outcome that still preserves output for the model and the exact exit code for runtimes. When tasks is non-nil, run_in_background starts a managed task and returns its id and output path instead of blocking.

func BrowserTabs

func BrowserTabs(providers ...BrowserTabsProvider) Tool

BrowserTabs returns a product tool that lists only the tabs belonging to the current coding session. It exposes metadata, not page content.

func BrowserTools

func BrowserTools(root string, browserControllers ...BrowserController) []Tool

BrowserTools returns the browser bridge tools. The tools are present even when the controller is nil; in that configuration they fail closed, preserving the default session contract while making the capability boundary explicit.

func Edit

func Edit(root string, ops FileOps, files *FileStateStore) Tool

Edit returns a tool that replaces an exact substring in a file. By default the match must be unique, so an ambiguous edit fails instead of changing the wrong place; set replace_all to change every occurrence. It runs sequentially with other tool calls so concurrent edits cannot corrupt a file.

func Glob

func Glob(root string, ops FileOps) Tool

Glob returns a tool that finds files by name pattern, skipping vendored directories, and returns paths sorted by most-recently-modified first.

func Grep

func Grep(root string, ops FileOps) Tool

Grep returns a tool that searches file contents across the workspace with a regular expression, skipping vendored directories. It returns matching file paths by default, or matching lines in content mode.

func InspectBrowser

func InspectBrowser(inspectors ...BrowserInspector) Tool

InspectBrowser returns a product tool that observes an explicit session-local tab or the selected controlled tab. The renderer may attach a request-scoped read lease to an explicit open tab and releases that lease after inspection.

func OpenPreview

func OpenPreview(root string, controllers ...BrowserController) Tool

OpenPreview returns a product tool that asks a connected Or client to display a web page or workspace HTML document. The tool does not claim success until the configured browser controller acknowledges the navigation.

func Read

func Read(root string, ops FileOps, files *FileStateStore, trustedPaths ...func(string) bool) Tool

Read returns a tool that reads a UTF-8 text file and returns its contents with 1-based line numbers, optionally windowed by offset and limit. Output is capped to keep a large file from filling the context window.

func TaskStop

func TaskStop(tasks *TaskManager) Tool

TaskStop returns a tool that stops a managed background task and its whole process group.

func Write

func Write(root string, ops FileOps, files *FileStateStore) Tool

Write returns a tool that writes a file in full, creating parent directories as needed and overwriting any existing file. It runs sequentially with other tool calls so concurrent writes cannot corrupt a file. Use Edit for targeted changes to an existing file.

func (Tool) Accesses

func (t Tool) Accesses(args map[string]any) []permission.Access

Accesses returns the declared effects of one validated call.

func (Tool) Name

func (t Tool) Name() string

Name returns the tool's advertised name.

Jump to

Keyboard shortcuts

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