Skip to content

feat: rename claude_model to task_model, address unmerged #272 review findings#284

Merged
umputun merged 2 commits intomasterfrom
task-model-rename
Apr 16, 2026
Merged

feat: rename claude_model to task_model, address unmerged #272 review findings#284
umputun merged 2 commits intomasterfrom
task-model-rename

Conversation

@umputun
Copy link
Copy Markdown
Owner

@umputun umputun commented Apr 16, 2026

Picks up unmerged follow-up commits from feat/claude-model-config (those 3 commits ended up on the branch but didn't make it into the squash-merge of #272).

Changes:

  • rename claude_model -> task_model and --claude-model -> --task-model for symmetry with review_model / --review-model
  • pass task model to plan mode (was missing in original PR)
  • strip duplicate --model flags from claude_args to avoid CLI errors when users put --model in args
  • fix typo in pkg/config/defaults/config: review_model section had # claude_model = example
  • add processor test for ReviewClaude executor separation (nil fallback + distinct review executor)
  • add ReviewModel merge test, normalize --flag=value form in docs
  • update README, CLAUDE.md, llms.txt, custom-providers.md
  • update review-claude tests for the post-codex-skip behavior added in Skip post-codex claude review when no findings #282

The claude_model name was introduced by the partial merge of #272, so the rename is correcting an in-flight feature rather than a stable API.

… findings

- rename claude_model -> task_model and --claude-model -> --task-model for symmetry with review_model/--review-model
- pass task model to plan mode (was missing)
- strip duplicate --model flags from claude_args to prevent CLI errors
- fix typo in pkg/config/defaults/config: review_model section had `# claude_model =` example
- add processor test for ReviewClaude executor separation (nil fallback + distinct review executor)
- add ReviewModel merge test, normalize --flag=value form in docs
- update docs (README, CLAUDE.md, llms.txt, custom-providers.md)
- update review-claude tests for post-codex-skip behavior added in #282

picks up unmerged follow-up commits from feat/claude-model-config branch
Copilot AI review requested due to automatic review settings April 16, 2026 22:46
@cloudflare-workers-and-pages
Copy link
Copy Markdown

cloudflare-workers-and-pages Bot commented Apr 16, 2026

Deploying ralphex with  Cloudflare Pages  Cloudflare Pages

Latest commit: 5076249
Status:⚡️  Build in progress...

View logs

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Renames the per-phase Claude model configuration from claude_model to task_model, wires the task model into plan mode, and hardens model flag injection to avoid duplicate --model CLI arguments.

Changes:

  • Rename config/CLI surface area to task_model / --task-model for symmetry with review_model / --review-model.
  • Ensure plan mode uses the resolved task model and add tests validating ReviewClaude executor routing/fallback.
  • Strip pre-existing --model entries from claude_args before injecting the configured model, and update docs to a consistent --flag=value style.

Reviewed changes

Copilot reviewed 13 out of 13 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
pkg/processor/runner.go Renames config fields and ensures task vs review executors use TaskModel/ReviewModel correctly.
pkg/processor/runner_test.go Adds coverage for review executor separation and nil fallback behavior.
pkg/executor/executor.go Adds stripFlag and uses it to avoid duplicate --model injection.
pkg/executor/executor_test.go Adds tests for stripFlag and model flag override behavior.
pkg/config/values.go Renames parsed key to task_model and merges TaskModel.
pkg/config/values_test.go Updates parsing/merge tests for task_model and expands ReviewModel merge tests.
pkg/config/config.go Renames exported config JSON key to task_model and wires through loader.
pkg/config/defaults/config Updates default config template comments/examples for task_model and review_model.
cmd/ralphex/main.go Renames CLI flag to --task-model and passes resolved task model to runner + plan mode.
README.md Updates examples/options table to include --task-model and normalize --flag=value usage.
CLAUDE.md Updates project conventions/docs examples for new flags and --flag=value style.
llms.txt Updates usage examples and adds per-phase model configuration docs snippet.
docs/custom-providers.md Documents optional --model injection in the ClaudeExecutor command line.
Comments suppressed due to low confidence (1)

pkg/config/values.go:189

  • Config parsing now only reads "task_model". Since the immediately-previous key was "claude_model", existing configs on the current mainline/branch will silently stop applying the model override after this rename. Consider accepting both keys (e.g., read task_model first, then fall back to claude_model) and optionally emitting a deprecation warning when claude_model is used.
	// claude settings
	if key, err := section.GetKey("claude_command"); err == nil {
		values.ClaudeCommand = key.String()
	}
	if key, err := section.GetKey("claude_args"); err == nil {
		values.ClaudeArgs = key.String()
	}
	if key, err := section.GetKey("task_model"); err == nil {
		values.TaskModel = key.String()
	}
	if key, err := section.GetKey("review_model"); err == nil {
		values.ReviewModel = key.String()
	}

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread CLAUDE.md Outdated
- `--wait` flag enables rate limit retry with specified duration (e.g., `--wait 1h`)
- `--session-timeout` flag sets per-session timeout for claude (e.g., `--session-timeout 30m`), kills hanging sessions
- `--idle-timeout` flag kills claude sessions when no output is received for a specified duration (e.g., `--idle-timeout 5m`), resets on each output line
- `--task-model` flag sets model for task execution (e.g., `--task-model=opus`); `--review-model` sets model for review phases (falls back to `--task-model`). Only applies to default Claude CLI, ignored by custom wrappers (`claude_command`)
Copy link

Copilot AI Apr 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The docs here say task_model/review_model are ignored by custom wrappers, but ralphex will still pass a --model flag when these are set; wrappers may ignore it or translate it to their own model selection. Consider adjusting wording to avoid implying it can never work with wrappers, and (if desired) document that provided wrappers currently ignore it unless extended.

Suggested change
- `--task-model` flag sets model for task execution (e.g., `--task-model=opus`); `--review-model` sets model for review phases (falls back to `--task-model`). Only applies to default Claude CLI, ignored by custom wrappers (`claude_command`)
- `--task-model` flag sets model for task execution (e.g., `--task-model=opus`); `--review-model` sets model for review phases (falls back to `--task-model`). ralphex passes these through as `--model`; with custom wrappers (`claude_command`), support depends on the wrapper, which may ignore the flag or translate it to its own model-selection mechanism. The provided wrappers currently ignore it unless extended

Copilot uses AI. Check for mistakes.
Comment thread README.md Outdated
Comment on lines +808 to +809
| `task_model` | Model for task execution (e.g., `opus`, `sonnet`). Only applies to default Claude CLI, ignored by custom wrappers | empty |
| `review_model` | Model for review phases. Falls back to `task_model` if empty. Only applies to default Claude CLI | empty |
Copy link

Copilot AI Apr 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The README claims task_model/review_model are ignored by custom wrappers, but the executor will pass --model whenever these are set and wrapper behavior determines whether it is ignored or mapped. Consider clarifying that this is wrapper-dependent (and that wrappers should accept/ignore unknown flags to avoid breaking when --model is present).

Suggested change
| `task_model` | Model for task execution (e.g., `opus`, `sonnet`). Only applies to default Claude CLI, ignored by custom wrappers | empty |
| `review_model` | Model for review phases. Falls back to `task_model` if empty. Only applies to default Claude CLI | empty |
| `task_model` | Model for task execution (e.g., `opus`, `sonnet`). Intended for the default Claude CLI; when set, the executor may still pass `--model` to custom wrappers, and whether it is ignored or mapped is wrapper-dependent. Custom wrappers should accept or ignore unknown flags to avoid breaking when `--model` is present | empty |
| `review_model` | Model for review phases. Falls back to `task_model` if empty. Intended for the default Claude CLI; when set, the executor may still pass `--model` to custom wrappers, and whether it is ignored or mapped is wrapper-dependent. Custom wrappers should accept or ignore unknown flags to avoid breaking when `--model` is present | empty |

Copilot uses AI. Check for mistakes.
Comment thread pkg/executor/executor.go Outdated
Comment on lines +152 to +161
// stripFlag removes a flag and its value from args (e.g., stripFlag(args, "--model")
// removes both "--model" and the following element). Returns a new slice.
func stripFlag(args []string, flag string) []string {
result := make([]string, 0, len(args))
for i := 0; i < len(args); i++ {
if args[i] == flag && i+1 < len(args) {
i++ // skip flag and its value
continue
}
result = append(result, args[i])
Copy link

Copilot AI Apr 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

stripFlag only removes the separate "--model " form when a value is present. It does not remove "--model=" (common long-flag form) and it leaves a trailing "--model" with no value intact, which can still produce duplicate/conflicting --model flags or a CLI parse error. Consider stripping both "--model=<...>" and a bare "--model" (no value) as well as repeated occurrences.

Suggested change
// stripFlag removes a flag and its value from args (e.g., stripFlag(args, "--model")
// removes both "--model" and the following element). Returns a new slice.
func stripFlag(args []string, flag string) []string {
result := make([]string, 0, len(args))
for i := 0; i < len(args); i++ {
if args[i] == flag && i+1 < len(args) {
i++ // skip flag and its value
continue
}
result = append(result, args[i])
// stripFlag removes all occurrences of a flag from args.
// It strips both "--flag value" and "--flag=value" forms, and also removes
// a bare trailing "--flag" with no value. Returns a new slice.
func stripFlag(args []string, flag string) []string {
result := make([]string, 0, len(args))
for i := 0; i < len(args); i++ {
switch {
case args[i] == flag:
if i+1 < len(args) {
i++ // skip flag and its value when provided separately
}
continue
case strings.HasPrefix(args[i], flag+"="):
continue // skip --flag=value form
default:
result = append(result, args[i])
}

Copilot uses AI. Check for mistakes.
Comment on lines +459 to +470
func TestStripFlag(t *testing.T) {
tests := []struct {
name string
args []string
flag string
want []string
}{
{name: "removes flag and value", args: []string{"--verbose", "--model", "opus", "--print"}, flag: "--model", want: []string{"--verbose", "--print"}},
{name: "flag not present", args: []string{"--verbose", "--print"}, flag: "--model", want: []string{"--verbose", "--print"}},
{name: "flag at end with value", args: []string{"--verbose", "--model", "opus"}, flag: "--model", want: []string{"--verbose"}},
{name: "empty args", args: []string{}, flag: "--model", want: []string{}},
}
Copy link

Copilot AI Apr 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new stripFlag tests don’t cover the problematic cases that currently slip through: "--model=opus" and a bare "--model" without a value. Adding these cases would lock in the intended behavior and prevent regressions when users include long flags in claude_args.

Copilot uses AI. Check for mistakes.
Comment thread cmd/ralphex/main.go
ReviewPatience int `long:"review-patience" default:"0" description:"terminate external review after N unchanged rounds (0 = disabled)"`
ClaudeModel string `long:"claude-model" description:"model for task execution (e.g., opus, sonnet, haiku)"`
ReviewModel string `long:"review-model" description:"model for review phases (falls back to --claude-model)"`
TaskModel string `long:"task-model" description:"model for task execution (e.g., opus, sonnet, haiku)"`
Copy link

Copilot AI Apr 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The CLI flag was renamed from --claude-model to --task-model without an alias. If users already adopted --claude-model from the partially-merged feature, their scripts will break. Consider keeping --claude-model as a deprecated alias (with lower precedence than --task-model when both are provided) for at least one release cycle.

Suggested change
TaskModel string `long:"task-model" description:"model for task execution (e.g., opus, sonnet, haiku)"`
TaskModel string `long:"task-model" description:"model for task execution (e.g., opus, sonnet, haiku)"`
ClaudeModel string `long:"claude-model" hidden:"true" description:"deprecated alias for --task-model"`

Copilot uses AI. Check for mistakes.
Comment thread llms.txt Outdated

**Stalemate detection:** `review_patience` config option (or `--review-patience` CLI flag) terminates the external review loop early when Claude produces no commits for N consecutive rounds. Set to 0 (default) to disable. Useful when the external tool and Claude can't agree on findings.

**Per-phase model configuration:** `task_model` config option (or `--task-model` CLI flag) sets the model for task execution (e.g., `opus`, `sonnet`, `haiku`). `review_model` (or `--review-model`) sets the model for review phases; falls back to `task_model` if empty. When set, `--model <value>` is injected into the Claude CLI args. Only applies to the default Claude CLI — custom wrappers (`claude_command`) ignore the `--model` flag. Empty by default (uses Claude CLI's default model).
Copy link

Copilot AI Apr 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doc states model overrides are ignored by custom wrappers, but the executor always appends [--model ] whenever task_model/review_model is set, regardless of claude_command. Whether it is ignored or mapped is wrapper-dependent (the wrapper may choose to consume/translate it). Consider rephrasing to reflect that ralphex passes --model and wrappers may ignore or implement it.

Suggested change
**Per-phase model configuration:** `task_model` config option (or `--task-model` CLI flag) sets the model for task execution (e.g., `opus`, `sonnet`, `haiku`). `review_model` (or `--review-model`) sets the model for review phases; falls back to `task_model` if empty. When set, `--model <value>` is injected into the Claude CLI args. Only applies to the default Claude CLIcustom wrappers (`claude_command`) ignore the `--model` flag. Empty by default (uses Claude CLI's default model).
**Per-phase model configuration:** `task_model` config option (or `--task-model` CLI flag) sets the model for task execution (e.g., `opus`, `sonnet`, `haiku`). `review_model` (or `--review-model`) sets the model for review phases; falls back to `task_model` if empty. When set, ralphex appends `--model <value>` to the Claude command args. With the default Claude CLI, this selects the requested model. With custom wrappers (`claude_command`), handling of `--model` is wrapper-dependent: wrappers may ignore it, consume it directly, or translate it to their own equivalent. Empty by default (uses Claude CLI's default model).

Copilot uses AI. Check for mistakes.
- stripFlag now handles --flag=value and bare --flag forms (was only handling --flag value space-form), prevents duplicate/orphaned --model in claude_args
- add stripFlag tests for equals form, bare flag, repeated occurrences, prefix-only false-match
- doc wording: clarify that task_model/review_model are passed as --model to the configured claude_command and may be ignored or implemented by custom wrappers
@umputun umputun merged commit b748eb5 into master Apr 16, 2026
2 of 3 checks passed
@umputun umputun deleted the task-model-rename branch April 16, 2026 22:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants