roles: capability-tier models with per-harness overrides - #140
Conversation
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
Reviewer's GuideIntroduce capability-tier Sequence diagram for Claude role model renderingsequenceDiagram
participant Role as agentRole
participant Renderer as renderClaudeAgentRole
participant Output as Claude role markdown
Role->>Renderer: renderClaudeAgentRole(role)
Renderer->>Renderer: strings.TrimSpace(role.Claude.Model)
alt claude.model is set
Renderer->>Output: writeYAMLScalar(model, claude.model)
else override is empty
Renderer->>Renderer: strings.TrimSpace(role.Model)
Renderer->>Output: writeYAMLScalar(model, generic model tier)
end
Flow diagram for per-harness model resolutionflowchart LR
Role[Role frontmatter] --> Generic[Generic model tier]
Role --> Overrides[Per-harness model overrides]
Generic --> Native[Claude Codex Droid native tier rendering]
Overrides --> Exact[Exact harness model identifier]
Generic --> Verbatim[OMP OpenCode verbatim rendering]
Verbatim --> Session[Active session model inheritance]
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
There was a problem hiding this comment.
Hey - I've found 2 issues
Prompt for AI Agents
Please address the comments from this code review:
## Individual Comments
### Comment 1
<location path="cmd/dotagents/session_hub.go" line_range="17-34" />
<code_context>
+ Resume []string `json:"resume"`
+}
+
+func runSessionHub(args []string) error {
+ if len(args) != 2 || args[0] != "harnesses" || args[1] != "--json" {
+ return errors.New("usage: dotagents session-hub harnesses --json")
+ }
+ registry := getHarnesses()
+ out := make([]sessionHubHarness, 0, len(registry))
+ for name, harness := range registry {
+ if harness.Sessions == nil {
+ continue
+ }
+ out = append(out, sessionHubHarness{Name: name, Store: harness.Sessions.Store, Resume: harness.Sessions.Resume})
+ }
+ sort.Slice(out, func(i, j int) bool { return out[i].Name < out[j].Name })
+ if err := json.NewEncoder(os.Stdout).Encode(map[string]any{"harnesses": out}); err != nil {
+ return fmt.Errorf("encode session-hub contract: %w", err)
+ }
+ return nil
+}
</code_context>
<issue_to_address>
**issue (bug_risk):** `runSessionHub` is never dispatched from `run`, so invoking `dotagents session-hub harnesses --json` returns the unknown-subcommand error instead of emitting the session-hub contract.
**Triggers:** When the session hub invokes the newly documented CLI contract.
**Suggested fix:** Add a `session-hub` case to the top-level command switch that calls `runSessionHub(args[1:])`.
</issue_to_address>
### Comment 2
<location path="cmd/dotagents/setup_scaffold.go" line_range="665-674" />
<code_context>
Effort string `yaml:"effort,omitempty"`
Tools []string `yaml:"tools,omitempty"`
Color string `yaml:"color,omitempty"`
+ Claude claudeRoleOptions `yaml:"claude,omitempty"`
Codex codexRoleOptions `yaml:"codex,omitempty"`
Droid droidRoleOptions `yaml:"droid,omitempty"`
Opencode opencodeRoleOptions `yaml:"opencode,omitempty"`
- }{Name: role.Name, Description: role.Description, Model: role.Model, Effort: role.Effort, Tools: role.Tools, Color: role.Color, Codex: role.Codex, Droid: role.Droid, Opencode: role.Opencode}
+ OMP ompRoleOptions `yaml:"omp,omitempty"`
+ }{
+ Name: role.Name, Description: role.Description, Model: role.Model, Effort: role.Effort,
+ Tools: role.Tools, Color: role.Color, Claude: role.Claude, Codex: role.Codex,
+ Droid: role.Droid, Opencode: role.Opencode, OMP: role.OMP,
+ }
meta, err := yaml.Marshal(front)
if err != nil {
</code_context>
<issue_to_address>
**issue (broader_impact):** OpenCode roles still omit the generic `role.Model` when `role.Opencode.Model` is empty, so a role with `model: opus` renders no model at all instead of rendering `opus` verbatim as the README promises.
**Triggers:** When a role defines only the generic capability-tier `model` and no `opencode.model` override.
**Suggested fix:** In `renderOpenCodeAgentRole`, fall back from `role.Opencode.Model` to `role.Model` before deciding whether to emit the model field.
</issue_to_address>Sourcery assessment
Approval pending. 2 findings to address first.
Blocking findings: cmd/dotagents/session_hub.go:34, cmd/dotagents/setup_scaffold.go:674
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
| func runSessionHub(args []string) error { | ||
| if len(args) != 2 || args[0] != "harnesses" || args[1] != "--json" { | ||
| return errors.New("usage: dotagents session-hub harnesses --json") | ||
| } | ||
| registry := getHarnesses() | ||
| out := make([]sessionHubHarness, 0, len(registry)) | ||
| for name, harness := range registry { | ||
| if harness.Sessions == nil { | ||
| continue | ||
| } | ||
| out = append(out, sessionHubHarness{Name: name, Store: harness.Sessions.Store, Resume: harness.Sessions.Resume}) | ||
| } | ||
| sort.Slice(out, func(i, j int) bool { return out[i].Name < out[j].Name }) | ||
| if err := json.NewEncoder(os.Stdout).Encode(map[string]any{"harnesses": out}); err != nil { | ||
| return fmt.Errorf("encode session-hub contract: %w", err) | ||
| } | ||
| return nil | ||
| } |
There was a problem hiding this comment.
issue (bug_risk): runSessionHub is never dispatched from run, so invoking dotagents session-hub harnesses --json returns the unknown-subcommand error instead of emitting the session-hub contract.
Triggers: When the session hub invokes the newly documented CLI contract.
Suggested fix: Add a session-hub case to the top-level command switch that calls runSessionHub(args[1:]).
| Claude claudeRoleOptions `yaml:"claude,omitempty"` | ||
| Codex codexRoleOptions `yaml:"codex,omitempty"` | ||
| Droid droidRoleOptions `yaml:"droid,omitempty"` | ||
| Opencode opencodeRoleOptions `yaml:"opencode,omitempty"` | ||
| }{Name: role.Name, Description: role.Description, Model: role.Model, Effort: role.Effort, Tools: role.Tools, Color: role.Color, Codex: role.Codex, Droid: role.Droid, Opencode: role.Opencode} | ||
| OMP ompRoleOptions `yaml:"omp,omitempty"` | ||
| }{ | ||
| Name: role.Name, Description: role.Description, Model: role.Model, Effort: role.Effort, | ||
| Tools: role.Tools, Color: role.Color, Claude: role.Claude, Codex: role.Codex, | ||
| Droid: role.Droid, Opencode: role.Opencode, OMP: role.OMP, | ||
| } |
There was a problem hiding this comment.
issue (broader_impact): OpenCode roles still omit the generic role.Model when role.Opencode.Model is empty, so a role with model: opus renders no model at all instead of rendering opus verbatim as the README promises.
Triggers: When a role defines only the generic capability-tier model and no opencode.model override.
Suggested fix: In renderOpenCodeAgentRole, fall back from role.Opencode.Model to role.Model before deciding whether to emit the model field.
Summary
modeltier (haiku/sonnet/opus) renders natively per harness; addclaude.modeloverride for exact idsTest plan
go test ./cmd/dotagents/green (incl. updated OMP renderer tests)Summary by Sourcery
Support capability-tier role models with per-harness overrides and expose session-aware harness metadata.
New Features:
Bug Fixes:
Enhancements:
Documentation:
Tests: