feat: implement subagents configuration management

- Added a new function to retrieve subagents configuration from settings, allowing users to enable/disable subagents and select sources for loading them.
- Updated the AgentService to incorporate subagents configuration, dynamically adding tools based on the settings.
- Enhanced the UI components to manage subagents, including a settings section for enabling/disabling and selecting sources.
- Introduced a new hook for managing subagents settings state and interactions.

These changes improve the flexibility and usability of subagents within the application, enhancing user experience and configuration options.
This commit is contained in:
Shirone
2026-01-07 10:32:42 +01:00
parent fe13d47b24
commit 5c601ff200
9 changed files with 345 additions and 77 deletions

View File

@@ -293,6 +293,29 @@ export async function getSkillsConfiguration(settingsService: SettingsService):
};
}
/**
* Get Subagents configuration from settings.
* Returns configuration for enabling subagents and which sources to load from.
*
* @param settingsService - Settings service instance
* @returns Subagents configuration with enabled state, sources, and tool inclusion flag
*/
export async function getSubagentsConfiguration(settingsService: SettingsService): Promise<{
enabled: boolean;
sources: Array<'user' | 'project'>;
shouldIncludeInTools: boolean;
}> {
const settings = await settingsService.getGlobalSettings();
const enabled = settings.enableSubagents ?? true; // Default enabled
const sources = settings.subagentsSources ?? ['user', 'project']; // Default both sources
return {
enabled,
sources,
shouldIncludeInTools: enabled && sources.length > 0,
};
}
/**
* Get custom subagents from settings, merging global and project-level definitions.
* Project-level subagents take precedence over global ones with the same name.

View File

@@ -72,17 +72,10 @@ export class ClaudeProvider extends BaseProvider {
// Build Claude SDK options
// AUTONOMOUS MODE: Always bypass permissions for fully autonomous operation
const hasMcpServers = options.mcpServers && Object.keys(options.mcpServers).length > 0;
const defaultTools = [
'Read',
'Write',
'Edit',
'Glob',
'Grep',
'Bash',
'WebSearch',
'WebFetch',
'Skill',
];
// Base tools available to all agents
// Note: 'Skill' and 'Task' tools are added dynamically by agent-service.ts
// based on whether skills/subagents are enabled in settings
const defaultTools = ['Read', 'Write', 'Edit', 'Glob', 'Grep', 'Bash', 'WebSearch', 'WebFetch'];
// AUTONOMOUS MODE: Always bypass permissions and allow unrestricted tools
// Only restrict tools when no MCP servers are configured

View File

@@ -25,6 +25,7 @@ import {
getMCPServersFromSettings,
getPromptCustomization,
getSkillsConfiguration,
getSubagentsConfiguration,
getCustomSubagents,
} from '../lib/settings-helpers.js';
@@ -248,10 +249,16 @@ export class AgentService {
? await getSkillsConfiguration(this.settingsService)
: { enabled: false, sources: [] as Array<'user' | 'project'>, shouldIncludeInTools: false };
// Get custom subagents from settings (merge global + project-level)
const customSubagents = this.settingsService
? await getCustomSubagents(this.settingsService, effectiveWorkDir)
: undefined;
// Get Subagents configuration from settings
const subagentsConfig = this.settingsService
? await getSubagentsConfiguration(this.settingsService)
: { enabled: false, sources: [] as Array<'user' | 'project'>, shouldIncludeInTools: false };
// Get custom subagents from settings (merge global + project-level) only if enabled
const customSubagents =
this.settingsService && subagentsConfig.enabled
? await getCustomSubagents(this.settingsService, effectiveWorkDir)
: undefined;
// Load project context files (CLAUDE.md, CODE_QUALITY.md, etc.)
const contextResult = await loadContextFiles({
@@ -297,18 +304,34 @@ export class AgentService {
const settingSources = [...new Set([...sdkSettingSources, ...skillSettingSources])];
// Enhance allowedTools with Skills and Subagents tools
// These tools are not in the provider's default set - they're added dynamically based on settings
const needsSkillTool = skillsConfig.shouldIncludeInTools;
const needsTaskTool =
subagentsConfig.shouldIncludeInTools &&
customSubagents &&
Object.keys(customSubagents).length > 0;
// Base tools that match the provider's default set
const baseTools = ['Read', 'Write', 'Edit', 'Glob', 'Grep', 'Bash', 'WebSearch', 'WebFetch'];
if (allowedTools) {
allowedTools = [...allowedTools]; // Create a copy to avoid mutating SDK options
// Add Skill tool if skills are enabled
if (skillsConfig.shouldIncludeInTools && !allowedTools.includes('Skill')) {
if (needsSkillTool && !allowedTools.includes('Skill')) {
allowedTools.push('Skill');
}
// Add Task tool if custom subagents are configured
if (
customSubagents &&
Object.keys(customSubagents).length > 0 &&
!allowedTools.includes('Task')
) {
if (needsTaskTool && !allowedTools.includes('Task')) {
allowedTools.push('Task');
}
} else if (needsSkillTool || needsTaskTool) {
// If no allowedTools specified but we need to add Skill/Task tools,
// build the full list including base tools
allowedTools = [...baseTools];
if (needsSkillTool) {
allowedTools.push('Skill');
}
if (needsTaskTool) {
allowedTools.push('Task');
}
}