Documentation
¶
Index ¶
- Constants
- Variables
- func CalculateMaxIterations(changedFiles int) int
- func WriteFileWithDirs(path string, data []byte) error
- type Agent
- type AgentOption
- type Approval
- type FileReview
- type PRComment
- type PRMetadata
- type Reporter
- type SessionMetrics
- type StructuredReview
- type TokenMetrics
- type ToolCallMetrics
- type ToolDispatcher
Constants ¶
const ( // MaxIterationsPerFile is the recommended number of iterations per changed file. MaxIterationsPerFile = 5 // AbsoluteMaxIter is the upper bound for the ReAct loop to prevent infinite recursion. AbsoluteMaxIter = 25 )
Variables ¶
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 ¶
CalculateMaxIterations returns a sensible iteration cap based on the number of changed files, bounded by AbsoluteMaxIter.
func WriteFileWithDirs ¶
WriteFileWithDirs creates any missing parent directories before writing the file with 0o644 permissions.
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) 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 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)
ReportToolCall(tc llm.ToolCall)
ReportUsage(usage llm.Usage)
ReportUsageSummary(usage llm.Usage)
ReportFinalReview()
ReportExtraction()
ReportExtractionRetry(attempt int)
ReportEmptyResponseRetry(attempt int)
ReportCapReached(maxIterations int)
ReportTruncated(maxTokens int)
}
Reporter defines how the Agent reports progress and diagnostics.
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
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.