tool

package
v0.34.1 Latest Latest
Warning

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

Go to latest
Published: Aug 30, 2026 License: MIT Imports: 33 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var ErrTooManyBashJobs = &bashJobError{"too many concurrent background bash jobs"}

ErrTooManyBashJobs is returned when the session background-job cap is hit.

View Source
var ErrUnknownBashJob = &bashJobError{"unknown bash job ID"}

ErrUnknownBashJob is returned when a job ID is not found.

Functions

func CleanupSpillFiles

func CleanupSpillFiles() error

CleanupSpillFiles removes expired regular spill files. It never follows a symlink, either for the spill directory or for an entry within it. It is safe to call at process/session startup and is also invoked before the first spill is created in a process.

func EditStartLine

func EditStartLine(content, oldText string) int

EditStartLine returns the 1-based line number where oldText starts in content, so edit previews can show real file line numbers. It prefers the first exact occurrence and falls back to the same fuzzy matching the edit tool uses. Returns 1 when oldText is empty or cannot be located (callers degrade to numbering from 1).

func EditStartLineForFile

func EditStartLineForFile(path, oldText string) int

EditStartLineForFile reads path and returns the 1-based line where oldText begins, for previewing an edit before the tool runs. It is deliberately defensive because it runs on a hot path from untrusted tool args: it only reads regular files (never devices/FIFOs, which could block or stream forever) and caps the read at maxPreviewFileBytes. On any problem it returns 1 so the caller degrades to numbering from the top.

func NewApplyPatch

func NewApplyPatch(cfg ToolConfig) core.Tool

NewApplyPatch creates the apply_patch tool for multi-file patches.

func NewBash

func NewBash(cfg ToolConfig) core.Tool

NewBash creates the bash tool.

func NewBashCancel

func NewBashCancel(cfg ToolConfig) core.Tool

NewBashCancel creates the cancellation tool paired with async bash.

func NewBashStatus

func NewBashStatus(cfg ToolConfig) core.Tool

NewBashStatus creates the status tool paired with async bash.

func NewBashWait

func NewBashWait(cfg ToolConfig) core.Tool

NewBashWait creates the blocking-wait tool paired with async bash. It lets the model block on a background job's completion instead of polling bash_status in a loop (which would burn turns and trip the doom-loop guard).

func NewEdit

func NewEdit(cfg ToolConfig) core.Tool

NewEdit creates the edit tool.

func NewFetch

func NewFetch(cfg ToolConfig) core.Tool

NewFetch creates the fetch_content tool.

func NewFind

func NewFind(cfg ToolConfig) core.Tool

NewFind creates the find tool.

func NewGrep

func NewGrep(cfg ToolConfig) core.Tool

NewGrep creates the grep tool.

func NewLs

func NewLs(cfg ToolConfig) core.Tool

NewLs creates the ls tool.

func NewMemory

func NewMemory(cfg ToolConfig) core.Tool

NewMemory creates the memory tool for managing cross-session memory as single-fact files (list/search/read/write/delete).

func NewMultiEdit

func NewMultiEdit(cfg ToolConfig) core.Tool

NewMultiEdit creates the multiedit tool for atomic batch edits to a single file.

func NewRead

func NewRead(cfg ToolConfig) core.Tool

NewRead creates the read tool.

func NewSessionCheckpoint

func NewSessionCheckpoint(slot *sessioncheckpoint.Slot) core.Tool

func NewWebSearch

func NewWebSearch(cfg ToolConfig) core.Tool

NewWebSearch creates the web_search tool backed by Brave Search API. baseURL overrides the API endpoint (for testing); pass "" for production.

func NewWrite

func NewWrite(cfg ToolConfig) core.Tool

NewWrite creates the write tool.

func RegisterApplyPatch

func RegisterApplyPatch(reg *core.Registry, cfg ToolConfig) error

func RegisterBash

func RegisterBash(reg *core.Registry, cfg ToolConfig) error

func RegisterBuiltins

func RegisterBuiltins(reg *core.Registry, cfg ToolConfig) error

RegisterBuiltins adds all built-in tools to the registry.

func RegisterEdit

func RegisterEdit(reg *core.Registry, cfg ToolConfig) error

func RegisterFetch

func RegisterFetch(reg *core.Registry, cfg ToolConfig) error

func RegisterFind

func RegisterFind(reg *core.Registry, cfg ToolConfig) error

func RegisterGrep

func RegisterGrep(reg *core.Registry, cfg ToolConfig) error

func RegisterLs

func RegisterLs(reg *core.Registry, cfg ToolConfig) error

func RegisterMemory

func RegisterMemory(reg *core.Registry, cfg ToolConfig) error

func RegisterMultiEdit

func RegisterMultiEdit(reg *core.Registry, cfg ToolConfig) error

func RegisterRead

func RegisterRead(reg *core.Registry, cfg ToolConfig) error

func RegisterScriptTools

func RegisterScriptTools(reg *core.Registry, cwd string) error

RegisterScriptTools registers script tools into the registry. Tools that collide with already-registered names are skipped with a warning to prevent untrusted repos from shadowing builtins.

func RegisterWebSearch

func RegisterWebSearch(reg *core.Registry, cfg ToolConfig) error

func RegisterWrite

func RegisterWrite(reg *core.Registry, cfg ToolConfig) error

func SafePath

func SafePath(cfg ToolConfig, path string) (string, error)

SafePath resolves path against cfg's workspace/PathPolicy, exactly as the built-in file tools do. Exposed so out-of-package tools (e.g. serve's send_file) enforce the same path boundary as read.

func SpillOutputDir

func SpillOutputDir() string

SpillOutputDir returns the directory where tool output spill files are stored.

func SummarizeArgs

func SummarizeArgs(args map[string]any) string

summarizeArgs creates a short string summary of tool arguments for logging.

func ValidateParams

func ValidateParams(t core.Tool, args map[string]any) error

ValidateParams validates tool call arguments against the tool's JSON Schema. V0 validates: required fields, type checks, enum values.

func ValidateToolCall

func ValidateToolCall(registry *core.Registry, toolName string, args map[string]any) error

ValidateToolCall validates a tool call's parameters against the registry. Returns an error string for the LLM if validation fails.

Types

type BashJobInfo

type BashJobInfo struct {
	JobID        string
	OwnerAgentID string
	Command      string
	CWD          string
	Status       string
	Output       string
	StartedAt    time.Time
	FinishedAt   time.Time
	// Awaited is set on the snapshot delivered to onEnd when a bash_wait call
	// owns the completion result. It signals the completion handler to suppress
	// result reinjection (the waiter already consumed it).
	Awaited bool
}

BashJobInfo is the UI/status-safe snapshot of a background bash command.

type BashJobs

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

BashJobs owns session-scoped background bash processes. Jobs deliberately do not persist shell state: they receive a launch-time snapshot, but a later background completion must not overwrite foreground cd/export state.

func NewBashJobs

func NewBashJobs(ctx context.Context, onStart func(BashJobInfo), onOutput func(BashJobInfo, string), onEnd func(BashJobInfo)) *BashJobs

NewBashJobs creates a session-scoped background job manager.

func (*BashJobs) Cancel

func (j *BashJobs) Cancel(jobID string) bool

Cancel stops a job's process group through its execution context.

func (*BashJobs) Get

func (j *BashJobs) Get(jobID string) (BashJobInfo, bool)

Get returns a current snapshot by ID.

func (*BashJobs) Snapshot

func (j *BashJobs) Snapshot() []BashJobInfo

Snapshot returns live and recently completed jobs. Output is authoritative after completion and is suitable for a reconnect/status view.

func (*BashJobs) Start

func (j *BashJobs) Start(command, cwd, ownerAgentID string, run func(context.Context, func(core.Result)) (core.Result, error)) (BashJobInfo, error)

Start launches run in the session context. run must return the same final result a synchronous bash invocation would return.

func (*BashJobs) Wait

func (j *BashJobs) Wait(ctx context.Context, jobID string, timeout time.Duration) (BashJobInfo, bool, error)

Wait blocks until the job finishes, the context is cancelled, or timeout elapses (timeout <= 0 waits indefinitely). It returns the job snapshot and a delivered flag. If the job finishes, the snapshot is final regardless of what woke the wait. On timeout it returns the current (still-running) snapshot without an error; the caller distinguishes via FinishedAt.

delivered reports whether THIS call owns the one-time full-output delivery to the model. It is true when the wait consumes the completion result (a blocked waiter, or the first caller to reach a terminal job before the async notification claimed it). It is false when the async notification already delivered the output — the caller should then return a brief acknowledgment instead of re-dumping the same output the model already saw.

type BashState

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

BashState holds per-agent shell state (cwd + exported env) persisted across bash tool calls within one session. Keyed by agentID (read from ctx); "" is the root/parent agent. Subagents get an isolated copy seeded from their parent (subshell semantics: child changes never propagate back).

func NewBashState

func NewBashState() *BashState

NewBashState returns an empty BashState.

func (*BashState) Drop

func (s *BashState) Drop(agentID string)

Drop removes an agent's snapshot (called when a subagent job finishes) so the map doesn't grow unbounded across many subagents.

func (*BashState) Seed

func (s *BashState) Seed(childID, parentID string)

Seed copies the parent agent's current snapshot into childID (called when a subagent starts). No-op if the parent has no snapshot yet.

func (*BashState) Snapshot

func (s *BashState) Snapshot(agentID string) (cwd string, env []string)

Snapshot returns the persisted cwd and a copy of the env for the given agent (nil-safe: unknown agent → "", nil).

func (*BashState) Update

func (s *BashState) Update(agentID, cwd string, env []string)

Update replaces the given agent's persisted state after a successful capture.

type FileTracker

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

FileTracker records when files were last read by the agent. Used by edit/write tools to warn when modifying files that haven't been read recently (stale edit protection).

func NewFileTracker

func NewFileTracker() *FileTracker

NewFileTracker creates a new file tracker.

func (*FileTracker) Clear

func (ft *FileTracker) Clear()

Clear resets the tracker (e.g. on session clear).

func (*FileTracker) LastRead

func (ft *FileTracker) LastRead(resolvedPath string) time.Time

LastRead returns when a file was last read. Returns zero time if never read.

func (*FileTracker) MarkRead

func (ft *FileTracker) MarkRead(resolvedPath string)

MarkRead records that a file was read at the current time.

func (*FileTracker) WasRead

func (ft *FileTracker) WasRead(resolvedPath string) bool

WasRead returns true if the file has been read at least once in this session.

type HunkType

type HunkType int

HunkType classifies a patch hunk operation.

const (
	HunkAdd    HunkType = iota // create a new file
	HunkDelete                 // delete an existing file
	HunkUpdate                 // modify an existing file
)

type PatchChunk

type PatchChunk struct {
	Context string    // @@ anchor text (empty if none)
	Ops     []PatchOp // operations in order
}

PatchChunk represents a contiguous block of changes within an update hunk.

type PatchHunk

type PatchHunk struct {
	Type     HunkType
	Path     string
	MovePath string       // only for update with rename (*** Move to:)
	Content  string       // only for add: full file content
	Chunks   []PatchChunk // only for update: diff chunks
}

PatchHunk represents an operation on a single file within a patch.

func ParsePatch

func ParsePatch(text string) ([]PatchHunk, error)

ParsePatch parses the Codex-style *** Begin Patch format.

type PatchOp

type PatchOp struct {
	Type PatchOpType
	Line string // line content without the prefix character
}

PatchOp is a single line operation within a chunk.

type PatchOpType

type PatchOpType int

PatchOpType classifies a line operation within a chunk.

const (
	OpContext PatchOpType = iota // ' ' line — present in both old and new
	OpAdd                        // '+' line — only in new
	OpRemove                     // '-' line — only in old
)

type PathPolicy

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

PathPolicy controls runtime-mutable path access rules. Thread-safe. Shared (via pointer) across all tool closures so that /path add and /path rm take effect immediately.

func NewPathPolicy

func NewPathPolicy(root string, allowed []string, unrestricted bool) *PathPolicy

NewPathPolicy creates a PathPolicy. root is the workspace directory. allowed are additional directories permitted outside root. unrestricted disables all path containment checks.

func (*PathPolicy) AddPath

func (p *PathPolicy) AddPath(dir string) error

AddPath adds a directory to the allowed paths list. Returns an error if the path does not exist or is not a directory.

func (*PathPolicy) AllowedPaths

func (p *PathPolicy) AllowedPaths() []string

AllowedPaths returns a snapshot of the current allowed paths.

func (*PathPolicy) IsAllowed

func (p *PathPolicy) IsAllowed(realPath string) bool

IsAllowed checks whether realPath (already symlink-resolved) is permitted. It checks workspace root containment, then allowed paths.

A nil policy means no policy was configured, and allows everything — so callers holding an optional *PathPolicy can pass it straight through, including when it is wrapped in an interface, where a nil check at the call site would not catch it.

func (*PathPolicy) RemovePath

func (p *PathPolicy) RemovePath(dir string) bool

RemovePath removes a directory from the allowed paths list. Returns true if the path was found and removed.

func (*PathPolicy) Restore

func (p *PathPolicy) Restore(allowed []string, unrestricted bool)

Restore replaces the mutable path-policy state without publishing a runtime configuration event. It is used when a persisted session is restored.

func (*PathPolicy) Scope

func (p *PathPolicy) Scope() string

Scope returns a human-readable scope description: "unrestricted", "workspace", or "ws+N" (N = number of extra allowed paths).

func (*PathPolicy) SetUnrestricted

func (p *PathPolicy) SetUnrestricted(v bool)

SetUnrestricted toggles unrestricted (sandbox-disabled) mode.

func (*PathPolicy) Unrestricted

func (p *PathPolicy) Unrestricted() bool

Unrestricted returns whether path checks are disabled.

func (*PathPolicy) WorkspaceRoot

func (p *PathPolicy) WorkspaceRoot() string

WorkspaceRoot returns the workspace root directory.

type ScriptDef

type ScriptDef struct {
	Name        string `json:"name"`
	Description string `json:"description"`
	Command     string `json:"command"`
	Timeout     int    `json:"timeout"` // seconds, 0 = 60s default
}

ScriptDef defines a user-provided script tool loaded from JSON.

func LoadScriptTools

func LoadScriptTools(cwd string) ([]ScriptDef, error)

LoadScriptTools discovers and loads tool definitions from .moa/tools/*.json. Returns nil (no error) if the directory doesn't exist.

type ShellConfig

type ShellConfig struct {
	Command   string
	Dir       string
	Timeout   time.Duration // 0 = no timeout (uses parent ctx deadline only)
	MaxOutput int           // per-stream max bytes (head+tail), default 25KB
}

ShellConfig configures a shell command execution.

type ShellResult

type ShellResult struct {
	Stdout   string
	Stderr   string
	ExitCode int
	TimedOut bool
	Elapsed  time.Duration
}

ShellResult holds the output of a shell command execution.

func RunShell

func RunShell(ctx context.Context, cfg ShellConfig) ShellResult

RunShell executes a bash command with process group handling, WaitDelay, and head+tail output buffering. Returns a structured result rather than a core.Result so callers can format output however they need.

type ToolConfig

type ToolConfig struct {
	WorkspaceRoot  string        // Required. All path operations resolve relative to this.
	DisableSandbox bool          // When true, safePath allows any absolute path (YOLO mode). Deprecated: use PathPolicy.
	AllowedPaths   []string      // Additional directories allowed outside WorkspaceRoot. Deprecated: use PathPolicy.
	BashTimeout    time.Duration // Default: 5 minutes.
	BraveAPIKey    string        // Brave Search API key (empty = web_search not registered).
	MemoryStore    *memory.Store // Per-project memory store (nil = memory tool not registered).

	// PathPolicy is the runtime-mutable path access policy. When non-nil,
	// safePath delegates containment checks to this policy instead of using
	// DisableSandbox/AllowedPaths directly. All tool closures share the same
	// pointer, so runtime changes (/path add, /path rm) take effect immediately.
	PathPolicy *PathPolicy

	// BeforeWrite is called before modifying a file (write/edit tools).
	// If it returns an error, the write is aborted. Used by the checkpoint
	// system to capture pre-edit state. nil = no hook.
	BeforeWrite func(path string) error

	// FileTracker records file reads for stale-edit protection. When set,
	// the read tool marks files as read and the edit tool warns when
	// editing files that haven't been read. nil = no tracking.
	FileTracker *FileTracker

	// BashState, when non-nil, makes the bash tool persist cwd and exported
	// env across calls (captured via an EXIT trap, re-applied via cmd.Dir/Env).
	// nil = stateless behavior (previous default).
	BashState *BashState

	// BashJobs owns session-scoped background bash commands. nil leaves the
	// async parameter unavailable (useful for standalone tool registrations).
	BashJobs *BashJobs
}

ToolConfig provides shared configuration for built-in tools.

func (*ToolConfig) Defaults

func (c *ToolConfig) Defaults()

Defaults fills in zero-value fields with defaults.

Jump to

Keyboard shortcuts

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