model

package
v0.4.1 Latest Latest
Warning

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

Go to latest
Published: Jun 29, 2026 License: MIT Imports: 8 Imported by: 0

Documentation

Overview

Package model defines the Model interface and prompt/parse helpers shared by all model-CLI adapters. Transport types (FindingCandidate, ModelReviewResult, ReviewInput) live in internal/review so that review (the domain leaf) does not depend on this package.

The model layer never validates findings against the diff — that's the review package's job. The model layer's contract is "produce a parsed, well-typed transport object from a CLI invocation."

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func BuildPrompt

func BuildPrompt(input *review.ReviewInput) string

BuildPrompt builds the structured prompt that all v1 model adapters send. The content mirrors docs/prompt-contract.md — JSON-only output, the schema shape inline, the review rules, and an explicit instruction to treat the diff as untrusted input.

The prompt is deterministic given the same ReviewInput: tests can pin substrings without flakiness, and reviewers using --print-prompt see exactly what the model will see.

func BuildSynthesisPrompt

func BuildSynthesisPrompt(input *review.ReviewInput, results []*review.ModelReviewResult) string

BuildSynthesisPrompt constructs the synthesis prompt sent to the lead model. The lead receives the original diff plus per-model findings from other reviewers and is asked to dedupe, merge, drop false positives, and re-emit a unified findings set in its own voice. The output schema is the SAME as a normal review (an object with a "findings" array) so existing parser/validator paths apply unchanged.

func ParseFindings

func ParseFindings(raw []byte) ([]review.FindingCandidate, error)

ParseFindings turns raw model stdout into review.FindingCandidate values.

The contract from docs/prompt-contract.md is strict JSON, but reality is that models occasionally wrap the envelope in markdown code fences (agy) or chatty prose (claude's "Here is the review: ..."). Rather than rejecting these and failing the whole review, stripWrapper peels any outer wrapper before parsing — it slices to the outermost JSON object delimited by the first `{` and the last `}`. Any other deviation (no JSON at all, malformed JSON, missing findings key) still returns a categorized *ParseError so callers can surface a useful message.

Types

type InputBudgetSetter added in v0.1.7

type InputBudgetSetter interface {
	SetInputBudget(bytes int)
}

InputBudgetSetter is an optional capability for adapters that cap the prompt size sent to their backing CLI. The app layer type-asserts to this interface and applies a user-supplied --input-budget value before Review runs. An adapter that didn't enforce a budget simply wouldn't implement it and would be skipped silently by the override loop. (All current adapters — codex, claude, antigravity — implement it.)

Implementations must treat n <= 0 as a no-op so a missing/zeroed flag can't accidentally turn the budget off and let an arbitrarily large prompt through.

type Model

type Model = Reviewer

Model is an alias for Reviewer kept so existing call sites that reference model.Model continue to compile. New code should prefer the explicit capability names (Reviewer for the base, Synthesizer for the optional synthesis path).

type ModelSetter added in v0.3.1

type ModelSetter interface {
	SetModel(name string)
}

ModelSetter is an optional capability for adapters whose backing CLI can run more than one model (currently only antigravity/agy, which exposes Gemini, Claude, and GPT-OSS variants). The app layer type-asserts to this interface and applies --antigravity-model before Review. Adapters that wrap a single-model CLI (codex, claude) don't implement it.

Implementations must treat an empty name as a no-op so an unset flag can't blank out the adapter's pinned default.

type ParseError

type ParseError struct {
	Kind  string // "prose_preamble" | "invalid_json" | "wrong_shape"
	Raw   string
	Cause error
}

ParseError describes why a model's stdout couldn't be parsed. Kind narrows the cause for actionable error messages; Raw is the FULL offending output, retained untruncated so it can be surfaced for diagnosis (diffsmith-2xy). Error() prints only a bounded snippet of it; callers wanting the whole payload read Raw directly.

func (*ParseError) Error

func (e *ParseError) Error() string

func (*ParseError) Unwrap

func (e *ParseError) Unwrap() error

type Reviewer added in v0.1.6

type Reviewer interface {
	Name() string
	Preflight(ctx context.Context) error
	Review(ctx context.Context, input *review.ReviewInput) (*review.ModelReviewResult, error)
}

Reviewer is the base capability every model-CLI adapter implements: preflight checks, then a single Review call against one diff. Each adapter pairs with exactly one CLI family (codex, claude, antigravity).

Callers must invoke Preflight before Review so the user sees an actionable error if the CLI is missing, rather than a stack trace from os/exec.

Multi-model synthesis is an OPTIONAL capability layered on top of Reviewer; see Synthesizer. Splitting the two means a future review-only adapter would not need to carry a fake Synthesize method that only exists to satisfy a composite interface. (All current adapters — codex, claude, antigravity — are full peers.)

type SelectedModels

type SelectedModels struct {
	All []Model
}

SelectedModels is the user's picker choice carried through the review pipeline. All is sorted by priority (codex > claude > antigravity). The synthesis-lead-priority concept is encoded in the All ordering itself — callers that need "the highest-priority surviving model" iterate All in order; the first match wins.

func NewSelectedModels

func NewSelectedModels(ms []Model) *SelectedModels

NewSelectedModels returns a SelectedModels with All sorted by the canonical priority order. Unknown model names are sorted after the known ones (lowest priority).

type Synthesizer added in v0.1.6

type Synthesizer interface {
	Synthesize(ctx context.Context, input *review.ReviewInput, results []*review.ModelReviewResult) (*review.ModelReviewResult, error)
}

Synthesizer is the optional capability: take the diff input plus per-model review results from N≥2 selected reviewers and re-emit a unified findings set in this model's voice. Used by the multi-model flow when at least two selected models successfully produced findings.

The synthesis call site (app/review.go) type-asserts the lead candidate against this interface and skips lead candidates that don't satisfy it — there is no fallback to a stub. A model that cannot synthesize is simply not eligible to lead synthesis.

Directories

Path Synopsis
Package antigravitycli implements the Antigravity model adapter.
Package antigravitycli implements the Antigravity model adapter.
Package claudecli implements the Claude model adapter via `claude --print --output-format=text`.
Package claudecli implements the Claude model adapter via `claude --print --output-format=text`.
Package codexcli implements the Codex model adapter via `codex exec --output-schema`.
Package codexcli implements the Codex model adapter via `codex exec --output-schema`.

Jump to

Keyboard shortcuts

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