review

package
v0.4.2 Latest Latest
Warning

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

Go to latest
Published: May 14, 2026 License: MIT Imports: 12 Imported by: 0

Documentation

Overview

Package review implements the MR-review pipeline: git diff → graph evidence → LLM review. Phase 3 of the optimization plan.

Two entry points:

  • CLI: `codeiq review --base <ref> --head <ref>` (cli/review.go)
  • MCP: `review_changes` tool (mcp/tools_review.go)

Both call ReviewService.Review which:

  1. Shells out to `git diff` for the file list + hunks.
  2. For each changed file, queries the graph for nodes-in-file, blast radius, and evidence packs.
  3. Renders a single prompt and calls the configured LLM (default: Ollama Cloud gpt-oss).
  4. Returns a structured review report (markdown for CLI, JSON for MCP).

Index

Constants

View Source
const SystemPrompt = `You are reviewing a pull request. Use the structured graph evidence to find correctness, security, and architectural issues. ` +
	`Return strictly JSON in this shape: ` +
	`{"summary": "<one-paragraph overview>", "findings": [{"file": "<path>", "line": <int>, "severity": "info|low|medium|high|critical", "comment": "<message>"}]}. ` +
	`No prose before or after the JSON. ` +
	`If the diff is trivial, return an empty findings array — do NOT invent issues.`

SystemPrompt is the single system message we use for every review. Plan §3.1 — "use the structured graph evidence to find correctness, security, and architectural issues".

Variables

This section is empty.

Functions

This section is empty.

Types

type ChangedFile

type ChangedFile struct {
	Path         string
	Hunks        []string
	AddedLines   int
	RemovedLines int
}

ChangedFile is one entry in the diff.

func GitDiff

func GitDiff(cwd, base, head string) ([]ChangedFile, error)

GitDiff shells out to `git diff --unified=3 <base>..<head>` from cwd and returns the parsed result. Mirrors the Java DiffParser shellout.

func ParseDiff

func ParseDiff(raw string) ([]ChangedFile, error)

ParseDiff parses raw unified `git diff` output into a per-file slice. File renames are reported under the new path. Binary diffs are recorded with empty hunks and zero line counts.

type Client

type Client struct {
	Config     Config
	HTTPClient *http.Client
}

Client wraps the OpenAI-compatible /chat/completions endpoint exposed by Ollama, Ollama Cloud, and proxies. The HTTPClient field is exported so tests can inject a stub.

func NewClient

func NewClient(cfg Config) *Client

NewClient returns a Client with cfg and a default *http.Client.

func (*Client) Review

func (c *Client) Review(ctx context.Context, userPrompt string) (*Report, error)

Review sends the assembled prompt to the LLM and parses the structured reply into a Report. The user prompt should already include the diff + evidence pack rendering.

type Config

type Config struct {
	// Endpoint is the OpenAI-compatible chat completions URL. Common
	// values:
	//   - https://ollama.com/api/v1            (Ollama Cloud)
	//   - http://localhost:11434/v1            (local Ollama)
	//   - https://api.openai.com/v1            (OpenAI proxy / compatible)
	Endpoint string

	// APIKey is the bearer token. Empty for local Ollama.
	APIKey string

	// Model is the model name, e.g. "gpt-oss:20b".
	Model string

	// Timeout caps a single LLM HTTP call.
	Timeout time.Duration

	// MaxFiles caps the per-review change set. 0 = unlimited.
	MaxFiles int

	// MaxContextTokens is a soft per-call budget the prompt builder
	// honors when assembling evidence (truncates oldest evidence first).
	MaxContextTokens int
}

Config selects the LLM endpoint + model + timeouts for the review path. Defaults target local Ollama; setting OLLAMA_API_KEY flips to Ollama Cloud (mirrors the Java ReviewConfig contract).

func DefaultConfig

func DefaultConfig() Config

DefaultConfig returns the standard Ollama defaults. When OLLAMA_API_KEY is set the endpoint flips to Ollama Cloud.

type Finding

type Finding struct {
	File     string `json:"file"`
	Line     int    `json:"line,omitempty"`
	Severity string `json:"severity"` // info | low | medium | high | critical
	Comment  string `json:"comment"`
}

Finding is one structured review comment from the LLM.

type GraphContext

type GraphContext interface {
	// EvidenceForFile returns a short, deterministic textual summary of
	// the graph context for a path: nodes-in-file, callers/dependents,
	// frameworks detected. Free-form; whatever the LLM finds useful.
	EvidenceForFile(path string) string
}

GraphContext is the small graph-side dep ReviewService needs. The concrete implementation lives in mcp/cli code; this interface keeps the review package decoupled from the graph.Store. nil is acceptable — review will just send the diff without graph evidence.

type KuzuGraphContext

type KuzuGraphContext struct {
	Store *graph.Store
}

KuzuGraphContext implements GraphContext by querying an open Kuzu store. Wire from CLI: open store, NewKuzuGraphContext(store), pass to NewService.

EvidenceForFile returns a compact textual summary that the LLM finds useful: nodes-in-file with kind + layer, plus 1-hop blast radius node IDs. Strictly read-only.

func NewKuzuGraphContext

func NewKuzuGraphContext(store *graph.Store) *KuzuGraphContext

NewKuzuGraphContext returns a context backed by store. nil Store yields empty evidence (the LLM degrades gracefully to diff-only review).

func (*KuzuGraphContext) EvidenceForFile

func (k *KuzuGraphContext) EvidenceForFile(path string) string

EvidenceForFile satisfies GraphContext. Empty string when the store is missing or the file has no graph nodes.

type Report

type Report struct {
	Summary   string    `json:"summary"`
	Findings  []Finding `json:"findings"`
	Model     string    `json:"model"`
	RequestID string    `json:"request_id,omitempty"`
}

Report is the structured LLM output. Both CLI (markdown) and MCP (JSON) paths consume this shape.

type Service

type Service struct {
	Client *Client
	Graph  GraphContext // may be nil
}

Service orchestrates diff → graph evidence → LLM call. Stateless; pass-by-value safe.

func NewService

func NewService(client *Client, graph GraphContext) *Service

NewService wires the Service. Graph may be nil for non-enriched invocations (the LLM gets just the diff).

func (*Service) Review

func (s *Service) Review(ctx context.Context, cwd, base, head string, focusFiles []string) (*Report, error)

Review runs the full pipeline against the given working tree and refs. Pass an empty base to compare against HEAD~1; empty head defaults to HEAD. FocusFiles, if non-empty, limits the review to those file paths.

Jump to

Keyboard shortcuts

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