Conversation
- Add subagents config field to agent schema for wildcard-based filtering - Add filterSubagents helper and runtime validation in Task tool - Add per-agent subagent filtering in prompt tool resolution - Add comprehensive tests for subagent filtering patterns
- Document subagents config option for filtering agent invocations - Add examples for exclusion patterns, wildcards, and precedence rules - Include Markdown agent configuration example
- Filter @ autocomplete suggestions based on current agent's subagents configuration - Fixes bug where all subagents were shown regardless of visibility settings
WalkthroughIntroduces a new Changes
Sequence DiagramsequenceDiagram
participant Agent Config
participant Agent.Info
participant Prompt Builder
participant Task Tool
participant Execution Context
Agent Config->>Agent.Info: Merge subagents record
Prompt Builder->>Agent.Info: Read agent.subagents whitelist
Prompt Builder->>Prompt Builder: filterSubagents(available_agents, whitelist)
Prompt Builder->>Task Tool: Set dynamic task.description with filtered list
Execution Context->>Task Tool: execute(subagent_type request)
Task Tool->>Task Tool: Wildcard.all(subagent_type, ctx.agent.subagents)
Task Tool-->>Execution Context: ✓ Allowed or ✗ Access denied
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning, 1 inconclusive)
✅ Passed checks (1 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Nitpick comments (3)
packages/opencode/src/cli/cmd/tui/component/prompt/autocomplete.tsx (1)
158-162: Type assertion could be more robust.The type assertion
as { subagents?: Record<string, boolean> }may be fragile. Consider using a safer approach:-const current = local.agent.current() as { subagents?: Record<string, boolean> } -const subagents = current.subagents ?? {} +const current = local.agent.current() +const subagents = (current as Agent.Info)?.subagents ?? {}This makes the type relationship clearer and aligns with the Agent.Info schema that includes subagents.
packages/opencode/src/session/prompt.ts (1)
807-822: Add defensive check for subagents.While
input.agent.subagentsshould always be defined based on the Agent.Info schema, adding a defensive check would make the code more robust:// Regenerate task tool description with filtered subagents if (tools.task) { const all = await Agent.list().then((x) => x.filter((a) => a.mode !== "primary")) - const filtered = filterSubagents(all, input.agent.subagents) + const filtered = filterSubagents(all, input.agent.subagents ?? {}) const description = TASK_DESCRIPTION.replace(This prevents potential runtime errors if subagents is somehow undefined and aligns with the pattern used in autocomplete.tsx.
packages/opencode/src/config/config.ts (1)
438-438: Consider adding JSDoc description for subagents field.The
subagentsfield lacks a description. Adding one would improve the generated schema documentation:-subagents: z.record(z.string(), z.boolean()).optional(), +subagents: z.record(z.string(), z.boolean()).optional().describe("Control which subagents this agent can invoke via the Task tool"),This aligns with the documentation pattern used for other fields like
toolsand would help users understand the field's purpose.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (2)
flake.lockis excluded by!**/*.lockpackages/sdk/js/src/gen/types.gen.tsis excluded by!**/gen/**
📒 Files selected for processing (7)
packages/opencode/src/agent/agent.ts(6 hunks)packages/opencode/src/cli/cmd/tui/component/prompt/autocomplete.tsx(3 hunks)packages/opencode/src/config/config.ts(1 hunks)packages/opencode/src/session/prompt.ts(2 hunks)packages/opencode/src/tool/task.ts(2 hunks)packages/opencode/test/subagents-filter.test.ts(1 hunks)packages/web/src/content/docs/agents.mdx(1 hunks)
🧰 Additional context used
📓 Path-based instructions (4)
**/*.{js,jsx,ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{js,jsx,ts,tsx}: DO NOT do unnecessary destructuring of variables
DO NOT useelsestatements unless necessary
DO NOT usetry/catchif it can be avoided
AVOIDtry/catchwhere possible
AVOIDletstatements
PREFER single word variable names where possible
Use as many Bun APIs as possible like Bun.file()
Files:
packages/opencode/src/config/config.tspackages/opencode/src/agent/agent.tspackages/opencode/test/subagents-filter.test.tspackages/opencode/src/session/prompt.tspackages/opencode/src/cli/cmd/tui/component/prompt/autocomplete.tsxpackages/opencode/src/tool/task.ts
**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
AVOID using
anytype
Files:
packages/opencode/src/config/config.tspackages/opencode/src/agent/agent.tspackages/opencode/test/subagents-filter.test.tspackages/opencode/src/session/prompt.tspackages/opencode/src/cli/cmd/tui/component/prompt/autocomplete.tsxpackages/opencode/src/tool/task.ts
packages/opencode/**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (packages/opencode/AGENTS.md)
Use Bun with TypeScript ESM modules as the runtime environment
Files:
packages/opencode/src/config/config.tspackages/opencode/src/agent/agent.tspackages/opencode/test/subagents-filter.test.tspackages/opencode/src/session/prompt.tspackages/opencode/src/cli/cmd/tui/component/prompt/autocomplete.tsxpackages/opencode/src/tool/task.ts
packages/opencode/**/*.{ts,tsx}
📄 CodeRabbit inference engine (packages/opencode/AGENTS.md)
packages/opencode/**/*.{ts,tsx}: Use relative imports for local modules with named imports preferred
Use Zod schemas for validation
Use TypeScript interfaces for defining data structures
Use camelCase for variable and function names
Use PascalCase for class and namespace names
Use Result patterns for error handling; avoid throwing exceptions in tools
Organize code using namespace-based structure (e.g.,Tool.define(),Session.create())
PasssessionIDin tool context and useApp.provide()for dependency injection
Validate all inputs with Zod schemas
UseLog.create({ service: "name" })pattern for logging
UseStoragenamespace for data persistence
Files:
packages/opencode/src/config/config.tspackages/opencode/src/agent/agent.tspackages/opencode/test/subagents-filter.test.tspackages/opencode/src/session/prompt.tspackages/opencode/src/cli/cmd/tui/component/prompt/autocomplete.tsxpackages/opencode/src/tool/task.ts
🧬 Code graph analysis (4)
packages/opencode/test/subagents-filter.test.ts (2)
packages/opencode/src/agent/agent.ts (2)
Info(12-41)Info(42-42)packages/opencode/src/tool/task.ts (1)
filterSubagents(16-18)
packages/opencode/src/session/prompt.ts (1)
packages/opencode/src/tool/task.ts (1)
filterSubagents(16-18)
packages/opencode/src/cli/cmd/tui/component/prompt/autocomplete.tsx (2)
packages/sdk/js/src/gen/sdk.gen.ts (1)
current(226-231)packages/opencode/src/cli/cmd/tui/context/sync.tsx (1)
sync(333-355)
packages/opencode/src/tool/task.ts (2)
packages/sdk/js/src/gen/types.gen.ts (1)
Agent(1476-1507)packages/opencode/src/agent/agent.ts (2)
Info(12-41)Info(42-42)
🔇 Additional comments (9)
packages/opencode/src/cli/cmd/tui/component/prompt/autocomplete.tsx (1)
8-8: LGTM! Clean imports for subagent filtering.The new imports support the subagent filtering feature and follow the established project conventions.
Also applies to: 13-13
packages/opencode/src/session/prompt.ts (1)
49-49: LGTM! Necessary imports for dynamic task description.The imports support the new functionality for filtering subagents and rebuilding task descriptions.
packages/opencode/test/subagents-filter.test.ts (1)
1-93: Excellent test coverage for subagent filtering.The test suite comprehensively covers:
- Empty configuration (all agents allowed)
- Explicit inclusion/exclusion
- Wildcard patterns
- Precedence rules
- Edge cases for Wildcard.all behavior
The tests are well-structured and validate the expected filtering semantics.
packages/opencode/src/tool/task.ts (2)
12-18: LGTM! Clean utility exports.The exported
filterSubagentsfunction andTASK_DESCRIPTIONconstant enable proper code reuse across the codebase. The filtering logic correctly allows agents whenWildcard.allreturnsundefined(no restriction) ortrue(explicitly allowed).
39-41: Guard validation logic is correct.The permission check properly validates that the calling agent has access to the requested subagent. The logic correctly allows access when
Wildcard.allreturnsundefined(no restriction) ortrue(explicitly allowed).Note: The guard assumes
callingis defined. Whilectx.agentshould always be valid in practice, consider whether an explicit check would add clarity:const calling = await Agent.get(ctx.agent) if (calling && Wildcard.all(params.subagent_type, calling.subagents) === false)The current implementation is acceptable since an invalid
ctx.agentwould fail at the earlier agent fetch on line 37.packages/opencode/src/agent/agent.ts (3)
36-36: LGTM! Schema addition is consistent.The
subagentsfield follows the same pattern astoolsand is correctly defined as a required field (not optional), which ensures all Agent.Info objects have this property initialized.
117-157: LGTM! Consistent default initialization.All agent types (built-in and custom) properly initialize
subagentsto an empty object, which correctly represents "no restrictions" - all subagents are allowed by default.
160-193: LGTM! Config parsing follows established patterns.The subagents configuration parsing correctly:
- Extracts the field from user config via destructuring
- Merges with existing agent subagents using spread operator
- Follows the same pattern as tools configuration
The lack of global defaults for subagents (unlike tools) is appropriate since subagents restrictions are agent-specific.
packages/web/src/content/docs/agents.mdx (1)
349-416: Excellent documentation for subagents feature.The new Subagents section provides:
- Clear explanation of the feature's purpose
- Progressive examples from simple to complex
- Wildcard pattern usage
- Precedence rules with practical examples
- Both JSON and Markdown configuration examples
- Important behavioral note about Task tool filtering
The documentation is well-structured, accurate, and aligns with the implemented behavior.
Summary by CodeRabbit
New Features
Documentation
Tests
✏️ Tip: You can customize this high-level summary in your review settings.