delegate_task per-call model and provider overrides
NousResearch/hermes-agent · cluster 609 · agent
Data as of
5 open items. Fix merged in #7360. Check it covers your case.
The short answer
- Known?
- Yes. 105 related items grouped here, 56 issues already closed.
- Fix event
- A fix was merged to main in PR #7360. Check it covers your case. No release data is tracked.
- Tracker
- The maintainers' tracker marks this
partially resolved, deciding PRs #16894, #41730. That is separate from the fix event. - Still open
- 4 issues and 1 PR.
Next step: read #7360, then check whether your report is one of the 4 still open.
Read #7360Pick up a Lab taskThese issues and PRs concern adding per-call model, provider, and profile override parameters to the delegate_task tool, along with fixes for bugs where delegation ignores configuration and subagents inherit the parent model or incorrect credentials instead of the intended settings.
Open issues4
- Issue#4928Feature: add named delegation capability profiles for subagents
- Issue#41889Feature Request: Cross-profile subagent support in delegate_task
- Issue#51540delegation.model ignored for opencode-go provider
- Issue#67699feature request: delegate_task should pass env vars or accept a profile parameter
Open PRs1
- PR#58337fix(delegate): keep child credential pools provider-scoped
Fixes on record
-
#7360 fix(delegate): salvage delegate PRs #6933 #6881
files:
run_agent.py,tests/run_agent/test_agent_guardrails.py,tests/tools/test_delegate.py,tools/delegate_tool.py -
#16894 fix(delegate): clear acp_command when override_provider is set
files:
tools/delegate_tool.py -
#19744 fix(delegation): clear parent OpenRouter filters when delegation.provider override is set
files:
tests/tools/test_delegate.py,tools/delegate_tool.pyShow the diff
-
tests/tools/test_delegate.py@@ -980,6 +980,48 @@ def test_cross_provider_delegation(self, mock_creds, mock_cfg): self.assertNotEqual(kwargs["base_url"], parent.base_url) self.assertNotEqual(kwargs["api_key"], parent.api_key) + @patch("tools.delegate_tool._load_config") + @patch("tools.delegate_tool._resolve_delegation_credentials") + def test_provider_override_clears_parent_openrouter_filters( + self, mock_creds, mock_cfg + ): + """Delegated provider should not inherit parent provider-preference filters.""" + mock_cfg.return_value = { + "max_iterations": 45, + "model": "google/gemini-3-flash-preview", + "provider": "openrouter", + } + mock_creds.return_value = { + "model": "google/gemini-3-flash-preview", + "provider": "openrouter", + "base_url": "https://openrouter.ai/api/v1", + "api_key": "sk-or-key", + "api_mode": "chat_completions", + } + parent = _make_mock_parent(depth=0) + parent.providers_allowed = ["anthropic/claude-3.5-sonnet"] + parent.providers_ignored = ["openai/gpt-4o-mini"] + parent.providers_order = ["google/gemini-2.5-pro"] + parent.provider_sort = "price" + + with patch("run_agent.AIAgent") as MockAgent: + mock_child = MagicMock() + mock_child.run_conversation.return_value = { + "final_response": "done", + "completed": True, + "api_calls": 1, + } + MockAgent.return_value = mock_child + + delegate_task(goal="Cross-provider test", parent_agent=parent) + + _, kwargs = MockAgent.call_args + self.assertEqual(kwargs["provider"], "openrouter") + self.assertIsNone(kwargs["providers_allowed"]) + self.assertIsNone(kwargs["providers_ignored"]) + self.assertIsNone(kwargs["providers_order"]) + self.assertIsNone(kwargs["provider_sort"]) + @patch("tools.delegate_tool._load_config") @patch("tools.delegate_tool._resolve_delegation_credentials") def test_direct_endpoint_credentials_reach_child_agent(self, mock_creds, mock_cfg): -
tools/delegate_tool.py@@ -1032,6 +1032,23 @@ def _child_thinking(text: str) -> None: # fallback_model parameter (which handles both list and dict forms). parent_fallback = getattr(parent_agent, "_fallback_chain", None) or None + # Inherit the parent's OpenRouter provider-preference filters by default + # (so subagents routed to the same provider honour the same routing + # constraints). BUT: when `delegation.provider` is set the user is + # explicitly asking the child to run on a different provider, and + # parent-level OpenRouter filters (e.g. `only=["Anthropic"]`) would + # silently force the child back onto the parent's provider. Clear the + # filters in that case so the delegated provider is honoured. + child_providers_allowed = getattr(parent_agent, "providers_allowed", None) + child_providers_ignored = getattr(parent_agent, "providers_ignored", None) + child_providers_order = getattr(parent_agent, "providers_order", None) + child_provider_sort = getattr(parent_agent, "provider_sort", None) + if override_provider: + child_providers_allowed = None + child_providers_ignored = None + child_providers_order = None + child_provider_sort = None + child = AIAgent( base_url=effective_base_url, api_key=[redacted:secret-assignment] @@ -1056,10 +1073,10 @@ def _child_thinking(text: str) -> None: thinking_callback=child_thinking_cb, session_db=getattr(parent_agent, "_session_db", None), parent_session_id=getattr(parent_agent, "session_id", None), - providers_allowed=parent_agent.providers_allowed, - providers_ignored=parent_agent.providers_ignored, - providers_order=parent_agent.providers_order, - provider_sort=parent_agent.provider_sort, + providers_allowed=child_providers_allowed, + providers_ignored=child_providers_ignored, + providers_order=child_providers_order, + provider_sort=child_provider_sort, tool_progress_callback=child_progress_cb, iteration_budget=None, # fresh budget per subagent )
-
-
#41730 fix(delegate): resolve custom-endpoint subagent pools by endpoint identity
files:
agent/credential_pool.py,tests/tools/test_delegate.py,tools/delegate_tool.pyShow the diff
-
agent/credential_pool.py@@ -374,7 +374,7 @@ def _iter_custom_providers(config: Optional[dict] = None): yield _normalize_custom_pool_name(name), entry -def get_custom_provider_pool_key(base_url: str, provider_name: Optional[str] = None) -> Optional[str]: +def get_custom_provider_pool_key(base_url: Optional[str], provider_name: Optional[str] = None) -> Optional[str]: """Look up the custom_providers list in config.yaml and return 'custom:<name>' for a matching base_url. When provider_name is given, prefer matching by name first (solving the case where -
tests/tools/test_delegate.py@@ -1518,6 +1518,73 @@ def test_different_provider_load_failure_returns_none(self): self.assertIsNone(result) + # --- Custom-endpoint identity resolution (issue #7833) --- + + def test_custom_different_endpoint_does_not_inherit_parent_pool(self): + """A child on custom endpoint B must not inherit the parent's custom + endpoint A pool just because both normalize to provider='custom'.""" + parent = _make_mock_parent() + parent.provider = "custom" + parent.base_url = "https://endpoint-a.example.com/v1" + parent._credential_pool = [redacted:secret-assignment]"parent_custom_a_pool") + + child_pool = MagicMock(name="endpoint_b_pool") + child_pool.has_credentials.return_value = True + + def fake_key(base_url, provider_name=None): + return { + "https://endpoint-a.example.com/v1": "custom:endpoint-a", + "https://endpoint-b.example.com/v1": "custom:endpoint-b", + }.get(base_url) + + with patch("agent.credential_pool.get_custom_provider_pool_key", side_effect=fake_key), \ + patch("agent.credential_pool.load_pool", return_value=child_pool) as load_mock: + result = _resolve_child_credential_pool( + "custom", parent, "https://endpoint-b.example.com/v1" + ) + + # Loaded the child's OWN endpoint pool, not the parent's. + load_mock.assert_called_once_with("custom:endpoint-b") + self.assertIs(result, child_pool) + self.assertIsNot(result, parent._credential_pool) + + def test_custom_same_endpoint_shares_parent_pool(self): + """A child on the SAME custom endpoint as the parent reuses the parent's + pool so rotation/cooldown state stays synchronized.""" + parent = _make_mock_parent() + parent.provider = "custom" + parent.base_url = "https://endpoint-a.example.com/v1" + parent._credential_pool = [redacted:secret-assignment]"parent_custom_a_pool") + + with patch( + "agent.credential_pool.get_custom_provider_pool_key", + return_value="custom:endpoint-a", + ): + result = _resolve_child_credential_pool( + "custom", parent, "https://endpoint-a.example.com/v1" + ) + + self.assertIs(result, parent._credential_pool) + + def test_custom_unregistered_endpoint_returns_none(self): + """A raw delegation.base_url with no matching custom_providers entry + must NOT inherit the parent's pool — return None so the child keeps its + fixed delegated credential.""" + parent = _make_mock_parent() + parent.provider = "custom" + parent.base_url = "https://endpoint-a.example.com/v1" + parent._credential_pool = [redacted:secret-assignment]"parent_custom_a_pool") + + with patch( + "agent.credential_pool.get_custom_provider_pool_key", + return_value=None, + ): + result = _resolve_child_credential_pool( + "custom", parent, "https://raw-unregistered.example.com/v1" + ) + + self.assertIsNone(result) + def test_build_child_agent_assigns_parent_pool_when_shared(self): parent = _make_mock_parent() mock_pool = MagicMock() -
tools/delegate_tool.py@@ -1184,7 +1184,9 @@ def _child_thinking(text: str) -> None: # Share a credential pool with the child when possible so subagents can # rotate credentials on rate limits instead of getting pinned to one key. - child_pool = _resolve_child_credential_pool(effective_provider, parent_agent) + child_pool = _resolve_child_credential_pool( + effective_provider, parent_agent, effective_base_url + ) if child_pool is not None: child._credential_pool = [redacted:secret-assignment] @@ -2368,7 +2370,11 @@ def delegate_task( ) -def _resolve_child_credential_pool(effective_provider: Optional[str], parent_agent): +def _resolve_child_credential_pool( + effective_provider: Optional[str], + parent_agent, + effective_base_url: Optional[str] = None, +): """Resolve a credential pool for the child agent. Rules: @@ -2377,12 +2383,60 @@ def _resolve_child_credential_pool(effective_provider: Optional[str], parent_age 2. Different provider -> try to load that provider's own pool. 3. No pool available -> return None and let the child keep the inherited fixed credential behavior. + + Custom endpoints are a special case: every direct ``delegation.base_url`` + runtime collapses to ``provider="custom"``, so bare provider equality would + treat two *different* custom endpoints as interchangeable and let the child + inherit the parent's pool. Leasing from that pool then overwrites the + child's delegated ``base_url`` with the parent's endpoint (issue #7833). + We therefore resolve custom runtimes by endpoint identity (the + ``custom:<name>`` pool key derived from the base_url) and only share the + parent's pool when both resolve to the *same* custom endpoint. """ if not effective_provider: return getattr(parent_agent, "_credential_pool", None) parent_provider = getattr(parent_agent, "provider", None) or "" parent_pool = getattr(parent_agent, "_credential_pool", None) + + # Custom endpoints: distinguish by endpoint identity, not the bare "custom" + # provider string. Two custom runtimes are only interchangeable when they + # resolve to the same custom:<name> pool key. + if effective_provider == "custom": + try: + from agent.credential_pool import get_custom_provider_pool_key, load_pool + + child_key = get_custom_provider_pool_key(effective_base_url) + if child_key is None: + # Unregistered endpoint (raw delegation.base_url with no + # matching custom_providers entry) -> no shared pool exists. + # Keep the child's fixed delegated credential rather than + # risk inheriting the parent's custom endpoint. + return None + + # Reuse the parent's pool only when it is the same custom endpoint. + parent_key = get_custom_provider_pool_key( + getattr(parent_agent, "base_url", None) + ) + if ( + parent_pool is not None + and parent_provider == "custom" + and parent_key is not None + and parent_key == child_key + ): + return parent_pool + + pool = load_pool(child_key) + if pool is not None and pool.has_credentials(): + return pool + except Exception as exc: + logger.debug( + "Could not resolve custom credential pool for child endpoint '%s': %s", + effective_base_url, + exc, + ) + return None + if parent_pool is not None and effective_provider == parent_provider: return parent_pool
-
-
#60577 fix(delegation): make active config authoritative for delegation limits
files:
tests/tools/test_delegate.py,tools/delegate_tool.pyShow the diff
-
tests/tools/test_delegate.py@@ -13,6 +13,7 @@ import os import threading import time +import types import unittest from unittest.mock import MagicMock, patch @@ -21,6 +22,7 @@ DELEGATE_TASK_SCHEMA, DelegateEvent, _get_max_concurrent_children, + _load_config, _LEGACY_EVENT_MAP, MAX_DEPTH, check_delegate_requirements, @@ -2390,6 +2392,71 @@ def test_progress_callback_task_progress_not_misrendered(self): class TestConcurrencyDefaults(unittest.TestCase): """Tests for the concurrency default and no hard ceiling.""" + def test_load_config_prefers_active_persistent_config_over_cli_defaults(self): + stale_cli = types.ModuleType("cli") + stale_cli.CLI_CONFIG = { + "delegation": { + "max_iterations": 45, + "model": "", + "provider": "", + "base_url": "", + "api_key": "", + } + } + active_config = { + "delegation": { + "max_iterations": 50, + "max_concurrent_children": 50, + "max_spawn_depth": 10, + } + } + + with patch.dict("sys.modules", {"cli": stale_cli}): + with patch( + "hermes_cli.config.load_config_readonly", return_value=active_config + ): + self.assertEqual(_load_config()["max_concurrent_children"], 50) + self.assertEqual(_get_max_concurrent_children(), 50) + + def test_load_config_falls_back_to_cli_config_when_persistent_load_fails(self): + fallback_cli = types.ModuleType("cli") + fallback_cli.CLI_CONFIG = { + "delegation": { + "max_iterations": 45, + "max_concurrent_children": 8, + } + } + + with patch.dict("sys.modules", {"cli": fallback_cli}): + with patch( + "hermes_cli.config.load_config_readonly", + side_effect=RuntimeError("boom"), + ): + self.assertEqual(_load_config()["max_concurrent_children"], 8) + + def test_load_config_prefers_cli_config_when_user_config_ignored(self): + # `hermes chat --ignore-user-config` sets HERMES_IGNORE_USER_CONFIG=1, + # which only load_cli_config() honors. The delegation loader must keep + # CLI_CONFIG authoritative under the flag so user config.yaml + # delegation keys stay suppressed. + ignoring_cli = types.ModuleType("cli") + ignoring_cli.CLI_CONFIG = { + "delegation": { + "max_iterations": 45, + "max_concurrent_children": 4, + } + } + user_config = {"delegation": {"max_concurrent_children": 50}} + + with patch.dict("sys.modules", {"cli": ignoring_cli}): + with patch.dict(os.environ, {"HERMES_IGNORE_USER_CONFIG": "1"}): + with patch( + "hermes_cli.config.load_config_readonly", + return_value=user_config, + ) as mock_loader: + self.assertEqual(_load_config()["max_concurrent_children"], 4) + mock_loader.assert_not_called() + @patch("tools.delegate_tool._load_config", return_value={}) def test_default_is_three(self, mock_cfg): # Clear env var if set -
tools/delegate_tool.py@@ -3098,26 +3098,40 @@ def _resolve_delegation_credentials(cfg: dict, parent_agent) -> dict: def _load_config() -> dict: - """Load delegation config from CLI_CONFIG or persistent config. - - Checks the runtime config (cli.py CLI_CONFIG) first, then falls back - to the persistent config (hermes_cli/config.py load_config()) so that - ``delegation.model`` / ``delegation.provider`` are picked up regardless - of the entry point (CLI, gateway, cron). + """Load delegation config from the active Hermes config. + + Prefer the shared persistent loader because it follows the active + HERMES_HOME/profile. ``cli.CLI_CONFIG`` is a legacy fallback for entry + points that cannot import the shared loader; importing it first can return + an old default ``delegation`` block and hide user-set keys such as + ``max_concurrent_children``. + + Uses ``load_config_readonly()``: every consumer of this dict is read-only + (``.get()`` lookups), and this runs on each ``get_definitions()`` schema + rebuild via ``_get_max_concurrent_children``, so skipping the defensive + deepcopy matters. Do NOT mutate the returned dict. + + ``HERMES_IGNORE_USER_CONFIG=1`` (``hermes chat --ignore-user-config``) is + only honored by the legacy ``cli`` loader, not the shared one, so when the + flag is set we keep ``cli.CLI_CONFIG`` authoritative to preserve the + flag's contract of suppressing user config.yaml settings. """ + prefer_legacy = os.environ.get("HERMES_IGNORE_USER_CONFIG") == "1" + if not prefer_legacy: + try: + from hermes_cli.config import load_config_readonly + + full = load_config_readonly() + cfg = full.get("delegation") or {} + if isinstance(cfg, dict): + return cfg + except Exception: + pass try: from cli import CLI_CONFIG cfg = CLI_CONFIG.get("delegation") or {} - if cfg: - return cfg - except Exception: - pass - try: - from hermes_cli.config import load_config - - full = load_config() - return full.get("delegation") or {} + return cfg if isinstance(cfg, dict) else {} except Exception: return {}
-
39 PRs closed without merging
From the close comments: done elsewhere 10 · duplicate 7 · merged via another change 3 · stale or abandoned 3 · superseded by another PR 3 · closed without comment 2 · won't fix / by design 1 · other 10
- #791 feat: allow configurable subagent model in config.yaml (#609) · done elsewhere
- #3734 feat: per-call model/provider override on delegate_task · closed without comment
-
#4929 feat(delegation): add named subagent capability profiles · other →
ba0bc01,#5583,#44412,#64213,#4928 -
#6933 fix(delegate): sync self.base_url with client_kwargs after credential resolution · merged via another change →
#7360 - #9255 feat(delegate): add task-tier profiles with per-task reasoning_effort and pool validation · stale or abandoned
Show 34 more
- #9737 feat(delegate): automatic tier routing + task-tier profiles with per-task reasoning_effort · stale or abandoned
-
#10996 feat(tools): add model parameter to delegate_task for per-task model selection · other →
#9737 - #12053 fix(delegate): read fresh config.yaml so delegation.model edits take effect (#11999) · stale or abandoned
-
#12105 fix(delegation): _load_config falls through to hermes_cli config when CLI_CONFIG has no delegation overrides (#11999) · done elsewhere →
#11999 -
#16329 fix(delegation): honor delegated provider routing for subagents · merged via another change →
#19744 -
#16503 fix(delegate): detect /anthropic URL suffix for proxy endpoints (#7833) · superseded by another PR →
#13567 -
#16839 fix(delegate): clear acp_command when override_provider is set · merged via another change →
#16894 -
#17581 Fix delegate_task model/provider precedence and expose per-task overrides · other →
a6f08ff,#10995 - #17718 fix: honor per-task model override in delegate_task · other
-
#23769 fix(delegation): accept per-call model override on delegate_task · duplicate →
#23649 -
#25026 feat(delegate): per-task model and provider override for delegate_task subagents · duplicate →
#3172,#16163,#17756,#15789,#14974 - #26486 fix(delegation): honor provider overrides for subagents · closed without comment
-
#34369 fix(delegate): detect credential/endpoint mismatch before sending request (#34318, #34334) · done elsewhere →
#34318,#34334 -
#34773 feat(delegate): per-task model/provider override in delegate_task tasks array · duplicate →
#14974,#17756,#20000,#23266,#32555,#34752,#34764,#15789 -
#34776 feat(phase34754): Centralized Model Complexity Configuration · duplicate →
#34752,#34727,#10995,#13663 -
#35033 feat(delegate): per-task model/provider overrides (+ fix two latent delegation bugs) · duplicate →
#14974,#25530,#23649,#17756 - #36790 feat(delegate): add per-task model/provider routing · won't fix / by design
- #37578 feat: add model/provider override param to delegate_task tool · other
- #39282 feat(delegate_task): add per-task model/provider override · done elsewhere
-
#41826 feat(delegation): add per-task model override for delegate_task · duplicate →
#6771,#14974,#15789,#12794,#16163 -
#41865 fix(delegate): honor model parameter end-to-end (fixes #41821, closes #41814) · other →
#41814,#53846 -
#43134 feat(delegate_tool): per-task model/provider override · superseded by another PR →
#43185 - #43185 fix(delegate_tool): address PR #43134 multi-provider review feedback · other
-
#50015 feat(delegate_task): per-call model/provider overrides · duplicate →
#6771,#15789,#47014,#47295,#46880,#32711,#6306,#23769,#12715,#12794,#12503,#7586 - #51368 fix(delegate): preserve named custom provider overrides · other
-
#51650 fix(delegation): fix opencode-go subagents ignoring delegation.model config · done elsewhere →
9ae1fa9,#51540 -
#53240 fix(delegation): resolve custom:* provider base_url from config instead of falling through to parent (Fixes #53064) · other →
#53064 -
#55175 fix(delegation): resolve api_key from provider env when base_url + provider set · done elsewhere →
efc1c2d -
#55478 fix(delegate): merge persistent + runtime delegation config sources · done elsewhere →
#60577,#59982 -
#59670 fix(tools): respect config model in delegate_task subagent spawn (#58298) · done elsewhere →
0263f1d,#58298 -
#61258 fix(delegation): prevent credential pool from overriding explicit delegation.base_url · done elsewhere →
f2c11ff,#61195 -
#61275 fix(delegate): keep delegation.base_url authoritative against credential-pool rotation · done elsewhere →
f2c11ff -
#64299 feat(delegate): per-call and per-task model/provider overrides for delegate_task · superseded by another PR →
#63461 - #72834 feat: add per-call model/provider override to delegate_task · other
Closed issues · 56
- Closed#609Allow configurable subagent model in config.yaml
- Closed#3719Feature: Per-call model/provider override on delegate_task
- Closed#5012[Feature]: Allow delegate_task to accept provider/model parameters
- Closed#6306Feature: Allow per-task model selection in delegate_task
- Closed#6825Bug: delegation.base_url correctly resolved but overwritten before first API call
- Closed#7833delegate_task can overwrite delegated custom endpoint with parent custom credential pool
- Closed#9712delegate_task(acp_command=...) silently ignored under Anthropic parent
- Closed#10653[Bug]: delegation config doesn`t work
- Closed#10995feat: delegate_task should support per-task model selection
- Closed#11999delegate_task ignores subagent model config — always inherits parent model
- Closed#14974[Feature]: delegation-per-task-endpoint-overrides
- Closed#15789feat: per-task model/provider overrides in delegate_task
- Closed#16816[Bug]: Add delegation.acp_command: none config option
- Closed#17685delegate_task: per-task model override is silently ignored — children always use parent's model
- Closed#17732Feature: per-call model/provider override in delegate_task
- Closed#18591Feature: Per-task model override for delegate_task subagents
- Closed#19567TUI delegation subagent incorrectly routed to copilot-acp instead of configured deepseek provider
- Closed#23467delegate_task model parameter silently discarded — subagents always inherit parent model
- Closed#24263Feature: Per-sub-agent provider/model selection in delegate_task
- Closed#26482delegation model override ignored — subagents always inherit parent provider/model
- Closed#27294[Bug] delegate_task ignores delegation.base_url — subagent always inherits parent model
- Closed#27295[Bug] delegate_task ignores delegation.base_url — subagent always inherits parent model
- Closed#27296[Bug] delegate_task ignores delegation.base_url — subagent always inherits parent model
- Closed#31155delegation.model override ignored — subagents always inherit parent model
- Closed#32711delegate_task() lacks model and provider parameters — prevents per-call subagent routing
- Closed#34318delegate_task sends API key to wrong provider endpoint (OpenRouter key → OpenAI)
- Closed#34334Optimization: Correct API key routing for delegate_task
- Closed#34462[TASK] Implement Per-Call Provider and Model Overrides for delegate_task
- Closed#34489Per-Task Model Override in delegate_task
- Closed#34727[FEATURE] Task Delegation + Intelligent Model Selection (Phases 7 & 3)
- Closed#34764feat(delegate): per-task model/provider override in delegate_task tasks array
- Closed#35409Add profile/model override parameter to delegate_task
- Closed#35437feat: add model/provider/base_url/api_format parameters to delegate_task (consolidating #5012, #10995, #17685, #23467, #32711)
- Closed#37574feat: add model/provider override param to delegate_task tool
- Closed#41814Feature: Per-task model override for delegate_task
- Closed#44900feat(delegation): add model override to delegate_task
- Closed#46295Feature Request: Add subagent configuration to Model page with provider selection
- Closed#47014Feature Request: Per-call model override for delegate_task
- Closed#47295feat: per-call model routing in delegate_task (multi-model delegation)
- Closed#49332delegate_task model override ignored — subagents use wrong model, consume unauthorized credits
- Closed#50202[Feature]: per-call model/provider override for delegate_task (multi-model subagent orchestration)
- Closed#51303Custom providers not recognized by delegate_task delegation system
- Closed#51401Feature Request: Per-Task Model Override in delegate_task
- Closed#52331[Feature]: Per-call model routing for delegate_task subagents
- Closed#53064delegation.provider=custom:* resolves wrong base_url (inherits parent provider base_url)
- Closed#53846delegate_task model parameter not honored — child agents always inherit parent session model
- Closed#55380Bug: delegate_task ignores delegation config — hardcoded to xiaomi
- Closed#56891Feature: Expose model parameter on delegate_task for per-call model selection
- Closed#58298Subagent delegation ignores config, always uses credential-pool model (glm-4-flash)
- Closed#58731Feature Request: Per-subagent model override in delegate_task
- Closed#61195[Bug]: delegation.base_url correctly resolved through init_agent() but subagent's actual API call still routes to OpenRouter → 401
- Closed#61622feat: support per-subagent model selection in delegate_task
- Closed#62443delegate_task subagent always resolves to Groq/llama-3.3-70b-versatile (401) regardless of delegation config
- Closed#62731Feature Request: Allow delegate_task to use different models per subtask
- Closed#66536[Feature]: Per-call model/provider override for delegate_task
- Closed#66819Feature request: Role-based subagents — inherit profile identity (SOUL.md + skills + tools)
How this cluster was grouped
-
Link evidence (
partly structural links): some members are connected by structural evidence (shared changed files, or a closing/superseded reference); the rest are joined by an automated relevance judgement over their text. - Members outside that structural core may belong to a different underlying problem.
-
Pairwise link density
0.03: the share of item pairs that carry a link, counting a structural link in full and a relevance-only link at 0.36.1.00means every pair is linked.
Pick up a Lab task
Check whether a fix covers the open issues here, with your own agent. Bring back evidence for maintainers.
Open the Lab