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 (gemini) 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 Model ¶
type Model interface {
Name() string
Preflight(ctx context.Context) error
Review(ctx context.Context, input *review.ReviewInput) (*review.ModelReviewResult, error)
// Synthesize takes the diff input plus per-model review results
// from other (or all) selected models and re-emits a unified
// []Finding set in this model's voice. Used by the multi-model
// flow when N≥2 selected models successfully produced findings.
Synthesize(ctx context.Context, input *review.ReviewInput, results []*review.ModelReviewResult) (*review.ModelReviewResult, error)
}
Model adapters produce normalized review findings for one CLI family.
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.
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 a truncated copy of the offending output for debug surfaces.
func (*ParseError) Error ¶
func (e *ParseError) Error() string
func (*ParseError) Unwrap ¶
func (e *ParseError) Unwrap() error
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 > gemini > 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).
Directories
¶
| Path | Synopsis |
|---|---|
|
Package antigravitycli implements the Antigravity model adapter (experimental in v1).
|
Package antigravitycli implements the Antigravity model adapter (experimental in v1). |
|
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`. |
|
Package geminicli implements the Gemini model adapter via `gemini -o text`.
|
Package geminicli implements the Gemini model adapter via `gemini -o text`. |