Documentation
¶
Overview ¶
Package tool provides concrete agent tools. Every runtime gets Read, Write, Edit, Glob, Grep, Bash, WebFetch, TodoWrite, NoteWrite, Skill, Task, and the MCP gateway tools; UploadArtifact, Worktree, GetIssue, ReportToIssue, MemoryRead, MemoryWrite, JobList, JobOutput, JobStop, and Monitor are registered only where the surface can serve them, as the constants below say.
Package tools provides concrete agent tools (e.g. read_file, write_file, webfetch, todowrite).
Package tools provides concrete agent tools (e.g. read_file, write_file, webfetch).
Index ¶
- Constants
- func GatewayTools(reg *mcp.Registry) []llm.Tool
- func LoadAgentDefs(dir string) ([]subagent.Def, error)
- func LoadAgentDefsFromPaths(dirs []string) ([]subagent.Def, error)
- type AgentDefResolution
- type AgentTypeConfig
- type AgentTypeToolsAt
- type ArtifactPublisher
- type ArtifactUpload
- type Bash
- func (b *Bash) Access(_ map[string]any) llm.Access
- func (b *Bash) CheckArgs(args map[string]any) llm.ToolAction
- func (b *Bash) DefaultAction() llm.ToolAction
- func (b *Bash) Description() string
- func (b *Bash) Execute(ctx context.Context, args map[string]any) (string, error)
- func (b *Bash) Name() string
- func (b *Bash) Parameters() any
- func (b *Bash) WithJobs(m *job.Manager) *Bash
- func (b *Bash) WithSandbox(v agent.SandboxView) *Bash
- type BuiltinSubAgentDef
- type EditFile
- func (e *EditFile) Access(_ map[string]any) llm.Access
- func (e *EditFile) CheckArgs(args map[string]any) llm.ToolAction
- func (e *EditFile) Description() string
- func (e *EditFile) Execute(ctx context.Context, args map[string]any) (string, error)
- func (e *EditFile) Name() string
- func (e *EditFile) Parameters() any
- type GetIssue
- type Glob
- type Grep
- type IssueChild
- type IssueClient
- type IssueComment
- type IssueReport
- type IssueSnapshot
- type JobList
- type JobOutput
- type JobStop
- type MemoryRead
- func (t *MemoryRead) Access(_ map[string]any) llm.Access
- func (t *MemoryRead) DefaultAction() llm.ToolAction
- func (t *MemoryRead) Description() string
- func (t *MemoryRead) Execute(ctx context.Context, args map[string]any) (string, error)
- func (t *MemoryRead) Name() string
- func (t *MemoryRead) Parameters() any
- type MemoryWrite
- func (t *MemoryWrite) Access(_ map[string]any) llm.Access
- func (t *MemoryWrite) DefaultAction() llm.ToolAction
- func (t *MemoryWrite) Description() string
- func (t *MemoryWrite) Execute(ctx context.Context, args map[string]any) (string, error)
- func (t *MemoryWrite) Name() string
- func (t *MemoryWrite) Parameters() any
- type Monitor
- func (m *Monitor) Access(_ map[string]any) llm.Access
- func (m *Monitor) CheckArgs(args map[string]any) llm.ToolAction
- func (m *Monitor) DefaultAction() llm.ToolAction
- func (m *Monitor) Description() string
- func (m *Monitor) Execute(ctx context.Context, args map[string]any) (string, error)
- func (m *Monitor) Name() string
- func (m *Monitor) Parameters() any
- func (m *Monitor) WithJobs(j *job.Manager) *Monitor
- func (m *Monitor) WithSandbox(v agent.SandboxView) *Monitor
- type NoteWrite
- func (t *NoteWrite) Access(_ map[string]any) llm.Access
- func (t *NoteWrite) DefaultAction() llm.ToolAction
- func (t *NoteWrite) Description() string
- func (t *NoteWrite) Execute(ctx context.Context, args map[string]any) (string, error)
- func (t *NoteWrite) Name() string
- func (t *NoteWrite) Parameters() any
- type PublishedArtifact
- type ReadFile
- func (r *ReadFile) Access(_ map[string]any) llm.Access
- func (r *ReadFile) CheckArgs(args map[string]any) llm.ToolAction
- func (r *ReadFile) Description() string
- func (r *ReadFile) Execute(ctx context.Context, args map[string]any) (string, error)
- func (r *ReadFile) Name() string
- func (r *ReadFile) Parameters() any
- type ReportToIssue
- type SkillEntry
- type SkillResolution
- type SkillTool
- type SubAgentRunOpts
- type SubAgentRunner
- type SubAgentRunnerOption
- type SubAgentSession
- type SubAgentSessionFactory
- type SubAgentTrace
- type SubAgentTraceFactory
- type TaskTool
- func (t *TaskTool) Access(args map[string]any) llm.Access
- func (t *TaskTool) Description() string
- func (t *TaskTool) Execute(ctx context.Context, args map[string]any) (string, error)
- func (t *TaskTool) Name() string
- func (t *TaskTool) Parameters() any
- func (t *TaskTool) WithJobs(m *job.Manager, workspace util.Workspace) *TaskTool
- func (t *TaskTool) WithWorktrees(m *worktree.Manager, toolsAt AgentTypeToolsAt) *TaskTool
- type TodoWrite
- func (t *TodoWrite) Access(_ map[string]any) llm.Access
- func (t *TodoWrite) DefaultAction() llm.ToolAction
- func (t *TodoWrite) Description() string
- func (t *TodoWrite) Execute(ctx context.Context, args map[string]any) (string, error)
- func (t *TodoWrite) Name() string
- func (t *TodoWrite) Parameters() any
- type UploadArtifact
- type WebFetch
- func (w *WebFetch) Access(_ map[string]any) llm.Access
- func (w *WebFetch) Description() string
- func (w *WebFetch) Execute(ctx context.Context, args map[string]any) (string, error)
- func (w *WebFetch) Name() string
- func (w *WebFetch) Parameters() any
- func (w *WebFetch) WithSandbox(v agent.SandboxView) *WebFetch
- type Worktree
- func (w *Worktree) Access(args map[string]any) llm.Access
- func (w *Worktree) CheckArgs(args map[string]any) llm.ToolAction
- func (w *Worktree) Description() string
- func (w *Worktree) Execute(ctx context.Context, args map[string]any) (string, error)
- func (w *Worktree) Name() string
- func (w *Worktree) Parameters() any
- type WriteFile
- func (w *WriteFile) Access(_ map[string]any) llm.Access
- func (w *WriteFile) CheckArgs(args map[string]any) llm.ToolAction
- func (w *WriteFile) Description() string
- func (w *WriteFile) Execute(ctx context.Context, args map[string]any) (string, error)
- func (w *WriteFile) Name() string
- func (w *WriteFile) Parameters() any
Constants ¶
const ( ToolNameLoadMCPTools = "LoadMcpTools" ToolNameCallMCPTool = "CallMcpTool" )
const ( ToolNameRead = "Read" ToolNameWrite = "Write" ToolNameEdit = "Edit" ToolNameGlob = "Glob" ToolNameGrep = "Grep" ToolNameBash = "Bash" ToolNameWebFetch = "WebFetch" ToolNameTodoWrite = "TodoWrite" ToolNameNoteWrite = "NoteWrite" ToolNameSkill = "Skill" ToolNameTask = "Task" // ToolNameUploadArtifact is registered only where the surface has an // artifact service; a session with none does not offer it at all. ToolNameUploadArtifact = "UploadArtifact" // ToolNameWorktree is registered only where a session may move its own // workspace root — the CLI and TUI — and never inside subagents, which // share the parent's root for the length of their run. ToolNameWorktree = "Worktree" // The Issue tools are registered only where the run is working one Issue // and can reach it -- a worker run started from an Issue, or a logged-in // local session linked to one -- and never inside subagents, which report // to their parent rather than to a space's thread. Both are scoped to that // one Issue when they are built; neither takes an issue id. See // docs/design/issue-agent-access.md. ToolNameGetIssue = "GetIssue" ToolNameReportToIssue = "ReportToIssue" // The memory tools are registered only on a local primary run whose session // belongs to a Project and whose user has not turned memory off. A subagent // gets neither, and no index either: it is the highest-volume run in a // session, so it would pay the resident cost most often, and a parent that // needs it to know something can say so in the delegated task. They are // named for the operation rather than the scope, matching NoteWrite and // TodoWrite; a second scope would be an argument, not a second pair of // tools. See docs/design/local-project-memory.md §9.3 and §9.4. ToolNameMemoryRead = agent.ToolNameMemoryRead ToolNameMemoryWrite = agent.ToolNameMemoryWrite // The Job tools and Monitor are registered only where local background // jobs are enabled (TUI and Desktop), and never inside subagents. ToolNameJobList = "JobList" ToolNameJobOutput = "JobOutput" ToolNameJobStop = "JobStop" ToolNameMonitor = "Monitor" )
Tool name constants — single source of truth for every tool's Name(). Use camelCase for LLM-facing names.
const ( GeneralSubAgentPrompt = `` /* 234-byte string literal not displayed */ ExploreSubAgentPrompt = `` /* 242-byte string literal not displayed */ ShellSubAgentPrompt = `` /* 194-byte string literal not displayed */ )
Built-in sub-agent system prompts.
const ( StatusPending = agent.TodoPending StatusInProgress = agent.TodoInProgress StatusCompleted = agent.TodoCompleted )
Valid todo statuses. The values live in internal/core/agent, which owns durable session state; these names stay for the tool's own schema and messages.
const DefaultLimit = 1000
DefaultLimit is the default number of lines returned when limit is not specified.
const (
// MaxContentRunes is the maximum runes of fetched content before truncation.
MaxContentRunes = 200_000
)
Variables ¶
This section is empty.
Functions ¶
func GatewayTools ¶
GatewayTools returns LoadMcpTools and CallMcpTool bound to reg.
func LoadAgentDefs ¶
LoadAgentDefs reads all files from dir, parses each as an agent definition, and returns the valid definitions sorted alphabetically by Name. If dir does not exist, returns (nil, nil) — not an error. Individual files that fail to parse are skipped with a log warning.
func LoadAgentDefsFromPaths ¶
LoadAgentDefsFromPaths loads agent definitions from multiple directories in priority order. Directories are scanned in order; if two directories contain a definition with the same Name, the first one wins (project-level overrides global-level). Missing directories are gracefully skipped. This is the unlabelled form, for a caller with no layering to express.
Types ¶
type AgentDefResolution ¶
type AgentDefResolution struct {
Defs []subagent.Def
Shadowed []plugin.Shadowed
Findings []plugin.Finding
}
AgentDefResolution is what scanning every source produced: the definitions that load, what a higher layer shadowed, and the collisions that stopped a name from loading at all.
func ResolveAgentDefs ¶
func ResolveAgentDefs(sources []plugin.Source) (AgentDefResolution, error)
ResolveAgentDefs scans priority-ordered sources and reduces them to one definition per name. Sources come from internal/config: workspace, then global, then each plugin in name order.
type AgentTypeConfig ¶
type AgentTypeConfig struct {
Tools []llm.Tool // tools available to this agent type
SystemPrompt string // system prompt for the sub-agent
Description string // LLM-readable description of this agent type
Model string // model name to use; "" = runner default
MaxIterations int // iteration cap; 0 = defaultSubAgentMaxIter (50)
}
AgentTypeConfig holds the configuration for one agent type (built-in or user-defined).
type AgentTypeToolsAt ¶
AgentTypeToolsAt rebuilds one agent type's tool set against a workspace root. Everything except the root is the set the parent would have used.
type ArtifactPublisher ¶
type ArtifactPublisher interface {
PublishArtifact(ctx context.Context, in ArtifactUpload) (PublishedArtifact, error)
}
ArtifactPublisher hands one local file to the artifact service.
A port rather than the capability itself: this package must not know whether the file reaches a server over a person's session or over a run token, and must not grow a dependency on the service to find out. A surface that has no implementation does not register the tool — see docs/design/unified-artifacts.md section 7.1.
type ArtifactUpload ¶
type ArtifactUpload struct {
// Path is the resolved absolute path of a regular, readable file.
Path string
// Filename is the name the artifact carries, already reduced to one element.
Filename string
Title string
// agent can hand a person one link that opens and renders.
Share bool
}
ArtifactUpload is one file an agent chose to publish.
type Bash ¶
type Bash struct {
// contains filtered or unexported fields
}
Bash runs a shell command in the workspace (one command per call).
func (*Bash) CheckArgs ¶
func (b *Bash) CheckArgs(args map[string]any) llm.ToolAction
CheckArgs implements llm.ArgChecker.
Decision order (each step short-circuits):
- Catastrophic patterns (rm -rf /, raw dd, mkfs on device) — always Deny.
- Risky patterns (curl, npm, sudo, …) — Ask, unless auto-allow applies.
Auto-allow demotes Ask → Allow when:
- the sandbox is enabled,
- its mode is auto_allow (config.auto_allow_bash_if_sandboxed),
- the command would actually be sandboxed (not in excluded_commands),
- the caller did not pass dangerously_disable_sandbox=true.
Matches Claude Code's documented behavior in /sandboxing: catastrophic destructive commands still prompt even in auto-allow mode; everything else is contained by the OS sandbox boundary.
func (*Bash) DefaultAction ¶
func (b *Bash) DefaultAction() llm.ToolAction
DefaultAction overrides the action derived from Access, leaving CheckArgs above as the only authority on shell commands.
The derived tier is a fallback for tools with no judgement of their own. Bash has one, and a sharper one: catastrophic denies, risky asks, the rest runs. Letting the category default apply on top would prompt for every `ls` and `git status`, which is how a permission prompt becomes something people switch off. See docs/design/tool-permissions.md §6.
func (*Bash) Description ¶
Description returns a short description so the LLM knows when to use this tool.
func (*Bash) Execute ¶
Execute runs the command in b.root with the given timeout, captures combined stdout+stderr, and returns the result (truncated if needed). On success (exit 0) returns output and nil error. On non-zero exit or timeout returns a clear message and nil error so the LLM receives a readable result. Returns error only for argument validation (missing or empty command).
func (*Bash) Parameters ¶
Parameters returns the OpenAI-style JSON schema for the tool arguments.
func (*Bash) WithJobs ¶
WithJobs returns a copy of b that can detach commands to the given job manager. Nil leaves background execution unavailable.
func (*Bash) WithSandbox ¶
func (b *Bash) WithSandbox(v agent.SandboxView) *Bash
WithSandbox returns a copy of b that wraps spawned commands through the given SandboxView. Pass agent.NoopSandbox{} (or nil) to disable. Returning a copy keeps Bash safe to share across goroutines.
type BuiltinSubAgentDef ¶
type BuiltinSubAgentDef struct {
Name string
ToolNames []string // nil ⇒ all base tools
SystemPrompt string
Description string
}
BuiltinSubAgentDef describes a built-in sub-agent type declaratively. ToolNames lists tool names resolved at runtime; nil means all base tools.
func BuiltinSubAgentDefs ¶
func BuiltinSubAgentDefs() []BuiltinSubAgentDef
BuiltinSubAgentDefs returns the built-in sub-agent types in display order. The returned definitions can be changed without altering later runtimes.
type EditFile ¶
type EditFile struct {
// contains filtered or unexported fields
}
EditFile performs exact string replacements in a file under a workspace root.
func NewEditFile ¶
NewEditFile creates an EditFile tool that edits files under the given workspace root.
func (*EditFile) Access ¶
Name returns the tool name for the LLM. Access implements llm.AccessDeclarer.
func (*EditFile) CheckArgs ¶
func (e *EditFile) CheckArgs(args map[string]any) llm.ToolAction
CheckArgs implements llm.ArgChecker. Editing a sensitive file (credentials, private keys) triggers Ask so the user can confirm intent in interactive sessions.
func (*EditFile) Description ¶
Description returns a short description so the LLM knows when to use this tool.
func (*EditFile) Execute ¶
Execute performs string replacement(s) in the file at args["file_path"]. Reads the file, validates old_string uniqueness when replace_all=false, performs replacement(s), and writes back.
func (*EditFile) Parameters ¶
Parameters returns the OpenAI-style JSON schema for the tool arguments.
type GetIssue ¶
type GetIssue struct {
// contains filtered or unexported fields
}
GetIssue reads the issue this run is working.
func NewGetIssue ¶
func NewGetIssue(client IssueClient) *GetIssue
func (*GetIssue) Description ¶
func (*GetIssue) Parameters ¶
type Glob ¶
type Glob struct {
// contains filtered or unexported fields
}
Glob lists files matching a glob pattern under a workspace root. Symlinks: doublestar.Glob with WithFilesOnly does not follow symlinks to directories; symlinks to files are included as matches.
func (*Glob) Description ¶
Description returns a short description so the LLM knows when to use this tool.
func (*Glob) Execute ¶
Execute lists files under the search directory that match the pattern, sorted by modification time (newest first). Returns one absolute path per line, or "No files matched the pattern.", or an error for validation/system failures.
func (*Glob) Parameters ¶
Parameters returns the OpenAI-style JSON schema for the tool arguments.
type Grep ¶
type Grep struct {
// contains filtered or unexported fields
}
Grep searches file contents by regex pattern under a workspace root.
func NewGrep ¶
NewGrep creates a Grep tool that searches file contents under the given workspace root.
func (*Grep) CheckArgs ¶
func (g *Grep) CheckArgs(args map[string]any) llm.ToolAction
CheckArgs implements llm.ArgChecker. Grepping inside a sensitive file (credentials, private keys) triggers Ask so the user can confirm intent in interactive sessions.
func (*Grep) Description ¶
Description returns a short description so the LLM knows when to use this tool.
func (*Grep) Execute ¶
Execute searches file contents under the tool's root for the given regex pattern. Returns formatted results based on output_mode, or "No matches found.", or an error.
func (*Grep) Parameters ¶
Parameters returns the OpenAI-style JSON schema for the tool arguments.
type IssueChild ¶
IssueChild is one sub-issue, as title and status. Not the child's own description: a parent's agent needs to know what was split out, not to read the whole subtree into its context.
type IssueClient ¶
type IssueClient interface {
Issue(ctx context.Context) (IssueSnapshot, error)
Report(ctx context.Context, in IssueReport) error
}
IssueClient reads and reports on the one Issue a run is working.
A port rather than the capability itself: this package must not learn whether the call reaches a server over a run token, a person's session, or an in-process service, and must not grow a dependency on the issue service to find out. A surface with no implementation does not register the tools -- see docs/design/issue-agent-access.md section 8.
There is no issue identifier in either method. The scope is fixed when the client is constructed, so the model cannot address a second issue; that is a decision, not an omission, and section 5.3 says why.
type IssueComment ¶
IssueComment is one statement on the thread. AuthorKind is carried because a model that cannot tell a spacemate's comment from its own principal's instruction has no basis for treating them differently.
type IssueReport ¶
type IssueReport struct {
Body string
// ArtifactIDs names artifacts the run already published. Naming, not
// attaching: the artifact exists under its own identity, and repeating an
// object-store path in a comment would create a second, weaker reference.
ArtifactIDs []string
}
IssueReport is one statement an agent makes about the work it did.
type IssueSnapshot ¶
type IssueSnapshot struct {
Title string
Description string
Status string
AssigneeKind string
Children []IssueChild
Comments []IssueComment
// OmittedComments is how many older comments the window left out, so the
// agent can say the thread is longer than what it read instead of assuming
// it saw all of it.
OmittedComments int
}
IssueSnapshot is the bounded view of the one Issue a run is working.
type JobList ¶
type JobList struct {
// contains filtered or unexported fields
}
JobList lists this runtime's background jobs.
func NewJobList ¶
func (*JobList) Description ¶
func (*JobList) Parameters ¶
type JobOutput ¶
type JobOutput struct {
// contains filtered or unexported fields
}
JobOutput reports one job's status and incremental output.
func NewJobOutput ¶
func (*JobOutput) Description ¶
func (*JobOutput) Parameters ¶
type JobStop ¶
type JobStop struct {
// contains filtered or unexported fields
}
JobStop stops one background job.
func NewJobStop ¶
func (*JobStop) Access ¶
Access declares write: stopping changes state. DefaultAction keeps it prompt-free — it only ever terminates jobs this runtime itself started, which the user can equally do from the activity view.
func (*JobStop) DefaultAction ¶
func (j *JobStop) DefaultAction() llm.ToolAction
func (*JobStop) Description ¶
func (*JobStop) Parameters ¶
type MemoryRead ¶
type MemoryRead struct{}
MemoryRead returns the bodies behind index lines.
func (*MemoryRead) Access ¶
func (t *MemoryRead) Access(_ map[string]any) llm.Access
Access implements llm.AccessDeclarer. Reading changes nothing the user owns.
func (*MemoryRead) DefaultAction ¶
func (t *MemoryRead) DefaultAction() llm.ToolAction
DefaultAction implements llm.PolicyProvider. The content is the agent's own recall, kept under BUILDMAX_HOME, and a prompt to read it would arrive on every run for no decision the user could usefully make.
func (*MemoryRead) Description ¶
func (t *MemoryRead) Description() string
func (*MemoryRead) Name ¶
func (t *MemoryRead) Name() string
func (*MemoryRead) Parameters ¶
func (t *MemoryRead) Parameters() any
type MemoryWrite ¶
type MemoryWrite struct{}
MemoryWrite creates or replaces exactly one memory.
Unlike a note, this outlives the session. That is the whole value and the whole risk: a missed memory costs convenience, while a false or sensitive one misleads every future run in the project.
func (*MemoryWrite) Access ¶
func (t *MemoryWrite) Access(_ map[string]any) llm.Access
Access implements llm.AccessDeclarer. Declaring it a write is what keeps two calls in one batch from racing each other into the store's lock.
func (*MemoryWrite) DefaultAction ¶
func (t *MemoryWrite) DefaultAction() llm.ToolAction
DefaultAction implements llm.PolicyProvider.
What this writes is the agent's own recall, kept under BUILDMAX_HOME and never in the user's repository, so a prompt on every call would be noise. The user's controls are the ones that matter and they are outside the model: the memories are theirs to read, edit, delete, or switch off for a run.
func (*MemoryWrite) Description ¶
func (t *MemoryWrite) Description() string
Description is the behavioural contract. Without the "do not keep" half, the store fills with restated code and task narration, and every future session in the project pays for both.
func (*MemoryWrite) Name ¶
func (t *MemoryWrite) Name() string
func (*MemoryWrite) Parameters ¶
func (t *MemoryWrite) Parameters() any
type Monitor ¶
type Monitor struct {
// contains filtered or unexported fields
}
Monitor starts an event watcher: a command expected to stay quiet until something worth delivering happens, whose stdout lines become bounded events. It is a specialized command job, not a second scheduler, and it reuses Bash's argument risk, permission, sandbox, and environment rules — watching is not a way around them.
func NewMonitor ¶
NewMonitor creates a Monitor for the given workspace.
func (*Monitor) CheckArgs ¶
func (m *Monitor) CheckArgs(args map[string]any) llm.ToolAction
CheckArgs applies Bash's command risk classification to the watched command: catastrophic denies, risky asks, the rest runs.
func (*Monitor) DefaultAction ¶
func (m *Monitor) DefaultAction() llm.ToolAction
DefaultAction defers to CheckArgs, the same authority Bash uses.
func (*Monitor) Description ¶
func (*Monitor) Parameters ¶
func (*Monitor) WithJobs ¶
WithJobs returns a copy that can start monitor jobs. Nil leaves the tool non-functional; surfaces without jobs do not register it at all.
func (*Monitor) WithSandbox ¶
func (m *Monitor) WithSandbox(v agent.SandboxView) *Monitor
WithSandbox returns a copy whose command resolution wraps through the given SandboxView, exactly as Bash does.
type NoteWrite ¶
type NoteWrite struct{}
NoteWrite records durable session notes. Unlike a tool result, a note is not a message: it survives history compaction and is re-rendered on every model call, so it is where the agent keeps what the conversation cannot be trusted to hold.
The store is reached through the context rather than held on the tool, because the tool registry is cached per model and shared across sessions.
func (*NoteWrite) Access ¶
Name returns the tool name for the LLM. Access implements llm.AccessDeclarer. Session notes have no lock, so this is a write and cannot run concurrently with a sibling call.
func (*NoteWrite) DefaultAction ¶
func (t *NoteWrite) DefaultAction() llm.ToolAction
DefaultAction implements llm.PolicyProvider, overriding the action the permission layer would otherwise derive from Access.
What this writes is the agent's own scratch state, not anything the user owns. Asking a user to approve the agent taking a note would be noise, and the noise would arrive on every run. The write classification above is still the honest one — it is what keeps this tool out of a parallel batch. See docs/design/tool-permissions.md §5.2.
func (*NoteWrite) Description ¶
Description tells the LLM what belongs in a note. The behavioural contract matters more than the name here: without a stated rule the list fills with narration and duplicated context.
func (*NoteWrite) Parameters ¶
Parameters returns the OpenAI-style JSON schema for the tool arguments.
type PublishedArtifact ¶
type PublishedArtifact struct {
ArtifactID string
Filename string
SizeBytes int64
// URL is where an authorized person opens it. Empty when the surface knows
// the id but not the address to render it at.
URL string
// ShareURL is a public link anyone can open, set only when Share was asked
// for and the server created one. ShareDownloadURL is its raw-download form.
// still published; only the link is missing.
ShareError string
}
PublishedArtifact is what the artifact service made of it.
type ReadFile ¶
type ReadFile struct {
// contains filtered or unexported fields
}
ReadFile reads a local file under a workspace root.
func NewReadFile ¶
NewReadFile creates a ReadFile tool that reads files under the given workspace root.
func (*ReadFile) Access ¶
Name returns the tool name for the LLM. Access implements llm.AccessDeclarer.
func (*ReadFile) CheckArgs ¶
func (r *ReadFile) CheckArgs(args map[string]any) llm.ToolAction
CheckArgs implements llm.ArgChecker. Reading a sensitive file (credentials, private keys) triggers Ask so the user can confirm intent in interactive sessions.
func (*ReadFile) Description ¶
Description returns a short description so the LLM knows when to use this tool.
func (*ReadFile) Execute ¶
Execute reads the file at args["file_path"] if it is under the tool's root. File contents are returned as UTF-8 text; invalid UTF-8 in the file is passed through as-is.
func (*ReadFile) Parameters ¶
Parameters returns the OpenAI-style JSON schema for the tool arguments.
type ReportToIssue ¶
type ReportToIssue struct {
// contains filtered or unexported fields
}
ReportToIssue posts one comment on the issue this run is working.
func NewReportToIssue ¶
func NewReportToIssue(client IssueClient) *ReportToIssue
func (*ReportToIssue) Description ¶
func (t *ReportToIssue) Description() string
func (*ReportToIssue) Name ¶
func (t *ReportToIssue) Name() string
func (*ReportToIssue) Parameters ¶
func (t *ReportToIssue) Parameters() any
type SkillEntry ¶
type SkillEntry struct {
Name string // skill identifier (directory name)
Description string // short description extracted from SKILL.md
Path string // absolute path to the SKILL.md file
// Origin is the layer this skill was found in. Status surfaces it so a
// plugin's contribution is visible, and so is anything that shadowed it.
Origin plugin.Origin
}
SkillEntry holds metadata for one discovered skill.
func DiscoverSkillEntries ¶
func DiscoverSkillEntries(searchPaths []string) []SkillEntry
DiscoverSkillEntries scans search paths for subdirectories containing SKILL.md. First-path-wins on name conflicts. Returns skills sorted alphabetically by name. This is the unlabelled form, for a caller with no layering to express.
type SkillResolution ¶
type SkillResolution struct {
Entries []SkillEntry
Shadowed []plugin.Shadowed
Findings []plugin.Finding
}
SkillResolution is what scanning every source produced: the skills that load, the definitions a higher layer shadowed, and the collisions that stopped a name from loading at all.
func ResolveSkills ¶
func ResolveSkills(sources []plugin.Source) SkillResolution
ResolveSkills scans priority-ordered sources and reduces them to one skill per name. Sources come from internal/config: workspace, then global, then each plugin in name order.
type SkillTool ¶
type SkillTool struct {
// contains filtered or unexported fields
}
SkillTool is an agent tool that discovers and invokes skills from disk. It implements agent.Tool.
func NewSkill ¶
NewSkill creates a SkillTool that discovers skills from the given search paths. Each search path is scanned one level deep for subdirectories containing a SKILL.md file. Missing directories are silently skipped. If multiple search paths contain a skill with the same name, the first one found wins (search paths are priority-ordered).
func NewSkillFromEntries ¶
func NewSkillFromEntries(entries []SkillEntry) *SkillTool
NewSkillFromEntries creates a SkillTool from pre-discovered skill entries. The provided entries are copied so callers can treat the returned tool as immutable.
func (*SkillTool) Access ¶
Name returns the tool name for the LLM. Access implements llm.AccessDeclarer.
func (*SkillTool) Description ¶
Description returns a static preamble followed by a dynamic listing of discovered skills.
func (*SkillTool) Execute ¶
Execute looks up the requested skill, reads its SKILL.md file, and returns the content. If args is provided, it is prepended as context.
func (*SkillTool) Parameters ¶
Parameters returns the OpenAI-style JSON schema for the tool arguments.
type SubAgentRunOpts ¶
type SubAgentRunOpts struct {
Tools []llm.Tool
SystemPrompt string
Description string
MaxIter int // 0 = defaultSubAgentMaxIter
Model string // "" = use runner default client
}
SubAgentRunOpts configures one sub-agent invocation.
type SubAgentRunner ¶
type SubAgentRunner interface {
RunSubAgent(ctx context.Context, opts SubAgentRunOpts, prompt string) (reply string, err error)
}
SubAgentRunner runs a sub-agent with the given options and prompt. It is implemented by agentapp and injected when building the Task tool so that tools do not depend on a concrete runner; tests can inject a mock.
func NewDefaultSubAgentRunner ¶
func NewDefaultSubAgentRunner(llmClient llm.LLMClient, policy coreagent.ToolPolicy, modelResolver func(string) (llm.LLMClient, error), opts ...SubAgentRunnerOption) (SubAgentRunner, error)
NewDefaultSubAgentRunner returns a SubAgentRunner backed by the given LLM client. policy is inherited from the parent agent run (nil = AllowAll). modelResolver looks up an LLM client by model name for agent types that specify a model; nil means always use client regardless of the model field.
type SubAgentRunnerOption ¶
type SubAgentRunnerOption func(*defaultSubAgentRunner)
SubAgentRunnerOption configures a SubAgentRunner.
func WithSubAgentHooks ¶
func WithSubAgentHooks(h coreagent.HookRunner) SubAgentRunnerOption
WithSubAgentHooks attaches a parent hook runner so subagent runs honor the same PreToolUse / PostToolUse / lifecycle hooks as the parent agent. Nil disables hooks.
func WithSubAgentMaxParallelTools ¶
func WithSubAgentMaxParallelTools(n int) SubAgentRunnerOption
WithSubAgentMaxParallelTools gives sub-agent runs the same tool-scheduling limit as the parent. Without it a sub-agent runs every call sequentially, which loses the setting exactly where it pays best: an exploration agent batches reads and searches for a living.
func WithSubAgentSessionFactory ¶
func WithSubAgentSessionFactory(f SubAgentSessionFactory) SubAgentRunnerOption
WithSubAgentSessionFactory supplies the private session each subagent run gets. Without it, subagent history is in-memory and discarded on return.
func WithSubAgentTraceFactory ¶
func WithSubAgentTraceFactory(factory SubAgentTraceFactory) SubAgentRunnerOption
WithSubAgentTraceFactory attaches durable trace creation at the assembly layer. A nil factory leaves subagent execution unchanged.
type SubAgentSession ¶
type SubAgentSession interface {
coreagent.NotesHistory
coreagent.CompactionHistory
ID() string
Close() error
}
SubAgentSession is one subagent's own conversation: everything the loop needs to read and commit history, plus the identity and close it needs to be a durable session rather than a scratch buffer.
It is an interface here for the same reason SubAgentTrace is: this package sits below infra, so it says what it needs and lets agentapp supply the durable implementation.
type SubAgentSessionFactory ¶
type SubAgentSessionFactory func(ctx context.Context, opts SubAgentRunOpts) (SubAgentSession, error)
SubAgentSessionFactory creates the private session for one subagent run.
§9 of the local session storage plan gives every subagent its own hidden bundle: it must never write into the parent's journal or durable state, and the parent's Task result stays the model-facing return path. A nil factory falls back to an in-memory session, which is what a test or an embedder with no store gets.
type SubAgentTrace ¶
SubAgentTrace receives the event stream for one subagent run. It is kept as a small interface so this package stays below infra: agentapp supplies the durable trace implementation without making the tool layer know where or how traces are stored.
type SubAgentTraceFactory ¶
type SubAgentTraceFactory func(ctx context.Context, sessionID string, opts SubAgentRunOpts) SubAgentTrace
SubAgentTraceFactory opens a trace for a subagent run. sessionID is the session the trace is filed under — the parent's, so a subagent's diagnostics stay reachable from a session a person can still find. Returning nil disables only this trace; the subagent must still run.
type TaskTool ¶
type TaskTool struct {
// contains filtered or unexported fields
}
TaskTool is an agent tool that spawns sub-agents to handle complex subtasks. It implements llm.Tool.
func NewTask ¶
func NewTask(runner SubAgentRunner, agentTypes map[string]AgentTypeConfig) (*TaskTool, error)
NewTask creates a TaskTool with the given sub-agent runner and agent type configurations. runner must not be nil; agentTypes must have at least one entry.
func (*TaskTool) Access ¶
Access implements llm.AccessDeclarer. A sub-agent writes whatever its tools write, so the answer is the requested type's tool set rather than the Task tool itself: a type restricted to read-only tools runs a nested loop that cannot write, and may overlap its neighbours.
Everything else is a write — an unknown type, a background run (which mutates the job manager and outlives the call), and a nil-args capability listing, which is asking about the tool and not about a call.
func (*TaskTool) Description ¶
Description returns a dynamically built description listing all available agent types.
func (*TaskTool) Execute ¶
Execute spawns a sub-agent of the requested type, runs the prompt, and returns the reply.
func (*TaskTool) Parameters ¶
Parameters returns the OpenAI-style JSON schema with a dynamic enum for subagent_type.
func (*TaskTool) WithJobs ¶
WithJobs returns a copy of t that can detach subagents to the given job manager. Nil leaves background execution unavailable.
func (*TaskTool) WithWorktrees ¶
func (t *TaskTool) WithWorktrees(m *worktree.Manager, toolsAt AgentTypeToolsAt) *TaskTool
WithWorktrees returns a copy of t that can give a delegate its own worktree.
Offered, never imposed: nothing forces one worktree per subagent, and the model decides per delegation whether the isolation is worth a tree the user will have to clean up by hand. See docs/design/workspace-root-and-worktrees.md D7.
type TodoWrite ¶
type TodoWrite struct{}
TodoWrite records the task list the LLM uses to trace progress.
The list is durable session state, not a message: it survives history compaction and is re-rendered on every model call. It is stored through the context, because the tool registry is cached per model and shared across sessions. A run with no store — a subagent, for instance — still gets a formatted list back, and is told the list was not kept.
func (*TodoWrite) Access ¶
Name returns the tool name for the LLM. Access implements llm.AccessDeclarer. Session task list has no lock, so this is a write and cannot run concurrently with a sibling call.
func (*TodoWrite) DefaultAction ¶
func (t *TodoWrite) DefaultAction() llm.ToolAction
DefaultAction implements llm.PolicyProvider, overriding the action the permission layer would otherwise derive from Access.
What this writes is the agent's own scratch state, not anything the user owns. Asking a user to approve the agent taking a note would be noise, and the noise would arrive on every run. The write classification above is still the honest one — it is what keeps this tool out of a parallel batch. See docs/design/tool-permissions.md §5.2.
func (*TodoWrite) Description ¶
Description returns a short description so the LLM knows when to use this tool.
func (*TodoWrite) Execute ¶
Execute parses and validates todos from args, stores them on the session when the run keeps durable state, and returns a formatted list for the LLM.
func (*TodoWrite) Parameters ¶
Parameters returns the OpenAI-style JSON schema for the tool arguments.
type UploadArtifact ¶
type UploadArtifact struct {
// contains filtered or unexported fields
}
UploadArtifact publishes one file the agent names as a durable artifact.
func NewUploadArtifact ¶
func NewUploadArtifact(ws util.Workspace, publisher ArtifactPublisher) *UploadArtifact
NewUploadArtifact creates the tool. It is only ever constructed where a publisher exists; see agentapp's tool assembly.
func (*UploadArtifact) Description ¶
func (t *UploadArtifact) Description() string
Description states the choosing rule, not just the mechanics.
Without it the tool is used as a save button and the space's artifact list fills with intermediate files. What the model has to understand is that this publishes, once, the file a person is meant to receive.
func (*UploadArtifact) Execute ¶
Execute validates the file, publishes it, and reports the reference.
func (*UploadArtifact) Name ¶
func (t *UploadArtifact) Name() string
func (*UploadArtifact) Parameters ¶
func (t *UploadArtifact) Parameters() any
type WebFetch ¶
type WebFetch struct {
// contains filtered or unexported fields
}
WebFetch is a tool that fetches a URL, converts HTML to markdown, optionally processes content with the LLM using a prompt, and returns the result. It implements the llm.Tool interface.
func NewWebFetch ¶
NewWebFetch creates a WebFetch tool with the given LLM client and cache TTL. llmClient may be nil: fetching without a "prompt" argument still works; if "prompt" is set, Execute returns an error until a non-nil client is provided.
func (*WebFetch) Access ¶
Name returns the tool name for the LLM. Access implements llm.AccessDeclarer. The only thing it writes is its own response cache, which cacheMu guards.
func (*WebFetch) Description ¶
Description returns a short description so the LLM knows when to use this tool.
func (*WebFetch) Execute ¶
Execute fetches the URL, converts HTML to markdown, optionally calls the LLM with content+prompt, and returns the result.
func (*WebFetch) Parameters ¶
Parameters returns the OpenAI-style JSON schema for the tool arguments.
func (*WebFetch) WithSandbox ¶
func (w *WebFetch) WithSandbox(v agent.SandboxView) *WebFetch
WithSandbox installs v as the host filter on w and returns w. Mutates in place because WebFetch holds shared cache state behind a mutex — copying would split the cache. Pass agent.NoopSandbox{} (or nil) to disable enforcement.
type Worktree ¶
type Worktree struct {
// contains filtered or unexported fields
}
Worktree creates, enters, leaves, lists, and removes Git worktrees, moving the session's workspace root as it goes.
Every other tool then follows: the point of the tool is that after entering, nothing needs a path prefix or a different call. See docs/design/workspace-root-and-worktrees.md.
func NewWorktree ¶
NewWorktree creates the tool over a worktree manager. Nil leaves the tool off the surface entirely rather than present and always failing.
func (*Worktree) Access ¶
Access reports what each action does to the workspace, so the permission tier is derived from the action rather than from the tool.
Creating and entering are ordinary writes: a new directory on a new branch interrupts nobody, and that autonomy is the point. Removing can destroy the only copy of work, so it asks — see CheckArgs and docs/design/workspace-root-and-worktrees.md D4.
func (*Worktree) CheckArgs ¶
func (w *Worktree) CheckArgs(args map[string]any) llm.ToolAction
CheckArgs makes removal ask while the rest runs.
func (*Worktree) Description ¶
func (*Worktree) Parameters ¶
type WriteFile ¶
type WriteFile struct {
// contains filtered or unexported fields
}
WriteFile writes content to a local file under a workspace root.
func NewWriteFile ¶
NewWriteFile creates a WriteFile tool that writes files under the given workspace root.
func (*WriteFile) Access ¶
Name returns the tool name for the LLM. Access implements llm.AccessDeclarer.
func (*WriteFile) CheckArgs ¶
func (w *WriteFile) CheckArgs(args map[string]any) llm.ToolAction
CheckArgs implements llm.ArgChecker. Writing to a sensitive file (credentials, private keys) triggers Ask so the user can confirm intent in interactive sessions.
func (*WriteFile) Description ¶
Description returns a short description so the LLM knows when to use this tool.
func (*WriteFile) Execute ¶
Execute writes args["content"] to the file at args["file_path"] if the path is under the tool's root. Creates parent directories if needed; overwrites if the file exists. Returns a short success message or error.
func (*WriteFile) Parameters ¶
Parameters returns the OpenAI-style JSON schema for the tool arguments.