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
- Variables
- func AgentTools(tools []Tool) []agent.AgentTool
- func CheckPreview(ctx context.Context, raw string) (string, error)
- func CoreToolsWithTasks(root string, ops Ops) ([]Tool, *TaskManager)
- func InternalAccess(map[string]any) []permission.Access
- func ResolvePreviewAsset(root, path string) (string, string, error)
- func ResolvePreviewDocument(root, path string) (string, string, error)
- type Answer
- type Asker
- type BrowserControlCapability
- type BrowserControlledTab
- type BrowserController
- type BrowserDisposition
- type BrowserInspectionResult
- type BrowserInspectionStatus
- type BrowserInspector
- type BrowserOpenTab
- type BrowserPageStatus
- type BrowserRequest
- type BrowserResult
- type BrowserResultStatus
- type BrowserTabStatus
- type BrowserTabsProvider
- type BrowserTabsResult
- type BrowserTabsStatus
- type ChangeKind
- type ExecOps
- type ExecResult
- type FileChange
- type FileOps
- type FileStateStore
- type FileVersion
- type Hunk
- type LocalOps
- func (LocalOps) Exec(ctx context.Context, command string, dir string) (ExecResult, error)
- func (LocalOps) MkdirAll(ctx context.Context, path string, perm os.FileMode) error
- func (LocalOps) Open(ctx context.Context, path string) (io.ReadCloser, error)
- func (LocalOps) ReadDir(_ context.Context, path string) ([]os.DirEntry, error)
- func (LocalOps) ReadFile(_ context.Context, path string) ([]byte, error)
- func (LocalOps) Stat(_ context.Context, path string) (os.FileInfo, error)
- func (LocalOps) WriteFile(ctx context.Context, path string, data []byte, perm os.FileMode) error
- type MutationFailure
- type Ops
- type Option
- type PreviewRequest
- type Question
- type QuestionAnswers
- type ReadResult
- type TaskInfo
- type TaskManager
- func (m *TaskManager) Completed() []TaskState
- func (m *TaskManager) OwnsOutputPath(path string) bool
- func (m *TaskManager) ReadOutput(id string, maxBytes int64) (TaskOutput, error)
- func (m *TaskManager) Shutdown()
- func (m *TaskManager) Snapshot() []TaskState
- func (m *TaskManager) Start(command, description, dir string) (TaskInfo, error)
- func (m *TaskManager) Stop(id string) error
- func (m *TaskManager) Subscribe(listener func(TaskState)) func()
- type TaskOutput
- type TaskState
- type TaskStatus
- type Tool
- func AskUserQuestion(asker Asker) Tool
- func Bash(root string, ops ExecOps, tasks *TaskManager) Tool
- func BrowserTabs(providers ...BrowserTabsProvider) Tool
- func BrowserTools(root string, browserControllers ...BrowserController) []Tool
- func Edit(root string, ops FileOps, files *FileStateStore) Tool
- func Glob(root string, ops FileOps) Tool
- func Grep(root string, ops FileOps) Tool
- func InspectBrowser(inspectors ...BrowserInspector) Tool
- func OpenPreview(root string, controllers ...BrowserController) Tool
- func Read(root string, ops FileOps, files *FileStateStore, ...) Tool
- func TaskStop(tasks *TaskManager) Tool
- func Write(root string, ops FileOps, files *FileStateStore) Tool
Constants ¶
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.
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.
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.
const DefaultBashTimeout = 120 * time.Second
DefaultBashTimeout bounds a single command when the model does not set one.
const MaxBrowserInspectionTextRunes = 12_000
const ToolNameAskUserQuestion = "ask_user_question"
ToolNameAskUserQuestion is the advertised name of the question tool.
Variables ¶
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") )
var ErrNoAsker = errors.New("no interactive surface is available to ask the user")
ErrNoAsker is returned when no product surface can reach the user.
var ErrTaskNotFound = errors.New("background task not found")
ErrTaskNotFound is returned when a task id is not owned by this manager.
Functions ¶
func AgentTools ¶
AgentTools extracts the executable agent.AgentTool from each Tool, for handing to the agent loop.
func CheckPreview ¶
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 ¶
ResolvePreviewAsset validates one file requested by a workspace preview.
Types ¶
type Answer ¶
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 ¶
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" 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" 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" 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)
}
ExecOps abstracts shell command execution for the bash tool.
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.
type FileVersion ¶
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 ¶
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.
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 ¶
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 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.
func NewTaskManager ¶
func NewTaskManager() *TaskManager
NewTaskManager returns an empty session-scoped task manager.
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 ¶
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 ¶
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 ¶
Glob returns a tool that finds files by name pattern, skipping vendored directories, and returns paths sorted by most-recently-modified first.
func Grep ¶
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 Coding 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 ¶
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.