Documentation
¶
Overview ¶
Package shell exposes a single LLM-callable shell tool plus a small Executor SPI. The package itself does not pick where commands run — local, sandboxed, or remote backends each implement Executor and plug in via NewTool.
The local executor (NewLocalExecutor) is the reference impl and covers the common case (run on the same host as the agent).
A non-zero exit status is a completed execution result. Transport, collection, and cleanup errors can leave the outcome unknown; Tool retains the observed output as core/tool.CallError evidence without inventing a definite failure. Response streams use content.Content so binary data and a UTF-8 prefix split by a byte limit survive serialization without losing the other observations.
Index ¶
Constants ¶
This section is empty.
Variables ¶
var ( // ErrEmptyCommand and ErrInvalidInput reject the command before execution. // Backends must not return either after dispatch or mutation. ErrEmptyCommand = errors.New("shell: command must not be empty") ErrInvalidConfig = errors.New("shell: executor configuration is invalid") ErrInvalidInput = errors.New("shell: input is invalid") ErrNilExecutor = errors.New("shell: executor must not be nil") )
Functions ¶
This section is empty.
Types ¶
type Executor ¶
type Executor interface {
// Run executes exactly one command within the executor's frozen authority.
// It honors ctx and Input.Timeout, returns non-zero exit status as Output
// rather than error, and reserves error for spawn, I/O, or collection failure.
// On error, Output retains all available execution facts. Neither an error
// nor missing output proves that the command had no side effects.
// A backend may return core/tool.Failure only when it can establish a
// complete unsuccessful outcome; that failure owns its model-visible output.
// Other errors retain uncertainty, with observed Output carried by the Tool
// as core/tool.CallError evidence. They are not automatic retry instructions.
Run(ctx context.Context, in Input) (Output, error)
}
Executor is the authority boundary behind the model-facing shell tool. The concrete implementation owns process creation, working-directory policy, environment exposure, output capture, termination, and platform semantics.
type LocalConfig ¶ added in v0.13.0
type LocalConfig struct {
Directory string
Shell string
// MaxBytesPerStream caps captured stdout and stderr independently.
// Zero selects 30 KiB per stream; truncation markers are additional bytes.
MaxBytesPerStream int
}
LocalConfig makes the local process authority visible at construction. The directory controls relative-path resolution but is not a filesystem jail; callers that need confinement must supply an OS sandbox or container.
type LocalExecutor ¶
type LocalExecutor struct {
// contains filtered or unexported fields
}
LocalExecutor runs commands on the local host through one immutable construction-time configuration. Each call owns a Unix process group and kills that group on cancellation or return, including background children. A command that deliberately creates another session requires a host sandbox to keep its lifetime confined; this executor is not a process sandbox.
func NewLocalExecutor ¶
func NewLocalExecutor(config LocalConfig) (*LocalExecutor, error)
NewLocalExecutor freezes an absolute working directory and output limits.
type Output ¶
type Output struct {
Stdout []byte
Stderr []byte
ExitCode int
Duration time.Duration
// Truncation is an observation, independent of markers in command output.
// A false value does not prove complete collection when Run returns an error.
StdoutTruncated bool
StderrTruncated bool
// CancellationObserved reports that cancellation or timeout was observed
// before returning; it does not establish why the process exited.
CancellationObserved bool
}
Output retains the executor's observations. A non-zero ExitCode is not an error. When Run returns an error, an unobserved exit code must not be reported as zero; ExitCode is -1 when no exit status was obtained. Available output remains evidence and does not establish a complete command result.
type Request ¶
type Request struct {
Command string `` /* 128-byte string literal not displayed */
TimeoutMS int `` /* 168-byte string literal not displayed */
}
Environment, working directory, and streaming remain executor-owned.
type Response ¶
type Response struct {
Stdout content.Content `json:"stdout"`
Stderr content.Content `json:"stderr"`
StdoutTruncated bool `json:"stdout_truncated,omitzero"`
StderrTruncated bool `json:"stderr_truncated,omitzero"`
ExitCode int `json:"exit_code"`
CancellationObserved bool `json:"cancellation_observed,omitzero"`
Duration string `json:"duration"`
}
Captured bytes remain lossless for binary output and truncated UTF-8 text.
type Tool ¶
type Tool struct {
// contains filtered or unexported fields
}
Tool retains Host-selected execution authority; model arguments cannot change the shell, working directory, or process policy.
func (*Tool) Call ¶
func (t *Tool) Call(ctx context.Context, invocation toolcontract.Invocation) (chat.ToolOutput, error)
func (*Tool) Definition ¶
func (t *Tool) Definition() chat.ToolDefinition
func (*Tool) Unwrap ¶ added in v0.19.0
func (t *Tool) Unwrap() toolcontract.Tool