Skip to content

Conversation

@marcusquinn
Copy link

Summary

Adds a new subagents configuration option that allows primary agents to specify which subagents appear in their Task tool description. This reduces token overhead when many subagents are configured but only a subset is relevant to a particular agent.

Closes #7269

Problem

The Task tool description includes all configured subagents, adding ~6-10k tokens to the system prompt regardless of whether the agent will use them. With 150+ subagents, this significantly impacts:

  • Token costs (especially with reasoning models)
  • Effective context window for actual work

Solution

Add a subagents field to agent config that filters which subagents appear in the Task tool description:

{
  "agent": {
    "build": {
      "subagents": ["explore", "general", "code-*"]
    }
  }
}
  • Supports glob patterns (e.g., code-*, *-reviewer)
  • If not set, all subagents are available (backward compatible)
  • Works alongside existing permission.task (which controls runtime access)

Changes

  • packages/opencode/src/config/config.ts - Add subagents field to Agent schema
  • packages/opencode/src/agent/agent.ts - Add subagents to Agent.Info and state
  • packages/opencode/src/tool/task.ts - Filter agents based on caller's subagents config
  • packages/opencode/test/tool/task-subagents.test.ts - Tests for filtering logic
  • packages/web/src/content/docs/agents.mdx - Documentation

Testing

cd packages/opencode && bun test test/tool/task-subagents.test.ts

All 9 tests pass.

Add a new 'subagents' configuration option that allows primary agents to
specify which subagents appear in their Task tool description. This reduces
token overhead when many subagents are configured but only a subset is
relevant to a particular agent.

- Add 'subagents' field to Agent config schema (supports glob patterns)
- Filter task tool description based on caller's subagents list
- Add tests for the new filtering behavior
- Update documentation with usage examples

Closes anomalyco#7269
@github-actions
Copy link
Contributor

github-actions bot commented Jan 8, 2026

The following comment was made by an LLM, it may be inaccurate:

Summary:

One potentially related PR found:

This addresses similar concerns around managing which subagents are included in context. Review it to ensure there's no duplicate effort or conflicting approaches.

@marcusquinn
Copy link
Author

Thanks for flagging #4119! After reviewing, these PRs address different problems:

PR Problem Solution
#4119 Parent session context passed to subagents is too large Filter what context is passed TO subagents at runtime
#7271 (this PR) Task tool description lists all subagents, bloating system prompt Filter which subagents APPEAR in the task tool description

#4119 optimizes the context sent to subagents when they're invoked.
#7271 optimizes the task tool's description in the system prompt (before any subagent is invoked).

They're complementary - both reduce token usage but at different points:

With 150 subagents, the task tool description alone adds ~6-10k tokens to every conversation's system prompt. This PR allows agents to specify which subagents they need, reducing that overhead.

@malhashemi
Copy link
Contributor

To let you know any subagent that you list as denied in the task tool using the new permission system is already hidden from the task tool. The functionality that you are proposing already exists, just use the new permission system

@marcusquinn
Copy link
Author

Thanks @malhashemi! I tested the permission.task approach and confirmed it works as you described.

However, I'd like to make the case that the allowlist approach is significantly more ergonomic for real-world usage at scale.

Real-World Numbers

Our setup (aidevops):

  • 14 primary agents (SEO, Accounts, Build+, Content, etc.)
  • 177 subagents (and growing rapidly)
  • Each primary agent needs only 5-20 relevant subagents

Config Comparison

Deny-list (current) - Accounts agent needing only quickfile:

"permission": {
  "external_directory": "allow",
  "task": {
    "*": "deny",
    "quickfile": "allow"
  }
}

Allowlist (proposed):

"subagents": ["quickfile"]

For Build+ needing ~20 subagents, the deny-list becomes:

"task": {
  "*": "deny",
  "code-standards": "allow",
  "code-simplifier": "allow",
  "best-practices": "allow",
  "git-workflow": "allow",
  "branch": "allow",
  "preflight": "allow",
  "postflight": "allow",
  "release": "allow",
  "version-bump": "allow",
  "conversation-starter": "allow",
  "osgrep": "allow",
  "augment-context-engine": "allow",
  "context-builder": "allow",
  "context7": "allow",
  "toon": "allow",
  "playwright": "allow",
  "stagehand": "allow",
  "github-cli": "allow",
  "coolify": "allow"
}

vs:

"subagents": ["code-standards", "code-simplifier", "best-practices", "git-workflow", "branch", "preflight", "postflight", "release", "version-bump", "conversation-starter", "osgrep", "augment-context-engine", "context-builder", "context7", "toon", "playwright", "stagehand", "github-cli", "coolify"]

Why Allowlist is Better

Aspect Deny-list Allowlist
Characters per entry "name": "allow" (16+) "name" (6+)
Boilerplate Requires "*": "deny" None
Semantic clarity "Deny all except these" "These are my subagents"
Consistency Different from tools pattern Matches tools: { "x": true }
14 agents × 15 avg subagents ~4,200 extra characters ~0 extra

Proposal

The subagents field could be syntactic sugar that internally generates permission.task rules. This:

  • Keeps the permission system as the source of truth
  • Provides a cleaner DX for the common "allowlist" case
  • Is fully backward compatible

Happy to revise the implementation if there's interest from maintainers. @rekram1-node @thdxr thoughts?

marcusquinn added a commit to marcusquinn/aidevops that referenced this pull request Jan 14, 2026
Add 'subagents:' frontmatter to primary agents that specifies which
subagents should appear in the Task tool description. This reduces
token overhead by filtering 220 subagents down to 3-30 per agent.

Changes:
- Add parse_frontmatter() to generate-opencode-agents.sh
- Generate permission.task deny-list rules from subagents list
- Add subagents frontmatter to all 13 primary agents

Token savings: ~6-10k tokens per conversation by hiding irrelevant
subagents from the Task tool description.

Related: anomalyco/opencode#7271
marcusquinn added a commit to marcusquinn/aidevops that referenced this pull request Jan 14, 2026
* feat(agents): add subagent filtering via frontmatter

Add 'subagents:' frontmatter to primary agents that specifies which
subagents should appear in the Task tool description. This reduces
token overhead by filtering 220 subagents down to 3-30 per agent.

Changes:
- Add parse_frontmatter() to generate-opencode-agents.sh
- Generate permission.task deny-list rules from subagents list
- Add subagents frontmatter to all 13 primary agents

Token savings: ~6-10k tokens per conversation by hiding irrelevant
subagents from the Task tool description.

Related: anomalyco/opencode#7271

* fix(parser): improve frontmatter parser robustness

Address Gemini Code Assist review feedback:
- Add encoding='utf-8' to file open
- Skip comments and empty lines in YAML parsing
- Use specific exception types instead of bare except
- Add warning message for parse failures

Co-authored-by: gemini-code-assist[bot] <176abortedflight+gemini-code-assist[bot]@users.noreply.github.com>

* fix(health): remove context7 subagent

context7 provides library/framework docs, not health information.
crawl4ai is sufficient for health research workflows.

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

---------

Co-authored-by: gemini-code-assist[bot] <176abortedflight+gemini-code-assist[bot]@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Reduce token overhead: Task tool injects all subagent descriptions into system prompt

2 participants