feat: add explicit policy override for subagents

This commit is contained in:
Akhilesh Kumar
2026-03-04 18:07:14 +00:00
parent 66721379f8
commit 26f8ff5a7d
6 changed files with 24 additions and 0 deletions

View File

@@ -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<Config>;
});
@@ -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,

View File

@@ -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<CompletedToolCall[]> {
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,

View File

@@ -1073,6 +1073,7 @@ export class LocalAgentExecutor<TOutput extends z.ZodTypeAny> {
toolRequests,
{
schedulerId: this.agentId,
agentName: this.definition.name,
parentCallId: this.parentCallId,
toolRegistry: this.toolRegistry,
signal,

View File

@@ -234,6 +234,7 @@ export interface AgentOverride {
modelConfig?: ModelConfig;
runConfig?: AgentRunConfig;
enabled?: boolean;
approvalMode?: ApprovalMode;
}
export interface AgentSettings {

View File

@@ -254,6 +254,7 @@ export class GeminiCliSession {
toolCallsToSchedule,
{
schedulerId: sessionId,
agentName: 'sdk-agent',
toolRegistry: scopedRegistry,
signal: abortSignal,
},

View File

@@ -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"]
}
}
},