feat: per-skill model/provider override via SKILL.md frontmatter - #19270
feat: per-skill model/provider override via SKILL.md frontmatter#19270luoyuctl wants to merge 1 commit into
Conversation
Allow skills to declare their preferred model and provider in SKILL.md frontmatter via optional 'model:' and 'provider:' fields. When the agent loads a skill with these fields (via skill_view tool or /skill-name slash command), it switches to the skill's preferred model for the current turn and restores the original model at the start of the next turn. Implementation: - skills_tool.py: include model_override/provider_override in skill_view() JSON response, extracted from SKILL.md frontmatter YAML - run_agent.py: add _maybe_apply_skill_model_override() method that detects skill_view results with model overrides, pushes current model onto a stack, and calls switch_model() — with debug logging on failure - run_agent.py: add _pre_skill_model_stack (LIFO) to support cascading skill switches (skill A loads skill B, each with their own model) - run_agent.py: restore original model(s) from stack at start of each user turn in run_conversation() - agent/skill_commands.py: add get_skill_model_override() helper for CLI/gateway slash-command handlers to check model overrides before injecting skill content Key design decisions: - Uses a stack for model tracking so chains of skill_view calls each get their own model and restore correctly in reverse order - Debug logging on switch and restore failures (not silent pass) - Non-blocking: model switch failures don't interrupt the conversation - Deduplicated: single method replaces copy-pasted logic in both parallel and sequential tool execution paths Closes NousResearch#5997
d48809a to
4aa0d0e
Compare
|
Thanks for the pointer to #8485 and #4833! I reviewed both. This PR takes a deliberately narrower approach for a few reasons:
Happy to adjust if there's a preferred integration path relative to #8485. |
|
This frontmatter schema is a clean extension point. A few observations from reviewing the patch:
Overall the pattern is sound and worth merging. The frontmatter approach is more ergonomic than CLI flags for skill-specific routing. |
|
Thanks for the thorough review, @ether-btc! Addressing each point: 1. Schema extensibility &
|
|
Thanks for the PR. Closing — switching the model mid-session invalidates the prompt cache, and this would do it twice per The underlying concern — not wanting to burn expensive-model tokens on structured skill workflows — is real but handled differently:
If you want to explore this, the right shape is probably skill-level |
|
ok |
Summary
Fixes #5997 — Allow skills to declare a preferred model and provider in their SKILL.md frontmatter.
Currently, all skills run on the main agent's model, forcing users to pay top-tier model costs even for simple, well-structured skills (e.g.,
gif-search,arxiv) that could run on cheaper models.This PR adds the
model:andprovider:optional fields to SKILL.md frontmatter. When a skill with these fields is loaded viaskill_view(), the agent switches to the skill's preferred model for the current turn, then restores the original model at the start of the next turn.Changes
tools/skills_tool.py: Includemodel_overrideandprovider_overridein theskill_view()JSON responserun_agent.py:_pre_skill_model = Noneto track the pre-switch model state_execute_tool_calls_parallel: detectskill_viewresults with model overrides and callswitch_model()_execute_tool_calls_sequential: same detection + switch logicrun_conversation(): restore the original model at the start of each new user turnHow It Works
When the agent calls
skill_view("my-skill"), the response includesmodel_overrideThe agent saves its current model, switches to the skill's model, and processes the skill's instructions
On the next user message, the agent restores the original model
Test Plan
skill_view()returnsmodel_override: Nonefor skills without model configskill_view()returns correctmodel_override/provider_overridefor skills with configtests/tools/test_skills_tool.py— 80 tests passed, no regressions