From 26f8ff5a7d4fc5b09f9d98551e116c4610a82dce Mon Sep 17 00:00:00 2001 From: Akhilesh Kumar Date: Wed, 4 Mar 2026 18:07:14 +0000 Subject: [PATCH] feat: add explicit policy override for subagents --- packages/core/src/agents/agent-scheduler.test.ts | 2 ++ packages/core/src/agents/agent-scheduler.ts | 14 ++++++++++++++ packages/core/src/agents/local-executor.ts | 1 + packages/core/src/config/config.ts | 1 + packages/sdk/src/session.ts | 1 + schemas/settings.schema.json | 5 +++++ 6 files changed, 24 insertions(+) diff --git a/packages/core/src/agents/agent-scheduler.test.ts b/packages/core/src/agents/agent-scheduler.test.ts index 5edcb664b6..6d980fffcc 100644 --- a/packages/core/src/agents/agent-scheduler.test.ts +++ b/packages/core/src/agents/agent-scheduler.test.ts @@ -31,6 +31,7 @@ describe('agent-scheduler', () => { mockConfig = { getMessageBus: vi.fn().mockReturnValue(mockMessageBus), getToolRegistry: vi.fn().mockReturnValue(mockToolRegistry), + getAgentsSettings: vi.fn().mockReturnValue({}), } as unknown as Mocked; }); @@ -47,6 +48,7 @@ describe('agent-scheduler', () => { const options = { schedulerId: 'subagent-1', + agentName: 'mock-agent', parentCallId: 'parent-1', toolRegistry: mockToolRegistry as unknown as ToolRegistry, signal: new AbortController().signal, diff --git a/packages/core/src/agents/agent-scheduler.ts b/packages/core/src/agents/agent-scheduler.ts index ecb4ed960a..8c667d3fd1 100644 --- a/packages/core/src/agents/agent-scheduler.ts +++ b/packages/core/src/agents/agent-scheduler.ts @@ -12,6 +12,7 @@ import type { } from '../scheduler/types.js'; import type { ToolRegistry } from '../tools/tool-registry.js'; import type { EditorType } from '../utils/editor.js'; +import { ApprovalMode } from '../policy/types.js'; /** * Options for scheduling agent tools. @@ -19,6 +20,8 @@ import type { EditorType } from '../utils/editor.js'; export interface AgentSchedulingOptions { /** The unique ID for this agent's scheduler. */ schedulerId: string; + /** The name of the agent executing the tools. */ + agentName: string; /** The ID of the tool call that invoked this agent. */ parentCallId?: string; /** The tool registry specific to this agent. */ @@ -46,6 +49,7 @@ export async function scheduleAgentTools( ): Promise { const { schedulerId, + agentName, parentCallId, toolRegistry, signal, @@ -57,6 +61,16 @@ export async function scheduleAgentTools( // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment const agentConfig: Config = Object.create(config); agentConfig.getToolRegistry = () => toolRegistry; + + // Apply any subagent-specific approval mode override, fallback to the main config mode. + const override = config.getAgentsSettings()?.overrides?.[agentName]; + if (override?.approvalMode) { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion + agentConfig.getApprovalMode = () => override.approvalMode as ApprovalMode; + } else { + // Subagents operate in YOLO mode by default, unless overridden. + agentConfig.getApprovalMode = () => ApprovalMode.YOLO; + } const scheduler = new Scheduler({ config: agentConfig, diff --git a/packages/core/src/agents/local-executor.ts b/packages/core/src/agents/local-executor.ts index 7bbecdac7c..ce79398c96 100644 --- a/packages/core/src/agents/local-executor.ts +++ b/packages/core/src/agents/local-executor.ts @@ -1073,6 +1073,7 @@ export class LocalAgentExecutor { toolRequests, { schedulerId: this.agentId, + agentName: this.definition.name, parentCallId: this.parentCallId, toolRegistry: this.toolRegistry, signal, diff --git a/packages/core/src/config/config.ts b/packages/core/src/config/config.ts index ce07271139..9ec5d8ce76 100644 --- a/packages/core/src/config/config.ts +++ b/packages/core/src/config/config.ts @@ -234,6 +234,7 @@ export interface AgentOverride { modelConfig?: ModelConfig; runConfig?: AgentRunConfig; enabled?: boolean; + approvalMode?: ApprovalMode; } export interface AgentSettings { diff --git a/packages/sdk/src/session.ts b/packages/sdk/src/session.ts index 8332ef29d0..8a47786080 100644 --- a/packages/sdk/src/session.ts +++ b/packages/sdk/src/session.ts @@ -254,6 +254,7 @@ export class GeminiCliSession { toolCallsToSchedule, { schedulerId: sessionId, + agentName: 'sdk-agent', toolRegistry: scopedRegistry, signal: abortSignal, }, diff --git a/schemas/settings.schema.json b/schemas/settings.schema.json index a0ef69eab5..be7745ff60 100644 --- a/schemas/settings.schema.json +++ b/schemas/settings.schema.json @@ -2225,6 +2225,11 @@ "enabled": { "type": "boolean", "description": "Whether to enable the agent." + }, + "approvalMode": { + "type": "string", + "description": "Approval mode for this subagent's internal tool calls.", + "enum": ["default", "yolo", "plan", "autoEdit"] } } },