executors

package
v1.0.0-beta.9 Latest Latest
Warning

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

Go to latest
Published: Apr 21, 2026 License: MIT Imports: 28 Imported by: 0

Documentation

Overview

Package executors provides tool executor implementations for the agentic system.

BashExecutor runs shell commands. When a sandbox is configured (SANDBOX_URL), commands execute inside the sandbox container. Otherwise, they run locally via os/exec with sensitive environment variables stripped.

Ported from semspec/tools/bash.

Package executors provides tool executor implementations for the agentic-tools component.

Package executors provides tool executor implementations for the agentic-tools component.

Package executors hosts the concrete tool implementations and their wire-to-global-registry entry points.

Stateless tools (bash, http_request, web_search, github_*) wire from env vars alone. Stateful tools (query_entity, read_loop_result, decide) need runtime deps (NATS KV buckets, platform identity) which only exist after the binary has initialised streams/buckets — so their wire functions take explicit arguments rather than registering at init() time.

The single caller of RegisterAll is main.go, after ensureStreams and before component.Start. Keeping wiring out of agentic-tools.Component leaves that component a pure tool-execution endpoint (it reads from the global registry, it doesn't write to it).

Index

Constants

This section is empty.

Variables

View Source
var ErrKeyNotFound = errs.ErrKeyNotFound

ErrKeyNotFound is returned when a key is not found in the KV store.

Functions

func RegisterAll

func RegisterAll(ctx context.Context, deps ToolDependencies)

RegisterAll wires every tool this package owns into the agentic-tools global registry. Failures are logged; stateful-tool wiring that can't reach its bucket skips silently and lets the rest proceed — same philosophy as the pre-refactor init() pattern.

Types

type BashExecutor

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

BashExecutor runs shell commands locally or via sandbox.

func NewBashExecutor

func NewBashExecutor(workDir, sandboxURL string, opts ...BashOption) *BashExecutor

NewBashExecutor creates a bash executor. If sandboxURL is non-empty, commands are routed to the sandbox container.

func NewBashExecutorFromEnv

func NewBashExecutorFromEnv() *BashExecutor

NewBashExecutorFromEnv creates a bash executor using environment variables. SANDBOX_URL enables sandbox mode. Work directory defaults to cwd.

func (*BashExecutor) Execute

Execute runs a shell command and returns the output.

func (*BashExecutor) ListTools

func (e *BashExecutor) ListTools() []agentic.ToolDefinition

ListTools returns the bash tool definition.

type BashOption

type BashOption func(*BashExecutor)

BashOption configures a BashExecutor.

func WithBashTimeout

func WithBashTimeout(d time.Duration) BashOption

WithBashTimeout overrides the default command timeout (120s).

type FlowExecutor

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

FlowExecutor implements CRUD tools for flow definitions. Mirrors RuleExecutor's shape (one executor per Pattern-B type, dispatching on ToolCall.Name to the right Manager method).

func NewFlowExecutor

func NewFlowExecutor(manager FlowManager) *FlowExecutor

NewFlowExecutor creates a flow management executor.

func (*FlowExecutor) Execute

Execute dispatches flow CRUD tool calls by name.

func (*FlowExecutor) ListTools

func (e *FlowExecutor) ListTools() []agentic.ToolDefinition

ListTools returns the five flow-CRUD tool definitions. Flow is a structured object (nodes, connections, runtime state, timestamps); the tool schema accepts a JSON object via `flow` parameter so LLMs can construct or edit definitions without a hand-crafted schema per field. Validation happens when the Manager unmarshals + Validate()s the payload.

type FlowManager

type FlowManager interface {
	Create(ctx context.Context, flow *flowstore.Flow) error
	Update(ctx context.Context, flow *flowstore.Flow) error
	Delete(ctx context.Context, id string) error
	Get(ctx context.Context, id string) (*flowstore.Flow, error)
	List(ctx context.Context) ([]*flowstore.Flow, error)
}

FlowManager is the subset of flowstore.Manager that FlowExecutor needs. Declared here so tests can substitute an in-memory fake without depending on the full *flowstore.Manager type. *flowstore.Manager satisfies it by duck typing.

type FlowTemplateExecutor

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

FlowTemplateExecutor implements Pattern-B CRUD plus an instantiate_flow_template tool that renders a template into a concrete flowstore.Flow using caller-supplied parameters. Instantiate is NOT stored — the coordinator still has to call create_flow to persist the resulting flow, which goes through flowstore.Manager's validation. Keeping render + persist separate lets the coordinator inspect the rendered flow before committing.

func NewFlowTemplateExecutor

func NewFlowTemplateExecutor(manager FlowTemplateManager) *FlowTemplateExecutor

NewFlowTemplateExecutor creates a flow-template management executor.

func (*FlowTemplateExecutor) Execute

Execute dispatches flow-template tool calls by name.

func (*FlowTemplateExecutor) ListTools

func (e *FlowTemplateExecutor) ListTools() []agentic.ToolDefinition

ListTools returns six tools: five CRUD + instantiate.

type FlowTemplateManager

type FlowTemplateManager interface {
	Create(ctx context.Context, t *flowtemplate.Template) error
	Update(ctx context.Context, t *flowtemplate.Template) error
	Delete(ctx context.Context, id string) error
	Get(ctx context.Context, id string) (*flowtemplate.Template, error)
	List(ctx context.Context) (map[string]*flowtemplate.Template, error)
}

FlowTemplateManager is the subset of flowtemplate.Manager that the executor needs. Declared here so tests can substitute in-memory fakes.

type GitHubClient

type GitHubClient interface {
	GetIssue(ctx context.Context, owner, repo string, number int) (*GitHubIssue, error)
	ListIssues(ctx context.Context, owner, repo string, opts ListIssuesOpts) ([]GitHubIssue, error)
	SearchIssues(ctx context.Context, query string) ([]GitHubIssue, error)
	GetPullRequest(ctx context.Context, owner, repo string, number int) (*GitHubPR, error)
	GetFileContent(ctx context.Context, owner, repo, path, ref string) (string, error)
	CreateBranch(ctx context.Context, owner, repo, branch, baseSHA string) error
	CommitFile(ctx context.Context, owner, repo, branch, path, content, message string) error
	CreatePullRequest(ctx context.Context, owner, repo, title, body, head, base string) (*GitHubPR, error)
	AddComment(ctx context.Context, owner, repo string, number int, body string) error
	AddLabels(ctx context.Context, owner, repo string, number int, labels []string) error
}

GitHubClient defines the interface for GitHub API operations. All methods accept context for cancellation and timeout propagation.

type GitHubHTTPClient

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

GitHubHTTPClient implements GitHubClient using the GitHub REST API v3. It authenticates via a Bearer token and parses only the fields the system needs.

func NewGitHubHTTPClient

func NewGitHubHTTPClient(token string) *GitHubHTTPClient

NewGitHubHTTPClient creates a new GitHubHTTPClient with the given personal access token.

func (*GitHubHTTPClient) AddComment

func (c *GitHubHTTPClient) AddComment(ctx context.Context, owner, repo string, number int, body string) error

AddComment posts a comment on an issue or pull request.

func (*GitHubHTTPClient) AddLabels

func (c *GitHubHTTPClient) AddLabels(ctx context.Context, owner, repo string, number int, labels []string) error

AddLabels applies labels to an issue or pull request.

func (*GitHubHTTPClient) CommitFile

func (c *GitHubHTTPClient) CommitFile(ctx context.Context, owner, repo, branch, path, content, message string) error

CommitFile creates or updates a single file on a branch using the Contents API. content is the raw file text; this method handles base64 encoding.

func (*GitHubHTTPClient) CreateBranch

func (c *GitHubHTTPClient) CreateBranch(ctx context.Context, owner, repo, branch, baseSHA string) error

CreateBranch creates a new branch from the given base SHA. It uses the Git refs API rather than the higher-level branch API so the caller controls exactly which commit the branch points at.

func (*GitHubHTTPClient) CreatePullRequest

func (c *GitHubHTTPClient) CreatePullRequest(ctx context.Context, owner, repo, title, body, head, base string) (*GitHubPR, error)

CreatePullRequest opens a new pull request from head into base.

func (*GitHubHTTPClient) GetFileContent

func (c *GitHubHTTPClient) GetFileContent(ctx context.Context, owner, repo, path, ref string) (string, error)

GetFileContent retrieves the decoded text content of a file at a specific ref.

func (*GitHubHTTPClient) GetIssue

func (c *GitHubHTTPClient) GetIssue(ctx context.Context, owner, repo string, number int) (*GitHubIssue, error)

GetIssue fetches a single issue by number.

func (*GitHubHTTPClient) GetPullRequest

func (c *GitHubHTTPClient) GetPullRequest(ctx context.Context, owner, repo string, number int) (*GitHubPR, error)

GetPullRequest fetches a single pull request by number.

func (*GitHubHTTPClient) ListIssues

func (c *GitHubHTTPClient) ListIssues(ctx context.Context, owner, repo string, opts ListIssuesOpts) ([]GitHubIssue, error)

ListIssues returns a list of issues for a repository filtered by opts.

func (*GitHubHTTPClient) SearchIssues

func (c *GitHubHTTPClient) SearchIssues(ctx context.Context, query string) ([]GitHubIssue, error)

SearchIssues executes a GitHub issue search query.

type GitHubIssue

type GitHubIssue struct {
	Number    int       `json:"number"`
	Title     string    `json:"title"`
	Body      string    `json:"body"`
	State     string    `json:"state"`
	Labels    []string  `json:"labels"`
	Assignee  string    `json:"assignee,omitempty"`
	Author    string    `json:"author"`
	HTMLURL   string    `json:"html_url"`
	CreatedAt time.Time `json:"created_at"`
	UpdatedAt time.Time `json:"updated_at"`
	Comments  int       `json:"comments"`
}

GitHubIssue represents a GitHub issue with the fields relevant to the agentic system.

type GitHubPR

type GitHubPR struct {
	Number    int       `json:"number"`
	Title     string    `json:"title"`
	Body      string    `json:"body"`
	State     string    `json:"state"`
	HTMLURL   string    `json:"html_url"`
	Head      string    `json:"head"`
	Base      string    `json:"base"`
	Mergeable *bool     `json:"mergeable,omitempty"`
	Additions int       `json:"additions"`
	Deletions int       `json:"deletions"`
	DiffURL   string    `json:"diff_url"`
	CreatedAt time.Time `json:"created_at"`
	UpdatedAt time.Time `json:"updated_at"`
}

GitHubPR represents a GitHub pull request with the fields relevant to the agentic system.

type GitHubReadExecutor

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

GitHubReadExecutor provides read-only GitHub tools to agentic agents. It fetches issues, pull requests, and file content without mutating any state.

func NewGitHubReadExecutor

func NewGitHubReadExecutor(client GitHubClient) *GitHubReadExecutor

NewGitHubReadExecutor creates a new GitHubReadExecutor backed by the given client.

func (*GitHubReadExecutor) Execute

Execute dispatches the tool call to the appropriate handler.

func (*GitHubReadExecutor) ListTools

func (e *GitHubReadExecutor) ListTools() []agentic.ToolDefinition

ListTools returns the tool definitions provided by this executor.

type GitHubWriteExecutor

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

GitHubWriteExecutor provides write tools that let agentic agents mutate GitHub state. Operations include branch creation, file commits, PR creation, comments, and labels.

func NewGitHubWriteExecutor

func NewGitHubWriteExecutor(client GitHubClient) *GitHubWriteExecutor

NewGitHubWriteExecutor creates a new GitHubWriteExecutor backed by the given client.

func (*GitHubWriteExecutor) Execute

Execute dispatches the tool call to the appropriate handler.

func (*GitHubWriteExecutor) ListTools

func (e *GitHubWriteExecutor) ListTools() []agentic.ToolDefinition

ListTools returns the tool definitions provided by this executor.

type GraphQueryExecutor

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

GraphQueryExecutor executes graph queries against the ENTITY_STATES KV bucket.

func NewGraphQueryExecutor

func NewGraphQueryExecutor(kvGetter KVGetter) *GraphQueryExecutor

NewGraphQueryExecutor creates a new GraphQueryExecutor with the given KV getter.

func (*GraphQueryExecutor) Execute

Execute executes a tool call and returns the result.

func (*GraphQueryExecutor) ListTools

func (e *GraphQueryExecutor) ListTools() []agentic.ToolDefinition

ListTools returns the tool definitions provided by this executor.

type HTTPRequestExecutor

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

HTTPRequestExecutor handles http_request tool calls.

func NewHTTPRequestExecutor

func NewHTTPRequestExecutor(opts ...HTTPRequestOption) *HTTPRequestExecutor

NewHTTPRequestExecutor creates an HTTP request executor.

func (*HTTPRequestExecutor) Execute

Execute handles an http_request tool call.

func (*HTTPRequestExecutor) ListTools

func (e *HTTPRequestExecutor) ListTools() []agentic.ToolDefinition

ListTools returns the http_request tool definition.

type HTTPRequestOption

type HTTPRequestOption func(*HTTPRequestExecutor)

HTTPRequestOption configures the executor.

func WithHTTPTimeout

func WithHTTPTimeout(d time.Duration) HTTPRequestOption

WithHTTPTimeout overrides the default request timeout (30s).

type JetStreamKVAdapter

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

JetStreamKVAdapter adapts a jetstream.KeyValue to our KVGetter interface.

func NewJetStreamKVAdapter

func NewJetStreamKVAdapter(kv any) *JetStreamKVAdapter

NewJetStreamKVAdapter creates a new adapter for jetstream.KeyValue. Usage: NewJetStreamKVAdapter(kvBucket) where kvBucket is a jetstream.KeyValue

func (*JetStreamKVAdapter) Get

func (a *JetStreamKVAdapter) Get(ctx context.Context, key string) (KVEntry, error)

Get implements KVGetter.

type KVEntry

type KVEntry interface {
	Value() []byte
	Revision() uint64
}

KVEntry defines the minimal interface needed to read an entry from the KV store.

type KVGetter

type KVGetter interface {
	Get(ctx context.Context, key string) (KVEntry, error)
}

KVGetter defines the minimal interface needed to query entities from a KV store. This allows for easier testing and decouples the executor from the full jetstream.KeyValue interface.

type ListIssuesOpts

type ListIssuesOpts struct {
	State  string // open, closed, all
	Labels []string
	Sort   string // created, updated, comments
	Limit  int
}

ListIssuesOpts configures the issue listing query.

type PersonaExecutor

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

PersonaExecutor implements CRUD tools for prompt personas. Same shape as RuleExecutor and FlowExecutor per ADR-029.

func NewPersonaExecutor

func NewPersonaExecutor(manager PersonaManager) *PersonaExecutor

NewPersonaExecutor creates a persona management executor.

func (*PersonaExecutor) Execute

Execute dispatches persona CRUD tool calls by name.

func (*PersonaExecutor) ListTools

func (e *PersonaExecutor) ListTools() []agentic.ToolDefinition

ListTools returns the five persona-CRUD tool definitions.

type PersonaManager

type PersonaManager interface {
	Create(ctx context.Context, p *persona.Persona) error
	Update(ctx context.Context, p *persona.Persona) error
	Delete(ctx context.Context, id string) error
	Get(ctx context.Context, id string) (*persona.Persona, error)
	List(ctx context.Context) (map[string]*persona.Persona, error)
}

PersonaManager is the subset of persona.Manager that PersonaExecutor needs. Declared here so tests can substitute in-memory fakes — same pattern as RuleManager and FlowManager.

type RuleExecutor

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

RuleExecutor implements CRUD tools for the rule engine.

func NewRuleExecutor

func NewRuleExecutor(manager RuleManager) *RuleExecutor

NewRuleExecutor creates a rule management executor.

func (*RuleExecutor) Execute

Execute dispatches rule tool calls.

func (*RuleExecutor) ListTools

func (e *RuleExecutor) ListTools() []agentic.ToolDefinition

ListTools returns the rule management tool definitions.

type RuleManager

type RuleManager interface {
	SaveRule(ctx context.Context, ruleID string, ruleDef rule.Definition) error
	DeleteRule(ctx context.Context, ruleID string) error
	GetRule(ctx context.Context, ruleID string) (*rule.Definition, error)
	ListRules(ctx context.Context) (map[string]rule.Definition, error)
}

RuleManager is the subset of rule.ConfigManager needed by RuleExecutor.

type StubWebSearchExecutor

type StubWebSearchExecutor struct{}

StubWebSearchExecutor returns canned search results when no Brave API key is available. Keeps web_search in the tool list so researcher-role agents and E2E fixtures work without external API dependencies.

func NewStubWebSearchExecutor

func NewStubWebSearchExecutor() *StubWebSearchExecutor

NewStubWebSearchExecutor creates a stub that returns canned search results.

func (*StubWebSearchExecutor) Execute

Execute returns canned search results for any query.

func (*StubWebSearchExecutor) ListTools

func (e *StubWebSearchExecutor) ListTools() []agentic.ToolDefinition

ListTools returns the web_search tool definition.

type ToolDependencies

type ToolDependencies struct {
	NATSClient          *natsclient.Client
	Platform            component.PlatformMeta
	Logger              *slog.Logger
	RuleManager         RuleManager         // Pattern-B step 1
	FlowManager         FlowManager         // Pattern-B step 2
	PersonaManager      PersonaManager      // Pattern-B step 3
	FlowTemplateManager FlowTemplateManager // Pattern-B step 4
	ComponentRegistry   *component.Registry // Pattern-B step 5; nil → list_components skipped
}

ToolDependencies carries the runtime inputs the tool-registration functions need. Using a struct rather than a growing positional arg list follows the project convention (memory: feedback_go_signatures — "4+ args → request struct"). Adding a new Pattern-B manager in the future means adding a field here, not shifting every call site.

Zero values are legal on optional fields:

  • Logger nil → slog.Default()
  • NATSClient nil → stateful tools (read_loop_result, decide, query_entity) are skipped
  • RuleManager nil → rule CRUD tools are skipped
  • ComponentRegistry nil → list_components skipped (Pattern-B step 5)

Platform is a value type (not pointer) because PlatformMeta is a small POD; the empty value is still safe for the decide tool to use.

type WebSearchExecutor

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

WebSearchExecutor implements the web_search agentic tool.

func NewWebSearchExecutor

func NewWebSearchExecutor(apiKey string) *WebSearchExecutor

NewWebSearchExecutor creates a web search executor backed by the Brave Search API.

func (*WebSearchExecutor) Execute

Execute dispatches tool calls.

func (*WebSearchExecutor) ListTools

func (e *WebSearchExecutor) ListTools() []agentic.ToolDefinition

ListTools returns the web_search tool definition.

Jump to

Keyboard shortcuts

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