Skip to content

Sewer56 subagent restrictions#57

Merged
shuv1337 merged 9 commits intointegrationfrom
sewer56-subagent-restrict
Nov 27, 2025
Merged

Sewer56 subagent restrictions#57
shuv1337 merged 9 commits intointegrationfrom
sewer56-subagent-restrict

Conversation

@shuv1337
Copy link
Collaborator

@shuv1337 shuv1337 commented Nov 27, 2025

Summary by CodeRabbit

  • New Features

    • Added subagents configuration to control which agents are available for specific tasks, supporting both explicit agent names and wildcard patterns.
    • Task descriptions dynamically reflect only available subagents.
  • Documentation

    • Added comprehensive guide on configuring subagents with practical examples for explicit exclusion and pattern-based filtering.
  • Tests

    • Added tests validating subagent filtering behavior with various configuration scenarios.

✏️ Tip: You can customize this high-level summary in your review settings.

Sewer56 and others added 7 commits November 26, 2025 07:54
- 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
@coderabbitai
Copy link

coderabbitai bot commented Nov 27, 2025

Walkthrough

Introduces a new subagents configuration field (record of string to boolean) across the Agent schema and config. Adds filtering logic to restrict which subagents are available to agents, with wildcard pattern support. Includes guard validation in task execution, dynamic task description generation, and comprehensive documentation.

Changes

Cohort / File(s) Summary
Schema and Configuration Updates
packages/opencode/src/agent/agent.ts, packages/opencode/src/config/config.ts
Adds optional subagents field (record of string to boolean) to Agent.Info schema and Agent config. Initializes subagents in default agent entries and merges user-provided subagents configuration.
Feature Integration
packages/opencode/src/session/prompt.ts, packages/opencode/src/cli/cmd/tui/component/prompt/autocomplete.tsx
Integrates subagents filtering into task description generation (prompt.ts) and agent autocomplete filtering (autocomplete.tsx) using derived subagents map and wildcard filtering.
Core Utility and Validation
packages/opencode/src/tool/task.ts
Exports new filterSubagents() utility function for filtering agents by subagents whitelist; re-exports task description constant; adds execution guard to verify requested subagent availability via wildcard matching.
Testing and Documentation
packages/opencode/test/subagents-filter.test.ts, packages/web/src/content/docs/agents.mdx
Comprehensive test suite validating filterSubagents behavior (empty config, boolean flags, wildcard patterns, precedence rules); documentation with configuration examples (JSON and Markdown), wildcard usage, and precedence clarification.

Sequence Diagram

sequenceDiagram
    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
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • Guard validation logic in TaskTool.execute: verify wildcard matching implementation and error handling are robust
  • filterSubagents utility: confirm wildcard pattern precedence (longer patterns override shorter) is correctly implemented
  • Config merging in agent.ts: ensure subagents are properly propagated through default entries and user config
  • Test coverage: validate all wildcard precedence scenarios and edge cases are covered
  • Integration points: verify prompt.ts correctly applies filtered subagents to task description and autocomplete.tsx uses derived map

Poem

🐰 A rabbit hops with glee,
Subagents now dance so free!
Wildcards match with care,
Filters sort with flair,
Tasks know who they'll be!

Pre-merge checks and finishing touches

❌ Failed checks (1 warning, 1 inconclusive)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
Title check ❓ Inconclusive The title 'Sewer56 subagent restrictions' is vague and lacks specificity about what restrictions are being implemented or why. Consider a more descriptive title like 'Add subagent filtering configuration' or 'Implement subagent access control' to better convey the change's purpose.
✅ Passed checks (1 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch sewer56-subagent-restrict

Comment @coderabbitai help to get the list of available commands and usage tips.

@shuv1337 shuv1337 merged commit a56c8f8 into integration Nov 27, 2025
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.subagents should 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 subagents field 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 tools and would help users understand the field's purpose.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c6151ca and 0fe4b9a.

⛔ Files ignored due to path filters (2)
  • flake.lock is excluded by !**/*.lock
  • packages/sdk/js/src/gen/types.gen.ts is 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 use else statements unless necessary
DO NOT use try/catch if it can be avoided
AVOID try/catch where possible
AVOID let statements
PREFER single word variable names where possible
Use as many Bun APIs as possible like Bun.file()

Files:

  • packages/opencode/src/config/config.ts
  • packages/opencode/src/agent/agent.ts
  • packages/opencode/test/subagents-filter.test.ts
  • packages/opencode/src/session/prompt.ts
  • packages/opencode/src/cli/cmd/tui/component/prompt/autocomplete.tsx
  • packages/opencode/src/tool/task.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

AVOID using any type

Files:

  • packages/opencode/src/config/config.ts
  • packages/opencode/src/agent/agent.ts
  • packages/opencode/test/subagents-filter.test.ts
  • packages/opencode/src/session/prompt.ts
  • packages/opencode/src/cli/cmd/tui/component/prompt/autocomplete.tsx
  • packages/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.ts
  • packages/opencode/src/agent/agent.ts
  • packages/opencode/test/subagents-filter.test.ts
  • packages/opencode/src/session/prompt.ts
  • packages/opencode/src/cli/cmd/tui/component/prompt/autocomplete.tsx
  • packages/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())
Pass sessionID in tool context and use App.provide() for dependency injection
Validate all inputs with Zod schemas
Use Log.create({ service: "name" }) pattern for logging
Use Storage namespace for data persistence

Files:

  • packages/opencode/src/config/config.ts
  • packages/opencode/src/agent/agent.ts
  • packages/opencode/test/subagents-filter.test.ts
  • packages/opencode/src/session/prompt.ts
  • packages/opencode/src/cli/cmd/tui/component/prompt/autocomplete.tsx
  • packages/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 filterSubagents function and TASK_DESCRIPTION constant enable proper code reuse across the codebase. The filtering logic correctly allows agents when Wildcard.all returns undefined (no restriction) or true (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.all returns undefined (no restriction) or true (explicitly allowed).

Note: The guard assumes calling is defined. While ctx.agent should 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.agent would fail at the earlier agent fetch on line 37.

packages/opencode/src/agent/agent.ts (3)

36-36: LGTM! Schema addition is consistent.

The subagents field follows the same pattern as tools and 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 subagents to 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.

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.

3 participants