Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions cmd/opencodereview/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ type reviewOptions struct {
audience string // --audience: "human" (default) or "agent"
background string // --background: optional requirement context
backgroundFile string // --background-file: path to a Markdown file used as background
provider string // --provider: override resolved LLM provider for this review
model string // --model: override resolved LLM model for this review
concurrency int
perFileTimeout int
Expand Down Expand Up @@ -135,6 +136,7 @@ func parseReviewFlags(args []string) (reviewOptions, error) {
a.StringVar(&opts.audience, "audience", "human", "output audience: human (show progress) or agent (summary only)")
a.StringVarP(&opts.background, "background", "b", "", "optional requirement/business context for the review")
a.StringVarP(&opts.backgroundFile, "background-file", "B", "", "optional requirement/business context from a Markdown file (combined with --background; inline value appears first when both are set)")
a.StringVar(&opts.provider, "provider", "", "override LLM provider for this review (e.g., openai)")
a.StringVar(&opts.model, "model", "", "override LLM model for this review (e.g., claude-opus-4-6)")
a.IntVar(&opts.maxTools, "max-tools", 0, "max tool call rounds per file (0 = template default; min 10)")
a.IntVar(&opts.maxGitProcs, "max-git-procs", 16, "max concurrent git subprocesses")
Expand Down Expand Up @@ -239,6 +241,7 @@ Flags:
--max-git-procs int max concurrent git subprocesses (default 16)
--from string source ref to start diff from (e.g., 'main')
--max-tools int max tool call rounds per file (0 = template default; min 10)
--provider string override LLM provider for this review (e.g., openai)
--model string override LLM model for this review (e.g., claude-opus-4-6)
-p, --preview preview which files will be reviewed without running the LLM
--repo string root directory of the git repository (default: current dir)
Expand Down
11 changes: 11 additions & 0 deletions cmd/opencodereview/flags_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,17 @@ func TestParseReviewFlagsModelOverride(t *testing.T) {
}
}

func TestParseReviewFlagsProviderOverride(t *testing.T) {
opts, err := parseReviewFlags([]string{"--provider", "openai"})
if err != nil {
t.Fatalf("parseReviewFlags: %v", err)
}

if opts.provider != "openai" {
t.Errorf("provider = %q, want %q", opts.provider, "openai")
}
}

func TestParseReviewFlagsResume(t *testing.T) {
opts, err := parseReviewFlags([]string{"--from", "main", "--to", "feature", "--resume", "session-123"})
if err != nil {
Expand Down
2 changes: 1 addition & 1 deletion cmd/opencodereview/review_cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ func runReview(args []string) error {
return err
}

rt, err := loadLLMRuntime(cc.Template, opts.toolConfigPath, opts.model)
rt, err := loadLLMRuntime(cc.Template, opts.toolConfigPath, opts.provider, opts.model)
if err != nil {
return err
}
Expand Down
5 changes: 4 additions & 1 deletion cmd/opencodereview/scan_cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ type scanOptions struct {
noSummary bool // --no-summary: skip the post-run PROJECT_SUMMARY_TASK
batch string // --batch: override scan template's BATCH_STRATEGY
maxTokensBudget int // --max-tokens-budget: cap total token usage; 0 = unlimited
provider string // --provider: override resolved LLM provider for this scan
model string // --model: override resolved LLM model for this scan
showHelp bool
}
Expand All @@ -66,6 +67,7 @@ func parseScanFlags(args []string) (scanOptions, error) {
a.BoolVar(&opts.noSummary, "no-summary", false, "skip the post-run PROJECT_SUMMARY_TASK (no project-level markdown summary)")
a.StringVar(&opts.batch, "batch", "", "override BATCH_STRATEGY from scan template: none | by-language | by-directory")
a.IntVar(&opts.maxTokensBudget, "max-tokens-budget", 0, "cap total token usage (input+output); dispatch stops once exceeded (0 = unlimited)")
a.StringVar(&opts.provider, "provider", "", "override LLM provider for this scan (e.g., openai)")
a.StringVar(&opts.model, "model", "", "override LLM model for this scan (e.g., claude-opus-4-6)")

if err := a.Parse(args); err != nil {
Expand Down Expand Up @@ -159,7 +161,7 @@ func runScan(args []string) error {
return runScanPreview(cc, scanTpl, scanPaths)
}

rt, err := loadLLMRuntime(cc.Template, opts.toolConfigPath, opts.model)
rt, err := loadLLMRuntime(cc.Template, opts.toolConfigPath, opts.provider, opts.model)
if err != nil {
return err
}
Expand Down Expand Up @@ -287,6 +289,7 @@ Flags:
--no-summary skip the post-run PROJECT_SUMMARY_TASK
--batch string override BATCH_STRATEGY: none | by-language | by-directory
--max-tokens-budget int cap total token usage; dispatch stops once exceeded (0 = unlimited)
--provider string override LLM provider for this scan (e.g., openai)
--model string override LLM model for this scan (e.g., claude-opus-4-6)
--audience string output audience: human (show progress) or agent (summary only) (default "human")
-b, --background string optional requirement/business context for the scan
Expand Down
10 changes: 10 additions & 0 deletions cmd/opencodereview/scan_cmd_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,16 @@ func TestParseScanFlags_ModelOverride(t *testing.T) {
}
}

func TestParseScanFlags_ProviderOverride(t *testing.T) {
opts, err := parseScanFlags([]string{"--provider", "openai"})
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if opts.provider != "openai" {
t.Errorf("provider = %q, want openai", opts.provider)
}
}

func TestParseScanFlags_AllStringFlags(t *testing.T) {
opts, err := parseScanFlags([]string{
"--tools", "/tmp/tools.json",
Expand Down
7 changes: 4 additions & 3 deletions cmd/opencodereview/shared.go
Original file line number Diff line number Diff line change
Expand Up @@ -139,9 +139,10 @@ type llmRuntime struct {
// loadLLMRuntime loads tool defs from toolConfigPath, reads the app config
// from the user's default config path (applying the configured language to
// tpl — defaulting when the config file is absent), resolves the LLM
// endpoint (honoring modelOverride from --model when non-empty), and
// endpoint (honoring providerOverride from --provider and modelOverride from --model
// when non-empty), and
// returns the runtime bundle. tpl is mutated in place.
func loadLLMRuntime(tpl *template.Template, toolConfigPath, modelOverride string) (*llmRuntime, error) {
func loadLLMRuntime(tpl *template.Template, toolConfigPath, providerOverride, modelOverride string) (*llmRuntime, error) {
toolEntries, err := toolsconfig.Load(toolConfigPath)
if err != nil {
return nil, fmt.Errorf("load tools: %w", err)
Expand All @@ -165,7 +166,7 @@ func loadLLMRuntime(tpl *template.Template, toolConfigPath, modelOverride string
}
tpl.ApplyLanguage(lang)

ep, err := llm.ResolveEndpointWithModelOverride(cfgPath, modelOverride)
ep, err := llm.ResolveEndpointWithOverrides(cfgPath, providerOverride, modelOverride)
if err != nil {
return nil, fmt.Errorf("resolve LLM endpoint: %w", err)
}
Expand Down
Loading
Loading