diff --git a/src/CodexAcpClient.ts b/src/CodexAcpClient.ts index 2ea875b5..01ed13c0 100644 --- a/src/CodexAcpClient.ts +++ b/src/CodexAcpClient.ts @@ -13,6 +13,7 @@ import type {Disposable} from "vscode-jsonrpc"; import type { ClientInfo, ReasoningEffort, + ReasoningSummary, ServiceTier, ServerNotification } from "./app-server"; @@ -672,7 +673,8 @@ export class CodexAcpClient { input: input, approvalPolicy: agentMode.approvalPolicy, sandboxPolicy: addAdditionalDirectoriesToSandboxPolicy(agentMode.sandboxPolicy, additionalDirectories), - summary: disableSummary ? "none" : "auto", + // Preserve safety overrides while honoring CODEX_CONFIG. + summary: resolveReasoningSummary(this.config, disableSummary), effort: effort, model: modelId.model, serviceTier: serviceTier, @@ -841,6 +843,22 @@ export class CodexAcpClient { export type JsonObject = { [key in string]?: JsonValue } +function resolveReasoningSummary(config: JsonObject, disableSummary: boolean): ReasoningSummary { + if (disableSummary) { + return "none"; + } + + switch (config["model_reasoning_summary"]) { + case "auto": + case "concise": + case "detailed": + case "none": + return config["model_reasoning_summary"]; + default: + return "auto"; + } +} + export type SessionMetadata = { sessionId: string, currentModelId: string, diff --git a/src/__tests__/CodexACPAgent/CodexAcpClient.test.ts b/src/__tests__/CodexACPAgent/CodexAcpClient.test.ts index 255d4ab2..87e832e1 100644 --- a/src/__tests__/CodexACPAgent/CodexAcpClient.test.ts +++ b/src/__tests__/CodexACPAgent/CodexAcpClient.test.ts @@ -16,6 +16,7 @@ import {AgentMode} from "../../AgentMode"; import type {Model, ReviewStartResponse, ThreadGoal, TurnCompletedNotification, TurnStartParams} from "../../app-server/v2"; import type {RateLimitsMap} from "../../RateLimitsMap"; import {ModelId} from "../../ModelId"; +import {CodexAcpClient} from "../../CodexAcpClient"; describe('ACP server test', { timeout: 40_000 }, () => { @@ -3057,14 +3058,25 @@ describe('ACP server test', { timeout: 40_000 }, () => { expect(turnStartSpy).toHaveBeenCalledWith(expect.objectContaining({ summary: "none" })); }); - it ('should enable reasoning.summary by default', async () => { - const { mockFixture, turnStartSpy } = setupPromptFixture({ - account: { type: "chatgpt", email: "test@example.com", planType: "pro" }, - }); + // Explicit adapter config must override the default summary mode. + it ('should prefer CODEX_CONFIG reasoning.summary', async () => { + const { mockFixture, turnStartSpy } = setupPromptFixture(); + const configuredClient = new CodexAcpClient( + mockFixture.getCodexAppServerClient(), + {model_reasoning_summary: "detailed"}, + ); - await mockFixture.getCodexAcpAgent().prompt({ sessionId: "id", prompt: [{ type: "text", text: "test" }] }); + await configuredClient.sendPrompt( + {sessionId: "id", prompt: [{type: "text", text: "test"}]}, + AgentMode.DEFAULT_AGENT_MODE, + ModelId.create("model-id", "medium"), + null, + false, + "/test/cwd", + [], + ); - expect(turnStartSpy).toHaveBeenCalledWith(expect.objectContaining({ summary: "auto" })); + expect(turnStartSpy).toHaveBeenCalledWith(expect.objectContaining({summary: "detailed"})); }); it ('should disable reasoning.summary when model lacks reasoning', async () => { @@ -3078,7 +3090,7 @@ describe('ACP server test', { timeout: 40_000 }, () => { expect(turnStartSpy).toHaveBeenCalledWith(expect.objectContaining({ summary: "none" })); }); - it ('should enable reasoning.summary when model supports reasoning', async () => { + it ('should use auto reasoning.summary by default when model supports reasoning', async () => { const { mockFixture, turnStartSpy } = setupPromptFixture({ account: { type: "chatgpt", email: "test@example.com", planType: "pro" }, supportedReasoningEfforts: [ @@ -3089,7 +3101,7 @@ describe('ACP server test', { timeout: 40_000 }, () => { await mockFixture.getCodexAcpAgent().prompt({ sessionId: "id", prompt: [{ type: "text", text: "test" }] }); - expect(turnStartSpy).toHaveBeenCalledWith(expect.objectContaining({ summary: "auto" })); + expect(turnStartSpy).toHaveBeenCalledWith(expect.objectContaining({summary: "auto"})); }); it ('should reject prompt with images when model does not support image input', async () => {