diff --git a/src/CodexAcpClient.ts b/src/CodexAcpClient.ts index f085481..2efb609 100644 --- a/src/CodexAcpClient.ts +++ b/src/CodexAcpClient.ts @@ -300,7 +300,7 @@ export class CodexAcpClient { } } - private getModelProvider(): string | null { + getModelProvider(): string | null { return this.gatewayConfig?.modelProvider ?? this.modelProvider; } diff --git a/src/CodexAcpServer.ts b/src/CodexAcpServer.ts index 3df015e..1a80d6c 100644 --- a/src/CodexAcpServer.ts +++ b/src/CodexAcpServer.ts @@ -1,14 +1,9 @@ import * as acp from "@agentclientprotocol/sdk"; -import { - RequestError, - type SessionId, - type SessionModelState, - type SessionModeState -} from "@agentclientprotocol/sdk"; +import {RequestError, type SessionId, type SessionModelState, type SessionModeState} from "@agentclientprotocol/sdk"; import {CodexEventHandler} from "./CodexEventHandler"; import {CodexApprovalHandler} from "./CodexApprovalHandler"; import {CodexElicitationHandler} from "./CodexElicitationHandler"; -import {getCodexAuthMethods, type CodexAuthRequest} from "./CodexAuthMethod"; +import {type CodexAuthRequest, getCodexAuthMethods} from "./CodexAuthMethod"; import {CodexAcpClient, type SessionMetadata, type SessionMetadataWithThread} from "./CodexAcpClient"; import type {McpStartupResult} from "./CodexAppServerClient"; import {ACPSessionConnection, type UpdateSessionEvent} from "./ACPSessionConnection"; @@ -17,10 +12,10 @@ import type { Account, CollabAgentToolCallStatus, Model, + ReasoningEffortOption, Thread, ThreadItem, - UserInput, - ReasoningEffortOption + UserInput } from "./app-server/v2"; import type {RateLimitsMap} from "./RateLimitsMap"; import {ModelId} from "./ModelId"; @@ -164,7 +159,7 @@ export class CodexAcpServer implements acp.Agent { sessionMetadata = await this.runWithProcessCheck(() => this.codexAcpClient.newSession(request)); } - const accountResponse = await this.runWithProcessCheck(() => this.codexAcpClient.getAccount()); + const account = await this.getActiveAccount(); const {sessionId, currentModelId, models} = sessionMetadata; const sessionMcpServers = this.resolveSessionMcpServers(requestedMcpServers, "sessionId" in request); const currentModel = this.findCurrentModel(models, currentModelId); @@ -179,7 +174,7 @@ export class CodexAcpServer implements acp.Agent { totalTokenUsage: null, modelContextWindow: null, rateLimits: null, - account: accountResponse.account, + account: account, cwd: request.cwd, sessionMcpServers: sessionMcpServers, } @@ -200,6 +195,14 @@ export class CodexAcpServer implements acp.Agent { return [sessionId, sessionModelState, sessionModeState]; } + private async getActiveAccount(){ + if (this.codexAcpClient.getModelProvider()) { + return null + } + const accountResponse = await this.runWithProcessCheck(() => this.codexAcpClient.getAccount()); + return accountResponse.account; + } + async loadSession(params: acp.LoadSessionRequest): Promise { logger.log("Loading session...", {sessionId: params.sessionId}); const { @@ -381,7 +384,7 @@ export class CodexAcpServer implements acp.Agent { this.codexAcpClient.loadSession(request) ); - const accountResponse = await this.runWithProcessCheck(() => this.codexAcpClient.getAccount()); + const account = await this.getActiveAccount(); const {sessionId, currentModelId, models, thread} = sessionMetadata; const sessionMcpServers = this.resolveSessionMcpServers(requestedMcpServers, true); const currentModel = this.findCurrentModel(models, currentModelId); @@ -396,7 +399,7 @@ export class CodexAcpServer implements acp.Agent { totalTokenUsage: null, modelContextWindow: null, rateLimits: null, - account: accountResponse.account, + account: account, cwd: request.cwd, sessionMcpServers: sessionMcpServers, }; diff --git a/src/__tests__/CodexACPAgent/CodexAcpClient.test.ts b/src/__tests__/CodexACPAgent/CodexAcpClient.test.ts index 2427b9e..b0cda9e 100644 --- a/src/__tests__/CodexACPAgent/CodexAcpClient.test.ts +++ b/src/__tests__/CodexACPAgent/CodexAcpClient.test.ts @@ -146,6 +146,60 @@ describe('ACP server test', { timeout: 40_000 }, () => { expect(newSessionResponse.sessionId).toBeDefined() }) + it('should show account in /status for api key auth and hide it for gateway auth', async () => { + const authFixture = createTestFixture(); + const codexAcpAgent = authFixture.getCodexAcpAgent(); + + await codexAcpAgent.initialize({ + protocolVersion: 1, + clientCapabilities: { + auth: { + _meta: { + gateway: true, + } + } + } + }); + await authFixture.getCodexAcpClient().logout(); + + await codexAcpAgent.authenticate({ + methodId: "api-key", + _meta: { "api-key": { apiKey: "TOKEN" } } + }); + const apiKeySession = await codexAcpAgent.newSession({cwd: "", mcpServers: []}); + authFixture.clearAcpConnectionDump(); + + await codexAcpAgent.prompt({ + sessionId: apiKeySession.sessionId, + prompt: [{ type: "text", text: "/status" }] + }); + + const apiKeyStatusDump = authFixture.getAcpConnectionDump([]); + expect(apiKeyStatusDump).toContain("**Account:** API key configured"); + + await codexAcpAgent.authenticate({ + methodId: "gateway", + _meta: { + "gateway": { + baseUrl: "https://www.example.com", + headers: { + "Custom-Auth-Header": "TOKEN" + } + } + } + }); + const gatewaySession = await codexAcpAgent.newSession({cwd: "", mcpServers: []}); + authFixture.clearAcpConnectionDump(); + + await codexAcpAgent.prompt({ + sessionId: gatewaySession.sessionId, + prompt: [{ type: "text", text: "/status" }] + }); + + const gatewayStatusDump = authFixture.getAcpConnectionDump([]); + expect(gatewayStatusDump).toContain("**Account:** not logged in"); + }); + it('supports legacy authentication/logout ext method', async () => { const mockFixture = createCodexMockTestFixture(); const codexAcpAgent = mockFixture.getCodexAcpAgent();