feat(coding-agent): introduced fine grained per agent advisor configuration
- Replaced blanket subagent advisor global settings with fine-grained per-agent configuration and frontmatter support. - Added dashboard keybindings and inline override editors for managing agent advisor patterns. - Implemented settings migration logic to convert legacy global options into per-agent settings. - Updated session persistence and execution layers to restore and enforce per-agent advisor behaviors.
This commit is contained in:
@@ -15,6 +15,7 @@ import { ModelRegistry } from "../config/model-registry";
|
||||
import {
|
||||
formatModelSelectorValue,
|
||||
formatModelStringWithRouting,
|
||||
resolveAgentAdvisorSelection,
|
||||
resolveAgentPrewalkPattern,
|
||||
resolveConfiguredModelPatterns,
|
||||
resolveExplicitModelRole,
|
||||
@@ -894,6 +895,9 @@ export function createSubagentSettings(
|
||||
// the parent task approval is the authorization boundary. Use yolo mode
|
||||
// to preserve unattended subagent execution. User `tools.approval` policies still apply.
|
||||
"tools.approvalMode": "yolo",
|
||||
// Subagents run unadvised by default; runSubprocess opts a spawn back in
|
||||
// per agent (frontmatter `advisor` / `task.agentAdvisor`) via overrides.
|
||||
"advisor.enabled": false,
|
||||
...overrides,
|
||||
},
|
||||
{ storage: baseSettings.getStorage() },
|
||||
@@ -2690,12 +2694,26 @@ export async function runSubprocess(options: ExecutorOptions): Promise<SingleRes
|
||||
}
|
||||
|
||||
const settings = options.settings ?? Settings.isolated();
|
||||
// Per-agent advisor: the agent definition's `advisor` frontmatter or the
|
||||
// `task.agentAdvisor` settings override (agent name → "on"/"off"/model
|
||||
// pattern) pairs the spawned session with an advisor. Subagents default to
|
||||
// no advisor (createSubagentSettings forces `advisor.enabled` off); an
|
||||
// explicit model pattern lands on the child's `modelRoles.advisor` so role
|
||||
// aliases and `:level` suffixes resolve inside the spawned session.
|
||||
const advisorSelection = resolveAgentAdvisorSelection({
|
||||
settingsOverride: settings.get("task.agentAdvisor")[agent.name],
|
||||
agentAdvisor: agent.advisor,
|
||||
});
|
||||
const subagentSettings = createSubagentSettings(
|
||||
settings,
|
||||
{
|
||||
...(agent.readSummarize === false ? { "read.summarize.enabled": false } : undefined),
|
||||
// Isolated runs must not expose roots outside the worktree.
|
||||
...(worktree !== undefined ? { "workspace.additionalDirectories": [] } : undefined),
|
||||
...(advisorSelection ? { "advisor.enabled": true } : undefined),
|
||||
...(advisorSelection?.model
|
||||
? { modelRoles: { ...settings.getModelRoles(), advisor: advisorSelection.model } }
|
||||
: undefined),
|
||||
},
|
||||
options.parentServiceTier,
|
||||
);
|
||||
@@ -3197,6 +3215,7 @@ export async function runSubprocess(options: ExecutorOptions): Promise<SingleRes
|
||||
readOnly: isReadOnlyAgent(agent),
|
||||
spawns: spawnsEnv,
|
||||
readSummarize: agent.readSummarize,
|
||||
advisor: advisorSelection ? (advisorSelection.model ?? "on") : undefined,
|
||||
outputSchema,
|
||||
outputSchemaMode: options.outputSchemaMode,
|
||||
restrictToolNames: restrictToolNames || undefined,
|
||||
|
||||
Reference in New Issue
Block a user