agent

package
v0.6.1 Latest Latest
Warning

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

Go to latest
Published: Sep 11, 2026 License: MIT Imports: 15 Imported by: 0

Documentation

Overview

Package agent stitches the heuristic registry, LLM provider, and read-only tool runner into a single Scan operation.

The flow:

  1. Run every registered heuristic concurrently → []Finding.
  2. If zero findings, short-circuit with an empty Recommendation slice (no LLM call needed; nothing to triage).
  3. Otherwise build the system prompt, an initial user message summarizing the findings, and call Provider.Generate in a loop: - if the model returns tool calls, dispatch each via the Runner, thread the results back as message-history Tool messages, and continue. - if the model returns no tool calls, parse its text as a JSON array of Recommendations and return.
  4. Cap the loop at Config.MaxToolCalls — the safety rail described in docs/plans/2026-05-02-sentra-design.md → "Safety rails".

The orchestrator never inspects file contents and never executes a recommendation — that's `sentra agent scan --apply`'s job (Phase 11.3). Apply is gated behind interactive confirms so the agent loop stays a pure "advice" surface.

Index

Constants

This section is empty.

Variables

View Source
var ErrBudgetExhausted = errors.New("agent: tool-call budget exhausted")

ErrBudgetExhausted is returned by Scan when the model exceeded Config.MaxToolCalls without ever emitting a final response. Callers receive whatever recommendations the loop accumulated along the way (currently always empty, since recommendations only land via the final-text path — but the contract leaves room for future "partial emit" semantics without a breaking signature change).

View Source
var ErrInvalidConfig = errors.New("agent: invalid config")

ErrInvalidConfig is returned by Config.Validate (and so by Scan, before any work) when a numeric cap is negative. Defaults only replaces zero, so a negative agent.max_findings_to_llm (or the env override) used to survive to `findings[:n]` and panic in the middle of a scan. A negative cap is a typo, not a request, so it is an error rather than a clamp.

View Source
var ErrInvalidResponse = errors.New("agent: model emitted invalid response")

ErrInvalidResponse is returned by Scan when the model's final text isn't a JSON array of Recommendation. The orchestrator does not attempt to repair the output — surfacing the error lets the caller decide whether to retry, fall back, or surface the problem to the user.

Functions

This section is empty.

Types

type Agent

type Agent struct {
	Repo       *repo.Repo
	Heuristics *heuristics.Registry
	Provider   llm.Provider
	Config     Config

	// Actions is the registered action vocabulary the LLM is told
	// it can emit. The system prompt's "Action is one of: ..." list
	// is generated from this registry, so the model's vocabulary
	// matches the dispatcher's vocabulary by construction. Nil
	// falls back to action.NewDefaultRegistry() — production wires
	// the same registry the CLI's dispatcher uses.
	Actions *action.Registry
}

Agent is the orchestrator. Repo and Heuristics are required; Provider is required for any non-trivial Scan (no-finding short-circuits skip it). Config governs the loop's safety rails.

func (*Agent) Scan

func (a *Agent) Scan(ctx context.Context, root string, stream chan<- string) ([]Recommendation, error)

Scan runs the heuristics, then drives the LLM loop until the model emits a final JSON array of recommendations or the tool-call budget is exhausted. The stream channel receives the model's text as it arrives; pass nil to disable. Scan owns no goroutines that outlive the call — when Scan returns, the stream channel won't see any more writes.

On no findings, Scan short-circuits with an empty result and writes a synthetic "no findings" message to stream so the TUI's tail viewport has something to display.

type Config

type Config struct {
	// MaxFindingsToLLM caps how many findings are fed into the initial
	// user message. Larger N → more model context cost; defaults to 50
	// per the design doc when zero.
	MaxFindingsToLLM int

	// MaxToolCalls is the per-Scan tool-call budget. Once the loop has
	// dispatched this many tool calls, the next round must produce a
	// final response or Scan fails with ErrBudgetExhausted. Defaults
	// to 10 when zero.
	MaxToolCalls int

	// Model is the LLM model identifier passed through to the provider.
	// The provider is free to ignore this if the value is empty.
	Model string

	// Walker controls the filesystem walk used to populate
	// heuristics.Input.Walked. The zero value uses walker defaults.
	Walker walker.Options

	// InputConfig carries heuristic thresholds and policies sourced
	// from the CLI config. Zero values preserve each heuristic's
	// documented defaults.
	InputConfig heuristics.InputConfig

	// LocalOnly skips the LLM loop and converts heuristic findings
	// directly into conservative recommendations.
	LocalOnly bool

	// Categories limits findings to matching Finding.Category or
	// Finding.Heuristic values before local or LLM triage.
	Categories []string
}

Config tunes the orchestrator's behavior. The zero value is unusable — MaxToolCalls of 0 would budget out before the first call. Tests build it inline; production wires it from sentra.yaml via the CLI.

func (Config) Defaults

func (c Config) Defaults() Config

Defaults fills in sensible default values for any zero-valued Config fields. Pulled out so tests can exercise the defaulting behavior independent of Scan; CLI wiring also calls it after koanf merge.

func (Config) Validate added in v0.5.0

func (c Config) Validate() error

Validate rejects caps the orchestrator cannot honor. Every numeric field that is sliced or looped on belongs here: MaxFindingsToLLM bounds a slice expression and MaxToolCalls bounds the loop budget. Zero is fine (Defaults fills it); negative is ErrInvalidConfig.

type Recommendation

type Recommendation struct {
	ID        string `json:"id"`
	Action    string `json:"action"`
	Target    string `json:"target"`
	Severity  string `json:"severity"`
	Rationale string `json:"rationale"`
}

Recommendation is the structured advice the LLM returns for a finding- like situation. The CLI renders these as a styled table; the TUI streams them in as the loop progresses.

Action is one of: "prune_snapshot", "add_to_ignore", "flag_secret", "none". The CLI's --apply path dispatches each action through a small handler map; "none" is a no-op, used by the model to flag findings the user should know about but where there's no automatic remediation.

Directories

Path Synopsis
Package action defines the vocabulary of remediations the Sentra agent can recommend, and a registry that maps each verb to a concrete side-effect.
Package action defines the vocabulary of remediations the Sentra agent can recommend, and a registry that maps each verb to a concrete side-effect.
Package heuristics implements local rules that scan a walked tree, snapshot history, and live-blob set, producing structured Finding records the LLM agent can later triage.
Package heuristics implements local rules that scan a walked tree, snapshot history, and live-blob set, producing structured Finding records the LLM agent can later triage.
Package llm defines the provider abstraction the Sentra agent uses to talk to a language model.
Package llm defines the provider abstraction the Sentra agent uses to talk to a language model.
Package tools implements the read-only investigation toolset the Sentra agent advertises to the LLM.
Package tools implements the read-only investigation toolset the Sentra agent advertises to the LLM.

Jump to

Keyboard shortcuts

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