Documentation
¶
Overview ¶
Package tools implements the agent's file and shell tools, sandboxed to a root directory.
Index ¶
- Constants
- Variables
- func ApplyPatch(root, input string) (string, error)
- func ApplyPatchPaths(input string) []string
- func ApplyPatchSpec() model.ToolSpec
- func ApplyWorkerSpec() model.ToolSpec
- func AskUserSpec() model.ToolSpec
- func Bash(ctx context.Context, root, command string, timeout time.Duration) (string, error)
- func BashStream(ctx context.Context, root, command string, timeout time.Duration, ...) (string, error)
- func ContainerRunNetwork(runArgs []string) string
- func DelegateSpec() model.ToolSpec
- func EditFile(root, path, oldStr, newStr string, replaceAll bool) (int, error)
- func ExtraDirsNotice(dirs []ExtraDir) string
- func Grep(root, pattern, path, include string, ignoreCase, fixedStrings bool) (string, error)
- func GrepWithContext(root, pattern, path, include string, ignoreCase, fixedStrings bool, ...) (string, error)
- func LSPSpec() model.ToolSpec
- func ListFiles(root, path, pattern string) (string, error)
- func LoadImageFile(path string, maxBytes int) (model.Image, error)
- func MemoryListSpec() model.ToolSpec
- func MemorySearchSpec() model.ToolSpec
- func ParseAskUser(arguments string) (question string, options []string, reason string)
- func PlanSpec() model.ToolSpec
- func ReadFile(root, path string, offset, limit int) (string, error)
- func Redacts(name string) bool
- func RememberSpec() model.ToolSpec
- func RememberSpecFor(max int) model.ToolSpec
- func ReservedToolNames() []string
- func Resolve(root, path string) (string, error)
- func ResolveOutputDir(root, dir string) (string, error)
- func RunSandboxHelper(args []string) int
- func SetProcessGroup(cmd *exec.Cmd)
- func SniffImage(data []byte) string
- func Specs(readOnly ...bool) []model.ToolSpec
- func StripExtraDirsNotice(system string) string
- func Truncate(s string, max int) string
- func TruncateWithNotice(body, notice string, max int) (string, bool)
- func UntrustedHistoryCall(name string, externalTools []string) bool
- func ValidDirMode(m string) bool
- func ValidateAccessPattern(p string) error
- func ViewImage(root, path string, maxBytes int) (string, *model.Image, error)
- func ViewImageSpec() model.ToolSpec
- func WebFetchSpec() model.ToolSpec
- func WorkerSpec() model.ToolSpec
- func WriteFile(root, path, content string) error
- type AccessPattern
- type CommandEnv
- type CommandTool
- type Container
- func (c *Container) Close() error
- func (c *Container) Command(ctx context.Context, root, command string) *exec.Cmd
- func (c *Container) Describe() string
- func (c *Container) Exec(ctx context.Context, root string, argv []string) *exec.Cmd
- func (c *Container) LockdownNetworkPrepared() bool
- func (c *Container) LockdownProxyErr() error
- func (c *Container) LockdownProxyNetwork() string
- func (c *Container) PrepareLockdownNetwork(ctx context.Context) (denied bool, err error)
- func (c *Container) PrepareLockdownProxy(ctx context.Context, allowed []string) error
- func (c *Container) RemoveLockdownNetwork(ctx context.Context) error
- func (c *Container) TakeNetworkDenials() []sandboxnet.Denial
- type ContainerNetworkCheck
- type DeniedError
- type Environment
- type Executor
- func (e *Executor) Catalog() []model.ToolSpec
- func (e *Executor) Close() string
- func (e *Executor) CommandToolArgv(name, raw string) []string
- func (e *Executor) FormatCorrection(reason string) string
- func (e *Executor) FormatError(call model.ToolCall) string
- func (e *Executor) LimitResult(call model.ToolCall, out string, isErr bool) Result
- func (e *Executor) Permits(name string) bool
- func (e *Executor) Processes() []RegisteredProcess
- func (e *Executor) ReadProcess(ctx context.Context, id string, waitMs, tail int) (string, error)
- func (e *Executor) Run(ctx context.Context, call model.ToolCall) string
- func (e *Executor) RunResult(ctx context.Context, call model.ToolCall) Result
- func (e *Executor) RunWithError(ctx context.Context, call model.ToolCall) (string, bool)
- func (e *Executor) RunWithImages(ctx context.Context, call model.ToolCall) (string, []model.Image, bool)
- func (e *Executor) StartProcess(command string) (string, error)
- func (e *Executor) StopProcess(id string, tail int) (string, error)
- func (e *Executor) UntrustedSource(name string) string
- type ExtraDir
- type FileAccess
- func (f *FileAccess) AddDirs(dirs []ExtraDir)
- func (f *FileAccess) CheckRead(full, name string) error
- func (f *FileAccess) CheckWrite(full, name string) error
- func (f *FileAccess) Counts() (read, write int)
- func (f *FileAccess) Hidden(full string) bool
- func (f *FileAccess) Rules() (read, write []string)
- type LSP
- type Local
- type OutputFiles
- type ReadDirError
- type RegisteredProcess
- type Result
- type Sandbox
- func (s *Sandbox) Cleanup()
- func (s *Sandbox) Command(ctx context.Context, argv []string) *exec.Cmd
- func (s *Sandbox) Describe() string
- func (s *Sandbox) DirectUntilTaint() bool
- func (s *Sandbox) LockdownConfinable() bool
- func (s *Sandbox) NarrowNetwork(allowed []string) error
- func (s *Sandbox) NetworkMode() string
- func (s *Sandbox) PrepareLockdownNetwork(allowed []string) error
- func (s *Sandbox) Proxied() bool
- func (s *Sandbox) TakeNetworkDenials() []sandboxnet.Denial
- type WebFetchRecord
- type WebFetcher
Constants ¶
const ( MaxAskUserQuestion = 2000 MaxAskUserOption = 200 MinAskUserOptions = 2 MaxAskUserOptions = 6 )
ask_user argument limits, in characters.
const ( DirRead = "read" DirWrite = "write" )
Additional directory modes.
const ( MemorySearchToolName = "memory_search" MemoryListToolName = "memory_list" )
Read-only project memory tools, offered with remember (MemoryTools).
const ( // DefaultMaxProcesses bounds concurrent background processes when // Executor.MaxProcesses is 0. DefaultMaxProcesses = 4 // DefaultProcessBufferBytes caps each background process's retained // output when Executor.ProcessBufferBytes is 0. DefaultProcessBufferBytes = 1 << 20 )
const ( UntrustedWebFetch = "web_fetch" UntrustedMCP = "mcp" )
Untrusted-content sources a tool result can come from. Project memory (#170) and the untrusted-content lockdown (#171) share this one definition, so a result that keeps memory writes pending is exactly a result that can taint a locked-down run. The names match the untrusted_content.sources values lockdown.SourceWebFetch and lockdown.SourceMCP.
const ( DefaultWebFetchMaxBytes = 2 << 20 // 2 MiB DefaultWebFetchTimeoutSeconds = 20 MaxWebFetchTimeoutSeconds = 120 // MaxWebFetchRedirects is how many redirects one fetch follows. MaxWebFetchRedirects = 5 )
Web fetch limits and defaults.
const ( WebFetchDeniedScheme = "only http and https URLs are allowed" WebFetchDeniedCredentials = "URLs with credentials are not allowed" WebFetchDeniedHost = "host not in web_fetch.allowed_domains" WebFetchDeniedNonPublic = "host resolves to a loopback, link-local or private address" WebFetchDeniedRedirects = "too many redirects" )
Web fetch denial reasons, recorded as denied_reason.
const ( WorkerToolName = "worker" ApplyWorkerToolName = "apply_worker" )
WorkerToolName runs an implementation subtask in a child agent confined to its own Git worktree; ApplyWorkerToolName applies a worker's commit to the working tree. The agent loop runs both; the executor never does.
const ApplyPatchToolName = "apply_patch"
ApplyPatchToolName is the opt-in multi-file patch tool.
const AskUserToolName = "ask_user"
AskUserToolName is the opt-in tool that ends a run with one question for the user. The agent loop handles its calls; the executor never runs them.
const ContainerLabel = "tinyagent"
ContainerLabel marks containers started by tinyagent.
const DefaultMaxImageBytes = 5 << 20
DefaultMaxImageBytes caps one image's raw size when max_image_bytes is unset.
const DefaultToolOutputDir = ".tinyagent/tool-output"
DefaultToolOutputDir is where saved tool output goes, relative to --cwd.
const DelegateToolName = "delegate"
DelegateToolName is the opt-in tool that hands a task to a read-only subagent with a fresh context.
const LSPToolName = "lsp"
LSPToolName is the opt-in read-only language-server tool.
const MaxExtraDirs = 10
MaxExtraDirs caps the number of additional directories one run may use.
const MaxLSPLocations = 100
MaxLSPLocations caps the locations one lsp call lists.
const MaxPatchBytes = 1 << 20
MaxPatchBytes caps one apply_patch input.
const PlanToolName = "update_plan"
PlanToolName is the opt-in plan tool.
const RememberToolName = "remember"
RememberToolName is the opt-in project memory tool (memory.enabled). It saves short notes about the project for later runs; writes never change the current run's prompt.
const SandboxHelperArg = "__sandbox_exec"
SandboxHelperArg is argv[1] of the re-executed tinyagent that applies the Linux sandbox and then execs the command. It is not a user-facing flag.
const UndoDir = ".tinyagent/undo"
UndoDir is where per-session file snapshots live, relative to the working directory. Its contents are local state and must never be committed.
const UndoToolName = "undo_file"
UndoToolName is the built-in tool that restores a file's session snapshot.
const ViewImageToolName = "view_image"
ViewImageToolName is the opt-in image tool (--images).
const WebFetchDeniedLockdown = "host not in untrusted_content.lockdown.web_fetch_allowed_domains after taint"
WebFetchDeniedLockdown is the denied_reason of a hop the untrusted-content lockdown Gate refused.
const WebFetchToolName = "web_fetch"
WebFetchToolName is the opt-in web_fetch tool.
Variables ¶
var CoreEnv = []string{"PATH", "HOME", "USER", "LOGNAME", "SHELL", "LANG", "LC_*", "TERM", "TZ", "TMPDIR"}
CoreEnv is the allowlist command_env inherit: core keeps. LC_* is a glob.
var ProviderEnv = []string{"OPENAI_API_KEY", "ANTHROPIC_API_KEY", "OPENROUTER_API_KEY"}
ProviderEnv are tinyagent's own provider credentials, always withheld by exclude_secrets.
Functions ¶
func ApplyPatch ¶ added in v0.5.0
ApplyPatch parses input, checks every operation before writing anything, then applies the operations in order. A write failure after the check stops the run and reports which operations were applied; those are not rolled back.
func ApplyPatchPaths ¶ added in v0.8.0
ApplyPatchPaths returns the paths (and move destinations) named in an apply_patch input, in patch order, without applying it. A malformed patch yields nil. It is used by the permissions policy to match path rules against an apply_patch call's files.
func ApplyPatchSpec ¶ added in v0.5.0
ApplyPatchSpec returns the apply_patch definition.
func ApplyWorkerSpec ¶ added in v0.8.0
ApplyWorkerSpec describes the apply_worker tool.
func AskUserSpec ¶ added in v0.5.0
AskUserSpec describes the ask_user tool.
func Bash ¶
Bash runs command in a fresh `bash -c` process in root. On timeout the whole process group is killed so background children do not linger.
func BashStream ¶ added in v0.4.0
func BashStream(ctx context.Context, root, command string, timeout time.Duration, live io.Writer) (string, error)
BashStream is Bash that also copies output to live, if non-nil, as it is produced. The returned result is the same as Bash's.
func ContainerRunNetwork ¶ added in v0.9.0
ContainerRunNetwork returns the network mode container run arguments set with --network or --net (the last one wins), or "" when they set none.
func DelegateSpec ¶ added in v0.5.0
DelegateSpec describes the delegate tool.
func EditFile ¶
EditFile replaces the single occurrence of oldStr with newStr, or every occurrence if replaceAll is set, and returns the number of replacements.
func ExtraDirsNotice ¶ added in v0.5.0
ExtraDirsNotice is the system prompt section that tells the model which additional directories it may use, or "" when there are none.
func Grep ¶
Grep returns lines matching pattern as "file:line: content". Binary and very large files are skipped. A non-empty include glob limits the search to matching files, using the same rules as ListFiles: a glob without "/" matches base names, a glob with "/" matches paths relative to the searched directory. When path is a single file, include is ignored. ignoreCase enables case-insensitive matching of file contents only. fixedStrings treats pattern as literal text instead of a Go regular expression.
func GrepWithContext ¶ added in v0.4.0
func GrepWithContext(root, pattern, path, include string, ignoreCase, fixedStrings bool, contextLines int) (string, error)
GrepWithContext returns matches with up to contextLines surrounding lines.
func ListFiles ¶
ListFiles lists the entries of a directory, or, with a pattern, walks it recursively and returns matching files. A pattern without "/" matches base names; a pattern with "/" matches paths relative to the listed directory.
func LoadImageFile ¶ added in v0.5.0
LoadImageFile reads a user-chosen image file (an --image attachment). The path is not sandboxed. The type is sniffed from content, and the image's Label is the file's base name, so no absolute path reaches the model.
func MemoryListSpec ¶ added in v0.9.0
MemoryListSpec describes memory_list.
func MemorySearchSpec ¶ added in v0.9.0
MemorySearchSpec describes memory_search.
func ParseAskUser ¶ added in v0.5.0
ParseAskUser validates ask_user arguments. It returns the trimmed question and options, or the reason they are malformed.
func ReadFile ¶
ReadFile returns a file's contents. A positive offset (1-based start line) or limit (max lines) returns just that range, ending in a "[lines A-B of N]" note when the range isn't the whole file.
func Redacts ¶ added in v0.5.0
Redacts reports whether redact_secrets masks name's results: every tool (bash, the process tools, web_fetch, MCP tools) except the built-in file tools.
func RememberSpec ¶ added in v0.9.0
RememberSpec describes the remember tool with the default entry size.
func RememberSpecFor ¶ added in v0.9.0
RememberSpecFor describes the remember tool for entries of at most max characters (memory.toml max_entry_size).
func ReservedToolNames ¶ added in v0.5.0
func ReservedToolNames() []string
ReservedToolNames are the built-in tool names, including opt-in ones, that a command tool may not use.
func Resolve ¶
Resolve maps a path relative to root (or absolute inside root) to an absolute path, rejecting anything that escapes root. The check is lexical; symlinks inside root that point outside it are followed.
func ResolveOutputDir ¶ added in v0.5.0
ResolveOutputDir checks that dir (relative to root, or absolute) is a directory strictly inside root and returns its absolute path. An empty dir means DefaultToolOutputDir.
func RunSandboxHelper ¶ added in v0.5.0
RunSandboxHelper applies the Landlock policy in args (see wrap) to the current thread and execs the command. It only returns on failure. The helper modes are net-allow, net-deny and net-port=<port> (connect only to that port); net-proxy=<port>:<socket> (see runProxied); and net-probe.
func SetProcessGroup ¶ added in v0.5.0
SetProcessGroup makes cancelling cmd kill its whole process group, as for bash. On Windows only the process itself is killed.
func SniffImage ¶ added in v0.5.0
SniffImage returns the MIME type of an accepted image format, decided by content rather than file extension, or "" for anything else.
func StripExtraDirsNotice ¶ added in v0.5.0
StripExtraDirsNotice removes an ExtraDirsNotice section from a system prompt, so a prompt can be compared regardless of which directories it listed.
func Truncate ¶ added in v0.5.0
Truncate caps s at max characters, keeping its head and tail; 0 means unlimited. It is the same cap applied to tool output.
func TruncateWithNotice ¶ added in v0.5.0
TruncateWithNotice cuts body so body, a newline, and notice together fit in max bytes, keeping notice whole at the end. It returns ok false when notice itself does not fit; callers then fall back to Truncate.
func UntrustedHistoryCall ¶ added in v0.9.0
UntrustedHistoryCall reports whether a recorded call to the tool name brought untrusted content into a checkpoint's history: a web_fetch call, or a call to one of the checkpoint's external tools. It is the UntrustedSource rule for a run that only exists as a trajectory.
func ValidDirMode ¶ added in v0.5.0
ValidDirMode reports whether m is a supported additional directory mode.
func ValidateAccessPattern ¶ added in v0.5.0
ValidateAccessPattern reports whether p is a supported file_access pattern: non-empty, no "!" negation, and valid glob syntax.
func ViewImage ¶ added in v0.5.0
ViewImage reads an image under root. The text names the path, MIME type, and size, followed by the image's placeholder.
func ViewImageSpec ¶ added in v0.5.0
ViewImageSpec returns the view_image definition.
func WebFetchSpec ¶ added in v0.5.0
WebFetchSpec returns the web_fetch definition.
func WorkerSpec ¶ added in v0.8.0
WorkerSpec describes the worker tool.
Types ¶
type AccessPattern ¶ added in v0.8.0
type AccessPattern struct {
// contains filtered or unexported fields
}
AccessPattern is a compiled gitignore-style pattern, in the same syntax as file_access, for matching one slash-separated relative path. It is used by the permissions policy's path matcher.
func CompileAccessPattern ¶ added in v0.8.0
func CompileAccessPattern(p string) (*AccessPattern, error)
CompileAccessPattern compiles one gitignore-style pattern for matching a relative path (slash-separated, relative to the working directory).
func (*AccessPattern) Match ¶ added in v0.8.0
func (a *AccessPattern) Match(relPath string) bool
Match reports whether relPath matches the pattern. relPath is relative to the working directory, slash-separated; the final segment is treated as a file (not a directory), so directory-only patterns (a trailing "/") do not match it.
type CommandEnv ¶ added in v0.5.0
type CommandEnv struct {
Inherit string // all, core or none
ExcludeSecrets bool
Vars []string // KEY=VALUE entries given to every command
Passed []string // sorted names in Vars
Withheld []string // sorted names in tinyagent's environment not in Vars
Missing []string // pass entries that matched nothing
}
CommandEnv is the environment computed once per run from a command_env policy. Only names are meant to be shown; Vars holds the values.
func NewCommandEnv ¶ added in v0.5.0
func NewCommandEnv(p config.CommandEnv, environ []string) *CommandEnv
NewCommandEnv applies p to environ (typically os.Environ()): the inherit base, then exclude_secrets, exclude, pass and set, in that order.
func (*CommandEnv) Describe ¶ added in v0.5.0
func (c *CommandEnv) Describe() string
Describe is the one-line summary printed at startup. It names no values.
type CommandTool ¶ added in v0.5.0
type CommandTool struct {
Name string
Description string
Schema *outschema.Schema
Argv []string // template; placeholders are whole elements
Timeout time.Duration
Dir string // absolute working directory inside Root
}
CommandTool is a checked command_tools entry: a model-callable tool that runs a fixed argv, filled in with schema-checked arguments, without a shell, in the run's environment.
func NewCommandTools ¶ added in v0.5.0
func NewCommandTools(defs []config.CommandTool, root string, bashTimeoutSec int) ([]*CommandTool, error)
NewCommandTools checks the command_tools definitions for a run rooted at root; bashTimeoutSec is the default timeout. Errors name the tool and key.
func (*CommandTool) Expand ¶ added in v0.5.0
func (c *CommandTool) Expand(raw string) ([]string, []string)
Expand checks raw arguments against the schema and returns the argv to run, or the validation problems.
func (*CommandTool) Spec ¶ added in v0.5.0
func (c *CommandTool) Spec() model.ToolSpec
Spec is the tool definition offered to the model.
type Container ¶ added in v0.5.0
type Container struct {
Runtime string // docker or podman
Image string
ID string
Mount string // host directory mounted at the same path
// Extra are additional directories mounted at the same paths; read
// mode ones are mounted read-only.
Extra []ExtraDir
// contains filtered or unexported fields
}
Container runs commands with `<runtime> exec` in one container per run, with the workspace bind-mounted at the same path.
func StartContainer ¶ added in v0.5.0
func StartContainer(ctx context.Context, rt, image string, runArgs []string, root string, extra []ExtraDir) (*Container, error)
StartContainer checks that runtime is usable and starts a container from image with root mounted at the same path, plus each additional directory in extra at its own path (read-only for read mode). It fails rather than falling back to the host. runArgs are extra `run` arguments, after the defaults.
func (*Container) Close ¶ added in v0.5.0
Close stops and removes the container. It is safe on a nil Container.
func (*Container) Exec ¶ added in v0.5.0
Exec runs argv in the container without a shell; the container's PATH finds argv[0].
func (*Container) LockdownNetworkPrepared ¶ added in v0.9.0
LockdownNetworkPrepared reports whether PrepareLockdownNetwork readied the container's network switch.
func (*Container) LockdownProxyErr ¶ added in v0.9.0
LockdownProxyErr returns why the container could not join the lockdown proxy's network at taint (it then has no network), nil otherwise.
func (*Container) LockdownProxyNetwork ¶ added in v0.9.0
LockdownProxyNetwork returns the internal network the container joins at taint, "" without a lockdown proxy.
func (*Container) PrepareLockdownNetwork ¶ added in v0.9.0
PrepareLockdownNetwork readies the container so the first taint can take its network away with RemoveLockdownNetwork. denied is true when the container already has no network (--network none in run_args), so there is nothing to remove. It fails when the network can't be removed by disconnecting runtime networks: host networking, another container's or a namespace's network, rootless slirp4netns or pasta networking.
func (*Container) PrepareLockdownProxy ¶ added in v0.9.0
PrepareLockdownProxy readies the opt-in container lockdown proxy: it creates an --internal runtime network, starts a proxy limited to allowed (untrusted_content.lockdown.allowed_domains) on that network's gateway address, and arranges for RemoveLockdownNetwork to connect the container to the network after disconnecting it, so later commands reach only those hosts, through HTTP_PROXY and friends. Call it after PrepareLockdownNetwork found a network to remove. On any error it cleans up and leaves the network switch as it was: commands then have no network after taint.
func (*Container) RemoveLockdownNetwork ¶ added in v0.9.0
RemoveLockdownNetwork disconnects the container from every network PrepareLockdownNetwork found, for the rest of the run, and checks that none is left. Processes already running in the container lose their network too. Commands started while it runs wait for it; if it fails, every later command fails instead of running with network. It runs once; later calls return the first result.
func (*Container) TakeNetworkDenials ¶ added in v0.9.0
func (c *Container) TakeNetworkDenials() []sandboxnet.Denial
TakeNetworkDenials returns the requests the container lockdown proxy refused since the last call.
type ContainerNetworkCheck ¶ added in v0.9.0
type ContainerNetworkCheck struct {
// Mode is the network mode the container would start with: the
// --network (or --net) value in container.run_args, or the runtime's
// default ("bridge", or podman's rootless default).
Mode string
// FromRunArgs is true when container.run_args set Mode.
FromRunArgs bool
// Denied: the container would have no network at all (--network none).
Denied bool
// Err is set when Mode can't be removed by disconnecting runtime
// networks, so a run would refuse commands after taint.
Err error
// Unknown explains why the mode couldn't be predicted (the runtime
// couldn't be asked). A run inspects the started container and decides
// then.
Unknown string
}
ContainerNetworkCheck is what --check predicts lockdown (#171) will do with the container's network at taint, without starting a container.
func CheckContainerLockdownNetwork ¶ added in v0.9.0
func CheckContainerLockdownNetwork(ctx context.Context, runtime string, runArgs []string) ContainerNetworkCheck
CheckContainerLockdownNetwork predicts, for --check, how lockdown will handle the network of a container started by runtime (docker when empty) with runArgs. It reads --network from runArgs; without one, docker's default is a bridge network, and for podman it asks `podman info` whether podman runs rootless, whose default (slirp4netns or pasta) can't be disconnected. It never starts a container.
type DeniedError ¶ added in v0.5.0
type DeniedError struct {
Path string // the path as the caller named it
List string // "deny_read" or "deny_write"
Pattern string // the rule that matched, as configured
}
DeniedError is returned for a call that touches a denied path.
func (*DeniedError) Error ¶ added in v0.5.0
func (e *DeniedError) Error() string
type Environment ¶ added in v0.5.0
type Environment interface {
// Command returns an unstarted `bash -c command` that runs in root.
// Cancelling ctx must kill the command and everything it spawned.
Command(ctx context.Context, root, command string) *exec.Cmd
// Exec returns an unstarted command that runs argv directly, without a
// shell, in root. argv[0] is looked up on the environment's PATH.
// Cancelling ctx must kill the command and everything it spawned.
Exec(ctx context.Context, root string, argv []string) *exec.Cmd
}
Environment decides where bash and start_process commands run.
type Executor ¶
type Executor struct {
Root string // absolute working directory
ReadOnly bool // permits only read_file, list_files, and grep
BashTimeout time.Duration
MaxOutputChars int // 0 = unlimited
// MaxProcesses bounds concurrently running background processes
// (0 = DefaultMaxProcesses).
MaxProcesses int
// ProcessBufferBytes caps the output kept per background process
// (0 = DefaultProcessBufferBytes); older output is dropped.
ProcessBufferBytes int
// Env decides where bash and start_process commands run. nil means
// Local{}: on the host, unsandboxed.
Env Environment
// Stream receives bash output as it is produced when a call sets
// stream: true. nil discards it (the result is unchanged either way).
Stream io.Writer
// CommandTools are the configured command_tools (never offered or run
// in read-only mode). CommandLog, when set, gets one line per call
// with the final argv.
CommandTools []*CommandTool
CommandLog io.Writer
ExternalSpecs []model.ToolSpec
// ExternalCall runs a tool from ExternalSpecs. ok is false when name is
// not an external tool; isErr marks a failed call.
ExternalCall func(ctx context.Context, name, args string) (out string, isErr, ok bool)
// Plan offers the opt-in update_plan tool (also in read-only mode). The
// agent handles its calls; the executor only advertises it.
Plan bool
// Images offers the opt-in view_image tool (also in read-only mode) and
// lets ExternalCallImages pass MCP images through. MaxImageBytes caps
// one image (0 = DefaultMaxImageBytes).
Images bool
MaxImageBytes int
// ExternalCallImages, when set and Images is on, replaces ExternalCall
// and also returns the result's images.
ExternalCallImages func(ctx context.Context, name, args string) (out string, images []model.Image, isErr, ok bool)
// Skills, when it holds at least one skill, adds the read-only skill
// tool (also in read-only mode). nil or empty offers nothing.
Skills *skills.Set
// ApplyPatch offers the opt-in apply_patch tool (never in read-only
// mode).
ApplyPatch bool
// Delegate offers the opt-in delegate tool (also in read-only mode).
// The agent loop runs its calls; the executor never does.
Delegate bool
// WebFetch, when set, offers the opt-in web_fetch tool (also in
// read-only mode). nil leaves it off.
WebFetch *WebFetcher
// LSP, when set, offers the opt-in read-only lsp tool (also in
// read-only mode) and, with AfterEdit, appends language-server
// diagnostics to write_file, edit_file and apply_patch results. nil
// leaves both off.
LSP *LSP
// AskUser offers the opt-in ask_user tool (also in read-only mode).
// The agent loop handles its calls; the executor never runs them.
AskUser bool
// OutputFiles, when set, saves the full text of over-limit results to a
// per-run file and keeps that directory out of grep and list_files
// walks. nil keeps plain truncation.
OutputFiles *OutputFiles
// FileAccess denies the built-in file tools access to configured paths
// (file_access config). nil denies nothing. It does not apply to bash,
// start_process, hooks or MCP servers.
FileAccess *FileAccess
// ExtraDirs are additional directories outside Root that the built-in
// file tools may reach by absolute path (additional_dirs). Read-mode
// directories, and all of them in read-only mode, refuse writes. nil
// keeps the tools inside Root.
ExtraDirs []ExtraDir
// Redactor, when set (redact_secrets), masks known secret values in
// the results of every tool except the built-in file tools, before
// truncation, saving and hooks. nil masks nothing.
Redactor *eventlog.Redactor
// Workers offers the opt-in worker and apply_worker tools (never in
// read-only mode). The agent loop runs their calls; the executor never
// does.
Workers bool
// Only, when set, restricts the catalog and dispatch to these tool
// names (a worker's configured tools). nil allows the whole catalog.
Only []string
// Remember, when set, offers the opt-in remember tool (never in
// read-only mode) and writes through it to the project memory store
// (memory.enabled). Once a web_fetch or external (MCP) tool runs, its
// later writes are saved pending as untrusted. nil leaves it off.
Remember *memory.Writer
// MemoryTools offers the read-only memory_search and memory_list tools
// next to remember (never in read-only mode); they read Remember's
// store.
MemoryTools bool
// UndoSession names this run's undo snapshot directory under
// .tinyagent/undo. Empty generates one on first use.
UndoSession string
// contains filtered or unexported fields
}
Executor runs tool calls against files under Root.
func (*Executor) Catalog ¶ added in v0.4.0
Catalog returns the fixed built-in, command and explicitly configured external tools. In read-only mode it returns only the read-only built-ins: command and external MCP tools must never be offered (or dispatched, see Run) when only read_file, list_files, and grep are available.
func (*Executor) Close ¶ added in v0.4.0
Close kills every background process still registered and returns a summary of each (status and output tail), or "" if there were none. Call it when the run ends so nothing is left running.
func (*Executor) CommandToolArgv ¶ added in v0.8.0
CommandToolArgv returns the resolved argv for a call to the command tool named name, or nil when name is not a command tool (or its arguments are invalid). It is used by the permissions policy to match command rules against a command tool's final argv without running it.
func (*Executor) FormatCorrection ¶ added in v0.5.0
FormatCorrection is the tool result sent to the model for a format error.
func (*Executor) FormatError ¶ added in v0.5.0
FormatError reports why call is not a usable tool call, or "" when it is well formed. A format error is a call whose arguments are not valid JSON or not a JSON object, whose name is not in the catalog, or whose arguments miss a required field or give a field the wrong JSON type. Failures that happen while a well-formed call runs are not format errors.
In read-only mode a built-in tool outside the read-only set is not a format error: it keeps its read-only denial.
func (*Executor) LimitResult ¶ added in v0.5.0
LimitResult bounds out like any other tool result: truncated to MaxOutputChars, or saved to a per-run file when OutputFiles is set.
func (*Executor) Permits ¶ added in v0.5.0
Permits reports whether a call to name would be dispatched: name is in the catalog, which in read-only mode holds only the read-only built-ins.
func (*Executor) Processes ¶ added in v0.5.0
func (e *Executor) Processes() []RegisteredProcess
Processes lists the registered background processes in start order.
func (*Executor) ReadProcess ¶ added in v0.4.0
ReadProcess returns output produced since the last read. With waitMs > 0 it blocks up to that long for new output; with tail > 0 it returns only the last tail lines.
func (*Executor) Run ¶
Run executes one tool call and returns text for the model. Tool failures are reported as text so the model can recover; Run never returns an error.
func (*Executor) RunResult ¶ added in v0.5.0
RunResult is RunWithImages plus where an over-limit result was saved.
func (*Executor) RunWithError ¶ added in v0.4.0
RunWithError executes a tool call and reports whether execution failed. The returned text is still suitable for passing back to the model.
func (*Executor) RunWithImages ¶ added in v0.5.0
func (e *Executor) RunWithImages(ctx context.Context, call model.ToolCall) (string, []model.Image, bool)
RunWithImages is RunWithError plus any images the result carries (only with Images on). The text already holds a placeholder for each image.
func (*Executor) StartProcess ¶ added in v0.4.0
StartProcess launches command with bash -c (in e.Env) in the background and returns its id with any output produced in the first moment.
func (*Executor) StopProcess ¶ added in v0.4.0
StopProcess kills id's whole process group and reports its exit status and unread output (the last tail lines when tail > 0).
func (*Executor) UntrustedSource ¶ added in v0.9.0
UntrustedSource reports which untrusted source a result of the tool name brings into context: UntrustedWebFetch for web_fetch when it is enabled, UntrustedMCP for an external (MCP) tool, and "" for every other tool. It decides by tool, never by content.
type ExtraDir ¶ added in v0.5.0
ExtraDir is a directory outside the root that the built-in file tools may reach (additional_dirs config, --add-dir-read and --add-dir-write). Path is absolute, clean and symlink-resolved; Mode is DirRead or DirWrite.
func ResolveExtraDirs ¶ added in v0.5.0
ResolveExtraDirs validates dirs for a run rooted at root (canonical) and returns them with each path made absolute (relative paths are taken from root), cleaned and symlink-resolved. It rejects missing paths, files, filesystem roots, paths equal to, inside or containing root, entries that overlap one another, invalid modes and more than MaxExtraDirs entries. With readOnly, every directory is returned in read mode.
type FileAccess ¶ added in v0.5.0
type FileAccess struct {
// contains filtered or unexported fields
}
FileAccess is the compiled file_access policy for the built-in file tools: gitignore-style deny_read and deny_write patterns relative to Root. A nil *FileAccess denies nothing. deny_read paths are also write-denied.
It covers only tinyagent's in-process file tools (read_file, write_file, edit_file, apply_patch, list_files, grep, view_image). bash, start_process, hooks and MCP servers are not affected.
func NewFileAccess ¶ added in v0.5.0
func NewFileAccess(root string, denyRead, denyWrite []string) (*FileAccess, error)
NewFileAccess compiles the patterns for root. It returns nil, and no error, when both lists are empty.
func (*FileAccess) AddDirs ¶ added in v0.5.0
func (f *FileAccess) AddDirs(dirs []ExtraDir)
AddDirs makes the rules also apply inside each additional directory, relative to that directory. It is a no-op on a nil *FileAccess.
func (*FileAccess) CheckRead ¶ added in v0.5.0
func (f *FileAccess) CheckRead(full, name string) error
CheckRead returns a *DeniedError when full (an absolute path under the root, as returned by Resolve) or its symlink-resolved target matches a deny_read rule. name is the path as the caller gave it.
func (*FileAccess) CheckWrite ¶ added in v0.5.0
func (f *FileAccess) CheckWrite(full, name string) error
CheckWrite is CheckRead for writes: deny_read rules apply too.
func (*FileAccess) Counts ¶ added in v0.5.0
func (f *FileAccess) Counts() (read, write int)
Counts returns the number of deny_read and deny_write rules.
func (*FileAccess) Hidden ¶ added in v0.5.0
func (f *FileAccess) Hidden(full string) bool
Hidden reports whether a walk should hide full: it matches a deny_read rule, directly or through its symlink target.
func (*FileAccess) Rules ¶ added in v0.5.0
func (f *FileAccess) Rules() (read, write []string)
Rules returns the configured deny_read and deny_write patterns.
type LSP ¶ added in v0.5.0
type LSP struct {
Manager *lsp.Manager
// AfterEdit appends diagnostics to edit results.
AfterEdit bool
// Wait is the longest wait for diagnostics.
Wait time.Duration
// Max caps the diagnostics listed per file.
Max int
// Warnings also reports warnings (severity: warning).
Warnings bool
}
LSP connects the executor to the configured language servers.
type Local ¶ added in v0.5.0
type Local struct {
Sandbox *Sandbox
// CommandEnv, when non-nil, is the whole environment commands get;
// nil inherits tinyagent's.
CommandEnv *CommandEnv
}
Local runs commands on the host, confined by Sandbox if it is non-nil.
func (Local) Exec ¶ added in v0.5.0
Exec runs argv without a shell. Unsandboxed, argv[0] is looked up on the command_env PATH (tinyagent's own without a policy); sandboxed, the sandbox wrapper looks it up on the PATH the command gets.
func (Local) TakeNetworkDenials ¶ added in v0.5.0
func (l Local) TakeNetworkDenials() []sandboxnet.Denial
TakeNetworkDenials returns the requests the sandbox allowlist proxy refused since the last call.
type OutputFiles ¶ added in v0.5.0
type OutputFiles struct {
Root string // absolute working root (--cwd)
Dir string // absolute output directory, inside Root
RunID string
// Warn, when set, reports the first save failure of the run.
Warn func(string)
// contains filtered or unexported fields
}
OutputFiles saves the full text of tool results that exceed the output limit, one file per tool call, in a per-run directory under Dir. The model sees a bounded preview plus a notice naming the file, which it can page with read_file (offset/limit) or search with grep.
func NewOutputFiles ¶ added in v0.5.0
func NewOutputFiles(root, dir string, now time.Time) (*OutputFiles, error)
NewOutputFiles validates dir and returns a store with a fresh run id. No directory is created until the first result is saved.
func (*OutputFiles) Contains ¶ added in v0.5.0
func (o *OutputFiles) Contains(p string) bool
Contains reports whether the absolute path p is the output directory or inside it.
func (*OutputFiles) Prune ¶ added in v0.5.0
func (o *OutputFiles) Prune(maxRuns int) error
Prune deletes the oldest earlier run directories so at most maxRuns remain (maxRuns 0 keeps all). It runs at startup, before the current run saves anything, and only touches directories named like run ids; other files are left alone.
func (*OutputFiles) RunDir ¶ added in v0.5.0
func (o *OutputFiles) RunDir() string
RunDir is the absolute directory holding this run's files.
type ReadDirError ¶ added in v0.5.0
type ReadDirError struct {
Path string // the path as the caller named it
Dir string // the additional directory
}
ReadDirError is returned for a write to a read-mode additional directory.
func (*ReadDirError) Error ¶ added in v0.5.0
func (e *ReadDirError) Error() string
type RegisteredProcess ¶ added in v0.5.0
RegisteredProcess describes one background process still registered.
type Result ¶ added in v0.5.0
type Result struct {
Text string
Images []model.Image
IsError bool
// OutputFile is the saved full output (relative to Root, slash
// separated) when OutputFiles is on and the text was over the limit.
OutputFile string
OutputBytes int
// Notice is the line ending Text that points at the saved file (or, for
// read_file, at the rest of the file); empty when none was added.
Notice string
// Paths are the absolute paths a successful built-in file tool call
// touched: read_file, write_file, edit_file, view_image and lsp's
// path, list_files and grep's path argument (default "."), and every
// file an apply_patch call added, updated, deleted or moved. They may
// lie outside Root (additional directories); nil for other tools and
// for failed calls.
Paths []string
// Instructions is the suffix of Text holding scoped AGENTS.md blocks
// appended by the agent loop; feedback re-truncation keeps it whole.
Instructions string
// Redactions counts the secret values Redactor masked in the result.
Redactions int
}
Result is one tool call's outcome for the model.
type Sandbox ¶ added in v0.5.0
type Sandbox struct {
Backend string // e.g. "landlock (ABI 6)" or "seatbelt"
Writable []string // directories commands may write, including Tmp
Network bool
// AllowedDomains, when set, are the only hosts commands may reach, over
// HTTP and HTTPS through a proxy tinyagent runs outside the sandbox.
AllowedDomains []string
Tmp string // per-run temporary directory, exported as TMPDIR
// contains filtered or unexported fields
}
Sandbox confines bash and start_process commands (and everything they spawn) at the OS level: writes are limited to Writable, and outbound network is denied unless Network is set, or limited to AllowedDomains through a filtering proxy. Reads stay unrestricted.
func CommandSandbox ¶ added in v0.9.0
func CommandSandbox(env Environment) *Sandbox
CommandSandbox returns the sandbox that confines env's commands, or nil when they run unsandboxed or in a container.
func NewSandbox ¶ added in v0.5.0
NewSandbox checks that this host can enforce the policy and creates the per-run temp directory. It fails rather than returning a weaker sandbox. root and extra must be existing directories. A non-empty allowed list (sandbox_allowed_domains entries) starts the filtering proxy; it can't be combined with network.
func (*Sandbox) Cleanup ¶ added in v0.5.0
func (s *Sandbox) Cleanup()
Cleanup stops the allowlist proxy and removes the per-run temp directory.
func (*Sandbox) Command ¶ added in v0.9.0
Command returns argv confined by the sandbox, like bash commands are.
func (*Sandbox) DirectUntilTaint ¶ added in v0.9.0
DirectUntilTaint reports whether commands keep their direct network (sandbox_network) until the first taint, when the lockdown takes it away (PrepareLockdownNetwork succeeded). Background processes started before then keep theirs, so the lockdown stops them at taint.
func (*Sandbox) LockdownConfinable ¶ added in v0.9.0
LockdownConfinable reports whether the untrusted-content lockdown (issue #171) can keep commands running after taint: their network is denied, or limited by the allowlist proxy, which NarrowNetwork can restrict further. sandbox_network gives commands direct network, which is confinable only once PrepareLockdownNetwork has readied its switch.
func (*Sandbox) NarrowNetwork ¶ added in v0.9.0
NarrowNetwork restricts the allowlist proxy, for the rest of the run, to hosts in both sandbox_allowed_domains and allowed (the untrusted_content.lockdown.allowed_domains entries), and closes the connections opened before. Background processes started earlier go through the same proxy, so they are narrowed too. With network denied there is nothing to narrow. A sandbox_network sandbox readied by PrepareLockdownNetwork loses its direct network instead: later commands get the network prepared there (allowed was fixed then). It fails for a sandbox lockdown can't confine.
func (*Sandbox) NetworkMode ¶ added in v0.5.0
NetworkMode describes the network policy: denied, allowed, or allowlist with its entries.
func (*Sandbox) PrepareLockdownNetwork ¶ added in v0.9.0
PrepareLockdownNetwork readies a sandbox_network sandbox for the untrusted-content lockdown: at the first taint NarrowNetwork takes its commands' direct network away. Commands started after that have their network denied when allowed (untrusted_content.lockdown.allowed_domains) is empty, or reach only those hosts through a proxy tinyagent starts now. It fails, leaving the sandbox unchanged, when the sandbox has no direct network, allowed is invalid, or this host can't deny the network (or create the network namespace the proxy needs); lockdown then refuses commands after taint. Call it once, before the run starts and before workers copy the sandbox.
func (*Sandbox) Proxied ¶ added in v0.9.0
Proxied reports whether commands reach the network through the allowlist proxy after taint: the sandbox_allowed_domains proxy, or the lockdown proxy PrepareLockdownNetwork started.
func (*Sandbox) TakeNetworkDenials ¶ added in v0.5.0
func (s *Sandbox) TakeNetworkDenials() []sandboxnet.Denial
TakeNetworkDenials returns the requests the allowlist proxy refused since the last call.
type WebFetchRecord ¶ added in v0.5.0
type WebFetchRecord struct {
URL string
FinalURL string
Status int
ContentType string
Bytes int
Truncated bool
Duration time.Duration
DeniedReason string
Error string
}
WebFetchRecord describes one fetch for events and verbose output.
func (WebFetchRecord) Fields ¶ added in v0.5.0
func (r WebFetchRecord) Fields() map[string]any
Fields returns the record as web_fetch event fields.
type WebFetcher ¶ added in v0.5.0
type WebFetcher struct {
// Domains are the configured web_fetch.allowed_domains entries.
Domains []string
MaxBytes int
Timeout time.Duration
// UserAgent is sent with every request.
UserAgent string
// Resolve and Dial default to the system resolver and a net.Dialer;
// tests replace them.
Resolve func(ctx context.Context, host string) ([]netip.Addr, error)
Dial func(ctx context.Context, network, addr string) (net.Conn, error)
// Gate, when set, is checked for every request hop after the
// allowlist (the untrusted-content lockdown sets it); an error
// refuses the hop before any connection.
Gate func(host string, port int) error
// contains filtered or unexported fields
}
WebFetcher runs web_fetch calls. It fetches in tinyagent's own process, never through bash, a sandbox or proxy environment variables, and only from hosts its rules allow.
func NewWebFetcher ¶ added in v0.5.0
func NewWebFetcher(domains []string, maxBytes int, timeout time.Duration, userAgent string) (*WebFetcher, error)
NewWebFetcher returns a fetcher for allowlist entries in the sandbox_allowed_domains syntax. An empty allowlist or a bad entry is an error. maxBytes and timeout of 0 use the defaults.
func (*WebFetcher) Fetch ¶ added in v0.5.0
Fetch fetches rawURL and returns the header line and text.
func (*WebFetcher) TakeRecords ¶ added in v0.5.0
func (f *WebFetcher) TakeRecords() []WebFetchRecord
TakeRecords returns the fetches made since the last call.
Source Files
¶
- askuser.go
- bash.go
- cmdenv.go
- command.go
- delegate.go
- dirs.go
- edit.go
- env.go
- fileaccess.go
- format.go
- glob.go
- grep.go
- htmltext.go
- image.go
- lockdown_container.go
- lockdown_container_check.go
- lockdown_container_proxy.go
- lockdown_sandbox.go
- lockdown_sandbox_network.go
- lsp.go
- memory_tools.go
- outputfiles.go
- patch.go
- process.go
- procgroup_unix.go
- read.go
- remember.go
- sandbox.go
- sandbox_linux.go
- tools.go
- undo.go
- untrusted.go
- webfetch.go
- worker.go
- write.go