fix(fleet): route AgentProfile pins through custom providers#4262
Conversation
Allow AgentProfile/Fleet provider pins to preserve user-named OpenAI-compatible custom providers (e.g. provider = "lm-studio") and thread that raw id through interactive agent(profile: ...), Fleet worker --provider launch, and codewhale exec --provider validation. Unknown or unconfigured provider ids fail closed instead of silently inheriting or falling back to DeepSeek. AgentProfile remains the canonical routing surface; do not introduce [subagents.routes]. Fixes #3965 Refs #3969 (stale alternate surface held; not merged as-is)
|
Claude finished @Hmbown's task in 3m 43s —— View job Review: route AgentProfile pins through custom providersTasks
Note: I could not run SummaryThe EPIC #2608 invariant is preserved throughout: provider selection stays explicit-config-only everywhere touched ( Minor findings (reuse/simplification, not correctness bugs):
Both are small and non-blocking. No correctness, provider-safety, or security issues found in the diff; test coverage for the new custom-provider paths (profile load, worker exec argv, launch-route resolver, receipt omission, |
broken_workspace_dir_degrades_to_built_ins_and_config used provider = "not-a-real-provider", which is now a valid simple custom provider token under #3965. Switch the fixture to a malformed id so workspace-dir load still fails closed and degrades to built-ins + config.
|
Claude finished @Hmbown's task in 1m 11s —— View job Review: route AgentProfile pins through custom providers (update)Tasks
SummaryThis update adds one new commit (
No correctness, provider/model routing-safety, or security issues in this delta. The rest of the diff is unchanged from my previous pass (provider selection remains explicit-config-only everywhere; unconfigured custom providers still fail closed rather than silently falling back). Still-open minor items from the previous review (not addressed in this commit, both non-blocking):
Neither blocks merge. |
Ensure each emit is durable before the next sequential emit or test read observes the file. Unflushed tokio File buffers can leave only one line visible under CI load (jsonl_sink_creates_parent_dir_and_appends_events).
|
Claude finished @Hmbown's task in 1m 59s —— View job Review: route AgentProfile pins through custom providers (update 2)Tasks
SummaryOne new commit since my last pass: Correctness: correct and minimal. Scope note: this commit is unrelated to the PR's stated purpose (AgentProfile/custom-provider routing) — it's a hooks-crate flakiness fix, likely bundled in to unblock CI on this branch. Not a problem, just flagging it's orthogonal to the routing changes for anyone auditing the diff by topic. Provider/model/route safety: no change in this delta; the explicit-config-only invariant (EPIC #2608) reviewed in the previous two passes is untouched. Everything else (profile.rs, worker_runtime.rs, main.rs, subagent/mod.rs, roster.rs, docs) is unchanged since the previous update — see prior comments in this thread. Still-open, non-blocking items from before:
No correctness, provider-safety, or security issues found. Nothing here blocks merge. |
Implement parent --disallowed-tools inheritance into sub-agents: - SpawnRequest carries disallowed_tools + inherit_disallowed_tools (default true) - WorkerRuntimeProfile gains denied_tools with derive_child() union semantics - SubAgentToolRegistry applies deny filtering in is_tool_allowed(), tools_for_model(), and execute() — restricted tools never reach the model - Wildcard matching: exact, prefix *, case-insensitive - Fleet worker_runtime threads disallowed_tools into WorkerRuntimeProfile 22 new tests: inheritance flows down, opt-out works, two-generation inheritance, wildcards, case-insensitive, deny-wins-over-allow, catalog filtering, execution gates, background runtime propagation. Harvested from PR #4096 by @JayBeest (rebased onto current main; the original PR was dirty against main after #4262 landed). Refs #4042 Signed-off-by: Hunter B <hmbown@gmail.com> Co-authored-by: JayBeest <67948678+JayBeest@users.noreply.github.com>
Summary
Fixes #3965 by making AgentProfile / Fleet profiles the canonical surface for per-child provider routing, including user-named OpenAI-compatible custom providers such as
lm-studio.This intentionally does not merge stale PR #3969 as-is. That PR adds a separate
[subagents.routes]config surface that would compete with the post-fleet redesign AgentProfile model. Refs #3969 by @heyparth1 for the original use-case report and alternate design; this PR implements the routing outcome on the current canonical surface rather than harvesting that branch.Behavior
provider = "lm-studio"(or any safe user-named id) is preserved as a raw string through:agent(profile: ...)in-process spawn--providercodewhale exec --providervalidationConfigsnapshot (they need[providers.<id>]resolution), rather than fabricating DeepSeek details.Docs
docs/SUBAGENTS.md: per-profile provider routes example (LM Studio)docs/CONFIGURATION.md,docs/FLEET.md,docs/PROVIDERS.md: named custom provider + AgentProfile pin guidanceTesting
cargo fmt --all -- --checkcargo test -p codewhale-tui --locked custom_provider -- --nocapture(20 passed)cargo test -p codewhale-tui --locked fleet_worker_launch_route -- --nocapturecargo test -p codewhale-tui --locked worker_command_threads_custom_profile_provider_name -- --nocapturecargo test -p codewhale-tui --locked agent_profile_loader_accepts_custom_provider_name -- --nocapturecargo test -p codewhale-tui --locked exec_provider_override_accepts_configured_custom_provider -- --nocapture./scripts/release/check-versions.sh(workspace=0.8.67, lockfile in sync)git diff --checkcargo clippy --workspace --all-targets --all-features(CI)cargo test --workspace --all-features(CI)Checklist