feat: add --effort support via model[:effort] syntax#285
Conversation
Extends task_model/review_model config and --task-model/--review-model CLI flags to carry Claude's --effort level using model[:effort] syntax (e.g., opus:high, :medium). Both parts are optional and independently usable. - ClaudeExecutor gains Effort field; --effort is injected alongside --model and deduped from claude_args (handles --effort=val and bare --effort) - ParseModelEffort helper splits spec on first colon; exported for external test package access - Runner.New compares parsed (model, effort) tuples when deciding whether to build a separate review executor, so "opus" and "opus:" don't produce redundant executors - Integration test verifies New wiring across 7 spec combinations, including same-model-different-effort (the main feature motivation) - docs/custom-providers.md command template updated to show --effort - Updated README, CLAUDE.md, llms.txt, config defaults, field godoc
There was a problem hiding this comment.
Pull request overview
Adds support for carrying Claude “reasoning effort” alongside the selected model by extending task_model / review_model (and corresponding CLI flags) to accept model[:effort], then wiring that into ClaudeExecutor so --effort <level> is injected next to --model <model>.
Changes:
- Introduces
ClaudeExecutor.Effortand injects/dedupes--effortin the generated Claude CLI args. - Adds
processor.ParseModelEffortand updates runner construction to compare parsed(model, effort)tuples (avoids redundant review executors for equivalent specs likeopusvsopus:). - Extends tests and updates docs/config defaults/README/CLAUDE.md/llms.txt to document the new syntax and behavior.
Reviewed changes
Copilot reviewed 12 out of 12 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| pkg/processor/runner.go | Parses model[:effort] and wires model/effort into task + review executors (tuple comparison for reuse). |
| pkg/processor/runner_test.go | Adds tests for parsing and runner wiring across model/effort combinations. |
| pkg/processor/export_test.go | Adds test-only accessors to inspect chosen executors from external tests. |
| pkg/executor/executor.go | Adds Effort field and --effort injection with dedupe behavior. |
| pkg/executor/executor_test.go | Adds coverage for --effort injection and dedupe (including --effort=... form). |
| pkg/config/defaults/config | Documents model[:effort] syntax and effort levels in embedded defaults. |
| pkg/config/config.go | Updates config field doc comments to reflect model[:effort]. |
| cmd/ralphex/main.go | Updates CLI flag descriptions to reflect model[:effort]. |
| docs/custom-providers.md | Updates provider command template and explains --model/--effort injection + stripping. |
| README.md | Updates CLI/config docs tables to document model[:effort] and effort levels. |
| CLAUDE.md | Updates user-facing documentation for model/effort configuration and wiring. |
| llms.txt | Updates configuration documentation and examples to include effort. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| // inject --effort flag if an effort override is configured; | ||
| // strip any existing --effort from args to avoid duplicate/conflicting flags | ||
| if e.Effort != "" { | ||
| args = stripFlag(args, "--effort") | ||
| args = append(args, "--effort", e.Effort) | ||
| } |
There was a problem hiding this comment.
stripFlag is used here to remove any pre-existing --effort before injecting the override, but its current implementation always skips the token following --effort when it appears as a standalone arg. If a user (or wrapper) has a bare --effort followed by another flag (e.g. --effort --verbose), stripFlag will incorrectly drop --verbose too. Consider updating stripFlag to only skip the next token when it’s a value (e.g., next token doesn’t start with -), so the documented “bare --effort” case is handled safely.
addresses copilot inline review on PR #285: stripFlag was too aggressive when encountering a bare flag in the middle of args — it always consumed the next token as a value, eating unrelated flags like "--effort --verbose". now only consumes the next token when it doesn't start with a dash.
|
@umputun whats your personal preferences on this with opus 4.7? |
Extends
task_model/review_model(and their CLI flags) to carry Claude's--effortlevel alongside the model, usingmodel[:effort]syntax. Single flag, both knobs.Examples:
ralphex --task-model=opus:high docs/plans/foo.md ralphex --review-model=:medium # effort onlyEffort levels:
low,medium,high,xhigh,max. Either part is optional:opus,opus:high,:medium,opus:, all work.Changes:
ClaudeExecutor.Effortfield; injects--effort <val>alongside existing--model, with the same dedupe treatment (handles--effort=valand bare--effort)ParseModelEfforthelper in pkg/processor (exported for external test package)Runner.Newcompares parsed(model, effort)tuples when deciding whether to build a separate review executor — soopusandopus:don't produce redundant executorsTestRunner_New_ModelEffortWiringcovers 7 spec combinations, including the same-model-different-effort case (the main feature motivation)docs/custom-providers.mdcommand template now shows--effort; README, CLAUDE.md, llms.txt, config defaults, field godoc all mention the new syntaxNot in a release yet, so no compat shim.