Skip to content

Conversation

@alex-solovyev
Copy link
Collaborator

Summary

  • Add resolve_model_from_frontmatter() — reads model: from subagent YAML frontmatter files
  • Add resolve_task_model() — priority chain: task explicit model > subagent frontmatter > fallback chain (t132.4) > availability checker (t132.3) > static default
  • Extend resolve_model() to map tier names (haiku/sonnet/opus/flash/pro/grok) to concrete provider/model strings, and pass through full provider/model strings unchanged
  • Wire resolve_task_model() into cmd_dispatch() so workers get the optimal model

This completes the model resolution pipeline: subagent authors declare model: sonnet in frontmatter, the supervisor resolves it through availability checking and fallback chains to a concrete anthropic/claude-sonnet-4-5 (or fallback) at dispatch time.

Fixes: t132.5 ref:GH#737

- 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
@alex-solovyev alex-solovyev merged commit fd4506e into main Feb 9, 2026
5 checks passed
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 9, 2026

Warning

Rate limit exceeded

@alex-solovyev has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 2 minutes and 13 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

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)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feature/t132.5-supervisor-model-resolution

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@gemini-code-assist
Copy link

Summary of Changes

Hello @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

  • Subagent Model Resolution: Introduced resolve_model_from_frontmatter() to read the model: field from subagent YAML frontmatter files, allowing subagents to declare their preferred models.
  • Prioritized Model Selection: Implemented resolve_task_model() which establishes a comprehensive priority chain for model selection: task explicit model > subagent frontmatter > fallback chain > availability checker > static default.
  • Extended Model Mapping: Enhanced resolve_model() to map new tier names (haiku, sonnet, opus, flash, pro, grok) to concrete provider/model strings and to directly pass through full provider/model strings unchanged.
  • Integrated Dispatch: Wired the new resolve_task_model() into cmd_dispatch() to ensure that workers receive the optimally resolved model for their tasks, enhancing dynamic model assignment.
Changelog
  • .agents/scripts/supervisor-helper.sh
    • Added detailed comments explaining the new model resolution logic and its integration points within the script.
    • Modified resolve_model() to directly return the input tier if it already contains a / (indicating a full provider/model string), preventing unnecessary further resolution.
    • Expanded the case statement in resolve_model() to include static mappings for new model tiers: haiku, flash, pro, and grok, alongside existing opus and sonnet tiers.
    • Introduced a new function resolve_model_from_frontmatter() which parses subagent .md files to extract model: values from YAML frontmatter, searching in both deployed and repository agent directories.
    • Added resolve_task_model() which orchestrates the model selection process: first checking for an explicit task model, then attempting to resolve from subagent frontmatter using resolve_model_from_frontmatter(), and finally falling back to resolve_model() with a default tier.
    • Updated cmd_dispatch() to call resolve_task_model() to determine the resolved_model before dispatching, and to log this resolved model.
    • Modified the metadata output in cmd_dispatch() to report the resolved_model instead of the raw tmodel.
Activity
  • The pull request was created by alex-solovyev.
  • The PR introduces a new feature for supervisor model resolution from subagent frontmatter.
  • The changes implement a new model resolution pipeline, integrating with existing fallback and availability checks.
  • The PR description outlines the new functions and their roles in the model resolution process, fixing t132.5 and referencing GH#737.
Using Gemini Code Assist

The 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 /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

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 .gemini/ folder in the base of the repository. Detailed instructions can be found here.

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

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

alex-solovyev added a commit that referenced this pull request Feb 9, 2026
@github-actions
Copy link

github-actions bot commented Feb 9, 2026

🔍 Code Quality Report

�[0;35m[MONITOR]�[0m Code Review Monitoring Report

�[0;34m[INFO]�[0m Latest Quality Status:
SonarCloud: 0 bugs, 0 vulnerabilities, 54 code smells

�[0;34m[INFO]�[0m Recent monitoring activity:
Mon Feb 9 17:11:26 UTC 2026: Code review monitoring started
Mon Feb 9 17:11:27 UTC 2026: SonarCloud - Bugs: 0, Vulnerabilities: 0, Code Smells: 54

📈 Current Quality Metrics

  • BUGS: 0
  • CODE SMELLS: 54
  • VULNERABILITIES: 0

Generated on: Mon Feb 9 17:11:29 UTC 2026


Generated by AI DevOps Framework Code Review Monitoring

@sonarqubecloud
Copy link

sonarqubecloud bot commented Feb 9, 2026

Copy link

@gemini-code-assist gemini-code-assist bot left a 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.

Comment on lines +2817 to +2865
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
}

Choose a reason for hiding this comment

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

high

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
}

Comment on lines +2768 to +2769
local subagent_name="$1"
local repo="${2:-.}"

Choose a reason for hiding this comment

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

medium

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.

Suggested change
local subagent_name="$1"
local repo="${2:-.}"
local subagent_name
subagent_name="$1"
local repo
repo="${2:-.}"
References
  1. 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

Choose a reason for hiding this comment

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

medium

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.

Suggested change
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
  1. Line 50: 2>/dev/null is 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

Choose a reason for hiding this comment

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

medium

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.

Suggested change
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
  1. Line 50: 2>/dev/null is acceptable ONLY when redirecting to log files, not blanket suppression. (link)

alex-solovyev added a commit that referenced this pull request Feb 9, 2026
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.
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.

1 participant