feat(core): add foundation for subagent tool isolation (#22708)

This commit is contained in:
AK
2026-03-16 20:54:33 -07:00
committed by GitHub
parent abe83fce0b
commit 695bcaea0d
9 changed files with 203 additions and 9 deletions
+60
View File
@@ -16,6 +16,7 @@ import {
DEFAULT_MAX_TIME_MINUTES,
} from './types.js';
import type { A2AAuthConfig } from './auth-provider/types.js';
import { MCPServerConfig } from '../config/config.js';
import { isValidToolName } from '../tools/tool-names.js';
import { FRONTMATTER_REGEX } from '../skills/skillLoader.js';
import { getErrorMessage } from '../utils/errors.js';
@@ -28,11 +29,29 @@ interface FrontmatterBaseAgentDefinition {
display_name?: string;
}
interface FrontmatterMCPServerConfig {
command?: string;
args?: string[];
env?: Record<string, string>;
cwd?: string;
url?: string;
http_url?: string;
headers?: Record<string, string>;
tcp?: string;
type?: 'sse' | 'http';
timeout?: number;
trust?: boolean;
description?: string;
include_tools?: string[];
exclude_tools?: string[];
}
interface FrontmatterLocalAgentDefinition
extends FrontmatterBaseAgentDefinition {
kind: 'local';
description: string;
tools?: string[];
mcp_servers?: Record<string, FrontmatterMCPServerConfig>;
system_prompt: string;
model?: string;
temperature?: number;
@@ -100,6 +119,23 @@ const nameSchema = z
.string()
.regex(/^[a-z0-9-_]+$/, 'Name must be a valid slug');
const mcpServerSchema = z.object({
command: z.string().optional(),
args: z.array(z.string()).optional(),
env: z.record(z.string()).optional(),
cwd: z.string().optional(),
url: z.string().optional(),
http_url: z.string().optional(),
headers: z.record(z.string()).optional(),
tcp: z.string().optional(),
type: z.enum(['sse', 'http']).optional(),
timeout: z.number().optional(),
trust: z.boolean().optional(),
description: z.string().optional(),
include_tools: z.array(z.string()).optional(),
exclude_tools: z.array(z.string()).optional(),
});
const localAgentSchema = z
.object({
kind: z.literal('local').optional().default('local'),
@@ -115,6 +151,7 @@ const localAgentSchema = z
}),
)
.optional(),
mcp_servers: z.record(mcpServerSchema).optional(),
model: z.string().optional(),
temperature: z.number().optional(),
max_turns: z.number().int().positive().optional(),
@@ -495,6 +532,28 @@ export function markdownToAgentDefinition(
// If a model is specified, use it. Otherwise, inherit
const modelName = markdown.model || 'inherit';
const mcpServers: Record<string, MCPServerConfig> = {};
if (markdown.kind === 'local' && markdown.mcp_servers) {
for (const [name, config] of Object.entries(markdown.mcp_servers)) {
mcpServers[name] = new MCPServerConfig(
config.command,
config.args,
config.env,
config.cwd,
config.url,
config.http_url,
config.headers,
config.tcp,
config.type,
config.timeout,
config.trust,
config.description,
config.include_tools,
config.exclude_tools,
);
}
}
return {
kind: 'local',
name: markdown.name,
@@ -520,6 +579,7 @@ export function markdownToAgentDefinition(
tools: markdown.tools,
}
: undefined,
mcpServers: Object.keys(mcpServers).length > 0 ? mcpServers : undefined,
inputConfig,
metadata,
};