feat(task): Add configurable subagent-to-subagent task delegation with budgets, and persistent sessions #7756
+486
−22
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
feat(task): Add configurable subagent-to-subagent task delegation with budgets, and persistent sessions
Fixes Issue #7296
Summary
This PR enables subagents to delegate tasks to other subagents using persistent or stateless sessions, with configurable call budgets to prevent infinite loops. The feature is opt-in only - default OpenCode behavior remains unchanged.
About This PR
This is my first PR for a project, which I vibe coded with Claude Code. System-based thinking and design I get, so I have competencies which I hope show. I ask that you don't hold back on the constructive criticism and help me understand how to improve any problems.
Background
I have been developing an Agentic Collaboration Framework (ACF) optimized for non-coding agentic workflows in OpenCode, specifically for tasks related to legal, medical, financial, and advocacy work. The ACF is designed for subagents to be able to task other subagents and for the tasking agent (primary and subagents) to exercise discretion whether to maintain a persistent session or a stateless one. This PR adds this functionality with a system designed to prevent infinite subagent tasking loops.
The default behavior of OpenCode to prevent subagents from tasking subagents remains the default setting of the PR. The user must modify their
opencode.jsonto enable subagents to task subagents by setting a task call budget (task_budget) for an agent. Permissions for thetasktool can be set to limit which agents a subagent can task.Architecture & System Design
Delegation Workflow Example
Key workflow patterns enabled:
Budget System Design
The budget system prevents infinite delegation loops through three mechanisms:
Budget resets when:
Configuration Reference
task_budget(Caller Configuration)Controls how many task calls a subagent can make within a single session.
undefinedor0> 0Location:
agent.<agent-name>.task_budget{ "agent": { "my-subagent": { "task_budget": 5 } } }callable_by_subagents(Target Configuration)Controls whether an agent can be called by other subagents (not just Primary).
undefinedorfalsetrueLocation:
agent.<agent-name>.callable_by_subagents{ "agent": { "assistant-flash": { "callable_by_subagents": true } } }permission.task(Permission Rules)Controls which specific agents a subagent is allowed to task. Uses existing OpenCode permission patterns.
{ "agent": { "principal-partner": { "task_budget": 10, "permission": { "task": { "*": "deny", "assistant-sonnet": "allow", "assistant-flash": "allow" } } } } }Rule evaluation: Most specific match wins.
"*": "deny"denies all, then specific allows override.Complete Example Configuration
{ "agent": { "principal-partner": { "description": "Orchestrates complex workflows", "mode": "subagent", "task_budget": 10, "callable_by_subagents": false, "permission": { "task": { "*": "deny", "assistant-sonnet": "allow", "assistant-flash": "allow" } } }, "assistant-sonnet": { "description": "Thorough analysis", "mode": "subagent", "task_budget": 3, "callable_by_subagents": true, "permission": { "task": { "*": "deny", "assistant-flash": "allow" } } }, "assistant-flash": { "description": "Fast analytical passes", "mode": "subagent", "task_budget": 2, "callable_by_subagents": true, "permission": { "task": { "*": "deny", "assistant-sonnet": "allow" } } } } }Error Messages
The system provides clear error messages for all denial cases:
Caller has no task budget configured. Set task_budget > 0 on the calling agent to enable nested delegation.Target "<agent>" is not callable by subagents. Set callable_by_subagents: true on the target agent to enable.Task budget exhausted (N/N calls). Return control to caller to continue.Cannot resume session: not a child of caller session. Session "<id>" is not owned by this caller.Testing
Test Methods
Testing was conducted using an isolated OpenCode configuration with the PR code. A human operator (NamedIdentity) conducted blinded experiments with AI agents to verify functionality.
Blinded Memory Test Protocol:
Test Results
Full testing transcript attached: See Test-Data-subagent-to-subagent-PR.md
Security Considerations
Potential Risk: Config Self-Modification
If a subagent is given write permission to config files without manual authorization, it could hypothetically modify
opencode.jsonto increase its own budget limit or change its permissions to call other agents.Assessment: I think this highly unlikely to occur with a frontier model performing relatively normal use-cases. The most likely way subagents might get out of control is if a user tries to make a subagent task another subagent, and instead of understanding how to modify subagent settings properly, demands that their primary agent "fix it". The primary agent might change config settings to do exactly what the user demanded, which then creates infinite loops in subagents when the user sends the subagent tasking prompt they were trying to make work.
Mitigation:
At the end of the day the user is responsible, and used responsibly I expect this PR for subagent-to-subagent tasking and persistent sessions will work well and improve the experience and utility of the OpenCode project.
Files Changed
packages/opencode/src/tool/task.ts- Core implementationpackages/opencode/test/task-delegation.test.ts- Unit tests (9 tests)Backwards Compatibility
task_budgetandcallable_by_subagentsgeneral,explore, etc. retain their existing behaviorCommits
feat(task): add subagent-to-subagent task delegation- Core implementationfix(task): use strict equality for callable_by_subagents check- Type safety fixfix(task): change budget scope from per-message to per-session- Budget tracking fixTest Plan