-
Notifications
You must be signed in to change notification settings - Fork 5
feat: supervisor model resolution from subagent frontmatter (t132.5) #787
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
- Add resolve_model_from_frontmatter() to read model: from YAML frontmatter - Add resolve_task_model() with priority chain: explicit model > frontmatter > fallback chain > static default - Extend resolve_model() to handle tier names (haiku/sonnet/opus/flash/pro/grok) and full provider/model strings - Wire resolve_task_model() into cmd_dispatch() so dispatched workers use the resolved model - Integrates with fallback-chain-helper.sh (t132.4) and model-availability-helper.sh (t132.3) Fixes: t132.5 ref:GH#737
|
Warning Rate limit exceeded
⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. ✨ Finishing touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Summary of ChangesHello @alex-solovyev, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request significantly upgrades the supervisor's model resolution capabilities. It introduces a flexible system that allows subagents to specify their preferred models via YAML frontmatter, which is then intelligently resolved through a multi-tiered priority chain. This ensures that tasks are dispatched with the most appropriate and available model, integrating seamlessly with existing fallback mechanisms and model availability checks. Highlights
Changelog
Activity
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
🔍 Code Quality Report�[0;35m[MONITOR]�[0m Code Review Monitoring Report �[0;34m[INFO]�[0m Latest Quality Status: �[0;34m[INFO]�[0m Recent monitoring activity: 📈 Current Quality Metrics
Generated on: Mon Feb 9 17:11:29 UTC 2026 Generated by AI DevOps Framework Code Review Monitoring |
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Code Review
This pull request introduces a sophisticated model resolution pipeline, which is a great feature. The implementation adds several new functions to supervisor-helper.sh to handle a priority-based model selection, including from subagent frontmatter. The code is generally well-structured, and the identified areas for improvement regarding adherence to the repository's style guide, error handling, and the logic for resolving models from frontmatter remain valid and are included in the detailed comments below. None of the comments contradict the provided repository rules.
| resolve_task_model() { | ||
| local task_id="$1" | ||
| local task_model="${2:-}" | ||
| local task_repo="${3:-.}" | ||
| local ai_cli="${4:-opencode}" | ||
|
|
||
| local default_model="anthropic/claude-opus-4-6" | ||
|
|
||
| # 1) If task has an explicit non-default model, use it | ||
| if [[ -n "$task_model" && "$task_model" != "$default_model" ]]; then | ||
| # Could be a tier name or full model string — resolve_model handles both | ||
| local resolved | ||
| resolved=$(resolve_model "$task_model" "$ai_cli") | ||
| if [[ -n "$resolved" ]]; then | ||
| log_info "Model for $task_id: $resolved (from task config)" | ||
| echo "$resolved" | ||
| return 0 | ||
| fi | ||
| fi | ||
|
|
||
| # 2) Try to find a model-specific subagent definition matching the task | ||
| # Look for tools/ai-assistants/models/*.md files that match the task's | ||
| # model tier or the task description keywords | ||
| local model_agents_dir="${HOME}/.aidevops/agents/tools/ai-assistants/models" | ||
| if [[ -d "$model_agents_dir" ]]; then | ||
| # If task_model is a tier name, check for a matching model agent | ||
| if [[ -n "$task_model" && ! "$task_model" == *"/"* ]]; then | ||
| local tier_agent="${model_agents_dir}/${task_model}.md" | ||
| if [[ -f "$tier_agent" ]]; then | ||
| local frontmatter_model | ||
| frontmatter_model=$(resolve_model_from_frontmatter "tools/ai-assistants/models/${task_model}" "$task_repo") || true | ||
| if [[ -n "$frontmatter_model" ]]; then | ||
| local resolved | ||
| resolved=$(resolve_model "$frontmatter_model" "$ai_cli") | ||
| log_info "Model for $task_id: $resolved (from subagent frontmatter: ${task_model}.md)" | ||
| echo "$resolved" | ||
| return 0 | ||
| fi | ||
| fi | ||
| fi | ||
| fi | ||
|
|
||
| # 3) Fall back to resolve_model with default tier | ||
| local resolved | ||
| resolved=$(resolve_model "coding" "$ai_cli") | ||
| log_info "Model for $task_id: $resolved (default coding tier)" | ||
| echo "$resolved" | ||
| return 0 | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The current logic for resolving the model from "subagent frontmatter" is complex and brittle. It relies on a hardcoded path (${HOME}/.aidevops/agents/tools/ai-assistants/models) and a special convention of "model agents" named after tiers, instead of using the frontmatter of the actual subagent executing the task.
A more robust and general approach would be to use the frontmatter of the subagent assigned to the task. The subagent name is available as $tsubagent in cmd_dispatch and can be passed to this function.
I recommend refactoring this function to accept the subagent name and use it with resolve_model_from_frontmatter. This would simplify the logic, remove the hardcoded path, and align better with the feature's description. The call in cmd_dispatch would then be updated to resolve_task_model "$task_id" "$tmodel" "$tsubagent" ....
resolve_task_model() {
local task_id
task_id="$1"
local task_model
task_model="${2:-}"
local subagent_name
subagent_name="${3:-}"
local task_repo
task_repo="${4:-.}"
local ai_cli
ai_cli="${5:-opencode}"
local default_model="anthropic/claude-opus-4-6"
local resolved
# 1) If task has an explicit non-default model, use it
if [[ -n "$task_model" && "$task_model" != "$default_model" ]]; then
resolved=$(resolve_model "$task_model" "$ai_cli")
if [[ -n "$resolved" ]]; then
log_info "Model for $task_id: $resolved (from task config)"
echo "$resolved"
return 0
fi
fi
# 2) Try to find model from the task's subagent frontmatter
if [[ -n "$subagent_name" ]]; then
local frontmatter_model
frontmatter_model=$(resolve_model_from_frontmatter "$subagent_name" "$task_repo") || true
if [[ -n "$frontmatter_model" ]]; then
resolved=$(resolve_model "$frontmatter_model" "$ai_cli")
if [[ -n "$resolved" ]]; then
log_info "Model for $task_id: $resolved (from subagent frontmatter: $subagent_name)"
echo "$resolved"
return 0
fi
fi
fi
# 3) Fall back to resolve_model with default tier
resolved=$(resolve_model "coding" "$ai_cli")
log_info "Model for $task_id: $resolved (default coding tier)"
echo "$resolved"
return 0
}| local subagent_name="$1" | ||
| local repo="${2:-.}" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The repository style guide (line 11) instruction "declare and assign separately for exit code safety" is a best practice. For consistency and to strictly follow the style guide's text, please separate declaration and assignment for local variables initialized from positional parameters.
| local subagent_name="$1" | |
| local repo="${2:-.}" | |
| local subagent_name | |
| subagent_name="$1" | |
| local repo | |
| repo="${2:-.}" |
References
- Line 11: Use
local var="$1"pattern in functions (declare and assign separately for exit code safety). (link)
|
|
||
| if [[ -f "$subagent_file" ]]; then | ||
| # Extract model: from YAML frontmatter (between --- delimiters) | ||
| model_value=$(sed -n '/^---$/,/^---$/{ /^model:/{ s/^model:[[:space:]]*//; p; q; } }' "$subagent_file" 2>/dev/null) || true |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The use of 2>/dev/null here and on line 2799 suppresses potentially important error messages from sed, such as file permission errors. This violates the repository style guide (line 50), which states that 2>/dev/null should only be used when redirecting to log files. Please remove the error suppression to aid in debugging. The || true guard already prevents script termination on failure.
| model_value=$(sed -n '/^---$/,/^---$/{ /^model:/{ s/^model:[[:space:]]*//; p; q; } }' "$subagent_file" 2>/dev/null) || true | |
| model_value=$(sed -n '/^---$/,/^---$/{ /^model:/{ s/^model:[[:space:]]*//; p; q; } }' "$subagent_file") || true |
References
- Line 50:
2>/dev/nullis acceptable ONLY when redirecting to log files, not blanket suppression. (link)
| # Try finding by name in subdirectories | ||
| # shellcheck disable=SC2044 | ||
| local found_file | ||
| found_file=$(find "$agents_dir" -name "${subagent_name}.md" -type f 2>/dev/null | head -1) || true |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The use of 2>/dev/null suppresses potentially important error messages from find, such as directory permission errors. This violates the repository style guide (line 50), which states that 2>/dev/null should only be used when redirecting to log files. Please remove the error suppression to aid in debugging. The || true guard already prevents script termination on failure.
| found_file=$(find "$agents_dir" -name "${subagent_name}.md" -type f 2>/dev/null | head -1) || true | |
| found_file=$(find "$agents_dir" -name "${subagent_name}.md" -type f | head -1) || true |
References
- Line 50:
2>/dev/nullis acceptable ONLY when redirecting to log files, not blanket suppression. (link)
All 8 subtasks of t132 (Cross-Provider Model Routing) are now complete: - t132.1: Model-specific subagents (PR #758) - t132.2: Provider/model registry (PR #761) - t132.3: Model availability checker (PR #770) - t132.4: Fallback chain config (PR #781) - t132.5: Supervisor model resolution (PR #787) - t132.6: Quality gate with escalation (PR #788) - t132.7: Multi-provider runner/cron support (PR #789) - t132.8: Cross-model review workflow (PR #791) Also fixed stale git conflict markers in TODO.md.



Summary
resolve_model_from_frontmatter()— readsmodel:from subagent YAML frontmatter filesresolve_task_model()— priority chain: task explicit model > subagent frontmatter > fallback chain (t132.4) > availability checker (t132.3) > static defaultresolve_model()to map tier names (haiku/sonnet/opus/flash/pro/grok) to concrete provider/model strings, and pass through fullprovider/modelstrings unchangedresolve_task_model()intocmd_dispatch()so workers get the optimal modelThis completes the model resolution pipeline: subagent authors declare
model: sonnetin frontmatter, the supervisor resolves it through availability checking and fallback chains to a concreteanthropic/claude-sonnet-4-5(or fallback) at dispatch time.Fixes: t132.5 ref:GH#737