feat: add per-workflow model configuration#5
Conversation
- Add optional `model` field to WorkflowConfig for specifying Claude model per workflow - Update Executor interface to accept model parameter - Add --verbose flag to fix Claude CLI stream-json requirement - Configure code-review workflow to use claude-sonnet-4-20250514 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Greptile OverviewGreptile SummaryThis PR introduces per-workflow model configuration, allowing different workflows to use specific Claude models. The implementation is well-structured and follows existing patterns in the codebase. Key ChangesConfiguration Layer
Executor Layer
Workflow Layer
Strengths
Areas for Improvement
Confidence Score: 4/5
Important Files ChangedFile Analysis
Sequence DiagramsequenceDiagram
participant User
participant Runner as workflow.Runner
participant Config as config.Config
participant Executor as claude.Executor
participant Claude as Claude CLI
User->>Runner: RunSingle(ctx, "code-review", "PROJ-123")
Runner->>Config: GetPrompt("code-review", "PROJ-123")
Config-->>Runner: "/bmad:...:code-review - Review story: PROJ-123..."
Runner->>Config: GetModel("code-review")
Config-->>Runner: "claude-sonnet-4-20250514"
Runner->>Executor: ExecuteWithResult(ctx, prompt, handler, "claude-sonnet-4-20250514")
Executor->>Claude: exec.Command("claude", "--dangerously-skip-permissions", "-p", prompt, "--output-format", "stream-json", "--verbose", "--model", "claude-sonnet-4-20250514")
Claude-->>Executor: Stream JSON events
Executor->>Runner: handler(event) for each event
Claude-->>Executor: Exit code
Executor-->>Runner: exitCode, err
Runner-->>User: exitCode
|
| func (c *Config) GetModel(workflowName string) string { | ||
| workflow, ok := c.Workflows[workflowName] | ||
| if !ok { | ||
| return "" | ||
| } | ||
| return workflow.Model |
There was a problem hiding this comment.
The new GetModel method lacks test coverage. Consider adding tests to verify:
- Returns correct model when workflow exists and has model configured
- Returns empty string when workflow exists but model is not set
- Returns empty string when workflow doesn't exist
Example test structure:
func TestConfig_GetModel(t *testing.T) {
cfg := &Config{
Workflows: map[string]WorkflowConfig{
"with-model": {Model: "claude-sonnet-4"},
"no-model": {PromptTemplate: "test"},
},
}
assert.Equal(t, "claude-sonnet-4", cfg.GetModel("with-model"))
assert.Equal(t, "", cfg.GetModel("no-model"))
assert.Equal(t, "", cfg.GetModel("unknown"))
}Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!
Prompt To Fix With AI
This is a comment left during a code review.
Path: internal/config/config.go
Line: 140:145
Comment:
The new `GetModel` method lacks test coverage. Consider adding tests to verify:
1. Returns correct model when workflow exists and has model configured
2. Returns empty string when workflow exists but model is not set
3. Returns empty string when workflow doesn't exist
Example test structure:
```go
func TestConfig_GetModel(t *testing.T) {
cfg := &Config{
Workflows: map[string]WorkflowConfig{
"with-model": {Model: "claude-sonnet-4"},
"no-model": {PromptTemplate: "test"},
},
}
assert.Equal(t, "claude-sonnet-4", cfg.GetModel("with-model"))
assert.Equal(t, "", cfg.GetModel("no-model"))
assert.Equal(t, "", cfg.GetModel("unknown"))
}
```
<sub>Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!</sub>
How can I resolve this? If you propose a fix, please make it concise.
Additional Comments (2)
Current documented signature: ExecuteWithResult(ctx context.Context, prompt string, handler EventHandler) (int, error)Actual signature after this PR: ExecuteWithResult(ctx context.Context, prompt string, handler EventHandler, model string) (int, error)Prompt To Fix With AIThis is a comment left during a code review.
Path: docs/PACKAGES.md
Line: 306:306
Comment:
The `ExecuteWithResult` signature shown in documentation is outdated. It's missing the new `model` parameter that was added in this PR.
Current documented signature:
```go
ExecuteWithResult(ctx context.Context, prompt string, handler EventHandler) (int, error)
```
Actual signature after this PR:
```go
ExecuteWithResult(ctx context.Context, prompt string, handler EventHandler, model string) (int, error)
```
How can I resolve this? If you propose a fix, please make it concise.
Additionally, the command shown on line 197 should now include Prompt To Fix With AIThis is a comment left during a code review.
Path: docs/ARCHITECTURE.md
Line: 196:196
Comment:
The documentation shows the old `ExecuteWithResult` call signature without the new `model` parameter. This should be updated to:
```
executor.ExecuteWithResult(ctx, prompt, handler, model)
```
Additionally, the command shown on line 197 should now include `--verbose` and potentially `--model` flags when a model is configured.
How can I resolve this? If you propose a fix, please make it concise. |
This commit combines and implements all open issues and PRs into a cohesive, production-ready solution: Fixes: - Fix #8, #11: Add missing cmd/bmad-automate/main.go entry point - Fix #8, #11: Fix .gitignore to not exclude cmd/bmad-automate directory - Fix #9: Reorder CLI arguments (--flags before -p prompt) and add --verbose - Fix #9: Add sync.WaitGroup for stderr handling in ExecuteWithResult - Fix #9: Use errors.As instead of type assertion for Go 1.13+ compatibility - Fix #4: Add Windows support to justfile with PowerShell and platform-specific recipes Features: - Feat #5, #6: Add per-workflow model configuration (opus/sonnet/haiku) - Feat #6: Add --auto-retry flag for rate limit handling (run/queue/epic/all-epics) - Feat #6: Add all-epics command to process all active epics at once - Feat #6: Add rate limit detection package with intelligent wait time parsing - Feat: Add version command displaying current version and release date - Feat: Enhanced dry-run mode showing which model will be used per workflow New Files: - cmd/bmad-automate/main.go - Entry point for the CLI - internal/cli/all_epics.go - New command to process all epics - internal/cli/retry.go - Auto-retry logic with rate limit handling - internal/cli/version.go - Version command - internal/cli/version_test.go - Tests for version command - internal/ratelimit/detector.go - Rate limit error detection - internal/ratelimit/detector_state.go - Thread-safe rate limit state - internal/ratelimit/detector_test.go - Tests for detector - internal/ratelimit/detector_state_test.go - Tests for state Modified: - internal/claude/client.go - Updated Executor interface with model parameter - internal/cli/root.go - Added new commands and interfaces - internal/cli/run.go - Added --auto-retry flag and model display in dry-run - internal/cli/epic.go - Added --auto-retry flag and model display - internal/cli/queue.go - Added --auto-retry flag and model display - internal/config/types.go - Added Model field to WorkflowConfig - internal/config/config.go - Added GetModel() method - internal/workflow/workflow.go - Updated to pass model to executor - internal/workflow/steps.go - Added Model field to Step - internal/router/lifecycle.go - Added Model field to LifecycleStep - internal/status/reader.go - Added GetAllEpics() method - justfile - Added Windows support - .gitignore - Fixed to not exclude cmd directory - All test files updated for new interfaces Co-Authored-By: Claude <noreply@anthropic.com>
This commit combines and implements all open issues and PRs into a cohesive, production-ready solution: Fixes: - Fix #8, #11: Add missing cmd/bmad-automate/main.go entry point - Fix #8, #11: Fix .gitignore to not exclude cmd/bmad-automate directory - Fix #9: Reorder CLI arguments (--flags before -p prompt) and add --verbose - Fix #9: Add sync.WaitGroup for stderr handling in ExecuteWithResult - Fix #9: Use errors.As instead of type assertion for Go 1.13+ compatibility - Fix #4: Add Windows support to justfile with PowerShell and platform-specific recipes Features: - Feat #5, #6: Add per-workflow model configuration (opus/sonnet/haiku) - Feat #6: Add --auto-retry flag for rate limit handling (run/queue/epic/all-epics) - Feat #6: Add all-epics command to process all active epics at once - Feat #6: Add rate limit detection package with intelligent wait time parsing - Feat: Add version command displaying current version and release date - Feat: Enhanced dry-run mode showing which model will be used per workflow New Files: - cmd/bmad-automate/main.go - Entry point for the CLI - internal/cli/all_epics.go - New command to process all epics - internal/cli/retry.go - Auto-retry logic with rate limit handling - internal/cli/version.go - Version command - internal/cli/version_test.go - Tests for version command - internal/ratelimit/detector.go - Rate limit error detection - internal/ratelimit/detector_state.go - Thread-safe rate limit state - internal/ratelimit/detector_test.go - Tests for detector - internal/ratelimit/detector_state_test.go - Tests for state Modified: - internal/claude/client.go - Updated Executor interface with model parameter - internal/cli/root.go - Added new commands and interfaces - internal/cli/run.go - Added --auto-retry flag and model display in dry-run - internal/cli/epic.go - Added --auto-retry flag and model display - internal/cli/queue.go - Added --auto-retry flag and model display - internal/config/types.go - Added Model field to WorkflowConfig - internal/config/config.go - Added GetModel() method - internal/workflow/workflow.go - Updated to pass model to executor - internal/workflow/steps.go - Added Model field to Step - internal/router/lifecycle.go - Added Model field to LifecycleStep - internal/status/reader.go - Added GetAllEpics() method - justfile - Added Windows support - .gitignore - Fixed to not exclude cmd directory - All test files updated for new interfaces Co-authored-by: Claude <noreply@anthropic.com>
modelfield to WorkflowConfig for specifying Claude model per workflow