prompt

package
v1.0.24 Latest Latest
Warning

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

Go to latest
Published: Aug 26, 2026 License: MIT Imports: 11 Imported by: 0

Documentation

Index

Constants

View Source
const MaxRuleCatalogTokens = 512

MaxRuleCatalogTokens is the ceiling AC-002 puts on the rendered catalog section. The current 21-rule catalog renders at roughly a quarter of it, so there is room to grow; growing PAST it is a loud build/assembly failure and never a silent truncation. That distinction is the whole point: a truncated list would make the model cite a rule that exists but was cut, and the gate would discard it -- this card's defect back by another road.

Variables

View Source
var DefaultRuleCatalog = []string{
	"performance/excessive-allocation",
	"performance/inefficient-algorithm",
	"performance/inefficient-loop",
	"performance/memory-leak",
	"performance/n-plus-one",
	"quality/dead-code",
	"quality/duplicate-code",
	"quality/high-complexity",
	"quality/long-function",
	"quality/magic-numbers",
	"quality/missing-error-handling",
	"quality/poor-naming",
	"quality/unused-variable",
	"security/command-injection",
	"security/hardcoded-secret",
	"security/insecure-random",
	"security/missing-auth",
	"security/path-traversal",
	"security/sql-injection",
	"security/weak-crypto",
	"security/xss",
}

DefaultRuleCatalog is the mirror of the embedded review catalog: every id of internal/review/rules/{security,quality,performance}.yml, sorted, exactly as RulesLoader.Get indexes them. Keep it sorted and keep it complete -- tests/unit/AUR-461.go proves both.

Functions

func HasSubstantiveCodeChange added in v1.0.12

func HasSubstantiveCodeChange(diff *types.Diff) bool

HasSubstantiveCodeChange distinguishes a code-bearing change from a repository-operation change. Config, workflow, documentation and comment-only edits may still be reviewed for their direct effect, but they must not receive fabricated praise about code quality in the published review. Unknown extensions remain code by default so a new source language is never silently excluded.

func RenderRuleCatalog added in v1.0.2

func RenderRuleCatalog(ids []string) string

RenderRuleCatalog renders the closed list injected into the review prompt. It deliberately carries ids only -- no titles: the ids are self-descriptive (security/command-injection is what the model called "shell-injection"), and mirroring titles too would double the surface that can drift from the YAML.

The rendered block must not open a ```json fence: AUR-459's TemplateTeachesOneSchema requires the template to show exactly one JSON example, and a second one here would teach a second schema.

func ReviewChangeScope added in v1.0.12

func ReviewChangeScope(diff *types.Diff) string

ReviewChangeScope is safe to place in the model prompt because it is derived from the diff, not authored by repository content.

func ValidateRuleCatalog added in v1.0.2

func ValidateRuleCatalog(ids []string, est TokenEstimator) error

ValidateRuleCatalog reports whether the rendered form of ids fits MaxRuleCatalogTokens under est, and rejects an empty or unsorted catalog. An empty catalog would render a section telling the model to choose from nothing.

Types

type BuildOptions

type BuildOptions struct {
	MaxTokens    int    // Maximum tokens for the entire prompt
	SchemaKind   string // Type of schema: "review", "test", "docs", "summary"
	Role         string // Role context: "reviewer", "tester", "documenter"
	ReserveReply int    // Tokens to reserve for the reply
	CIContext    string // Existing CI/check context, when the caller has it
	Language     string // Human-facing review language, e.g. "pt-BR"
	ChangeScope  string // Deterministic scope classification for the review
}

BuildOptions configures prompt building

type ContextSegment

type ContextSegment struct {
	Content  string       // The actual content
	Priority PriorityTier // Priority level for trimming
	SortKey  string       // Stable sort key for deterministic ordering
	Tokens   int          // Estimated token count
	FilePath string       // Path of the diff file this segment came from (AUR-467)
	IsProse  bool         // True when FilePath classified as documentation, not code (AUR-467)
}

ContextSegment represents a piece of context with priority

type Document

type Document struct {
	Path    string // Document path
	Content string // Document content
	Type    string // Document type: "style-guide", "standards", "examples"
}

Document represents additional context documents

type HeuristicEstimator

type HeuristicEstimator struct{}

HeuristicEstimator is the production TokenEstimator. builder.go in the restored c12d7ab engine constructed its default estimator as &StubEstimator{}, but StubEstimator only ever existed in types_test.go -- it never compiled into a production binary (see AUR-430's restoration audit). This type is that estimator, promoted to production: the same ~4-characters-per-token heuristic already used, unrelated to any vendor, by internal/llm/estimator.go's heuristicTokens fallback. Keeping the same ratio here means a budget computed by this package roughly agrees with the one internal/llm falls back to when a provider cannot report its own token count.

func NewHeuristicEstimator

func NewHeuristicEstimator() *HeuristicEstimator

NewHeuristicEstimator creates the default production TokenEstimator.

func (*HeuristicEstimator) Estimate

func (e *HeuristicEstimator) Estimate(text string) int

Estimate approximates token count at ~4 characters per token, never returning zero for non-empty input so a non-empty segment can never be budgeted as free.

type LanguageRules

type LanguageRules struct {
	Language string   // Programming language
	Rules    []string // List of rules to apply
}

LanguageRules contains language-specific review rules

type ParseError

type ParseError struct {
	Kind ParseErrorKind
	// Raw is the response that failed to parse, bounded to a safe preview
	// length so a large or adversarial response cannot balloon an error
	// message that ends up in logs.
	Raw string
	Err error
}

ParseError is the typed, clear failure ParseReviewResponse returns instead of silently degrading to an empty result. See the "Parser fallback" note in docs/specs/AUR-430.md for the reasoning: a caller (or a human reading the review) must be able to tell "no problems found" apart from "the engine could not understand the model," and a bare error string forces every caller back to substring matching to make that distinction.

func (*ParseError) Error

func (e *ParseError) Error() string

func (*ParseError) Unwrap

func (e *ParseError) Unwrap() error

type ParseErrorKind

type ParseErrorKind string

ParseErrorKind classifies why ParseReviewResponse could not produce a structured result. It exists so a caller (or an operator reading logs) can tell "the model said something, but not JSON we could use" apart from every other kind of failure, instead of matching on an error string.

const (
	// ParseErrorNoJSON means no JSON object could be located in the
	// response at all (no code fence, no bare `{...}`).
	ParseErrorNoJSON ParseErrorKind = "no_json_found"
	// ParseErrorInvalidJSON means a JSON-shaped span was found but it did
	// not decode even after repairJSON's best-effort cleanup.
	ParseErrorInvalidJSON ParseErrorKind = "invalid_json"
	// ParseErrorValidation means the JSON decoded but failed structural
	// validation (missing required issue fields, out-of-range scores).
	ParseErrorValidation ParseErrorKind = "validation_failed"
	// ParseErrorNoFindings means neither the JSON path nor the degraded
	// freeform-text fallback (see degradedExtract) could recover a single
	// finding from the response.
	ParseErrorNoFindings ParseErrorKind = "no_findings_recovered"
)

type PriorityTier

type PriorityTier int

PriorityTier defines priority levels for context segments

const (
	// PriorityHigh for changed functions/critical code
	PriorityHigh PriorityTier = 1
	// PriorityMedium for headers and imports
	PriorityMedium PriorityTier = 2
	// PriorityLow for comments and documentation
	PriorityLow PriorityTier = 3
)

type PromptBuilder

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

PromptBuilder builds prompts for LLM code review

func NewPromptBuilder

func NewPromptBuilder() *PromptBuilder

NewPromptBuilder creates a new prompt builder

func NewPromptBuilderWithEstimator

func NewPromptBuilderWithEstimator(estimator TokenEstimator) *PromptBuilder

NewPromptBuilderWithEstimator creates a prompt builder with custom estimator

func (*PromptBuilder) BuildDocumentationPrompt

func (b *PromptBuilder) BuildDocumentationPrompt(diff *types.Diff, language string) string

BuildDocumentationPrompt builds a prompt for generating documentation

func (*PromptBuilder) BuildPrompt

func (b *PromptBuilder) BuildPrompt(diff *types.Diff, metrics *analyzer.DiffMetrics, opts BuildOptions) (PromptParts, error)

BuildPrompt builds a complete prompt with token budgeting

func (*PromptBuilder) BuildReviewPrompt

func (b *PromptBuilder) BuildReviewPrompt(diff *types.Diff, metrics *analyzer.DiffMetrics) string

BuildReviewPrompt builds a prompt for code review

func (*PromptBuilder) BuildSummaryPrompt

func (b *PromptBuilder) BuildSummaryPrompt(diff *types.Diff, metrics *analyzer.DiffMetrics) string

BuildSummaryPrompt builds a prompt for generating a summary

func (*PromptBuilder) BuildTestPrompt

func (b *PromptBuilder) BuildTestPrompt(diff *types.Diff, language string) string

BuildTestPrompt builds a prompt for generating tests

func (*PromptBuilder) RuleCatalog added in v1.0.2

func (b *PromptBuilder) RuleCatalog() []string

RuleCatalog returns the ids this builder renders into the review prompt.

func (*PromptBuilder) SetRuleCatalog added in v1.0.2

func (b *PromptBuilder) SetRuleCatalog(ids []string) error

SetRuleCatalog replaces the mirrored catalog this builder renders. It is the injection seam for a future caller that can pass internal/review's live loader ids down (see the import-cycle note at the top of this file); production today uses DefaultRuleCatalog. It validates eagerly so an over-budget or empty injected catalog is reported at the seam that caused it rather than at some later prompt assembly.

func (*PromptBuilder) TruncatePrompt

func (b *PromptBuilder) TruncatePrompt(prompt string, maxTokens int) string

TruncatePrompt truncates a prompt to fit within token limits

type PromptParts

type PromptParts struct {
	System string            // System message/instructions
	User   string            // User message/content
	Meta   map[string]string // Metadata for tracking
}

PromptParts represents structured prompt components

type ResponseParser

type ResponseParser struct{}

ResponseParser parses LLM responses into structured data

func NewResponseParser

func NewResponseParser() *ResponseParser

NewResponseParser creates a new response parser

func (*ResponseParser) ExtractCodeBlocks

func (p *ResponseParser) ExtractCodeBlocks(response string) []string

ExtractCodeBlocks extracts all code blocks from response

func (*ResponseParser) ParseDocumentationResponse

func (p *ResponseParser) ParseDocumentationResponse(response string) (string, error)

ParseDocumentationResponse parses documentation from LLM response

func (*ResponseParser) ParseReviewResponse

func (p *ResponseParser) ParseReviewResponse(response string) (*types.ReviewResult, error)

ParseReviewResponse parses a review response from LLM

func (*ResponseParser) ParseSummaryResponse

func (p *ResponseParser) ParseSummaryResponse(response string) (string, error)

ParseSummaryResponse parses a summary from LLM response

func (*ResponseParser) ParseTestResponse

func (p *ResponseParser) ParseTestResponse(response string, language string) (string, error)

ParseTestResponse parses generated tests from LLM response

func (*ResponseParser) SanitizeResponse

func (p *ResponseParser) SanitizeResponse(response string) string

SanitizeResponse removes common LLM artifacts from response

type TokenBudget

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

TokenBudget manages token allocation and context trimming

func NewTokenBudget

func NewTokenBudget(estimator TokenEstimator, maxTokens, reserveReply int) *TokenBudget

NewTokenBudget creates a new token budget manager

func (*TokenBudget) Available

func (b *TokenBudget) Available() int

Available returns tokens available for context

func (*TokenBudget) BuildContextSegments

func (b *TokenBudget) BuildContextSegments(diff *types.Diff, detector *analyzer.LanguageDetector) []ContextSegment

BuildContextSegments creates prioritized segments from diff

func (*TokenBudget) EstimateTotal

func (b *TokenBudget) EstimateTotal(segments []ContextSegment) int

EstimateTotal estimates total tokens for segments

func (*TokenBudget) TrimToFit

func (b *TokenBudget) TrimToFit(segments []ContextSegment, baseTokens int) []ContextSegment

TrimToFit trims segments to fit within available tokens.

AUR-475: a segment that does not fit whole is SKIPPED, never truncated (AC-002 forbids partial files -- half a hunk produces a finding about code the reviewer never actually saw), and the loop always CONTINUES to the next, possibly smaller, segment instead of stopping at the first one that doesn't fit. Before this fix the loop `break`d there: one large file at the front of the priority order (e.g. the AGENTS.md hunk AUR-467 measured) consumed the budget and every segment behind it -- fifteen `.mjs` files in the measured case -- was dropped whole, not because it didn't fit but because nothing after the first miss was ever offered a chance. Coverage was a lottery on ordering, not a fact about size.

type TokenEstimator

type TokenEstimator interface {
	// Estimate returns the estimated token count for the given text
	Estimate(text string) int
}

TokenEstimator estimates token counts for text

Jump to

Keyboard shortcuts

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