Skip to content

Commit bb3048b

Browse files
committed
Add requestId to device code auth elicitation requests
1 parent 76b5588 commit bb3048b

14 files changed

Lines changed: 226 additions & 198 deletions

src/CodexAcpClient.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ export class CodexAcpClient {
8282
async authenticate(
8383
connection: AcpClientConnection,
8484
authRequest: acp.AuthenticateRequest,
85+
requestId: acp.JsonRpcId,
8586
env: NodeJS.ProcessEnv = process.env,
8687
): Promise<Boolean> {
8788
if (!isCodexAuthRequest(authRequest)) {
@@ -100,7 +101,7 @@ export class CodexAcpClient {
100101
return true;
101102
}
102103
if (env["NO_BROWSER"]) {
103-
return await this.authenticateWithChatGptDeviceCode(connection);
104+
return await this.authenticateWithChatGptDeviceCode(connection, requestId);
104105
} else {
105106
return await this.authenticateWithChatGptBrowser();
106107
}
@@ -151,14 +152,15 @@ export class CodexAcpClient {
151152
return result.success;
152153
}
153154

154-
private async authenticateWithChatGptDeviceCode(connection: AcpClientConnection): Promise<Boolean> {
155+
private async authenticateWithChatGptDeviceCode(connection: AcpClientConnection, requestId: acp.JsonRpcId): Promise<Boolean> {
155156
const loginCompletedPromise = this.awaitNextLoginCompleted();
156157
const loginResponse = await this.codexClient.accountLogin({type: "chatgptDeviceCode"});
157158
if (loginResponse.type == "chatgptDeviceCode") {
158159
const url = loginResponse.verificationUrl;
159160
const userCode = loginResponse.userCode;
160161

161162
await this.requestDeviceCodeAuth(connection, {
163+
requestId,
162164
elicitationId: `chatgpt-login-${crypto.randomUUID()}`,
163165
url,
164166
message: `Follow these steps to sign in with ChatGPT using device code authorization:\n\
@@ -174,15 +176,13 @@ export class CodexAcpClient {
174176

175177
private async requestDeviceCodeAuth(
176178
client: AcpClientConnection,
177-
request: { elicitationId: string; url: string; message: string },
179+
request: { requestId: acp.JsonRpcId, elicitationId: string; url: string; message: string },
178180
): Promise<void> {
179181
const response = await client.request(
180182
acp.methods.client.elicitation.create,
181183
{
182184
mode: "url",
183-
// This should be the authenticate requestId, but this is not exposed by the ACP SDK.
184-
// The elicitation still works, but won't be tied to the authenticate request.
185-
requestId: null,
185+
requestId: request.requestId,
186186
elicitationId: request.elicitationId,
187187
url: request.url,
188188
message: request.message,

src/CodexAcpServer.ts

Lines changed: 31 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -233,15 +233,15 @@ export class CodexAcpServer {
233233
}
234234
}
235235

236-
async checkAuthorization(){
236+
async checkAuthorization(requestId: acp.JsonRpcId){
237237
const authNeeded = await this.runWithProcessCheck(() => this.codexAcpClient.authRequired());
238238
logger.log("Auth requirement checked", {authRequired: authNeeded});
239239
if (authNeeded) {
240240
if (this.defaultAuthRequest) {
241241
logger.log("Authenticating with default auth request...", {
242242
authRequest: this.defaultAuthRequest
243243
});
244-
await this.authenticate(this.defaultAuthRequest)
244+
await this.authenticate(this.defaultAuthRequest, requestId);
245245
logger.log("Authentication completed");
246246
} else {
247247
logger.log("Authentication required but no default auth request provided, return to IDE");
@@ -250,9 +250,12 @@ export class CodexAcpServer {
250250
}
251251
}
252252

253-
async getOrCreateSession(request: acp.NewSessionRequest | acp.ResumeSessionRequest): Promise<[SessionId, LegacySessionModelState, SessionModeState]> {
253+
async getOrCreateSession(
254+
request: acp.NewSessionRequest | acp.ResumeSessionRequest,
255+
requestId: acp.JsonRpcId,
256+
): Promise<[SessionId, LegacySessionModelState, SessionModeState]> {
254257
try {
255-
return await this.tryCreateSession(request);
258+
return await this.tryCreateSession(request, requestId);
256259
} catch (e) {
257260
const error = e instanceof Error ? e : new Error(String(e));
258261
await this.handleError(error);
@@ -331,11 +334,14 @@ export class CodexAcpServer {
331334
return generation;
332335
}
333336

334-
async tryCreateSession(request: acp.NewSessionRequest | acp.ResumeSessionRequest): Promise<[SessionId, LegacySessionModelState, SessionModeState]> {
337+
async tryCreateSession(
338+
request: acp.NewSessionRequest | acp.ResumeSessionRequest,
339+
requestId: acp.JsonRpcId,
340+
): Promise<[SessionId, LegacySessionModelState, SessionModeState]> {
335341
const requestedSessionGeneration = "sessionId" in request
336342
? this.beginSessionOpen(request.sessionId)
337343
: null;
338-
await this.checkAuthorization();
344+
await this.checkAuthorization(requestId);
339345
const requestedMcpServers = request.mcpServers ?? [];
340346
const mcpServerStartupVersion = requestedMcpServers.length > 0
341347
? this.codexAcpClient.getMcpServerStartupVersion()
@@ -453,14 +459,17 @@ export class CodexAcpServer {
453459
return null;
454460
}
455461

456-
async loadSession(params: acp.LoadSessionRequest): Promise<LegacyLoadSessionResponse> {
462+
async loadSession(
463+
params: acp.LoadSessionRequest,
464+
requestId: acp.JsonRpcId,
465+
): Promise<LegacyLoadSessionResponse> {
457466
logger.log("Loading session...", {sessionId: params.sessionId});
458467
const {
459468
sessionId,
460469
modelState,
461470
modeState,
462471
thread,
463-
} = await this.getOrCreateSessionWithHistory(params);
472+
} = await this.getOrCreateSessionWithHistory(params, requestId);
464473

465474
await this.streamThreadHistory(sessionId, thread);
466475

@@ -476,9 +485,12 @@ export class CodexAcpServer {
476485
};
477486
}
478487

479-
async resumeSession(params: acp.ResumeSessionRequest): Promise<LegacyResumeSessionResponse> {
488+
async resumeSession(
489+
params: acp.ResumeSessionRequest,
490+
requestId: acp.JsonRpcId,
491+
): Promise<LegacyResumeSessionResponse> {
480492
logger.log("Resuming session...", {sessionId: params.sessionId});
481-
const [sessionId, modelState, modeState] = await this.getOrCreateSession(params);
493+
const [sessionId, modelState, modeState] = await this.getOrCreateSession(params, requestId);
482494

483495
logger.log("Session resumed", {
484496
sessionId: sessionId,
@@ -492,9 +504,9 @@ export class CodexAcpServer {
492504
};
493505
}
494506

495-
async listSessions(params: acp.ListSessionsRequest): Promise<acp.ListSessionsResponse> {
507+
async listSessions(params: acp.ListSessionsRequest, requestId: acp.JsonRpcId): Promise<acp.ListSessionsResponse> {
496508
logger.log("Listing sessions...", {cwd: params.cwd, cursor: params.cursor});
497-
await this.checkAuthorization();
509+
await this.checkAuthorization(requestId);
498510
const response = await this.runWithProcessCheck(() => this.codexAcpClient.listSessions(params));
499511
return {
500512
...response,
@@ -582,9 +594,10 @@ export class CodexAcpServer {
582594

583595
async newSession(
584596
params: acp.NewSessionRequest,
597+
requestId: acp.JsonRpcId,
585598
): Promise<LegacyNewSessionResponse> {
586599
logger.log("Starting new session...");
587-
const [sessionId, modelState, modeState] = await this.getOrCreateSession(params);
600+
const [sessionId, modelState, modeState] = await this.getOrCreateSession(params, requestId);
588601

589602
logger.log("New session created", {
590603
sessionId: sessionId,
@@ -602,9 +615,10 @@ export class CodexAcpServer {
602615

603616
async authenticate(
604617
_params: acp.AuthenticateRequest,
618+
requestId: acp.JsonRpcId,
605619
): Promise<acp.AuthenticateResponse> {
606620
logger.log("Authenticate request received");
607-
const isAuthenticated = await this.runWithProcessCheck(() => this.codexAcpClient.authenticate(this.connection, _params));
621+
const isAuthenticated = await this.runWithProcessCheck(() => this.codexAcpClient.authenticate(this.connection, _params, requestId));
608622
if (!isAuthenticated) {
609623
logger.log("Authenticate request failed");
610624
throw RequestError.invalidParams();
@@ -838,15 +852,16 @@ export class CodexAcpServer {
838852
}
839853

840854
private async getOrCreateSessionWithHistory(
841-
request: acp.LoadSessionRequest
855+
request: acp.LoadSessionRequest,
856+
requestId: acp.JsonRpcId,
842857
): Promise<{
843858
sessionId: SessionId;
844859
modelState: LegacySessionModelState;
845860
modeState: SessionModeState;
846861
thread: Thread;
847862
}> {
848863
const requestedSessionGeneration = this.beginSessionOpen(request.sessionId);
849-
await this.checkAuthorization();
864+
await this.checkAuthorization(requestId);
850865
const requestedMcpServers = request.mcpServers ?? [];
851866
const mcpServerStartupVersion = requestedMcpServers.length > 0
852867
? this.codexAcpClient.getMcpServerStartupVersion()

0 commit comments

Comments
 (0)