agent

package
v0.1.6 Latest Latest
Warning

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

Go to latest
Published: Mar 10, 2026 License: MIT Imports: 13 Imported by: 0

Documentation

Overview

Package agent handles agent-assisted review via LLM providers.

Index

Constants

View Source
const (
	// ConservativeTokenBudget is the max tokens for auto-detected conservative mode.
	ConservativeTokenBudget = 10_000

	// ConservativeCircuitThreshold is the circuit breaker threshold for conservative mode.
	ConservativeCircuitThreshold = 3
)

Variables

View Source
var (
	OpenAIModels   = DefaultOpenAIModels
	GroqModels     = DefaultGroqModels
	OllamaModels   = DefaultOllamaModels
	LMStudioModels = DefaultLMStudioModels
)

Backward-compatible aliases

View Source
var AutoDetectEnvVars = []string{"OPENROUTER_API_KEY", "CERTIFY_API_KEY", "OPENAI_API_KEY", "GROQ_API_KEY"}

AutoDetectEnvVars lists environment variables checked for cloud API keys, in priority order.

View Source
var ConservativeModels = []string{
	"qwen/qwen3-coder:free",
	"qwen/qwen-2.5-coder-32b-instruct:free",
	"mistralai/mistral-small-3.1-24b-instruct:free",
	"meta-llama/llama-3.3-70b-instruct:free",
	"microsoft/phi-4:free",
}

ConservativeModels lists free-tier OpenRouter models in fallback order. These are default suggestions — users can choose any model via config or the extension.

View Source
var DefaultGroqModels = []string{
	"llama-3.3-70b-versatile",
	"llama-3.1-8b-instant",
	"gemma2-9b-it",
}

DefaultGroqModels lists suggested models for Groq.

View Source
var DefaultLMStudioModels = []string{
	"loaded-model",
}

DefaultLMStudioModels lists models for LM Studio.

View Source
var DefaultModels = map[string][]string{
	"openrouter": nil,
	"openai":     nil,
	"groq":       nil,
	"ollama":     nil,
	"lmstudio":   nil,
}

DefaultModels maps provider name to default model suggestions.

View Source
var DefaultOllamaModels = []string{
	"qwen2.5-coder:7b",
	"qwen2.5-coder:3b",
	"llama3.2:3b",
	"phi4",
	"gemma2:9b",
}

DefaultOllamaModels lists common Ollama models.

View Source
var DefaultOpenAIModels = []string{
	"gpt-4o-mini",
	"gpt-4o",
	"gpt-4.1-mini",
	"gpt-4.1-nano",
	"o3-mini",
}

DefaultOpenAIModels lists suggested models for OpenAI.

Functions

func DetectAPIKey

func DetectAPIKey() (key string, envVar string)

DetectAPIKey checks environment variables for an API key (cloud providers). Returns the key and the env var name it was found in. Returns empty strings if no key is found.

func FormatDeepObservations added in v0.1.4

func FormatDeepObservations(result ReviewResult) []string

FormatDeepObservations creates formatted observation strings from a ReviewResult.

func FormatProviderSummary

func FormatProviderSummary(providers []DetectedProvider) string

FormatProviderSummary returns a human-readable summary of detected providers.

func FormatReviewForRecord added in v0.1.4

func FormatReviewForRecord(result ReviewResult) string

FormatReviewForRecord creates a compact review summary suitable for record storage.

func HasAnyProvider

func HasAnyProvider() bool

HasAnyProvider returns true if any provider (cloud or local) is available.

func IsDeepReview added in v0.1.4

func IsDeepReview(result ReviewResult) bool

IsDeepReview returns true if the result came from a deep review (local model).

func ProviderNames

func ProviderNames(providers []DetectedProvider) []string

ProviderNames returns the display names of detected providers.

Types

type APIError

type APIError struct {
	StatusCode int
	Body       string
}

APIError represents an HTTP API error.

func (*APIError) Error

func (e *APIError) Error() string

type ChatRequest

type ChatRequest struct {
	Model       string    `json:"model"`
	Messages    []Message `json:"messages"`
	Temperature float64   `json:"temperature,omitempty"`
	MaxTokens   int       `json:"max_tokens,omitempty"`
	// ResponseFormat can request structured JSON output
	ResponseFormat *ResponseFormat `json:"response_format,omitempty"`
}

ChatRequest is an OpenAI-compatible chat completion request.

type ChatResponse

type ChatResponse struct {
	ID      string   `json:"id"`
	Model   string   `json:"model"`
	Choices []Choice `json:"choices"`
	Usage   Usage    `json:"usage"`
}

ChatResponse is an OpenAI-compatible chat completion response.

func (ChatResponse) Content

func (r ChatResponse) Content() string

Content returns the first choice's message content, or empty string.

type Choice

type Choice struct {
	Index        int     `json:"index"`
	Message      Message `json:"message"`
	FinishReason string  `json:"finish_reason"`
}

Choice represents a single completion choice.

type CircuitBreaker

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

CircuitBreaker wraps a Provider and stops calling it after consecutive failures.

func NewCircuitBreaker

func NewCircuitBreaker(provider Provider, threshold int) *CircuitBreaker

NewCircuitBreaker wraps a provider with a circuit breaker. After `threshold` consecutive failures, the circuit opens and all calls return immediately with an error until a successful call closes it.

func (*CircuitBreaker) Chat

Chat delegates to the wrapped provider unless the circuit is open.

func (*CircuitBreaker) IsOpen

func (cb *CircuitBreaker) IsOpen() bool

IsOpen returns true if the circuit is currently open.

func (*CircuitBreaker) Name

func (cb *CircuitBreaker) Name() string

Name returns the wrapped provider's name.

type Coordinator

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

Coordinator manages file-level dedup, token budgets, and pipeline execution.

func NewConservativeCoordinator

func NewConservativeCoordinator(providers []DetectedProvider) *Coordinator

NewConservativeCoordinator builds a Coordinator from all detected providers. Uses StrategyQuick (prescreen only), conservative token budget, free-tier models. Cloud providers are tried first, then local providers as fallback.

func NewCoordinator

func NewCoordinator(provider Provider, cfg CoordinatorConfig) *Coordinator

NewCoordinator creates a review coordinator.

func (*Coordinator) IsLocal added in v0.1.4

func (c *Coordinator) IsLocal() bool

IsLocal returns true if the coordinator is using a local strategy.

func (*Coordinator) ReviewUnit

func (c *Coordinator) ReviewUnit(ctx context.Context, unit domain.Unit, source string, ev []domain.Evidence) ReviewResult

ReviewUnit returns the review result for a unit, deduplicating by file.

func (*Coordinator) Stats

func (c *Coordinator) Stats() (filesReviewed, totalFiles, tokensSpent int)

Stats returns coordinator statistics.

type CoordinatorConfig

type CoordinatorConfig struct {
	Models      domain.ModelAssignments
	Strategy    Strategy
	TokenBudget int // max tokens to spend across all reviews (0=unlimited)
}

CoordinatorConfig configures the review coordinator.

type DecisionResponse

type DecisionResponse struct {
	Status    string   `json:"status"`
	Reasoning string   `json:"reasoning"`
	Actions   []string `json:"actions"`
}

DecisionResponse is the structured output from the decision step.

type DeepReviewResponse added in v0.1.4

type DeepReviewResponse struct {
	Summary      string   `json:"summary"`
	Review       string   `json:"review"`
	Risks        []string `json:"risks"`
	SystemImpact []string `json:"system_impact"`
	Suggestions  []string `json:"suggestions"`
	Strengths    []string `json:"strengths"`
}

DeepReviewResponse is the structured output from deep review.

type DetectedProvider

type DetectedProvider struct {
	Name    string   // "openrouter", "groq", "ollama", "lmstudio"
	BaseURL string   // API base URL
	APIKey  string   // API key (empty for local providers)
	Models  []string // Preferred models for this provider
	Local   bool     // True for local providers (no auth required)
}

DetectedProvider describes an auto-detected LLM provider.

func DetectProviders

func DetectProviders() []DetectedProvider

DetectProviders checks for available LLM providers in priority order. Cloud providers (requiring API keys) come first, local providers last.

type FallbackProvider

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

FallbackProvider tries multiple providers in order until one succeeds. Only retryable errors (429, 5xx) trigger fallback; auth errors abort immediately.

func NewFallbackProvider

func NewFallbackProvider(providers []Provider) *FallbackProvider

NewFallbackProvider creates a provider that falls back through a list.

func (*FallbackProvider) Chat

func (*FallbackProvider) Name

func (f *FallbackProvider) Name() string

type Message

type Message struct {
	Role    string `json:"role"`
	Content string `json:"content"`
}

Message represents a chat message (OpenAI-compatible).

func AdaptiveMessages

func AdaptiveMessages(systemPrompt, userContent string, useSystem bool) []Message

AdaptiveMessages builds a message list that works with or without system message support. When useSystem=true, sends separate system + user messages. When useSystem=false, combines system instruction into the user message.

type ModelChain

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

ModelChain creates a FallbackProvider with one OpenRouterProvider per model. Each provider is configured with longer backoff suitable for free-tier rate limits.

func NewModelChain

func NewModelChain(baseURL, apiKey, referer, title string, models []string) *ModelChain

NewModelChain creates a chain of model-specific providers. When model A returns 429, automatically tries model B, etc.

func (*ModelChain) Chat

func (mc *ModelChain) Chat(ctx context.Context, req ChatRequest) (ChatResponse, error)

func (*ModelChain) Name

func (mc *ModelChain) Name() string

type ModelConfig

type ModelConfig struct {
	ID                string `json:"id"`
	ContextWindow     int    `json:"context_window"`
	MaxOutput         int    `json:"max_output"`
	StructuredOutputs bool   `json:"structured_outputs"`
	ToolCalling       bool   `json:"tool_calling"`
	Reasoning         bool   `json:"reasoning"`
}

ModelConfig describes a model's capabilities.

type ModelInfo

type ModelInfo struct {
	ID            string `json:"id"`
	OwnedBy       string `json:"owned_by,omitempty"`
	ContextWindow int    `json:"context_window,omitempty"`
	Created       int64  `json:"created,omitempty"`
}

ModelInfo describes a model available from a provider.

func ListModels

func ListModels(ctx context.Context, baseURL, apiKey string) ([]ModelInfo, error)

ListModels queries an OpenAI-compatible /models endpoint. Falls back to Ollama's /api/tags if the standard endpoint returns 404. apiKey can be empty for local providers.

type OpenRouterProvider

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

OpenRouterProvider implements Provider for the OpenRouter API. Also works with any OpenAI-compatible endpoint (Groq, Ollama, LM Studio).

func NewLocalProvider

func NewLocalProvider(baseURL, name string) *OpenRouterProvider

NewLocalProvider creates a provider for local OpenAI-compatible servers (Ollama, LM Studio). No API key required, no auth headers sent.

func NewOpenRouterProvider

func NewOpenRouterProvider(baseURL, apiKey, httpReferer, xTitle string) *OpenRouterProvider

NewOpenRouterProvider creates a new OpenRouter provider.

func (*OpenRouterProvider) Chat

Chat sends a chat completion request with retry logic.

func (*OpenRouterProvider) Name

func (p *OpenRouterProvider) Name() string

Name returns the provider name.

type Pipeline

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

Pipeline orchestrates review stages in sequence.

func NewPipeline

func NewPipeline(provider Provider, cfg PipelineConfig) *Pipeline

NewPipeline builds a pipeline based on strategy and model assignments.

func (*Pipeline) Run

func (p *Pipeline) Run(ctx context.Context, input StageInput) (ReviewResult, error)

Run executes the pipeline stages in order. Each stage can short-circuit (stop the pipeline). Errors cause graceful degradation, not failure.

type PipelineConfig

type PipelineConfig struct {
	Strategy Strategy
	Models   domain.ModelAssignments
}

PipelineConfig configures the review pipeline.

type PrescreenResponse

type PrescreenResponse struct {
	NeedsReview bool     `json:"needs_review"`
	Reason      string   `json:"reason"`
	Confidence  float64  `json:"confidence"`
	Suggestions []string `json:"suggestions,omitempty"`
}

PrescreenResponse is the structured output from the prescreen step.

type PromptRegistry

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

PromptRegistry loads and caches prompt templates by task type.

func NewPromptRegistry

func NewPromptRegistry(dir string) *PromptRegistry

NewPromptRegistry creates a registry that loads templates from a directory.

func (*PromptRegistry) Get

func (r *PromptRegistry) Get(task TaskType) (*PromptTemplate, error)

Get returns the prompt template for a task type, loading and caching on first access.

type PromptTemplate

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

PromptTemplate is a loaded prompt template with variable substitution.

func LoadPrompt

func LoadPrompt(path string) (*PromptTemplate, error)

LoadPrompt loads a prompt template from a file.

func (*PromptTemplate) Render

func (p *PromptTemplate) Render(vars map[string]string) (string, error)

Render substitutes variables into the template. Variables are specified as {{.Key}} in the template.

func (*PromptTemplate) Version

func (p *PromptTemplate) Version() string

Version extracts the version from the filename (e.g., "prescreen.v1.md" → "v1").

type Provider

type Provider interface {
	// Chat sends a chat completion request and returns the response.
	Chat(ctx context.Context, req ChatRequest) (ChatResponse, error)

	// Name returns the provider name.
	Name() string
}

Provider is the interface for LLM API providers.

type RateLimiter

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

RateLimiter implements a simple token bucket rate limiter.

func NewRateLimiter

func NewRateLimiter(maxRate int, interval time.Duration) *RateLimiter

NewRateLimiter creates a rate limiter that allows maxRate requests per interval.

func (*RateLimiter) Allow

func (rl *RateLimiter) Allow() bool

Allow checks if a request is allowed (non-blocking).

func (*RateLimiter) Wait

func (rl *RateLimiter) Wait()

Wait blocks until a token is available.

type RemediationResponse

type RemediationResponse struct {
	Steps []RemediationStep `json:"steps"`
}

RemediationResponse is the structured output from the remediation step.

type RemediationStep

type RemediationStep struct {
	Priority    int    `json:"priority"`
	Dimension   string `json:"dimension"`
	Description string `json:"description"`
	Effort      string `json:"effort"` // low, medium, high
}

RemediationStep is a single remediation action.

type RepoSummary

type RepoSummary struct {
	Languages    []string // Detected languages (e.g., "go", "typescript")
	UnitCount    int      // Total code units discovered
	FilePatterns []string // Top-level directories or patterns found
	Policies     []string // Currently configured policy pack names
}

RepoSummary holds repository metadata for generating AI suggestions.

type ResponseFormat

type ResponseFormat struct {
	Type   string `json:"type"` // "json_object" or "json_schema"
	Schema any    `json:"json_schema,omitempty"`
}

ResponseFormat requests a specific output format.

type ReviewInput

type ReviewInput struct {
	Unit       domain.Unit
	SourceCode string
	Evidence   []domain.Evidence
}

ReviewInput holds everything needed for an agent review.

type ReviewResult

type ReviewResult struct {
	Reviewed        bool               `json:"reviewed"`
	Prescreened     bool               `json:"prescreened"`
	ReviewOutput    string             `json:"review_output,omitempty"`
	Scores          map[string]float64 `json:"scores,omitempty"`
	Status          string             `json:"status,omitempty"`
	Actions         []string           `json:"actions,omitempty"`
	Remediation     []RemediationStep  `json:"remediation,omitempty"`
	Confidence      float64            `json:"confidence"`
	TokensUsed      int                `json:"tokens_used"`
	ModelsUsed      []string           `json:"models_used,omitempty"`
	PrescreenReason string             `json:"prescreen_reason,omitempty"`
	Suggestions     []string           `json:"suggestions,omitempty"`
}

ReviewResult holds the outcome of an agent review.

func (ReviewResult) ToDeepEvidence added in v0.1.4

func (r ReviewResult) ToDeepEvidence() domain.Evidence

ToDeepEvidence creates evidence from a deep review result.

func (ReviewResult) ToEvidence

func (r ReviewResult) ToEvidence() domain.Evidence

ToEvidence converts the review result to a domain.Evidence. Model attribution is embedded in the Source field.

func (ReviewResult) ToPrescreenEvidence added in v0.1.3

func (r ReviewResult) ToPrescreenEvidence() domain.Evidence

ToPrescreenEvidence converts a prescreen-only result to evidence. Used when AI evaluated but determined no detailed review was needed.

type Reviewer

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

Reviewer orchestrates the 5-step agent review pipeline.

func NewReviewer

func NewReviewer(provider Provider, router *Router) *Reviewer

NewReviewer creates a new agent reviewer.

func (*Reviewer) Review

func (rv *Reviewer) Review(ctx context.Context, input ReviewInput) (ReviewResult, error)

Review runs the full agent review pipeline.

type Router

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

Router maps task types to specific models with fallback.

func NewRouter

func NewRouter(assignments domain.ModelAssignments) *Router

NewRouter creates a model router.

func (*Router) ModelFor

func (r *Router) ModelFor(task TaskType) string

ModelFor returns the model ID for the given task type. Falls back to the fallback model if no specific assignment exists.

type ScanSuggestion

type ScanSuggestion struct {
	Suggestions string // Human-readable suggestion text
	TokensUsed  int    // Tokens consumed by this call
	Model       string // Model that generated the suggestion
}

ScanSuggestion holds the result of an AI-powered scan suggestion.

func SuggestForRepo

func SuggestForRepo(ctx context.Context, provider Provider, summary RepoSummary) ScanSuggestion

SuggestForRepo sends a single LLM call to generate policy/scope suggestions based on the repository summary. Returns empty ScanSuggestion on any failure (graceful degradation — never blocks, never errors).

type ScoringResponse

type ScoringResponse struct {
	Scores     map[string]float64 `json:"scores"`
	Confidence float64            `json:"confidence"`
	Reasoning  string             `json:"reasoning"`
}

ScoringResponse is the structured output from the scoring step.

type Stage

type Stage interface {
	Execute(ctx context.Context, input StageInput) (StageResult, bool, error)
	Name() string
}

Stage is a single step in the review pipeline. Returns (result, shouldContinue, error).

func NewDeepReviewStage added in v0.1.4

func NewDeepReviewStage(provider Provider, model string) Stage

NewDeepReviewStage creates a comprehensive review stage for local models. Unlike the standard prescreen→review flow, this always performs a full analysis since local model tokens are free.

func NewPrescreenStage

func NewPrescreenStage(provider Provider, model string) Stage

NewPrescreenStage creates the prescreen gate stage.

func NewReviewStage

func NewReviewStage(provider Provider, model string) Stage

NewReviewStage creates the detailed code review stage.

func NewScoringStage

func NewScoringStage(provider Provider, model string) Stage

NewScoringStage creates the dimension scoring stage.

type StageInput

type StageInput struct {
	Unit            domain.Unit
	SourceCode      string
	Evidence        []domain.Evidence
	EvidenceSummary string
	ReviewOutput    string // set by ReviewStage, read by ScoringStage
}

StageInput holds all data flowing through the pipeline.

type StageResult

type StageResult struct {
	Reviewed        bool
	ReviewOutput    string
	Scores          map[string]float64
	Status          string
	Actions         []string
	Remediation     []RemediationStep
	Confidence      float64
	TokensUsed      int
	ModelsUsed      []string // attribution: which models contributed
	PrescreenReason string   // brief quality assessment from prescreen
	Suggestions     []string // actionable improvement suggestions
}

StageResult accumulates output from pipeline stages.

type Strategy

type Strategy int

Strategy determines how many pipeline stages to execute.

const (
	// StrategyQuick runs prescreen only — cheap gate.
	StrategyQuick Strategy = iota
	// StrategyStandard runs prescreen → review → scoring (3 stages).
	StrategyStandard
	// StrategyFull runs all 5 stages including decision and remediation.
	StrategyFull
	// StrategyLocal skips prescreen gate, runs deep review → scoring.
	// Designed for local models with zero token cost.
	StrategyLocal
)

type TaskType

type TaskType int

TaskType identifies the kind of agent review task.

const (
	TaskPrescreen   TaskType = iota // Quick pre-filter
	TaskReview                      // Detailed code review
	TaskScoring                     // Dimension scoring
	TaskDecision                    // Status determination with reasoning
	TaskRemediation                 // Remediation suggestion generation
)

func (TaskType) String

func (t TaskType) String() string

String returns the string representation of a TaskType.

type Usage

type Usage struct {
	PromptTokens     int `json:"prompt_tokens"`
	CompletionTokens int `json:"completion_tokens"`
	TotalTokens      int `json:"total_tokens"`
}

Usage reports token consumption.

Jump to

Keyboard shortcuts

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