Documentation
¶
Overview ¶
Package tool defines the CoreTool contract and the built-in file/shell tools that give the agent its hands. Every tool is self-describing: a name and description for the model, a JSON-Schema input, behavioral flags used by the scheduler (read-only / concurrency-safe), a permission self-check, and a Call method. New tools are built through Build, which applies fail-closed defaults.
Index ¶
- Constants
- func BackgroundTasksDisabled() bool
- func Capture(tc *ToolContext, s string) string
- func CaptureOnce(tc *ToolContext, s string) string
- func EnsureRipgrep() string
- func InteractiveShellDisabled() bool
- func RenderDeferredToolsBlock(names []string) string
- func RenderTodoReminder(todos []Todo) string
- func RipgrepPath() string
- func ValidateInput(schema map[string]any, raw json.RawMessage) error
- type Answer
- type AskUserFunc
- type CoreTool
- func Build(s Spec) CoreTool
- func DefaultTools() []CoreTool
- func NewAskUserQuestion(ask AskUserFunc) CoreTool
- func NewBash() CoreTool
- func NewEdit() CoreTool
- func NewExecuteExtraTool(reg *Registry, unlock *UnlockSet) CoreTool
- func NewGlob() CoreTool
- func NewGrep() CoreTool
- func NewLS() CoreTool
- func NewMonitor() CoreTool
- func NewMultiEdit() CoreTool
- func NewRead() CoreTool
- func NewSearchExtraTools(reg *Registry, deferred []string) CoreTool
- func NewShellClose() CoreTool
- func NewShellList() CoreTool
- func NewShellOpen() CoreTool
- func NewShellRead() CoreTool
- func NewShellSend() CoreTool
- func NewSleep() CoreTool
- func NewTaskList() CoreTool
- func NewTaskOutput() CoreTool
- func NewTaskStop() CoreTool
- func NewWebFetch(cfg WebFetchConfig) CoreTool
- func NewWebSearch(cfg WebSearchConfig) (CoreTool, error)
- func NewWrite() CoreTool
- func ShellSessionTools() []CoreTool
- type Manager
- func (m *Manager) Background(id string)
- func (m *Manager) Cleanup()
- func (m *Manager) DrainNotifications() []Notification
- func (m *Manager) Forget(id string)
- func (m *Manager) Get(id string) (TaskInfo, bool)
- func (m *Manager) Kill(id string) bool
- func (m *Manager) KillAll() int
- func (m *Manager) List() []TaskInfo
- func (m *Manager) Output(id string, maxBytes int) (string, error)
- func (m *Manager) RunForeground(ctx context.Context, spec SpawnSpec, timeout time.Duration) (t *Task, finished bool, output string, err error)
- func (m *Manager) Spawn(spec SpawnSpec) (*Task, error)
- func (m *Manager) Wait(ctx context.Context, id string, timeout time.Duration) (TaskInfo, bool)
- type Notification
- type Option
- type ProgressInfo
- type Question
- type Registry
- type Result
- type SearchResult
- type SpawnSpec
- type Spec
- type Task
- type TaskInfo
- type TaskKind
- type TaskStatus
- type Todo
- type TodoStatus
- type TodoStore
- type ToolContext
- type UnlockSet
- type WebFetchConfig
- type WebSearchConfig
Constants ¶
const ( SearchExtraToolsName = "SearchExtraTools" ExecuteExtraToolName = "ExecuteExtraTool" )
Fixed names of the two always-loaded access tools.
Variables ¶
This section is empty.
Functions ¶
func BackgroundTasksDisabled ¶
func BackgroundTasksDisabled() bool
BackgroundTasksDisabled reports whether background execution is turned off via the AGENT_CORE_DISABLE_BACKGROUND_TASKS environment variable.
func Capture ¶
func Capture(tc *ToolContext, s string) string
Capture bounds a tool's textual output for the model. When the output exceeds the limit (ToolContext.MaxOutputChars, default 30000) and the host configured an OutputDir, the FULL output is written to a file there and a tight head + a pointer to that file is returned — so the model can read slices on demand (grep/sed) instead of losing the overflow. Without an OutputDir it falls back to a head+tail truncation (the overflow is discarded). Tools that produce potentially large output should return Capture(tc, output) rather than the raw string.
func CaptureOnce ¶
func CaptureOnce(tc *ToolContext, s string) string
CaptureOnce is Capture with an idempotency guard: output a tool already ran through Capture (so it carries a spill pointer or truncation notice) is returned unchanged. This lets a single post-tool net cap every tool's output without re-truncating or re-spilling what built-in / MCP / custom tools already handled themselves. Output within the limit is a no-op either way, since Capture returns it unchanged.
func EnsureRipgrep ¶
func EnsureRipgrep() string
EnsureRipgrep warms ripgrep resolution so the cost (including a possible npm install) is paid at startup rather than on the first Grep call. Hosts may call it once at boot. Returns the resolved path ("" = Go fallback).
func InteractiveShellDisabled ¶
func InteractiveShellDisabled() bool
InteractiveShellDisabled reports whether interactive shell sessions are turned off via AGENT_CORE_DISABLE_INTERACTIVE_SHELL (mirrors BackgroundTasksDisabled).
func RenderDeferredToolsBlock ¶
RenderDeferredToolsBlock renders the <available-deferred-tools> block: the given tool names (one per line, sorted) plus the fixed usage instruction. Returns "" if names is empty. Hosts place this in the CACHED system-prompt prefix (a SystemPrompt segment before DynamicBoundary) — see design doc §2.1 / C1.
func RenderTodoReminder ¶
RenderTodoReminder renders the todo list for the system-reminder body, one numbered item per line ("N. [status] content"). Returns "" for an empty list.
func RipgrepPath ¶
func RipgrepPath() string
RipgrepPath returns the resolved ripgrep binary path, or "" when the pure-Go grep should be used. The heavy resolution (detect + optional npm install) runs at most once per process.
func ValidateInput ¶
func ValidateInput(schema map[string]any, raw json.RawMessage) error
ValidateInput checks a raw JSON input against a minimal subset of JSON Schema sufficient for tool inputs: object type, required properties, and per-property primitive type checks (string/number/integer/boolean/array/object). It never panics; a non-nil error means the input is invalid (FR-04.5, NFR-07).
Types ¶
type Answer ¶
type Answer struct {
// Selected holds the chosen option label(s). For free-form input the host
// may return the typed text here.
Selected []string
}
Answer is the user's response to a Question.
type AskUserFunc ¶
AskUserFunc is the host's question callback (a CLI prompt, a GUI, a web form, or an automated policy). Like CanUseTool it is synchronous: the tool blocks until it returns. The host decides the UI; the SDK only defines the contract.
type CoreTool ¶
type CoreTool interface {
Name() string
Description() string
Prompt() string
InputSchema() map[string]any
IsReadOnly(input json.RawMessage) bool
IsConcurrencySafe(input json.RawMessage) bool
CheckPermissions(ctx context.Context, input json.RawMessage, pc permission.Context) permission.Decision
Call(ctx context.Context, input json.RawMessage, tc *ToolContext) (Result, error)
}
CoreTool is a capability the agent can invoke (FR-04.1).
func DefaultTools ¶
func DefaultTools() []CoreTool
DefaultTools returns the core toolset every agent gets: the file/shell tools (Read, Write, Edit, MultiEdit, LS, Glob, Grep, Bash) plus Sleep — a small context-cancellable wait that pairs with background execution. Network and stateful tools (WebFetch, TodoWrite) remain opt-in via their own constructors.
func NewAskUserQuestion ¶
func NewAskUserQuestion(ask AskUserFunc) CoreTool
NewAskUserQuestion builds the AskUserQuestion tool bound to a host callback. It lets the agent pause a long task to ask the user a structured question (with options) and continue with the answer — without ending the turn.
func NewBash ¶
func NewBash() CoreTool
NewBash builds the Bash tool: run a shell command with a timeout, optionally in the background.
func NewEdit ¶
func NewEdit() CoreTool
NewEdit builds the Edit tool: exact string replacement with uniqueness check.
func NewExecuteExtraTool ¶
NewExecuteExtraTool builds the always-loaded invoker for deferred tools. It runs the named tool from reg, but only if it is currently in the unlock set. Schema is validated before the call. unlock may be nil (then every registry tool is callable — no gating).
func NewGlob ¶
func NewGlob() CoreTool
NewGlob builds the Glob tool: find files by pattern, newest first.
func NewMonitor ¶
func NewMonitor() CoreTool
NewMonitor builds the Monitor tool: start a long-running streaming process in the background (tail -f, watch, a dev server, a polling loop) and return immediately. Inspect it with Read/TaskOutput and end it with TaskStop.
func NewMultiEdit ¶
func NewMultiEdit() CoreTool
NewMultiEdit builds the MultiEdit tool: applies a sequence of exact-string replacements to one file atomically. Edits apply in order to the in-memory content; if any fails to match, nothing is written.
func NewRead ¶
func NewRead() CoreTool
NewRead builds the Read tool: reads a file with cat -n style line numbers and optional offset/limit.
func NewSearchExtraTools ¶
NewSearchExtraTools builds the always-loaded discovery tool. deferred is the set of tool names whose schemas are withheld; the tool searches those names in reg and returns each match's name + description + params schema.
func NewSleep ¶
func NewSleep() CoreTool
NewSleep returns a tool that waits N seconds, interruptible via context. It pairs with background task execution: after spawning long-running work (e.g. a Bash command with run_in_background), an agent can sleep, then read partial output with TaskOutput. Part of DefaultTools — every agent gets it.
The wait is cancelled the moment ctx is done (pause/stop/timeout), returning promptly rather than blocking out the deadline.
func NewTaskList ¶
func NewTaskList() CoreTool
NewTaskList builds the TaskList tool: enumerate this session's background tasks.
func NewTaskOutput ¶
func NewTaskOutput() CoreTool
NewTaskOutput builds the TaskOutput tool: read the captured output of a background task (from Bash run_in_background or Monitor), optionally blocking until it finishes.
func NewTaskStop ¶
func NewTaskStop() CoreTool
NewTaskStop builds the TaskStop tool: kill a running background task (or all).
func NewWebFetch ¶
func NewWebFetch(cfg WebFetchConfig) CoreTool
NewWebFetch builds the WebFetch tool: fetches a URL over HTTP(S) and returns its content as Markdown (HTML is parsed and rendered; non-HTML is returned as-is). With extract=true it also appends a RECON section that preserves the signal HTML→Markdown normally discards — comments, <script> sources, inline endpoints, forms/inputs (including hidden) and meta tags — useful for security reconnaissance. cfg optionally routes requests through a proxy and/or skips TLS verification (see WebFetchConfig). It is network-facing, so it is not part of DefaultTools and requires permission to run.
func NewWebSearch ¶
func NewWebSearch(cfg WebSearchConfig) (CoreTool, error)
NewWebSearch builds the web_search tool for the configured backend. It returns an error when the config is unusable (unknown backend, or brave-free without a key) so a session fails fast at construction instead of at first call. The tool is network-facing, so it is not part of DefaultTools and requires permission.
func NewWrite ¶
func NewWrite() CoreTool
NewWrite builds the Write tool: creates or overwrites a file.
func ShellSessionTools ¶
func ShellSessionTools() []CoreTool
ShellSessionTools returns the five interactive-shell tools. Callers add them to Options.Tools only when interactive shell is enabled for the agent.
type Manager ¶
type Manager struct {
// contains filtered or unexported fields
}
Manager owns the background tasks of one Session.
func NewManager ¶
NewManager creates the per-session task directory and garbage-collects stale directories left by previous sessions.
func (*Manager) Background ¶
Background marks a task as backgrounded: its completion will be surfaced to the model. If the task already finished (a race against a fast command), the notification is enqueued immediately.
func (*Manager) Cleanup ¶
func (m *Manager) Cleanup()
Cleanup kills all tasks, cancels the root context, and removes the session's task directory. Safe to call on a nil Manager.
func (*Manager) DrainNotifications ¶
func (m *Manager) DrainNotifications() []Notification
DrainNotifications returns and clears the pending completion notifications.
func (*Manager) Forget ¶
Forget removes a task from the registry and deletes its output file. Used for foreground commands once their output has been returned inline.
func (*Manager) Output ¶
Output returns the tail of a task's output file, up to maxBytes (default 30000).
func (*Manager) RunForeground ¶
func (m *Manager) RunForeground(ctx context.Context, spec SpawnSpec, timeout time.Duration) (t *Task, finished bool, output string, err error)
RunForeground starts a task and waits up to timeout. finished is true if the process exited within the timeout (output is then returned); otherwise the task keeps running and the caller decides whether to background or kill it. A cancelled ctx kills the task and returns ctx.Err().
type Notification ¶
type Notification struct {
TaskID string
Kind TaskKind
Status TaskStatus
OutputPath string
Summary string
}
Notification is surfaced to the model when a backgrounded task exits.
func (Notification) String ¶
func (n Notification) String() string
String renders the notification as the <task-notification> block injected into the conversation. It deliberately carries only the path, not the output.
type Option ¶
Option is one selectable choice for an AskUserQuestion.
func (*Option) UnmarshalJSON ¶
UnmarshalJSON lets Option accept the lowercase JSON the model emits.
type ProgressInfo ¶
type ProgressInfo struct {
Message string
}
ProgressInfo is an incremental progress update emitted during a long tool run.
type Question ¶
type Question struct {
Header string // short label/category, e.g. "Auth method"
Question string // the full question text
Options []Option
MultiSelect bool
}
Question is a single structured question the agent poses mid-task.
type Registry ¶
type Registry struct {
// contains filtered or unexported fields
}
Registry is an ordered, name-indexed collection of tools (FR-04.3).
func NewRegistry ¶
NewRegistry builds a registry from tools, preserving order.
func (*Registry) Schemas ¶
func (r *Registry) Schemas() []llm.ToolSchema
Schemas renders the registry into provider-facing tool definitions, merging each tool's extended Prompt into its description.
type Result ¶
type Result struct {
Content []llm.ContentBlock
IsError bool
// Extra holds additional messages the tool injects into the conversation
// right after its tool_result (e.g. the Skill tool emits the invoked skill's
// instructions as an independent user message rather than burying them in the
// tool_result). Appended in order; nil for ordinary tools.
Extra []llm.Message
}
Result is the outcome of a tool call. Content is the tool_result payload fed back to the model.
type SearchResult ¶
type SearchResult struct {
Title string `json:"title"`
URL string `json:"url"`
Description string `json:"description"`
Position int `json:"position"`
}
SearchResult is one web-search hit, normalized across backends.
func WebSearchProbe ¶
func WebSearchProbe(ctx context.Context, cfg WebSearchConfig, query string, limit int) ([]SearchResult, error)
WebSearchProbe runs a one-off search with cfg and returns the results, bypassing the tool/permission layer. It's the entry point for a connectivity/config check (e.g. a "test" button): same backend selection + proxy/TLS handling as the web_search tool, so a success means the live tool would reach the backend too.
type SpawnSpec ¶
type SpawnSpec struct {
Command string
Description string
Kind TaskKind
WorkingDir string
// Env holds extra "KEY=VALUE" entries layered onto the process environment for
// this command (see ToolContext.Env). Empty = inherit unchanged.
Env []string
}
SpawnSpec describes a process to launch in the background.
type Spec ¶
type Spec struct {
Name string
Description string
Prompt string
Schema map[string]any
ReadOnly func(json.RawMessage) bool
Concurrent func(json.RawMessage) bool
Permissions func(ctx context.Context, input json.RawMessage, pc permission.Context) permission.Decision
Run func(ctx context.Context, input json.RawMessage, tc *ToolContext) (Result, error)
// RawInput hands Run whatever the model produced, skipping the schema check
// the harness otherwise applies first.
//
// Schema stays required and is still advertised to the model — the two are
// separate jobs. Schema tells the model what to send; validation decides what
// gets through. A tool that repairs malformed arguments itself needs the
// first and is defeated by the second: a truncated or fence-wrapped call is
// not valid JSON, so it would be rejected before Run ever saw it, and the
// repair could never run.
//
// Only set this on a tool that treats its input as untrusted bytes and
// answers every shape with a Result rather than an error.
RawInput bool
}
Spec declares a tool. Build fills unset behavioral fields with fail-closed defaults (FR-04.2): not read-only, not concurrency-safe, requires approval.
type Task ¶
type Task struct {
ID string
Kind TaskKind
Command string
Description string
Status TaskStatus
ExitCode int
StartTime time.Time
EndTime time.Time
OutputPath string
// contains filtered or unexported fields
}
Task is a single background process tracked by a Manager. Its mutable fields are guarded by Manager.mu; read snapshots through Manager methods (which copy into TaskInfo).
type TaskInfo ¶
type TaskInfo struct {
ID string
Kind TaskKind
Command string
Description string
Status TaskStatus
ExitCode int
StartTime time.Time
EndTime time.Time
OutputPath string
Backgrounded bool
}
TaskInfo is an immutable snapshot of a task for safe reads outside the lock.
type TaskKind ¶
type TaskKind string
TaskKind distinguishes a one-shot background command from a long-lived monitor.
type TaskStatus ¶
type TaskStatus string
TaskStatus is the lifecycle state of a background task.
const ( TaskRunning TaskStatus = "running" TaskCompleted TaskStatus = "completed" TaskFailed TaskStatus = "failed" TaskKilled TaskStatus = "killed" )
func (TaskStatus) Terminal ¶
func (s TaskStatus) Terminal() bool
Terminal reports whether the status is final (the process has exited).
type Todo ¶
type Todo struct {
Content string `json:"content"`
Status TodoStatus `json:"status"`
}
Todo is one task in the agent's working plan.
type TodoStatus ¶
type TodoStatus string
TodoStatus is the state of a todo item.
const ( TodoPending TodoStatus = "pending" TodoInProgress TodoStatus = "in_progress" TodoCompleted TodoStatus = "completed" )
type TodoStore ¶
type TodoStore struct {
// contains filtered or unexported fields
}
TodoStore holds the current todo list across tool calls. It is safe for concurrent reads; the host can inspect progress via List.
type ToolContext ¶
type ToolContext struct {
WorkingDir string
AgentID string
// ToolUseID is the id of the tool_use block this call answers. Tools that
// need to refer back to their own call in the conversation — to anchor
// something to it, or to recognise it later — read it here.
ToolUseID string
MaxOutputChars int
// OutputDir, when set, makes oversized tool output spill to a file there
// (full content preserved) instead of being discarded by truncation; the
// tool returns a head + a pointer to the file. Empty disables spilling.
OutputDir string
// Emit reports progress; may be nil. Safe to call from the tool goroutine.
Emit func(ProgressInfo)
// Tasks is the background-task manager for this session; may be nil (background
// execution disabled). Tools use it to spawn, read, and stop background work.
Tasks *Manager
// Env holds extra "KEY=VALUE" entries injected into the environment of Bash
// subprocesses (both foreground and background). Applied on top of the parent
// process environment, so these override inherited values. Empty = inherit
// unchanged. Used e.g. to route child-command HTTP through a proxy + trust a
// CA, without affecting the agent's own process.
Env []string
}
ToolContext carries per-call execution state into a tool.
type UnlockSet ¶
type UnlockSet struct {
// contains filtered or unexported fields
}
UnlockSet is a session-scoped, concurrency-safe set of deferred-tool names that are currently callable via ExecuteExtraTool. Globally-available deferred tools are seeded at construction; skill-gated ones are added at runtime when their skill loads. Withholding the schema (deferred) is separate from gating the call (unlock): a name may be listed yet locked until its skill is invoked.
func NewUnlockSet ¶
NewUnlockSet builds an unlock set seeded with the given tool names.
type WebFetchConfig ¶
type WebFetchConfig struct {
// Proxy, when set, routes requests through this http(s) proxy URL. Empty = direct.
Proxy string
// CACert, when set, is a path to a PEM CA certificate added to the system
// trust pool. This lets WebFetch *verify* HTTPS fetched through a MITM/recording
// proxy that re-signs certificates with its own CA — the proper alternative to
// InsecureTLS, keeping verification on for every other connection. Preferred
// over InsecureTLS; ignored when InsecureTLS is set.
CACert string
// InsecureTLS skips TLS certificate verification entirely (equivalent to
// curl -k). A blunt fallback when no CA cert is available; prefer CACert.
InsecureTLS bool
}
WebFetchConfig tunes the network behavior of a WebFetch tool.
type WebSearchConfig ¶
type WebSearchConfig struct {
// Backend chooses the provider: "ddgs" (DuckDuckGo scrape, no key),
// "brave-free" (Brave Search API, needs BraveAPIKey), "tavily" (Tavily
// Search API, needs TavilyAPIKey), or "deepseek" (DeepSeek's server-side
// web search, needs DeepSeek*). Empty defaults to "ddgs".
Backend string
// BraveAPIKey authenticates the "brave-free" backend. Required (and only
// used) when Backend == "brave-free".
BraveAPIKey string
// TavilyAPIKey authenticates the "tavily" backend. Required (and only
// used) when Backend == "tavily".
TavilyAPIKey string
// DeepSeekBaseURL / DeepSeekAPIKey / DeepSeekModel configure the "deepseek"
// backend. That backend does NOT call a search API — DeepSeek has none.
// Search there only exists inside its Anthropic-compatible messages endpoint
// as the web_search_20250305 server tool, so this provider spends one model
// call per search. BaseURL must be the Anthropic-format root (the provider
// appends /v1/messages); the OpenAI-format endpoint rejects server tools
// outright ("unknown variant, expected `function`").
DeepSeekBaseURL string
DeepSeekAPIKey string
DeepSeekModel string
// Proxy, when set, routes search requests through this http(s) proxy URL —
// useful when the search endpoint is only reachable via a proxy. Empty = direct.
Proxy string
// CACert / InsecureTLS mirror WebFetchConfig: trust a proxy's CA in addition
// to the system roots (CACert), or skip TLS verification entirely (InsecureTLS).
// Prefer CACert. See WebFetchConfig for the full semantics.
CACert string
InsecureTLS bool
}
WebSearchConfig selects and configures the active search backend.