Add per-sub-agent provider routing#3969
Conversation
|
Thanks @heyparth1 for taking the time to contribute. This repository is observing a maintainer-managed PR intake gate in dry-run mode, so this pull request is staying open. This note helps maintainers prepare the allowlist before any enforcement is considered. Please read |
|
Thanks @JayBeest! Yes, this pins any sub-agent to any configured provider/model (not just local vs cloud); smart/keyword routing is a good follow-up but out of scope here. |
|
Thanks for the pointer — I've reshaped the PR description to follow the repository's PR template (Summary / Testing / Checklist) and re-verified the contribution shape from CONTRIBUTING.md: single-purpose scope, tests included, docs updated. I also ran the template's exact checks ( |
|
Thanks @heyparth1. Explicit per-sub-agent provider routing is interesting and the reported local verification is appreciated, but I am leaving it out of 0.8.67 because it is currently blocked and touches provider/model routing semantics for sub-agents. I am cutting 0.8.67 soon; please keep this warm for 0.8.68 after a rebase so we can review the routing behavior and docs without rushing it. |
|
Thanks for this @heyparth1 — it's genuinely well done: Heads up on timing: we're actively reworking the sub-agent fleet/routing system right now (the #3932–#3935 cluster — role taxonomy, model classes, per-role routing, wizard-authored profiles). Your PR lands new per-role routing machinery in the same spawn/resolution path that redesign is about to reshape, and I'd rather not have us design per-role provider routing twice and then reconcile a merge conflict. So I'm going to hold this and land it aligned with the new fleet system in v0.8.68, rather than merge it into the current path now. Moving it to the v0.8.68 milestone and keeping it open — nothing about the approach here is rejected, it's a sequencing call so this routing slots cleanly into the new taxonomy. I'll revisit it (with credit) once the fleet work is out. Appreciate the contribution. Generated by Claude Code |
|
Great update, thanks @Hmbown! Delaying to align with the fleet redesign (#3932–#3935) is clearly the right move—better to build on a stable foundation than layer new routing on a path that's about to change. I'm genuinely impressed with how quickly @heyparth1 turned this around. The implementation matches exactly what I had in mind with the original issue, and the feedback on the approach is really encouraging. On the broader direction: I'd love to help scope or discuss what comes after this foundation. A few areas I'm thinking about: These all build on the explicit routing this PR establishes. Where's the best place to continue that conversation? I'm guessing just opening new issues as they crystallize (like I did with this one) is the right approach, but let me know if there's a design thread or discussion space I should be watching. Thanks again to everyone involved—this is shaping up to be a really powerful foundation. Co-authored by my Chinese Friend (DeepSeek) |
Summary
Adds explicit per-sub-agent provider routing (#3965): a new
[subagents.routes.<role>]config table pins a sub-agent role or type to aspecific provider — and optionally a model — so one session can, for example,
run
explore/formatchildren on a local LM Studio endpoint whilegeneralruns on DeepSeek, with no manual provider switching.
How it works:
config.rs: newSubagentRouteConfig+routestable onSubagentsConfig,exposed via
Config::subagent_provider_routes()(lowercased keys, trimmedvalues). Same role/type/
defaultkey precedence as[subagents.models].tools/subagent/mod.rs:SubAgentRuntimecarries anOption<Arc<SubagentProviderRouting>>bundle (routes + config snapshot).At spawn, a matching route builds the child's client through the existing
v0.8.67: Ship configured-provider route manager for /provider and /model #3830 route resolver (
route_runtime::resolve_runtime_route+DeepSeekClient::from_candidate) — the same path/providerswitchinguses — and swaps it into the child runtime. The routed client drops with
the child; no new auth/client-lifecycle machinery.
core/engine.rs: routing bundle is rebuilt fromapi_configat eachruntime construction, so mid-session
/providerchanges are picked up.the unchanged legacy path. A per-call explicit
modelstill wins over theroute's model; both validate against the routed provider. A route naming a
provider that is neither built-in nor a
[providers.<name>]custom entryfails that spawn with a clear error instead of silently falling back to
DeepSeek.
docs/SUBAGENTS.md: new "Per-role provider routes (Per-sub-agent provider assignment (explicit routing) + LM Studio support #3965)" section with theLM Studio example above.
First-class LM Studio detection is intentionally out of scope: as the issue
notes, the #3861 custom-provider form already covers LM Studio — the missing
piece was per-sub-agent routing, which this PR adds.
Closes #3965
Testing
cargo fmt --all -- --checkcargo clippy --workspace --all-targets --all-featurescargo test --workspace --all-featuresNew regression tests (all green; suite: 5727 passed / 0 failed):
config::tests::subagent_provider_routes_parse_and_normalize— TOML parsingand key/value normalization for
[subagents.routes].tools::subagent::tests::role_provider_route_builds_client_on_routed_provider— the issue's headline scenario: parent on DeepSeek,
explorerouted to anLM Studio-style custom provider; asserts the routed client binds to
http://localhost:1234/v1with the route's model while the parent client isuntouched.
tools::subagent::tests::role_without_provider_route_inherits_parent—unrouted roles keep the legacy inherit behavior.
tools::subagent::tests::provider_route_with_unknown_provider_fails_clearly— unknown provider is rejected with an error naming it and pointing at the
[providers.<name>]config path.Checklist
docs/SUBAGENTS.mdsection + doccomments on all new config/runtime surfaces)
spawn path, and engine wiring only)
a harvest — original work for Per-sub-agent provider assignment (explicit routing) + LM Studio support #3965)