diff --git a/packages/coding-agent/src/sdk.ts b/packages/coding-agent/src/sdk.ts index c33a68a19..009c532b6 100644 --- a/packages/coding-agent/src/sdk.ts +++ b/packages/coding-agent/src/sdk.ts @@ -2792,6 +2792,7 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {} ...(settings.get("disabledExtensions") ?? []), ]); toolSession.contextFiles = contextFiles; + session.setAdvisorContextPrompt(formatAdvisorContextPrompt(contextFiles)); } const memoryBackend = restrictToolNames ? undefined : await resolveMemoryBackend(settings); const memoryInstructions = memoryBackend diff --git a/packages/coding-agent/src/session/agent-session.ts b/packages/coding-agent/src/session/agent-session.ts index e3f097cff..83e7e36e5 100644 --- a/packages/coding-agent/src/session/agent-session.ts +++ b/packages/coding-agent/src/session/agent-session.ts @@ -8719,6 +8719,15 @@ export class AgentSession { return this.#advisors.applyAdvisorConfigs(advisors, sharedInstructions); } + /** + * Refresh the project context prompt advisor sessions run against after + * context files change on `/reload-plugins`. Rebuilds live advisor runtimes so + * they stop evaluating turns against stale `AGENTS.md` instructions. + */ + setAdvisorContextPrompt(contextPrompt: string | undefined): void { + this.#advisors.setContextPrompt(contextPrompt); + } + /** * Whether the advisor setting is enabled for this session. */ diff --git a/packages/coding-agent/src/session/session-advisors.ts b/packages/coding-agent/src/session/session-advisors.ts index 97e6751ed..f30a411aa 100644 --- a/packages/coding-agent/src/session/session-advisors.ts +++ b/packages/coding-agent/src/session/session-advisors.ts @@ -1579,6 +1579,20 @@ export class SessionAdvisors { return this.#advisors.length; } + /** + * Swap the project context prompt handed to advisor sessions after context + * files change (`/reload-plugins` edit/disable). Rebuilds live runtimes in + * place so the next advisor turn evaluates against the current instructions; + * a no-op when the rendered prompt is unchanged. + */ + setContextPrompt(contextPrompt: string | undefined): void { + if (contextPrompt === this.#advisorContextPrompt) return; + this.#advisorContextPrompt = contextPrompt; + if (!this.#advisorEnabled || this.#advisors.length === 0) return; + this.#stopAdvisorRuntime(); + this.#buildAdvisorRuntime(true); + } + /** * Whether the advisor setting is enabled for this session. */ diff --git a/packages/coding-agent/test/sdk-context-file-refresh.test.ts b/packages/coding-agent/test/sdk-context-file-refresh.test.ts index 02d0ee665..913f4a15a 100644 --- a/packages/coding-agent/test/sdk-context-file-refresh.test.ts +++ b/packages/coding-agent/test/sdk-context-file-refresh.test.ts @@ -16,8 +16,15 @@ const PROJECT_CONTEXT_EXTENSION_ID = "context-file:project:AGENTS.md"; async function createContextSession( cwd: string, settings: Settings, + options: { advisor?: boolean } = {}, ): Promise<{ session: AgentSession; authStorage: AuthStorage }> { const authStorage = await AuthStorage.create(`${cwd}/auth.db`); + const model = getBundledModel("openai", "gpt-4o-mini"); + if (options.advisor) { + authStorage.setRuntimeApiKey("openai", "test-key"); + settings.set("advisor.enabled", true); + settings.setModelRole("advisor", `${model.provider}/${model.id}`); + } const modelRegistry = new ModelRegistry(authStorage); const { session } = await createAgentSession({ cwd, @@ -25,7 +32,7 @@ async function createContextSession( modelRegistry, sessionManager: SessionManager.inMemory(cwd), settings, - model: getBundledModel("openai", "gpt-4o-mini"), + model, disableExtensionDiscovery: true, promptTemplates: [], slashCommands: [], @@ -99,4 +106,29 @@ describe("context-file prompt refresh", () => { authStorage.close(); } }); + + it("refreshes the advisor context prompt when context files change", async () => { + using tempDir = TempDir.createSync("@omp-context-refresh-advisor-"); + const contextPath = tempDir.join("AGENTS.md"); + await Bun.write(contextPath, INITIAL_CONTEXT); + const { session, authStorage } = await createContextSession(tempDir.path(), Settings.isolated({}), { + advisor: true, + }); + + try { + const advisorPrompt = () => session.getAdvisorAgent()?.state.systemPrompt.join("\n") ?? ""; + expect(session.isAdvisorActive()).toBe(true); + expect(advisorPrompt()).toContain(INITIAL_CONTEXT); + + await Bun.write(contextPath, UPDATED_CONTEXT); + await session.refreshSkills(); + + const refreshed = advisorPrompt(); + expect(refreshed).toContain(UPDATED_CONTEXT); + expect(refreshed).not.toContain(INITIAL_CONTEXT); + } finally { + await session.dispose(); + authStorage.close(); + } + }); });