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:
@@ -62,7 +62,12 @@ function createRevivedSession(activeToolNames: string[][]): RevivedSessionHandle
|
||||
return { session, observer: () => observer };
|
||||
}
|
||||
|
||||
async function createPersistedSession(cwd: string, restrictToolNames?: boolean, modelRole?: string): Promise<string> {
|
||||
async function createPersistedSession(
|
||||
cwd: string,
|
||||
restrictToolNames?: boolean,
|
||||
modelRole?: string,
|
||||
advisor?: string,
|
||||
): Promise<string> {
|
||||
const manager = SessionManager.create(cwd, path.join(cwd, "sessions"));
|
||||
const sessionFile = manager.getSessionFile();
|
||||
if (!sessionFile) throw new Error("Expected a persisted session file");
|
||||
@@ -73,6 +78,7 @@ async function createPersistedSession(cwd: string, restrictToolNames?: boolean,
|
||||
restrictToolNames,
|
||||
modelRole,
|
||||
resolvedModel: modelRole ? "anthropic/claude-sonnet-4-5" : undefined,
|
||||
advisor,
|
||||
});
|
||||
manager.appendMessage({
|
||||
role: "assistant",
|
||||
@@ -180,6 +186,32 @@ describe("persisted subagent revival", () => {
|
||||
expect(capturedOptions?.mcpManager).toBe(hostileMcp);
|
||||
expect(capturedOptions?.customTools?.map(tool => tool.name)).toEqual(["mcp__server_read"]);
|
||||
});
|
||||
it("restores the persisted per-agent advisor opt-in on cold revival", async () => {
|
||||
const cwd = makeTempDir("@pi-advisor-revive-");
|
||||
const advisedFile = await createPersistedSession(cwd, undefined, undefined, "moonshot/k3");
|
||||
const roleAdvisedFile = await createPersistedSession(cwd, undefined, undefined, "on");
|
||||
const unadvisedFile = await createPersistedSession(cwd);
|
||||
const captured: Settings[] = [];
|
||||
vi.spyOn(sdkModule, "createAgentSession").mockImplementation(async options => {
|
||||
if (options?.settings) captured.push(options.settings);
|
||||
return { session: createRevivedSession([]).session } as CreateAgentSessionResult;
|
||||
});
|
||||
|
||||
const factory = createFactory(cwd);
|
||||
for (const sessionFile of [advisedFile, roleAdvisedFile, unadvisedFile]) {
|
||||
const ref = createRef(sessionFile);
|
||||
const reviver = await factory(ref);
|
||||
if (!reviver) throw new Error("Expected a persisted reviver");
|
||||
await reviver(ref);
|
||||
}
|
||||
|
||||
const [advised, roleAdvised, unadvised] = captured;
|
||||
expect(advised.get("advisor.enabled")).toBe(true);
|
||||
expect(advised.getModelRole("advisor")).toBe("moonshot/k3");
|
||||
expect(roleAdvised.get("advisor.enabled")).toBe(true);
|
||||
expect(roleAdvised.getModelRole("advisor")).toBeUndefined();
|
||||
expect(unadvised.get("advisor.enabled")).toBe(false);
|
||||
});
|
||||
|
||||
it("restores the persisted custom model role before reopening the session", async () => {
|
||||
const cwd = makeTempDir("@pi-custom-role-revive-");
|
||||
|
||||
Reference in New Issue
Block a user