core

package
v0.6.0 Latest Latest
Warning

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

Go to latest
Published: Jun 15, 2026 License: Apache-2.0 Imports: 24 Imported by: 0

Documentation

Index

Constants

View Source
const (
	// MaxIterationsPerFile is the recommended number of ReAct loop iterations to
	// allocate per changed file in the diff.
	MaxIterationsPerFile = 5
	// AbsoluteMaxIter is the hard upper bound for the ReAct loop to prevent
	// infinite recursion or excessive token spend.
	AbsoluteMaxIter = 25
	// MaxToolConcurrency is the maximum number of tools allowed to run
	// in parallel in a single turn.
	MaxToolConcurrency = 8
)

Variables

View Source
var StructuredReviewSchema = map[string]any{
	"type": "object",
	"properties": map[string]any{
		"approval": map[string]any{
			"type": "object",
			"properties": map[string]any{
				"approved": map[string]any{
					"type":        "boolean",
					"description": "Whether the changes are approved for merging.",
				},
				"rationale": map[string]any{
					"type":        "string",
					"description": "The high-level reasoning for the approval or rejection.",
				},
				"action": map[string]any{
					"type":        "string",
					"description": "The GitHub review action: 'APPROVE' if approved, 'REQUEST_CHANGES' if there are issues, or 'COMMENT' for neutral feedback.",
					"enum":        []string{"APPROVE", "REQUEST_CHANGES", "COMMENT"},
				},
			},
			"required": []string{"approved", "rationale", "action"},
		},
		"non_specific_review": map[string]any{
			"type":        "string",
			"description": "General review notes that are not tied to specific files or line ranges.",
		},
		"files_review": map[string]any{
			"type": "array",
			"items": map[string]any{
				"type": "object",
				"properties": map[string]any{
					"path": map[string]any{
						"type":        "string",
						"description": "The relative path to the file being reviewed.",
					},
					"lines": map[string]any{
						"type":        "string",
						"description": "The specific line number (e.g., '42') or range (e.g., '10-25') this review applies to.",
					},
					"review": map[string]any{
						"type":        "string",
						"description": "The detailed feedback for this specific chunk of code.",
					},
				},
				"required": []string{"path", "review"},
			},
		},
	},
	"required": []string{"approval", "files_review"},
}

StructuredReviewSchema is the JSON Schema representation of StructuredReview. This is used by LLM providers to enforce the output format. Note: raw_free_text is excluded from the schema to save tokens; it is populated manually by the caller.

Functions

func CalculateMaxIterations

func CalculateMaxIterations(changedFiles int) int

CalculateMaxIterations returns a sensible iteration cap based on the number of changed files, bounded by AbsoluteMaxIter.

func WithTestREPLStreams added in v0.6.0

func WithTestREPLStreams(ctx context.Context, in io.Reader, err io.Writer) context.Context

WithTestREPLStreams wraps a context to override standard input/stderr of the interactive REPL.

Types

type Agent

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

Agent orchestrates the ReAct (Reason + Act) loop between the LLM and the tool registry.

func NewAgent

func NewAgent(model llm.Model, registry ToolDispatcher, opts ...AgentOption) *Agent

NewAgent creates an Agent. Diagnostic / progress output goes to os.Stderr by default; override with WithStderr or WithReporter. The final review is returned as a string (caller routes it to stdout).

func (*Agent) ExtractStructuredReview

func (a *Agent) ExtractStructuredReview(ctx context.Context, extractionSystemPrompt, rawReview string, config llm.StructuredConfig) (*StructuredReview, error)

ExtractStructuredReview takes a raw markdown review and converts it into a machine-readable StructuredReview using a second LLM pass. Hard LLM errors are returned immediately (the underlying RetryingModel has already exhausted its own retry budget for them). Only soft application-level failures — empty content and malformed JSON — are retried here, up to extractionMaxAttempts times total, to overcome non-determinism in LLM output.

func (*Agent) GetMetrics added in v0.4.0

func (a *Agent) GetMetrics() SessionMetrics

GetMetrics returns the collected usage and execution metrics for the session.

func (*Agent) Reporter added in v0.5.0

func (a *Agent) Reporter() Reporter

Reporter returns the Agent's reporter.

func (*Agent) RunChatFlight added in v0.6.0

func (a *Agent) RunChatFlight(ctx context.Context, userText string, maxIterations, maxTokens int) (string, error)

RunChatFlight executes the conversational ReAct loop for a single chat turn in the REPL.

func (*Agent) RunReview

func (a *Agent) RunReview(ctx context.Context, stableSystem, dynamicSystem, requestText string, maxIterations, maxTokens int) (string, error)

RunReview executes the ReAct loop. stableSystem is the stable prompt prefix (Zones 1+2); dynamicSystem is the per-PR dynamic suffix (Zone 3, e.g. AGENTS.md / REVIEWERS.md content). When dynamicSystem is non-empty, providers that support prompt caching (e.g. Anthropic) will cache the stable prefix. Pass an empty string for dynamicSystem when there is no per-PR dynamic content. maxIterations controls how many tool-call rounds are permitted before the loop is forcibly terminated. Pass 0 to use the default cap. maxTokens limits the length of the LLM response.

type AgentOption

type AgentOption func(*Agent)

AgentOption configures an Agent.

func WithReporter

func WithReporter(r Reporter) AgentOption

WithReporter sets a custom reporter for the Agent.

func WithStderr

func WithStderr(w io.Writer) AgentOption

WithStderr redirects diagnostic/progress output to w instead of os.Stderr. Useful in tests to suppress noise (pass io.Discard).

type Approval

type Approval struct {
	Approved  bool   `json:"approved"`
	Rationale string `json:"rationale"`
	Action    string `json:"action,omitempty"` // The GitHub review action: "APPROVE", "REQUEST_CHANGES", "COMMENT".
}

Approval represents the overall decision on the code changes.

type ConsoleFormatter added in v0.6.0

type ConsoleFormatter interface {
	NotifyUser() string
	FormatToolCalls(tcs []llm.ToolCall) string
	FormatReviewHeader(files int, guidelines, model string) string
	FormatConfig(cfg *config.Config, targetDir string) string
	FormatReview(result string) string
	StyleStderr(plain, styled string, color string, bold bool) string
	FormatPostReviewReply(message string) string
}

ConsoleFormatter abstracts formatting and styling for console output.

type FileReview

type FileReview struct {
	Path   string `json:"path"`
	Lines  string `json:"lines,omitempty"` // A single line ("42") or a single range ("10-25").
	Review string `json:"review"`
}

FileReview represents feedback for a specific part of a file.

func (*FileReview) ParseLines

func (fr *FileReview) ParseLines() (int, int, error)

ParseLines parses the 'lines' string into individual line numbers. Returns startLine and endLine. For single lines, startLine == endLine.

type PRComment

type PRComment struct {
	ID         int64     `json:"id"`
	Author     string    `json:"author"`
	Body       string    `json:"body"`
	IsSelf     bool      `json:"is_self"`
	Date       time.Time `json:"date"`
	Path       string    `json:"path,omitempty"`
	Line       int       `json:"line,omitempty"`
	StartLine  int       `json:"start_line,omitempty"`
	IsOutdated bool      `json:"is_outdated"`
}

PRComment represents a single comment on a pull request.

type PRMetadata

type PRMetadata struct {
	RepoFullName  string      `json:"repo_full_name"`
	PRNumber      int         `json:"pr_number"`
	Title         string      `json:"title"`
	Description   string      `json:"description"`
	Author        string      `json:"author"`
	CreatedAt     time.Time   `json:"created_at"`
	Comments      []PRComment `json:"comments"`
	IdentifiedTag string      `json:"identified_tag,omitempty"`
}

PRMetadata represents the context of a pull request.

type Reporter

type Reporter interface {
	ReportIteration(iter int)
	ReportToolCalls(tcs []llm.ToolCall)
	ReportUsage(usage llm.Usage)
	ReportUsageSummary(usage llm.Usage)
	ReportFinalReview()
	ReportExtraction()
	ReportExtractionRetry(attempt int)
	ReportEmptyResponseRetry(attempt int)
	ReportCapReached(maxIterations int)
	ReportTruncated(maxTokens int)
	ReportMCPStatus(name string, status string, err error)
	ReportToolStatus(name string, status string, err error)
	ReportReviewHeader(files int, guidelines string, model string)

	// Additional lifecycle methods
	ReportConfig(cfg *config.Config, targetDir string)
	ReportFetchingDiff()
	ReportFetchingCommits()
	ReportNoChanges()
	ReportReview(result string) error
	ReportReviewWritten(file string)
	ReportStructuredReviewWritten(file string)
	ReportMetricsWritten(file string)
	ReportWarning(msg string, err error)
	ReportError(err error)
	NotifyUser()
	ReportPostReviewReply(message string)
}

Reporter defines how the Agent reports progress and diagnostics.

func NewDefaultReporter added in v0.5.0

func NewDefaultReporter(w io.Writer) Reporter

NewDefaultReporter creates a raw reporter for backward compatibility.

func NewMarkdownReporter added in v0.6.0

func NewMarkdownReporter(stdout, stderr io.Writer) Reporter

NewMarkdownReporter creates a reporter that renders markdown via glamour.

func NewRawReporter added in v0.6.0

func NewRawReporter(stdout, stderr io.Writer) Reporter

NewRawReporter creates a reporter that prints raw text.

func NewTuiReporter added in v0.6.0

func NewTuiReporter(stdout, stderr io.Writer, cancel context.CancelFunc) Reporter

NewTuiReporter constructs a TUI reporter.

type Reviewer added in v0.5.0

type Reviewer struct {
	Agent                    *Agent
	Config                   *config.Config
	RootDir                  string
	StablePrompt             string
	Guidelines               string
	SupplementalGuidelines   []string
	ApprovalEvaluationPrompt string
	// contains filtered or unexported fields
}

Reviewer encapsulates an initialized Agent and its environment.

func NewReviewer added in v0.5.0

func NewReviewer(ctx context.Context, cfg *config.Config, targetDir string, reporter Reporter) (r *Reviewer, err error)

NewReviewer instantiates a Reviewer based on the provided configuration. targetDir is the directory where local tools (like grep) will operate.

func (*Reviewer) Close added in v0.5.0

func (r *Reviewer) Close() error

Close releases resources (like MCP server connections).

func (*Reviewer) Run added in v0.5.0

func (r *Reviewer) Run(ctx context.Context, changedFiles []string, requestText string) (string, error)

Run executes a review for the given changes.

func (*Reviewer) RunInteractivePostReview added in v0.6.0

func (r *Reviewer) RunInteractivePostReview(ctx context.Context) error

RunInteractivePostReview starts a continuous chat loop with the developer.

type SessionMetrics added in v0.4.0

type SessionMetrics struct {
	Tokens     TokenMetrics    `json:"tokens"`
	Iterations int             `json:"iterations"`
	ToolCalls  ToolCallMetrics `json:"tool_calls"`
}

SessionMetrics captures detailed usage and execution metrics for an agent session.

type StructuredReview

type StructuredReview struct {
	RawFreeText       string       `json:"raw_free_text"`
	Approval          Approval     `json:"approval"`
	NonSpecificReview string       `json:"non_specific_review,omitempty"`
	FilesReview       []FileReview `json:"files_review"`
}

StructuredReview represents the final extracted code review in a machine-readable format.

type TokenMetrics added in v0.4.0

type TokenMetrics struct {
	Input       int `json:"input"`
	Output      int `json:"output"`
	Thinking    int `json:"thinking"`
	Cached      int `json:"cached"`
	TotalInput  int `json:"total_input"`
	TotalOutput int `json:"total_output"`
}

TokenMetrics breaks down token consumption by category.

type ToolCallMetrics added in v0.4.0

type ToolCallMetrics struct {
	Total  int            `json:"total"`
	ByTool map[string]int `json:"by_tool"`
}

ToolCallMetrics tracks how many times tools were invoked.

type ToolDispatcher

type ToolDispatcher interface {
	ToTools() []llm.ToolDef
	HandleCall(ctx context.Context, tc llm.ToolCall) (string, error)
}

ToolDispatcher is the minimal interface the Agent needs from a tool registry. *tools.Registry satisfies this interface; tests can supply a lightweight stub.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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