@agentclientprotocol/codex-acp 0.0.44 → 0.0.46
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +1129 -309
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -14441,6 +14441,7 @@ var AGENT_METHODS = {
|
|
|
14441
14441
|
document_did_save: "document/didSave",
|
|
14442
14442
|
initialize: "initialize",
|
|
14443
14443
|
logout: "logout",
|
|
14444
|
+
mcp_message: "mcp/message",
|
|
14444
14445
|
nes_accept: "nes/accept",
|
|
14445
14446
|
nes_close: "nes/close",
|
|
14446
14447
|
nes_reject: "nes/reject",
|
|
@@ -14451,6 +14452,7 @@ var AGENT_METHODS = {
|
|
|
14451
14452
|
providers_set: "providers/set",
|
|
14452
14453
|
session_cancel: "session/cancel",
|
|
14453
14454
|
session_close: "session/close",
|
|
14455
|
+
session_delete: "session/delete",
|
|
14454
14456
|
session_fork: "session/fork",
|
|
14455
14457
|
session_list: "session/list",
|
|
14456
14458
|
session_load: "session/load",
|
|
@@ -14466,6 +14468,9 @@ var CLIENT_METHODS = {
|
|
|
14466
14468
|
elicitation_create: "elicitation/create",
|
|
14467
14469
|
fs_read_text_file: "fs/read_text_file",
|
|
14468
14470
|
fs_write_text_file: "fs/write_text_file",
|
|
14471
|
+
mcp_connect: "mcp/connect",
|
|
14472
|
+
mcp_disconnect: "mcp/disconnect",
|
|
14473
|
+
mcp_message: "mcp/message",
|
|
14469
14474
|
session_request_permission: "session/request_permission",
|
|
14470
14475
|
session_update: "session/update",
|
|
14471
14476
|
terminal_create: "terminal/create",
|
|
@@ -14551,6 +14556,9 @@ var zCreateTerminalResponse = external_exports.object({
|
|
|
14551
14556
|
_meta: external_exports.record(external_exports.string(), external_exports.unknown()).nullish(),
|
|
14552
14557
|
terminalId: external_exports.string()
|
|
14553
14558
|
});
|
|
14559
|
+
var zDeleteSessionResponse = external_exports.object({
|
|
14560
|
+
_meta: external_exports.record(external_exports.string(), external_exports.unknown()).nullish()
|
|
14561
|
+
});
|
|
14554
14562
|
var zDiff = external_exports.object({
|
|
14555
14563
|
_meta: external_exports.record(external_exports.string(), external_exports.unknown()).nullish(),
|
|
14556
14564
|
newText: external_exports.string(),
|
|
@@ -14564,6 +14572,9 @@ var zDisableProvidersRequest = external_exports.object({
|
|
|
14564
14572
|
var zDisableProvidersResponse = external_exports.object({
|
|
14565
14573
|
_meta: external_exports.record(external_exports.string(), external_exports.unknown()).nullish()
|
|
14566
14574
|
});
|
|
14575
|
+
var zDisconnectMcpResponse = external_exports.object({
|
|
14576
|
+
_meta: external_exports.record(external_exports.string(), external_exports.unknown()).nullish()
|
|
14577
|
+
});
|
|
14567
14578
|
var zElicitationContentValue = external_exports.union([
|
|
14568
14579
|
external_exports.string(),
|
|
14569
14580
|
external_exports.number(),
|
|
@@ -14669,7 +14680,6 @@ var zListProvidersRequest = external_exports.object({
|
|
|
14669
14680
|
});
|
|
14670
14681
|
var zListSessionsRequest = external_exports.object({
|
|
14671
14682
|
_meta: external_exports.record(external_exports.string(), external_exports.unknown()).nullish(),
|
|
14672
|
-
additionalDirectories: external_exports.array(external_exports.string()).optional(),
|
|
14673
14683
|
cursor: external_exports.string().nullish(),
|
|
14674
14684
|
cwd: external_exports.string().nullish()
|
|
14675
14685
|
});
|
|
@@ -14696,9 +14706,29 @@ var zLogoutResponse = external_exports.object({
|
|
|
14696
14706
|
});
|
|
14697
14707
|
var zMcpCapabilities = external_exports.object({
|
|
14698
14708
|
_meta: external_exports.record(external_exports.string(), external_exports.unknown()).nullish(),
|
|
14709
|
+
acp: external_exports.boolean().optional().default(false),
|
|
14699
14710
|
http: external_exports.boolean().optional().default(false),
|
|
14700
14711
|
sse: external_exports.boolean().optional().default(false)
|
|
14701
14712
|
});
|
|
14713
|
+
var zMcpConnectionId = external_exports.string();
|
|
14714
|
+
var zConnectMcpResponse = external_exports.object({
|
|
14715
|
+
_meta: external_exports.record(external_exports.string(), external_exports.unknown()).nullish(),
|
|
14716
|
+
connectionId: zMcpConnectionId
|
|
14717
|
+
});
|
|
14718
|
+
var zDisconnectMcpRequest = external_exports.object({
|
|
14719
|
+
_meta: external_exports.record(external_exports.string(), external_exports.unknown()).nullish(),
|
|
14720
|
+
connectionId: zMcpConnectionId
|
|
14721
|
+
});
|
|
14722
|
+
var zMcpServerAcpId = external_exports.string();
|
|
14723
|
+
var zConnectMcpRequest = external_exports.object({
|
|
14724
|
+
_meta: external_exports.record(external_exports.string(), external_exports.unknown()).nullish(),
|
|
14725
|
+
acpId: zMcpServerAcpId
|
|
14726
|
+
});
|
|
14727
|
+
var zMcpServerAcp = external_exports.object({
|
|
14728
|
+
_meta: external_exports.record(external_exports.string(), external_exports.unknown()).nullish(),
|
|
14729
|
+
id: zMcpServerAcpId,
|
|
14730
|
+
name: external_exports.string()
|
|
14731
|
+
});
|
|
14702
14732
|
var zMcpServerHttp = external_exports.object({
|
|
14703
14733
|
_meta: external_exports.record(external_exports.string(), external_exports.unknown()).nullish(),
|
|
14704
14734
|
headers: external_exports.array(zHttpHeader),
|
|
@@ -14725,8 +14755,24 @@ var zMcpServer = external_exports.union([
|
|
|
14725
14755
|
zMcpServerSse.and(external_exports.object({
|
|
14726
14756
|
type: external_exports.literal("sse")
|
|
14727
14757
|
})),
|
|
14758
|
+
zMcpServerAcp.and(external_exports.object({
|
|
14759
|
+
type: external_exports.literal("acp")
|
|
14760
|
+
})),
|
|
14728
14761
|
zMcpServerStdio
|
|
14729
14762
|
]);
|
|
14763
|
+
var zMessageMcpNotification = external_exports.object({
|
|
14764
|
+
_meta: external_exports.record(external_exports.string(), external_exports.unknown()).nullish(),
|
|
14765
|
+
connectionId: zMcpConnectionId,
|
|
14766
|
+
method: external_exports.string(),
|
|
14767
|
+
params: external_exports.record(external_exports.string(), external_exports.unknown()).nullish()
|
|
14768
|
+
});
|
|
14769
|
+
var zMessageMcpRequest = external_exports.object({
|
|
14770
|
+
_meta: external_exports.record(external_exports.string(), external_exports.unknown()).nullish(),
|
|
14771
|
+
connectionId: zMcpConnectionId,
|
|
14772
|
+
method: external_exports.string(),
|
|
14773
|
+
params: external_exports.record(external_exports.string(), external_exports.unknown()).nullish()
|
|
14774
|
+
});
|
|
14775
|
+
var zMessageMcpResponse = external_exports.unknown();
|
|
14730
14776
|
var zModelId = external_exports.string();
|
|
14731
14777
|
var zModelInfo = external_exports.object({
|
|
14732
14778
|
_meta: external_exports.record(external_exports.string(), external_exports.unknown()).nullish(),
|
|
@@ -15134,6 +15180,9 @@ var zConfigOptionUpdate = external_exports.object({
|
|
|
15134
15180
|
_meta: external_exports.record(external_exports.string(), external_exports.unknown()).nullish(),
|
|
15135
15181
|
configOptions: external_exports.array(zSessionConfigOption)
|
|
15136
15182
|
});
|
|
15183
|
+
var zSessionDeleteCapabilities = external_exports.object({
|
|
15184
|
+
_meta: external_exports.record(external_exports.string(), external_exports.unknown()).nullish()
|
|
15185
|
+
});
|
|
15137
15186
|
var zSessionForkCapabilities = external_exports.object({
|
|
15138
15187
|
_meta: external_exports.record(external_exports.string(), external_exports.unknown()).nullish()
|
|
15139
15188
|
});
|
|
@@ -15164,6 +15213,10 @@ var zCreateTerminalRequest = external_exports.object({
|
|
|
15164
15213
|
outputByteLimit: external_exports.number().nullish(),
|
|
15165
15214
|
sessionId: zSessionId
|
|
15166
15215
|
});
|
|
15216
|
+
var zDeleteSessionRequest = external_exports.object({
|
|
15217
|
+
_meta: external_exports.record(external_exports.string(), external_exports.unknown()).nullish(),
|
|
15218
|
+
sessionId: zSessionId
|
|
15219
|
+
});
|
|
15167
15220
|
var zDidCloseDocumentNotification = external_exports.object({
|
|
15168
15221
|
_meta: external_exports.record(external_exports.string(), external_exports.unknown()).nullish(),
|
|
15169
15222
|
sessionId: zSessionId,
|
|
@@ -15313,6 +15366,7 @@ var zSessionCapabilities = external_exports.object({
|
|
|
15313
15366
|
_meta: external_exports.record(external_exports.string(), external_exports.unknown()).nullish(),
|
|
15314
15367
|
additionalDirectories: zSessionAdditionalDirectoriesCapabilities.nullish(),
|
|
15315
15368
|
close: zSessionCloseCapabilities.nullish(),
|
|
15369
|
+
delete: zSessionDeleteCapabilities.nullish(),
|
|
15316
15370
|
fork: zSessionForkCapabilities.nullish(),
|
|
15317
15371
|
list: zSessionListCapabilities.nullish(),
|
|
15318
15372
|
resume: zSessionResumeCapabilities.nullish()
|
|
@@ -15455,6 +15509,7 @@ var zClientNotification = external_exports.object({
|
|
|
15455
15509
|
zDidFocusDocumentNotification,
|
|
15456
15510
|
zAcceptNesNotification,
|
|
15457
15511
|
zRejectNesNotification,
|
|
15512
|
+
zMessageMcpNotification,
|
|
15458
15513
|
zExtNotification
|
|
15459
15514
|
]).nullish()
|
|
15460
15515
|
});
|
|
@@ -15487,7 +15542,11 @@ var zAgentCapabilities = external_exports.object({
|
|
|
15487
15542
|
_meta: external_exports.record(external_exports.string(), external_exports.unknown()).nullish(),
|
|
15488
15543
|
auth: zAgentAuthCapabilities.optional().default({}),
|
|
15489
15544
|
loadSession: external_exports.boolean().optional().default(false),
|
|
15490
|
-
mcpCapabilities: zMcpCapabilities.optional().default({
|
|
15545
|
+
mcpCapabilities: zMcpCapabilities.optional().default({
|
|
15546
|
+
acp: false,
|
|
15547
|
+
http: false,
|
|
15548
|
+
sse: false
|
|
15549
|
+
}),
|
|
15491
15550
|
nes: zNesCapabilities.nullish(),
|
|
15492
15551
|
positionEncoding: zPositionEncodingKind.nullish(),
|
|
15493
15552
|
promptCapabilities: zPromptCapabilities.optional().default({
|
|
@@ -15503,7 +15562,11 @@ var zInitializeResponse = external_exports.object({
|
|
|
15503
15562
|
agentCapabilities: zAgentCapabilities.optional().default({
|
|
15504
15563
|
auth: {},
|
|
15505
15564
|
loadSession: false,
|
|
15506
|
-
mcpCapabilities: {
|
|
15565
|
+
mcpCapabilities: {
|
|
15566
|
+
acp: false,
|
|
15567
|
+
http: false,
|
|
15568
|
+
sse: false
|
|
15569
|
+
},
|
|
15507
15570
|
promptCapabilities: {
|
|
15508
15571
|
audio: false,
|
|
15509
15572
|
embeddedContext: false,
|
|
@@ -15734,6 +15797,7 @@ var zAgentResponse = external_exports.union([
|
|
|
15734
15797
|
zNewSessionResponse,
|
|
15735
15798
|
zLoadSessionResponse,
|
|
15736
15799
|
zListSessionsResponse,
|
|
15800
|
+
zDeleteSessionResponse,
|
|
15737
15801
|
zForkSessionResponse,
|
|
15738
15802
|
zResumeSessionResponse,
|
|
15739
15803
|
zCloseSessionResponse,
|
|
@@ -15744,7 +15808,8 @@ var zAgentResponse = external_exports.union([
|
|
|
15744
15808
|
zStartNesResponse,
|
|
15745
15809
|
zSuggestNesResponse,
|
|
15746
15810
|
zCloseNesResponse,
|
|
15747
|
-
zExtResponse
|
|
15811
|
+
zExtResponse,
|
|
15812
|
+
zMessageMcpResponse
|
|
15748
15813
|
])
|
|
15749
15814
|
}),
|
|
15750
15815
|
external_exports.object({
|
|
@@ -15803,6 +15868,7 @@ var zAgentNotification = external_exports.object({
|
|
|
15803
15868
|
params: external_exports.union([
|
|
15804
15869
|
zSessionNotification,
|
|
15805
15870
|
zCompleteElicitationNotification,
|
|
15871
|
+
zMessageMcpNotification,
|
|
15806
15872
|
zExtNotification
|
|
15807
15873
|
]).nullish()
|
|
15808
15874
|
});
|
|
@@ -15841,6 +15907,7 @@ var zClientRequest = external_exports.object({
|
|
|
15841
15907
|
zNewSessionRequest,
|
|
15842
15908
|
zLoadSessionRequest,
|
|
15843
15909
|
zListSessionsRequest,
|
|
15910
|
+
zDeleteSessionRequest,
|
|
15844
15911
|
zForkSessionRequest,
|
|
15845
15912
|
zResumeSessionRequest,
|
|
15846
15913
|
zCloseSessionRequest,
|
|
@@ -15851,6 +15918,7 @@ var zClientRequest = external_exports.object({
|
|
|
15851
15918
|
zStartNesRequest,
|
|
15852
15919
|
zSuggestNesRequest,
|
|
15853
15920
|
zCloseNesRequest,
|
|
15921
|
+
zMessageMcpRequest,
|
|
15854
15922
|
zExtRequest
|
|
15855
15923
|
]).nullish()
|
|
15856
15924
|
});
|
|
@@ -15873,6 +15941,9 @@ var zAgentRequest = external_exports.object({
|
|
|
15873
15941
|
zWaitForTerminalExitRequest,
|
|
15874
15942
|
zKillTerminalRequest,
|
|
15875
15943
|
zCreateElicitationRequest,
|
|
15944
|
+
zConnectMcpRequest,
|
|
15945
|
+
zMessageMcpRequest,
|
|
15946
|
+
zDisconnectMcpRequest,
|
|
15876
15947
|
zExtRequest
|
|
15877
15948
|
]).nullish()
|
|
15878
15949
|
});
|
|
@@ -15892,7 +15963,10 @@ var zClientResponse = external_exports.union([
|
|
|
15892
15963
|
zWaitForTerminalExitResponse,
|
|
15893
15964
|
zKillTerminalResponse,
|
|
15894
15965
|
zCreateElicitationResponse,
|
|
15895
|
-
|
|
15966
|
+
zConnectMcpResponse,
|
|
15967
|
+
zDisconnectMcpResponse,
|
|
15968
|
+
zExtResponse,
|
|
15969
|
+
zMessageMcpResponse
|
|
15896
15970
|
])
|
|
15897
15971
|
}),
|
|
15898
15972
|
external_exports.object({
|
|
@@ -15967,6 +16041,15 @@ function ndJsonStream(output, input) {
|
|
|
15967
16041
|
}
|
|
15968
16042
|
|
|
15969
16043
|
// node_modules/@agentclientprotocol/sdk/dist/acp.js
|
|
16044
|
+
function emptyObjectResponse(response) {
|
|
16045
|
+
return response ?? {};
|
|
16046
|
+
}
|
|
16047
|
+
function rejectedPromise(error40) {
|
|
16048
|
+
const promise2 = Promise.reject(error40);
|
|
16049
|
+
promise2.catch(() => {
|
|
16050
|
+
});
|
|
16051
|
+
return promise2;
|
|
16052
|
+
}
|
|
15970
16053
|
var AgentSideConnection = class {
|
|
15971
16054
|
connection;
|
|
15972
16055
|
/**
|
|
@@ -16007,6 +16090,14 @@ var AgentSideConnection = class {
|
|
|
16007
16090
|
const validatedParams = zListSessionsRequest.parse(params);
|
|
16008
16091
|
return agent.listSessions(validatedParams);
|
|
16009
16092
|
}
|
|
16093
|
+
case AGENT_METHODS.session_delete: {
|
|
16094
|
+
if (!agent.unstable_deleteSession) {
|
|
16095
|
+
throw RequestError.methodNotFound(method);
|
|
16096
|
+
}
|
|
16097
|
+
const validatedParams = zDeleteSessionRequest.parse(params);
|
|
16098
|
+
const result = await agent.unstable_deleteSession(validatedParams);
|
|
16099
|
+
return result ?? {};
|
|
16100
|
+
}
|
|
16010
16101
|
case AGENT_METHODS.session_fork: {
|
|
16011
16102
|
if (!agent.unstable_forkSession) {
|
|
16012
16103
|
throw RequestError.methodNotFound(method);
|
|
@@ -16191,8 +16282,8 @@ var AgentSideConnection = class {
|
|
|
16191
16282
|
*
|
|
16192
16283
|
* See protocol docs: [Agent Reports Output](https://agentclientprotocol.com/protocol/prompt-turn#3-agent-reports-output)
|
|
16193
16284
|
*/
|
|
16194
|
-
|
|
16195
|
-
return
|
|
16285
|
+
sessionUpdate(params) {
|
|
16286
|
+
return this.connection.sendNotification(CLIENT_METHODS.session_update, params);
|
|
16196
16287
|
}
|
|
16197
16288
|
/**
|
|
16198
16289
|
* Requests permission from the user for a tool call operation.
|
|
@@ -16206,8 +16297,8 @@ var AgentSideConnection = class {
|
|
|
16206
16297
|
*
|
|
16207
16298
|
* See protocol docs: [Requesting Permission](https://agentclientprotocol.com/protocol/tool-calls#requesting-permission)
|
|
16208
16299
|
*/
|
|
16209
|
-
|
|
16210
|
-
return
|
|
16300
|
+
requestPermission(params) {
|
|
16301
|
+
return this.connection.sendRequest(CLIENT_METHODS.session_request_permission, params);
|
|
16211
16302
|
}
|
|
16212
16303
|
/**
|
|
16213
16304
|
* Reads content from a text file in the client's file system.
|
|
@@ -16217,8 +16308,8 @@ var AgentSideConnection = class {
|
|
|
16217
16308
|
*
|
|
16218
16309
|
* See protocol docs: [Client](https://agentclientprotocol.com/protocol/overview#client)
|
|
16219
16310
|
*/
|
|
16220
|
-
|
|
16221
|
-
return
|
|
16311
|
+
readTextFile(params) {
|
|
16312
|
+
return this.connection.sendRequest(CLIENT_METHODS.fs_read_text_file, params);
|
|
16222
16313
|
}
|
|
16223
16314
|
/**
|
|
16224
16315
|
* Writes content to a text file in the client's file system.
|
|
@@ -16228,8 +16319,8 @@ var AgentSideConnection = class {
|
|
|
16228
16319
|
*
|
|
16229
16320
|
* See protocol docs: [Client](https://agentclientprotocol.com/protocol/overview#client)
|
|
16230
16321
|
*/
|
|
16231
|
-
|
|
16232
|
-
return
|
|
16322
|
+
writeTextFile(params) {
|
|
16323
|
+
return this.connection.sendRequest(CLIENT_METHODS.fs_write_text_file, params, emptyObjectResponse);
|
|
16233
16324
|
}
|
|
16234
16325
|
/**
|
|
16235
16326
|
* Executes a command in a new terminal.
|
|
@@ -16243,9 +16334,8 @@ var AgentSideConnection = class {
|
|
|
16243
16334
|
* @param params - The terminal creation parameters
|
|
16244
16335
|
* @returns A handle to control and monitor the terminal
|
|
16245
16336
|
*/
|
|
16246
|
-
|
|
16247
|
-
|
|
16248
|
-
return new TerminalHandle(response.terminalId, params.sessionId, this.connection);
|
|
16337
|
+
createTerminal(params) {
|
|
16338
|
+
return this.connection.sendRequest(CLIENT_METHODS.terminal_create, params, (response) => new TerminalHandle(response.terminalId, params.sessionId, this.connection));
|
|
16249
16339
|
}
|
|
16250
16340
|
/**
|
|
16251
16341
|
* **UNSTABLE**
|
|
@@ -16256,8 +16346,8 @@ var AgentSideConnection = class {
|
|
|
16256
16346
|
*
|
|
16257
16347
|
* @experimental
|
|
16258
16348
|
*/
|
|
16259
|
-
|
|
16260
|
-
return
|
|
16349
|
+
unstable_createElicitation(params) {
|
|
16350
|
+
return this.connection.sendRequest(CLIENT_METHODS.elicitation_create, params);
|
|
16261
16351
|
}
|
|
16262
16352
|
/**
|
|
16263
16353
|
* **UNSTABLE**
|
|
@@ -16268,24 +16358,24 @@ var AgentSideConnection = class {
|
|
|
16268
16358
|
*
|
|
16269
16359
|
* @experimental
|
|
16270
16360
|
*/
|
|
16271
|
-
|
|
16272
|
-
return
|
|
16361
|
+
unstable_completeElicitation(params) {
|
|
16362
|
+
return this.connection.sendNotification(CLIENT_METHODS.elicitation_complete, params);
|
|
16273
16363
|
}
|
|
16274
16364
|
/**
|
|
16275
16365
|
* Extension method
|
|
16276
16366
|
*
|
|
16277
16367
|
* Allows the Agent to send an arbitrary request that is not part of the ACP spec.
|
|
16278
16368
|
*/
|
|
16279
|
-
|
|
16280
|
-
return
|
|
16369
|
+
extMethod(method, params) {
|
|
16370
|
+
return this.connection.sendRequest(method, params);
|
|
16281
16371
|
}
|
|
16282
16372
|
/**
|
|
16283
16373
|
* Extension notification
|
|
16284
16374
|
*
|
|
16285
16375
|
* Allows the Agent to send an arbitrary notification that is not part of the ACP spec.
|
|
16286
16376
|
*/
|
|
16287
|
-
|
|
16288
|
-
return
|
|
16377
|
+
extNotification(method, params) {
|
|
16378
|
+
return this.connection.sendNotification(method, params);
|
|
16289
16379
|
}
|
|
16290
16380
|
/**
|
|
16291
16381
|
* AbortSignal that aborts when the connection closes.
|
|
@@ -16349,8 +16439,8 @@ var TerminalHandle = class {
|
|
|
16349
16439
|
/**
|
|
16350
16440
|
* Gets the current terminal output without waiting for the command to exit.
|
|
16351
16441
|
*/
|
|
16352
|
-
|
|
16353
|
-
return
|
|
16442
|
+
currentOutput() {
|
|
16443
|
+
return this.connection.sendRequest(CLIENT_METHODS.terminal_output, {
|
|
16354
16444
|
sessionId: this.sessionId,
|
|
16355
16445
|
terminalId: this.id
|
|
16356
16446
|
});
|
|
@@ -16358,8 +16448,8 @@ var TerminalHandle = class {
|
|
|
16358
16448
|
/**
|
|
16359
16449
|
* Waits for the terminal command to complete and returns its exit status.
|
|
16360
16450
|
*/
|
|
16361
|
-
|
|
16362
|
-
return
|
|
16451
|
+
waitForExit() {
|
|
16452
|
+
return this.connection.sendRequest(CLIENT_METHODS.terminal_wait_for_exit, {
|
|
16363
16453
|
sessionId: this.sessionId,
|
|
16364
16454
|
terminalId: this.id
|
|
16365
16455
|
});
|
|
@@ -16374,11 +16464,11 @@ var TerminalHandle = class {
|
|
|
16374
16464
|
*
|
|
16375
16465
|
* Useful for implementing timeouts or cancellation.
|
|
16376
16466
|
*/
|
|
16377
|
-
|
|
16378
|
-
return
|
|
16467
|
+
kill() {
|
|
16468
|
+
return this.connection.sendRequest(CLIENT_METHODS.terminal_kill, {
|
|
16379
16469
|
sessionId: this.sessionId,
|
|
16380
16470
|
terminalId: this.id
|
|
16381
|
-
})
|
|
16471
|
+
}, emptyObjectResponse);
|
|
16382
16472
|
}
|
|
16383
16473
|
/**
|
|
16384
16474
|
* Releases the terminal and frees all associated resources.
|
|
@@ -16392,11 +16482,11 @@ var TerminalHandle = class {
|
|
|
16392
16482
|
*
|
|
16393
16483
|
* **Important:** Always call this method when done with the terminal.
|
|
16394
16484
|
*/
|
|
16395
|
-
|
|
16396
|
-
return
|
|
16485
|
+
release() {
|
|
16486
|
+
return this.connection.sendRequest(CLIENT_METHODS.terminal_release, {
|
|
16397
16487
|
sessionId: this.sessionId,
|
|
16398
16488
|
terminalId: this.id
|
|
16399
|
-
})
|
|
16489
|
+
}, emptyObjectResponse);
|
|
16400
16490
|
}
|
|
16401
16491
|
async [Symbol.asyncDispose]() {
|
|
16402
16492
|
await this.release();
|
|
@@ -16581,25 +16671,36 @@ var Connection = class {
|
|
|
16581
16671
|
console.error("Got response to unknown request", response.id);
|
|
16582
16672
|
}
|
|
16583
16673
|
}
|
|
16584
|
-
sendRequest(method, params) {
|
|
16585
|
-
this.
|
|
16674
|
+
sendRequest(method, params, mapResponse) {
|
|
16675
|
+
if (this.abortController.signal.aborted) {
|
|
16676
|
+
return rejectedPromise(this.closedReason());
|
|
16677
|
+
}
|
|
16586
16678
|
const id = this.nextRequestId++;
|
|
16587
16679
|
const responsePromise = new Promise((resolve, reject) => {
|
|
16588
|
-
this.pendingResponses.set(id, {
|
|
16680
|
+
this.pendingResponses.set(id, {
|
|
16681
|
+
resolve: (response) => {
|
|
16682
|
+
try {
|
|
16683
|
+
resolve(mapResponse ? mapResponse(response) : response);
|
|
16684
|
+
} catch (error40) {
|
|
16685
|
+
reject(error40);
|
|
16686
|
+
}
|
|
16687
|
+
},
|
|
16688
|
+
reject
|
|
16689
|
+
});
|
|
16589
16690
|
});
|
|
16590
16691
|
responsePromise.catch(() => {
|
|
16591
16692
|
});
|
|
16592
16693
|
void this.sendMessage({ jsonrpc: "2.0", id, method, params });
|
|
16593
16694
|
return responsePromise;
|
|
16594
16695
|
}
|
|
16595
|
-
|
|
16596
|
-
this.throwIfClosed();
|
|
16597
|
-
await this.sendMessage({ jsonrpc: "2.0", method, params });
|
|
16598
|
-
}
|
|
16599
|
-
throwIfClosed() {
|
|
16696
|
+
sendNotification(method, params) {
|
|
16600
16697
|
if (this.abortController.signal.aborted) {
|
|
16601
|
-
|
|
16698
|
+
return rejectedPromise(this.closedReason());
|
|
16602
16699
|
}
|
|
16700
|
+
return this.sendMessage({ jsonrpc: "2.0", method, params });
|
|
16701
|
+
}
|
|
16702
|
+
closedReason() {
|
|
16703
|
+
return this.abortController.signal.reason ?? new Error("ACP connection closed");
|
|
16603
16704
|
}
|
|
16604
16705
|
async sendMessage(message) {
|
|
16605
16706
|
this.writeQueue = this.writeQueue.then(async () => {
|
|
@@ -17218,6 +17319,30 @@ function applyStructuredPatch(source, patch, options = {}) {
|
|
|
17218
17319
|
return resultLines.join("\n");
|
|
17219
17320
|
}
|
|
17220
17321
|
|
|
17322
|
+
// node_modules/diff/libesm/patch/reverse.js
|
|
17323
|
+
function reversePatch(structuredPatch) {
|
|
17324
|
+
if (Array.isArray(structuredPatch)) {
|
|
17325
|
+
return structuredPatch.map((patch) => reversePatch(patch)).reverse();
|
|
17326
|
+
}
|
|
17327
|
+
return Object.assign(Object.assign({}, structuredPatch), { oldFileName: structuredPatch.newFileName, oldHeader: structuredPatch.newHeader, newFileName: structuredPatch.oldFileName, newHeader: structuredPatch.oldHeader, hunks: structuredPatch.hunks.map((hunk) => {
|
|
17328
|
+
return {
|
|
17329
|
+
oldLines: hunk.newLines,
|
|
17330
|
+
oldStart: hunk.newStart,
|
|
17331
|
+
newLines: hunk.oldLines,
|
|
17332
|
+
newStart: hunk.oldStart,
|
|
17333
|
+
lines: hunk.lines.map((l) => {
|
|
17334
|
+
if (l.startsWith("-")) {
|
|
17335
|
+
return `+${l.slice(1)}`;
|
|
17336
|
+
}
|
|
17337
|
+
if (l.startsWith("+")) {
|
|
17338
|
+
return `-${l.slice(1)}`;
|
|
17339
|
+
}
|
|
17340
|
+
return l;
|
|
17341
|
+
})
|
|
17342
|
+
};
|
|
17343
|
+
}) });
|
|
17344
|
+
}
|
|
17345
|
+
|
|
17221
17346
|
// src/CodexToolCallMapper.ts
|
|
17222
17347
|
import { readFile } from "node:fs/promises";
|
|
17223
17348
|
import path2 from "node:path";
|
|
@@ -17369,7 +17494,7 @@ function createCommandActionEvent(id, status, cwd, commandAction) {
|
|
|
17369
17494
|
toolCallId: id,
|
|
17370
17495
|
status: acpStatus,
|
|
17371
17496
|
kind: "read",
|
|
17372
|
-
title:
|
|
17497
|
+
title: `Read file '${commandAction.path}'`,
|
|
17373
17498
|
locations: [{ path: commandAction.path }]
|
|
17374
17499
|
};
|
|
17375
17500
|
} else if (commandAction.type === "search") {
|
|
@@ -17420,80 +17545,93 @@ function createSearchTitle(query, path5) {
|
|
|
17420
17545
|
return "Search";
|
|
17421
17546
|
}
|
|
17422
17547
|
async function createPatchContent(change) {
|
|
17423
|
-
|
|
17424
|
-
|
|
17425
|
-
|
|
17426
|
-
|
|
17427
|
-
|
|
17428
|
-
|
|
17429
|
-
|
|
17430
|
-
|
|
17431
|
-
|
|
17432
|
-
|
|
17433
|
-
|
|
17434
|
-
if (change.kind.type === "delete") {
|
|
17435
|
-
const oldContent2 = await readFile(change.path, { encoding: "utf8" }).catch(
|
|
17436
|
-
() => isUnifiedDiff(change.diff) ? patchToDeletedContent(change.diff) : change.diff
|
|
17437
|
-
);
|
|
17438
|
-
return {
|
|
17439
|
-
type: "diff",
|
|
17440
|
-
oldText: oldContent2,
|
|
17441
|
-
newText: "",
|
|
17442
|
-
path: change.path,
|
|
17443
|
-
_meta: {
|
|
17444
|
-
kind: "delete"
|
|
17445
|
-
}
|
|
17446
|
-
};
|
|
17447
|
-
}
|
|
17448
|
-
const oldContent = change.kind.type === "add" ? "" : await readFile(change.path, { encoding: "utf8" }).catch(() => null);
|
|
17449
|
-
if (oldContent === null) {
|
|
17450
|
-
return null;
|
|
17451
|
-
}
|
|
17452
|
-
const newContent = applyPatch(oldContent, change.diff);
|
|
17453
|
-
if (newContent === false) {
|
|
17548
|
+
try {
|
|
17549
|
+
switch (change.kind.type) {
|
|
17550
|
+
case "add":
|
|
17551
|
+
return await createAddFileContent(change);
|
|
17552
|
+
case "delete":
|
|
17553
|
+
return await createDeleteFileContent(change);
|
|
17554
|
+
case "update":
|
|
17555
|
+
return await createUpdateFileContent(change);
|
|
17556
|
+
}
|
|
17557
|
+
} catch (error40) {
|
|
17558
|
+
logger.log(`Error processing file update change: ${error40}`);
|
|
17454
17559
|
return null;
|
|
17455
17560
|
}
|
|
17561
|
+
}
|
|
17562
|
+
async function createAddFileContent(change) {
|
|
17456
17563
|
return {
|
|
17457
17564
|
type: "diff",
|
|
17458
|
-
oldText:
|
|
17459
|
-
newText:
|
|
17565
|
+
oldText: null,
|
|
17566
|
+
newText: change.diff,
|
|
17567
|
+
// app-server always returns file content instead of diff
|
|
17460
17568
|
path: change.path,
|
|
17461
17569
|
_meta: {
|
|
17462
|
-
kind:
|
|
17570
|
+
kind: "add"
|
|
17463
17571
|
}
|
|
17464
17572
|
};
|
|
17465
17573
|
}
|
|
17466
|
-
function
|
|
17467
|
-
|
|
17468
|
-
|
|
17469
|
-
|
|
17470
|
-
|
|
17471
|
-
|
|
17472
|
-
|
|
17473
|
-
|
|
17474
|
-
|
|
17475
|
-
|
|
17476
|
-
|
|
17477
|
-
|
|
17478
|
-
|
|
17479
|
-
if (line === "\") {
|
|
17480
|
-
hasNoTrailingNewlineMarker = true;
|
|
17481
|
-
continue;
|
|
17482
|
-
}
|
|
17483
|
-
if (line.startsWith("-") || line.startsWith(" ")) {
|
|
17484
|
-
oldLines.push(line.slice(1));
|
|
17574
|
+
async function createUpdateFileContent(change) {
|
|
17575
|
+
if (change.kind.type !== "update") return null;
|
|
17576
|
+
const unifiedDiff = recoverCorruptedDiff(change.diff);
|
|
17577
|
+
const movePath = change.kind.move_path;
|
|
17578
|
+
const oldContent = await readFileContent(change.path);
|
|
17579
|
+
if (oldContent !== null) {
|
|
17580
|
+
const patchedContent = applyPatch(oldContent, unifiedDiff);
|
|
17581
|
+
if (patchedContent === false) {
|
|
17582
|
+
const revertedPatch2 = revertPatch(unifiedDiff);
|
|
17583
|
+
if (revertedPatch2) {
|
|
17584
|
+
const revertedContent2 = applyPatch(oldContent, revertedPatch2);
|
|
17585
|
+
if (revertedContent2 !== false) {
|
|
17586
|
+
return createUpdateDiffContent(change.path, revertedContent2, oldContent);
|
|
17485
17587
|
}
|
|
17486
17588
|
}
|
|
17589
|
+
return null;
|
|
17487
17590
|
}
|
|
17488
|
-
|
|
17489
|
-
return "";
|
|
17490
|
-
}
|
|
17491
|
-
const oldText = oldLines.join("\n");
|
|
17492
|
-
return hasNoTrailingNewlineMarker || !unifiedDiff.endsWith("\n") ? oldText : `${oldText}
|
|
17493
|
-
`;
|
|
17494
|
-
} catch {
|
|
17495
|
-
return null;
|
|
17591
|
+
return createUpdateDiffContent(movePath ?? change.path, oldContent, patchedContent);
|
|
17496
17592
|
}
|
|
17593
|
+
if (!movePath) return null;
|
|
17594
|
+
const newContent = await readFileContent(movePath);
|
|
17595
|
+
if (newContent === null) return null;
|
|
17596
|
+
const revertedPatch = revertPatch(unifiedDiff);
|
|
17597
|
+
if (!revertedPatch) return null;
|
|
17598
|
+
const revertedContent = applyPatch(newContent, revertedPatch);
|
|
17599
|
+
if (revertedContent === false) return null;
|
|
17600
|
+
return createUpdateDiffContent(movePath, revertedContent, newContent);
|
|
17601
|
+
}
|
|
17602
|
+
function revertPatch(unifiedDiff) {
|
|
17603
|
+
const [patch] = parsePatch(unifiedDiff);
|
|
17604
|
+
if (!patch) return null;
|
|
17605
|
+
return reversePatch(patch);
|
|
17606
|
+
}
|
|
17607
|
+
function createUpdateDiffContent(path5, oldText, newText) {
|
|
17608
|
+
return {
|
|
17609
|
+
type: "diff",
|
|
17610
|
+
oldText,
|
|
17611
|
+
newText,
|
|
17612
|
+
path: path5,
|
|
17613
|
+
_meta: {
|
|
17614
|
+
kind: "update"
|
|
17615
|
+
}
|
|
17616
|
+
};
|
|
17617
|
+
}
|
|
17618
|
+
async function createDeleteFileContent(change) {
|
|
17619
|
+
return {
|
|
17620
|
+
type: "diff",
|
|
17621
|
+
oldText: change.diff,
|
|
17622
|
+
// app-server always returns file content instead of diff
|
|
17623
|
+
newText: "",
|
|
17624
|
+
path: change.path,
|
|
17625
|
+
_meta: {
|
|
17626
|
+
kind: "delete"
|
|
17627
|
+
}
|
|
17628
|
+
};
|
|
17629
|
+
}
|
|
17630
|
+
async function readFileContent(filePath) {
|
|
17631
|
+
return await readFile(filePath, { encoding: "utf8" }).catch(() => null);
|
|
17632
|
+
}
|
|
17633
|
+
function recoverCorruptedDiff(diff) {
|
|
17634
|
+
return diff.replace(/\n\nMoved to: .*$/, "");
|
|
17497
17635
|
}
|
|
17498
17636
|
|
|
17499
17637
|
// src/CodexEventHandler.ts
|
|
@@ -17536,6 +17674,27 @@ var CodexEventHandler = class {
|
|
|
17536
17674
|
return null;
|
|
17537
17675
|
case "thread/tokenUsage/updated":
|
|
17538
17676
|
return this.createUsageUpdate(notification.params);
|
|
17677
|
+
case "thread/name/updated":
|
|
17678
|
+
return {
|
|
17679
|
+
sessionUpdate: "session_info_update",
|
|
17680
|
+
title: notification.params.threadName ?? null
|
|
17681
|
+
};
|
|
17682
|
+
case "thread/status/changed":
|
|
17683
|
+
return this.createCodexSessionInfoUpdate({
|
|
17684
|
+
threadStatus: notification.params.status
|
|
17685
|
+
});
|
|
17686
|
+
case "thread/archived":
|
|
17687
|
+
return this.createCodexSessionInfoUpdate({
|
|
17688
|
+
archived: true
|
|
17689
|
+
});
|
|
17690
|
+
case "thread/unarchived":
|
|
17691
|
+
return this.createCodexSessionInfoUpdate({
|
|
17692
|
+
archived: false
|
|
17693
|
+
});
|
|
17694
|
+
case "thread/closed":
|
|
17695
|
+
return this.createCodexSessionInfoUpdate({
|
|
17696
|
+
closed: true
|
|
17697
|
+
});
|
|
17539
17698
|
case "item/commandExecution/outputDelta":
|
|
17540
17699
|
return this.createCommandOutputDeltaEvent(notification.params);
|
|
17541
17700
|
case "item/mcpToolCall/progress":
|
|
@@ -17582,10 +17741,6 @@ var CodexEventHandler = class {
|
|
|
17582
17741
|
case "serverRequest/resolved":
|
|
17583
17742
|
case "model/verification":
|
|
17584
17743
|
case "windows/worldWritableWarning":
|
|
17585
|
-
case "thread/status/changed":
|
|
17586
|
-
case "thread/archived":
|
|
17587
|
-
case "thread/unarchived":
|
|
17588
|
-
case "thread/closed":
|
|
17589
17744
|
case "thread/realtime/started":
|
|
17590
17745
|
case "thread/realtime/itemAdded":
|
|
17591
17746
|
case "thread/realtime/transcript/delta":
|
|
@@ -17602,15 +17757,25 @@ var CodexEventHandler = class {
|
|
|
17602
17757
|
case "externalAgentConfig/import/completed":
|
|
17603
17758
|
case "rawResponseItem/completed":
|
|
17604
17759
|
case "thread/started":
|
|
17605
|
-
case "thread/name/updated":
|
|
17606
17760
|
case "item/plan/delta":
|
|
17607
17761
|
case "thread/goal/updated":
|
|
17608
17762
|
case "thread/goal/cleared":
|
|
17609
17763
|
case "remoteControl/status/changed":
|
|
17610
17764
|
case "app/list/updated":
|
|
17765
|
+
case "thread/settings/updated":
|
|
17766
|
+
case "process/outputDelta":
|
|
17767
|
+
case "process/exited":
|
|
17611
17768
|
return null;
|
|
17612
17769
|
}
|
|
17613
17770
|
}
|
|
17771
|
+
createCodexSessionInfoUpdate(codexMetadata) {
|
|
17772
|
+
return {
|
|
17773
|
+
sessionUpdate: "session_info_update",
|
|
17774
|
+
_meta: {
|
|
17775
|
+
codex: codexMetadata
|
|
17776
|
+
}
|
|
17777
|
+
};
|
|
17778
|
+
}
|
|
17614
17779
|
async createTextEvent(event) {
|
|
17615
17780
|
return {
|
|
17616
17781
|
sessionUpdate: "agent_message_chunk",
|
|
@@ -17934,42 +18099,28 @@ var CodexApprovalHandler = class {
|
|
|
17934
18099
|
}
|
|
17935
18100
|
}
|
|
17936
18101
|
buildCommandPermissionRequest(sessionId, params) {
|
|
17937
|
-
const reasonContent = this.createContentFromReason(params.reason ?? null);
|
|
17938
18102
|
return {
|
|
17939
18103
|
sessionId,
|
|
17940
18104
|
toolCall: {
|
|
17941
18105
|
toolCallId: params.itemId,
|
|
17942
18106
|
kind: "execute",
|
|
17943
18107
|
status: "pending",
|
|
17944
|
-
content: reasonContent ? [reasonContent] : null,
|
|
17945
18108
|
rawInput: params.command ? { command: stripShellPrefix(params.command), cwd: params.cwd } : null
|
|
17946
18109
|
},
|
|
17947
|
-
options: APPROVAL_OPTIONS
|
|
17948
|
-
|
|
17949
|
-
}
|
|
17950
|
-
createContentFromReason(reason) {
|
|
17951
|
-
if (reason === null || reason === "") {
|
|
17952
|
-
return null;
|
|
17953
|
-
}
|
|
17954
|
-
return {
|
|
17955
|
-
type: "content",
|
|
17956
|
-
content: {
|
|
17957
|
-
type: "text",
|
|
17958
|
-
text: reason
|
|
17959
|
-
}
|
|
18110
|
+
options: APPROVAL_OPTIONS,
|
|
18111
|
+
_meta: { codex: { params } }
|
|
17960
18112
|
};
|
|
17961
18113
|
}
|
|
17962
18114
|
buildFileChangePermissionRequest(sessionId, params) {
|
|
17963
|
-
const reasonContent = this.createContentFromReason(params.reason ?? null);
|
|
17964
18115
|
return {
|
|
17965
18116
|
sessionId,
|
|
17966
18117
|
toolCall: {
|
|
17967
18118
|
toolCallId: params.itemId,
|
|
17968
18119
|
kind: "edit",
|
|
17969
|
-
status: "pending"
|
|
17970
|
-
content: reasonContent ? [reasonContent] : null
|
|
18120
|
+
status: "pending"
|
|
17971
18121
|
},
|
|
17972
|
-
options: APPROVAL_OPTIONS
|
|
18122
|
+
options: APPROVAL_OPTIONS,
|
|
18123
|
+
_meta: { codex: { params } }
|
|
17973
18124
|
};
|
|
17974
18125
|
}
|
|
17975
18126
|
convertCommandResponse(response) {
|
|
@@ -18000,12 +18151,19 @@ var CodexApprovalHandler = class {
|
|
|
18000
18151
|
}
|
|
18001
18152
|
};
|
|
18002
18153
|
|
|
18154
|
+
// src/McpApprovalOptionId.ts
|
|
18155
|
+
var McpApprovalOptionId = {
|
|
18156
|
+
AllowOnce: "allow_once",
|
|
18157
|
+
AllowSession: "allow_session",
|
|
18158
|
+
AllowAlways: "allow_always",
|
|
18159
|
+
Decline: "decline"
|
|
18160
|
+
};
|
|
18161
|
+
|
|
18003
18162
|
// src/CodexElicitationHandler.ts
|
|
18004
18163
|
var ELICITATION_OPTIONS = [
|
|
18005
18164
|
{ optionId: "accept", name: "Accept", kind: "allow_once" },
|
|
18006
18165
|
{ optionId: "decline", name: "Decline", kind: "reject_once" }
|
|
18007
18166
|
];
|
|
18008
|
-
var OPTION_ALLOW_SESSION = "allow_session";
|
|
18009
18167
|
function parsePersistOptions(meta) {
|
|
18010
18168
|
const result = /* @__PURE__ */ new Set();
|
|
18011
18169
|
if (!meta || typeof meta !== "object") return result;
|
|
@@ -18025,15 +18183,15 @@ function isMcpToolCallApproval(meta) {
|
|
|
18025
18183
|
}
|
|
18026
18184
|
function buildToolApprovalOptions(persistOptions) {
|
|
18027
18185
|
const options = [
|
|
18028
|
-
{ optionId:
|
|
18186
|
+
{ optionId: McpApprovalOptionId.AllowOnce, name: "Allow", kind: "allow_once" }
|
|
18029
18187
|
];
|
|
18030
18188
|
if (persistOptions.has("session")) {
|
|
18031
|
-
options.push({ optionId:
|
|
18189
|
+
options.push({ optionId: McpApprovalOptionId.AllowSession, name: "Allow for This Session", kind: "allow_always" });
|
|
18032
18190
|
}
|
|
18033
18191
|
if (persistOptions.has("always")) {
|
|
18034
|
-
options.push({ optionId:
|
|
18192
|
+
options.push({ optionId: McpApprovalOptionId.AllowAlways, name: "Allow and Don't Ask Again", kind: "allow_always" });
|
|
18035
18193
|
}
|
|
18036
|
-
options.push({ optionId:
|
|
18194
|
+
options.push({ optionId: McpApprovalOptionId.Decline, name: "Decline", kind: "reject_once" });
|
|
18037
18195
|
return options;
|
|
18038
18196
|
}
|
|
18039
18197
|
var CodexElicitationHandler = class {
|
|
@@ -18080,7 +18238,7 @@ var CodexElicitationHandler = class {
|
|
|
18080
18238
|
const response = await this.connection.requestPermission(request);
|
|
18081
18239
|
if (correlatedCallId !== void 0 && response.outcome.outcome !== "cancelled") {
|
|
18082
18240
|
const optionId = response.outcome.optionId;
|
|
18083
|
-
if (optionId !==
|
|
18241
|
+
if (optionId !== McpApprovalOptionId.Decline) {
|
|
18084
18242
|
await this.connection.sessionUpdate({
|
|
18085
18243
|
sessionId: this.sessionState.sessionId,
|
|
18086
18244
|
update: { sessionUpdate: "tool_call_update", toolCallId: correlatedCallId, status: "in_progress" }
|
|
@@ -18158,13 +18316,13 @@ var CodexElicitationHandler = class {
|
|
|
18158
18316
|
return { action: "cancel", content: null, _meta: null };
|
|
18159
18317
|
}
|
|
18160
18318
|
const optionId = response.outcome.optionId;
|
|
18161
|
-
if (optionId ===
|
|
18319
|
+
if (optionId === McpApprovalOptionId.AllowSession) {
|
|
18162
18320
|
return { action: "accept", content: null, _meta: { persist: "session" } };
|
|
18163
18321
|
}
|
|
18164
|
-
if (optionId ===
|
|
18322
|
+
if (optionId === McpApprovalOptionId.AllowAlways) {
|
|
18165
18323
|
return { action: "accept", content: null, _meta: { persist: "always" } };
|
|
18166
18324
|
}
|
|
18167
|
-
if (optionId ===
|
|
18325
|
+
if (optionId === McpApprovalOptionId.AllowOnce || optionId === "accept") {
|
|
18168
18326
|
return { action: "accept", content: null, _meta: null };
|
|
18169
18327
|
}
|
|
18170
18328
|
return { action: "decline", content: null, _meta: null };
|
|
@@ -18870,6 +19028,7 @@ var ModelId = class _ModelId {
|
|
|
18870
19028
|
};
|
|
18871
19029
|
|
|
18872
19030
|
// src/AgentMode.ts
|
|
19031
|
+
var MODE_CONFIG_ID = "mode";
|
|
18873
19032
|
var AgentMode = class _AgentMode {
|
|
18874
19033
|
id;
|
|
18875
19034
|
name;
|
|
@@ -18932,6 +19091,21 @@ var AgentMode = class _AgentMode {
|
|
|
18932
19091
|
currentModeId: this.id
|
|
18933
19092
|
};
|
|
18934
19093
|
}
|
|
19094
|
+
toConfigOption() {
|
|
19095
|
+
return {
|
|
19096
|
+
id: MODE_CONFIG_ID,
|
|
19097
|
+
name: "Mode",
|
|
19098
|
+
description: "Approval and sandboxing preset for the session",
|
|
19099
|
+
category: "mode",
|
|
19100
|
+
type: "select",
|
|
19101
|
+
currentValue: this.id,
|
|
19102
|
+
options: _AgentMode.all().map((mode) => ({
|
|
19103
|
+
value: mode.id,
|
|
19104
|
+
name: mode.name,
|
|
19105
|
+
description: mode.description
|
|
19106
|
+
}))
|
|
19107
|
+
};
|
|
19108
|
+
}
|
|
18935
19109
|
static all() {
|
|
18936
19110
|
return [_AgentMode.ReadOnly, _AgentMode.Agent, _AgentMode.AgentFullAccess];
|
|
18937
19111
|
}
|
|
@@ -18952,13 +19126,19 @@ var AgentMode = class _AgentMode {
|
|
|
18952
19126
|
// src/CodexAcpClient.ts
|
|
18953
19127
|
import path4 from "node:path";
|
|
18954
19128
|
|
|
19129
|
+
// src/McpServerName.ts
|
|
19130
|
+
var MCP_SERVER_NAME_WHITESPACE = /\p{White_Space}/gu;
|
|
19131
|
+
function sanitizeMcpServerName(name) {
|
|
19132
|
+
return name.replace(MCP_SERVER_NAME_WHITESPACE, "_");
|
|
19133
|
+
}
|
|
19134
|
+
|
|
18955
19135
|
// package.json
|
|
18956
19136
|
var package_default = {
|
|
18957
19137
|
name: "@agentclientprotocol/codex-acp",
|
|
18958
19138
|
publishConfig: {
|
|
18959
19139
|
access: "public"
|
|
18960
19140
|
},
|
|
18961
|
-
version: "0.0.
|
|
19141
|
+
version: "0.0.46",
|
|
18962
19142
|
description: "",
|
|
18963
19143
|
main: "dist/index.js",
|
|
18964
19144
|
bin: {
|
|
@@ -19016,8 +19196,8 @@ var package_default = {
|
|
|
19016
19196
|
vitest: "^4.0.10"
|
|
19017
19197
|
},
|
|
19018
19198
|
dependencies: {
|
|
19019
|
-
"@agentclientprotocol/sdk": "^0.
|
|
19020
|
-
"@openai/codex": "^0.
|
|
19199
|
+
"@agentclientprotocol/sdk": "^0.22.1",
|
|
19200
|
+
"@openai/codex": "^0.137.0",
|
|
19021
19201
|
diff: "^8.0.3",
|
|
19022
19202
|
open: "^11.0.0",
|
|
19023
19203
|
"vscode-jsonrpc": "^8.2.1"
|
|
@@ -19032,6 +19212,7 @@ var CodexAcpClient = class {
|
|
|
19032
19212
|
gatewayConfig;
|
|
19033
19213
|
pendingLoginCompleted = null;
|
|
19034
19214
|
pendingAccountUpdated = null;
|
|
19215
|
+
sessionNotificationQueues = /* @__PURE__ */ new Map();
|
|
19035
19216
|
constructor(codexClient, codexConfig, modelProvider) {
|
|
19036
19217
|
this.codexClient = codexClient;
|
|
19037
19218
|
this.config = codexConfig ?? {};
|
|
@@ -19157,47 +19338,39 @@ var CodexAcpClient = class {
|
|
|
19157
19338
|
async getAccount() {
|
|
19158
19339
|
return this.codexClient.accountRead({ refreshToken: false });
|
|
19159
19340
|
}
|
|
19160
|
-
async resumeSession(request) {
|
|
19341
|
+
async resumeSession(request, onSubscribed) {
|
|
19161
19342
|
await this.refreshSkills(request.cwd, request._meta);
|
|
19162
19343
|
const response = await this.codexClient.threadResume({
|
|
19163
|
-
approvalPolicy: null,
|
|
19164
|
-
sandbox: null,
|
|
19165
|
-
baseInstructions: null,
|
|
19166
19344
|
config: await this.createSessionConfig(request.cwd, request.mcpServers ?? []),
|
|
19167
19345
|
cwd: request.cwd,
|
|
19168
|
-
developerInstructions: null,
|
|
19169
|
-
model: null,
|
|
19170
19346
|
modelProvider: this.getResumeModelProvider(),
|
|
19171
|
-
personality: null,
|
|
19172
19347
|
threadId: request.sessionId
|
|
19173
19348
|
});
|
|
19349
|
+
onSubscribed?.();
|
|
19174
19350
|
const codexModels = await this.fetchAvailableModels();
|
|
19175
19351
|
const currentModelId = this.createModelId(codexModels, response.model, response.reasoningEffort).toString();
|
|
19176
19352
|
return {
|
|
19177
19353
|
sessionId: request.sessionId,
|
|
19178
19354
|
currentModelId,
|
|
19179
|
-
models: codexModels
|
|
19355
|
+
models: codexModels,
|
|
19356
|
+
currentServiceTier: response.serviceTier ?? null
|
|
19180
19357
|
};
|
|
19181
19358
|
}
|
|
19182
|
-
async loadSession(request) {
|
|
19359
|
+
async loadSession(request, onSubscribed) {
|
|
19183
19360
|
const response = await this.codexClient.threadResume({
|
|
19184
|
-
approvalPolicy: null,
|
|
19185
|
-
sandbox: null,
|
|
19186
|
-
baseInstructions: null,
|
|
19187
19361
|
config: await this.createSessionConfig(request.cwd, request.mcpServers ?? []),
|
|
19188
19362
|
cwd: request.cwd,
|
|
19189
|
-
developerInstructions: null,
|
|
19190
|
-
model: null,
|
|
19191
19363
|
modelProvider: this.getResumeModelProvider(),
|
|
19192
|
-
personality: null,
|
|
19193
19364
|
threadId: request.sessionId
|
|
19194
19365
|
});
|
|
19366
|
+
onSubscribed?.();
|
|
19195
19367
|
const codexModels = await this.fetchAvailableModels();
|
|
19196
19368
|
const currentModelId = this.createModelId(codexModels, response.model, response.reasoningEffort).toString();
|
|
19197
19369
|
return {
|
|
19198
19370
|
sessionId: request.sessionId,
|
|
19199
19371
|
currentModelId,
|
|
19200
19372
|
models: codexModels,
|
|
19373
|
+
currentServiceTier: response.serviceTier ?? null,
|
|
19201
19374
|
thread: response.thread
|
|
19202
19375
|
};
|
|
19203
19376
|
}
|
|
@@ -19206,14 +19379,7 @@ var CodexAcpClient = class {
|
|
|
19206
19379
|
const response = await this.codexClient.threadStart({
|
|
19207
19380
|
config: await this.createSessionConfig(request.cwd, request.mcpServers),
|
|
19208
19381
|
modelProvider: this.getModelProvider(),
|
|
19209
|
-
|
|
19210
|
-
cwd: request.cwd,
|
|
19211
|
-
approvalPolicy: null,
|
|
19212
|
-
sandbox: null,
|
|
19213
|
-
baseInstructions: null,
|
|
19214
|
-
developerInstructions: null,
|
|
19215
|
-
personality: null,
|
|
19216
|
-
ephemeral: null
|
|
19382
|
+
cwd: request.cwd
|
|
19217
19383
|
});
|
|
19218
19384
|
const codexModels = await this.fetchAvailableModels();
|
|
19219
19385
|
if (codexModels.length === 0) {
|
|
@@ -19223,9 +19389,17 @@ var CodexAcpClient = class {
|
|
|
19223
19389
|
return {
|
|
19224
19390
|
sessionId: response.thread.id,
|
|
19225
19391
|
currentModelId,
|
|
19226
|
-
models: codexModels
|
|
19392
|
+
models: codexModels,
|
|
19393
|
+
currentServiceTier: response.serviceTier ?? null
|
|
19227
19394
|
};
|
|
19228
19395
|
}
|
|
19396
|
+
async closeSession(sessionId) {
|
|
19397
|
+
try {
|
|
19398
|
+
await this.codexClient.threadUnsubscribe({ threadId: sessionId });
|
|
19399
|
+
} finally {
|
|
19400
|
+
this.codexClient.clearThreadHandlers(sessionId);
|
|
19401
|
+
}
|
|
19402
|
+
}
|
|
19229
19403
|
async awaitMcpServerStartup(serverNames, afterVersion) {
|
|
19230
19404
|
return await this.codexClient.awaitMcpServerStartup(serverNames, afterVersion);
|
|
19231
19405
|
}
|
|
@@ -19245,13 +19419,17 @@ var CodexAcpClient = class {
|
|
|
19245
19419
|
return mergedConfig;
|
|
19246
19420
|
}
|
|
19247
19421
|
const existingNames = await this.getConfigMcpServerNames(projectPath);
|
|
19248
|
-
const
|
|
19422
|
+
const requestedServers = mcpServers.map((mcp) => ({
|
|
19423
|
+
name: sanitizeMcpServerName(mcp.name),
|
|
19424
|
+
server: mcp
|
|
19425
|
+
}));
|
|
19426
|
+
const uniqueServers = requestedServers.filter((mcp) => !existingNames.has(mcp.name));
|
|
19249
19427
|
if (uniqueServers.length === 0) {
|
|
19250
19428
|
return mergedConfig;
|
|
19251
19429
|
}
|
|
19252
19430
|
return {
|
|
19253
19431
|
...mergedConfig,
|
|
19254
|
-
"mcp_servers": Object.fromEntries(uniqueServers.map((mcp) => [mcp.name, this.createMcpSeverConfig(mcp)]))
|
|
19432
|
+
"mcp_servers": Object.fromEntries(uniqueServers.map((mcp) => [mcp.name, this.createMcpSeverConfig(mcp.server)]))
|
|
19255
19433
|
};
|
|
19256
19434
|
}
|
|
19257
19435
|
async getConfigMcpServerNames(projectPath) {
|
|
@@ -19272,14 +19450,13 @@ var CodexAcpClient = class {
|
|
|
19272
19450
|
if (!cwd) {
|
|
19273
19451
|
return;
|
|
19274
19452
|
}
|
|
19275
|
-
const additionalRoots = readAdditionalRoots(meta);
|
|
19453
|
+
const additionalRoots = readAdditionalRoots(meta).map((root) => path4.join(root, ".agents", "skills"));
|
|
19454
|
+
if (additionalRoots.length > 0) {
|
|
19455
|
+
await this.codexClient.skillsExtraRootsSet({ extraRoots: additionalRoots });
|
|
19456
|
+
}
|
|
19276
19457
|
await this.codexClient.listSkills({
|
|
19277
19458
|
cwds: [cwd],
|
|
19278
|
-
forceReload: true
|
|
19279
|
-
perCwdExtraUserRoots: [{
|
|
19280
|
-
cwd,
|
|
19281
|
-
extraUserRoots: additionalRoots
|
|
19282
|
-
}]
|
|
19459
|
+
forceReload: true
|
|
19283
19460
|
});
|
|
19284
19461
|
}
|
|
19285
19462
|
/**
|
|
@@ -19287,13 +19464,17 @@ var CodexAcpClient = class {
|
|
|
19287
19464
|
*/
|
|
19288
19465
|
createMcpSeverConfig(mcpServer) {
|
|
19289
19466
|
if ("type" in mcpServer) {
|
|
19290
|
-
|
|
19291
|
-
|
|
19467
|
+
switch (mcpServer.type) {
|
|
19468
|
+
case "acp":
|
|
19469
|
+
throw RequestError.invalidRequest("Codex doesn't support MCP ACP transport protocol");
|
|
19470
|
+
case "sse":
|
|
19471
|
+
throw RequestError.invalidRequest("Codex doesn't support MCP SSE transport protocol");
|
|
19472
|
+
case "http":
|
|
19473
|
+
return {
|
|
19474
|
+
"url": mcpServer.url,
|
|
19475
|
+
"http_headers": Object.fromEntries(mcpServer.headers.map((h) => [h.name, h.value]))
|
|
19476
|
+
};
|
|
19292
19477
|
}
|
|
19293
|
-
return {
|
|
19294
|
-
"url": mcpServer.url,
|
|
19295
|
-
"http_headers": Object.fromEntries(mcpServer.headers.map((h) => [h.name, h.value]))
|
|
19296
|
-
};
|
|
19297
19478
|
}
|
|
19298
19479
|
return {
|
|
19299
19480
|
"command": mcpServer.command,
|
|
@@ -19313,26 +19494,73 @@ var CodexAcpClient = class {
|
|
|
19313
19494
|
return ModelId.create(selectedModel.id, reasoningEffort ?? selectedModel.defaultReasoningEffort);
|
|
19314
19495
|
}
|
|
19315
19496
|
async subscribeToSessionEvents(sessionId, eventHandler, approvalHandler, elicitationHandler) {
|
|
19316
|
-
this.codexClient.onServerNotification(sessionId,
|
|
19317
|
-
|
|
19318
|
-
|
|
19497
|
+
this.codexClient.onServerNotification(sessionId, (event) => {
|
|
19498
|
+
this.enqueueSessionNotification(sessionId, () => eventHandler(event));
|
|
19499
|
+
});
|
|
19500
|
+
this.codexClient.onApprovalRequest(sessionId, {
|
|
19501
|
+
handleCommandExecution: async (params) => {
|
|
19502
|
+
await this.waitForSessionNotifications(sessionId);
|
|
19503
|
+
return await approvalHandler.handleCommandExecution(params);
|
|
19504
|
+
},
|
|
19505
|
+
handleFileChange: async (params) => {
|
|
19506
|
+
await this.waitForSessionNotifications(sessionId);
|
|
19507
|
+
return await approvalHandler.handleFileChange(params);
|
|
19508
|
+
}
|
|
19509
|
+
});
|
|
19510
|
+
this.codexClient.onElicitationRequest(sessionId, {
|
|
19511
|
+
handleElicitation: async (params) => {
|
|
19512
|
+
await this.waitForSessionNotifications(sessionId);
|
|
19513
|
+
return await elicitationHandler.handleElicitation(params);
|
|
19514
|
+
}
|
|
19515
|
+
});
|
|
19516
|
+
}
|
|
19517
|
+
async waitForSessionNotifications(sessionId) {
|
|
19518
|
+
while (true) {
|
|
19519
|
+
const queue = this.sessionNotificationQueues.get(sessionId);
|
|
19520
|
+
if (!queue) return;
|
|
19521
|
+
await queue;
|
|
19522
|
+
}
|
|
19523
|
+
}
|
|
19524
|
+
enqueueSessionNotification(sessionId, operation) {
|
|
19525
|
+
const run = async () => {
|
|
19526
|
+
try {
|
|
19527
|
+
await operation();
|
|
19528
|
+
} catch (error40) {
|
|
19529
|
+
logger.error("Error handling Codex session notification", error40);
|
|
19530
|
+
}
|
|
19531
|
+
};
|
|
19532
|
+
const previous = this.sessionNotificationQueues.get(sessionId);
|
|
19533
|
+
const next = previous ? previous.then(run, run) : run();
|
|
19534
|
+
this.sessionNotificationQueues.set(sessionId, next);
|
|
19535
|
+
void next.finally(() => {
|
|
19536
|
+
if (this.sessionNotificationQueues.get(sessionId) === next) {
|
|
19537
|
+
this.sessionNotificationQueues.delete(sessionId);
|
|
19538
|
+
}
|
|
19539
|
+
});
|
|
19319
19540
|
}
|
|
19320
|
-
async sendPrompt(request, agentMode, modelId, disableSummary, cwd) {
|
|
19541
|
+
async sendPrompt(request, agentMode, modelId, serviceTier, disableSummary, cwd, onTurnStarted, shouldCancel) {
|
|
19321
19542
|
const input = buildPromptItems(request.prompt);
|
|
19322
19543
|
const effort = modelId.effort;
|
|
19323
19544
|
await this.refreshSkills(cwd, request._meta);
|
|
19545
|
+
if (shouldCancel?.()) {
|
|
19546
|
+
return null;
|
|
19547
|
+
}
|
|
19324
19548
|
return await this.codexClient.runTurn({
|
|
19325
|
-
outputSchema: null,
|
|
19326
19549
|
threadId: request.sessionId,
|
|
19327
19550
|
input,
|
|
19328
19551
|
approvalPolicy: agentMode.approvalPolicy,
|
|
19329
19552
|
sandboxPolicy: agentMode.sandboxPolicy,
|
|
19330
19553
|
summary: disableSummary ? "none" : null,
|
|
19331
|
-
personality: null,
|
|
19332
|
-
cwd: null,
|
|
19333
19554
|
effort,
|
|
19334
|
-
model: modelId.model
|
|
19335
|
-
|
|
19555
|
+
model: modelId.model,
|
|
19556
|
+
serviceTier
|
|
19557
|
+
}, onTurnStarted);
|
|
19558
|
+
}
|
|
19559
|
+
resolveTurnInterrupted(params) {
|
|
19560
|
+
this.codexClient.resolveTurnInterrupted(params.threadId, params.turnId);
|
|
19561
|
+
}
|
|
19562
|
+
markTurnStale(params) {
|
|
19563
|
+
this.codexClient.markTurnStale(params.threadId, params.turnId);
|
|
19336
19564
|
}
|
|
19337
19565
|
async listSkills(params) {
|
|
19338
19566
|
return this.codexClient.listSkills(params ?? {});
|
|
@@ -19374,8 +19602,8 @@ var CodexAcpClient = class {
|
|
|
19374
19602
|
});
|
|
19375
19603
|
});
|
|
19376
19604
|
}
|
|
19377
|
-
async listMcpServers(
|
|
19378
|
-
return this.codexClient.listMcpServerStatus(
|
|
19605
|
+
async listMcpServers() {
|
|
19606
|
+
return this.codexClient.listMcpServerStatus({});
|
|
19379
19607
|
}
|
|
19380
19608
|
async listSessions(request) {
|
|
19381
19609
|
const sourceKinds = [
|
|
@@ -19403,11 +19631,8 @@ var CodexAcpClient = class {
|
|
|
19403
19631
|
const modelProviders = preferredProvider ? [preferredProvider] : [];
|
|
19404
19632
|
const listResponse = await this.codexClient.threadList({
|
|
19405
19633
|
cursor: request.cursor ?? null,
|
|
19406
|
-
limit: null,
|
|
19407
|
-
sortKey: null,
|
|
19408
19634
|
modelProviders,
|
|
19409
|
-
sourceKinds
|
|
19410
|
-
archived: null
|
|
19635
|
+
sourceKinds
|
|
19411
19636
|
});
|
|
19412
19637
|
if (listResponse.data.length === 0) {
|
|
19413
19638
|
const diagnostics = await this.runSessionListDiagnostics();
|
|
@@ -19416,14 +19641,14 @@ var CodexAcpClient = class {
|
|
|
19416
19641
|
let sessions = listResponse.data.map((thread) => ({
|
|
19417
19642
|
sessionId: thread.id,
|
|
19418
19643
|
cwd: thread.cwd,
|
|
19419
|
-
title: thread.preview || null,
|
|
19644
|
+
title: (thread.name ?? thread.preview) || null,
|
|
19420
19645
|
updatedAt: new Date(thread.updatedAt * 1e3).toISOString()
|
|
19421
19646
|
}));
|
|
19422
19647
|
if (requestedCwd) {
|
|
19423
19648
|
const filtered = listResponse.data.filter(filterByCwd).map((thread) => ({
|
|
19424
19649
|
sessionId: thread.id,
|
|
19425
19650
|
cwd: thread.cwd,
|
|
19426
|
-
title: thread.preview || null,
|
|
19651
|
+
title: (thread.name ?? thread.preview) || null,
|
|
19427
19652
|
updatedAt: new Date(thread.updatedAt * 1e3).toISOString()
|
|
19428
19653
|
}));
|
|
19429
19654
|
if (filtered.length > 0 || path4.isAbsolute(requestedCwd)) {
|
|
@@ -19455,30 +19680,9 @@ var CodexAcpClient = class {
|
|
|
19455
19680
|
}
|
|
19456
19681
|
async runSessionListDiagnostics() {
|
|
19457
19682
|
const [allProviders, archivedAllProviders, customGateway] = await Promise.all([
|
|
19458
|
-
this.codexClient.threadList({
|
|
19459
|
-
|
|
19460
|
-
|
|
19461
|
-
sortKey: null,
|
|
19462
|
-
modelProviders: [],
|
|
19463
|
-
sourceKinds: null,
|
|
19464
|
-
archived: null
|
|
19465
|
-
}),
|
|
19466
|
-
this.codexClient.threadList({
|
|
19467
|
-
cursor: null,
|
|
19468
|
-
limit: null,
|
|
19469
|
-
sortKey: null,
|
|
19470
|
-
modelProviders: [],
|
|
19471
|
-
sourceKinds: null,
|
|
19472
|
-
archived: true
|
|
19473
|
-
}),
|
|
19474
|
-
this.codexClient.threadList({
|
|
19475
|
-
cursor: null,
|
|
19476
|
-
limit: null,
|
|
19477
|
-
sortKey: null,
|
|
19478
|
-
modelProviders: ["custom-gateway"],
|
|
19479
|
-
sourceKinds: null,
|
|
19480
|
-
archived: null
|
|
19481
|
-
})
|
|
19683
|
+
this.codexClient.threadList({}),
|
|
19684
|
+
this.codexClient.threadList({ archived: true }),
|
|
19685
|
+
this.codexClient.threadList({ modelProviders: ["custom-gateway"] })
|
|
19482
19686
|
]);
|
|
19483
19687
|
return {
|
|
19484
19688
|
allProviders: {
|
|
@@ -19557,6 +19761,44 @@ function mergeGatewayConfig(config2, gatewayConfig) {
|
|
|
19557
19761
|
}
|
|
19558
19762
|
}
|
|
19559
19763
|
|
|
19764
|
+
// src/ModelConfigOption.ts
|
|
19765
|
+
var MODEL_CONFIG_ID = "model";
|
|
19766
|
+
var REASONING_EFFORT_CONFIG_ID = "reasoning_effort";
|
|
19767
|
+
function findSupportedEffort(options, effort) {
|
|
19768
|
+
if (!effort) return void 0;
|
|
19769
|
+
return options.find((o) => o.reasoningEffort === effort)?.reasoningEffort;
|
|
19770
|
+
}
|
|
19771
|
+
function createModelConfigOption(availableModels, currentBaseModelId) {
|
|
19772
|
+
return {
|
|
19773
|
+
id: MODEL_CONFIG_ID,
|
|
19774
|
+
name: "Model",
|
|
19775
|
+
description: "Model Codex uses for the session",
|
|
19776
|
+
category: "model",
|
|
19777
|
+
type: "select",
|
|
19778
|
+
currentValue: currentBaseModelId,
|
|
19779
|
+
options: availableModels.map((model) => ({
|
|
19780
|
+
value: model.id,
|
|
19781
|
+
name: model.displayName,
|
|
19782
|
+
description: model.description
|
|
19783
|
+
}))
|
|
19784
|
+
};
|
|
19785
|
+
}
|
|
19786
|
+
function createReasoningEffortConfigOption(supportedReasoningEfforts, currentEffort) {
|
|
19787
|
+
return {
|
|
19788
|
+
id: REASONING_EFFORT_CONFIG_ID,
|
|
19789
|
+
name: "Reasoning effort",
|
|
19790
|
+
description: "How much reasoning effort the model should use",
|
|
19791
|
+
category: "thought_level",
|
|
19792
|
+
type: "select",
|
|
19793
|
+
currentValue: currentEffort,
|
|
19794
|
+
options: supportedReasoningEfforts.map((option) => ({
|
|
19795
|
+
value: option.reasoningEffort,
|
|
19796
|
+
name: option.reasoningEffort,
|
|
19797
|
+
description: option.description
|
|
19798
|
+
}))
|
|
19799
|
+
};
|
|
19800
|
+
}
|
|
19801
|
+
|
|
19560
19802
|
// src/CodexCommands.ts
|
|
19561
19803
|
var CodexCommands = class {
|
|
19562
19804
|
connection;
|
|
@@ -19583,13 +19825,6 @@ var CodexCommands = class {
|
|
|
19583
19825
|
logger.error(`Failed to publish available commands for session ${sessionId}`, err);
|
|
19584
19826
|
}
|
|
19585
19827
|
}
|
|
19586
|
-
async tryHandle(prompt, sessionState) {
|
|
19587
|
-
const command = this.parseCommand(prompt);
|
|
19588
|
-
if (command) {
|
|
19589
|
-
return this.handleCommand(command, sessionState);
|
|
19590
|
-
}
|
|
19591
|
-
return false;
|
|
19592
|
-
}
|
|
19593
19828
|
buildAvailableCommands(skillsEntries) {
|
|
19594
19829
|
const commands = /* @__PURE__ */ new Map();
|
|
19595
19830
|
for (const builtin of this.getBuiltinCommands()) {
|
|
@@ -19636,25 +19871,22 @@ var CodexCommands = class {
|
|
|
19636
19871
|
}
|
|
19637
19872
|
];
|
|
19638
19873
|
}
|
|
19639
|
-
|
|
19640
|
-
|
|
19641
|
-
|
|
19642
|
-
|
|
19643
|
-
if (
|
|
19644
|
-
const
|
|
19645
|
-
if (!trimmed.startsWith("/")) return null;
|
|
19646
|
-
const commandText = trimmed.slice(1).trim();
|
|
19874
|
+
getCommandName(prompt) {
|
|
19875
|
+
const firstBlock = prompt[0];
|
|
19876
|
+
if (!firstBlock || firstBlock.type != "text") return null;
|
|
19877
|
+
const text = firstBlock.text.trim();
|
|
19878
|
+
if (!text.startsWith("/")) return null;
|
|
19879
|
+
const commandText = text.slice(1).trim();
|
|
19647
19880
|
if (commandText.length === 0) return null;
|
|
19648
|
-
const [name
|
|
19649
|
-
|
|
19650
|
-
return {
|
|
19651
|
-
name: name.toLowerCase(),
|
|
19652
|
-
input: input.length > 0 ? input : null
|
|
19653
|
-
};
|
|
19881
|
+
const [name] = commandText.split(/\s+/);
|
|
19882
|
+
return name?.toLowerCase() ?? null;
|
|
19654
19883
|
}
|
|
19655
|
-
async
|
|
19884
|
+
async tryHandleCommand(prompt, sessionState) {
|
|
19885
|
+
const commandName = this.getCommandName(prompt);
|
|
19886
|
+
if (commandName === null) return false;
|
|
19887
|
+
if (commandName.startsWith("$")) return false;
|
|
19656
19888
|
const sessionId = sessionState.sessionId;
|
|
19657
|
-
switch (
|
|
19889
|
+
switch (commandName) {
|
|
19658
19890
|
case "status": {
|
|
19659
19891
|
const session = new ACPSessionConnection(this.connection, sessionId);
|
|
19660
19892
|
const message = this.buildStatusMessage(sessionState);
|
|
@@ -19706,7 +19938,7 @@ var CodexCommands = class {
|
|
|
19706
19938
|
return true;
|
|
19707
19939
|
}
|
|
19708
19940
|
default:
|
|
19709
|
-
await this.sendUnknownCommandMessage(
|
|
19941
|
+
await this.sendUnknownCommandMessage(commandName, sessionId);
|
|
19710
19942
|
return true;
|
|
19711
19943
|
}
|
|
19712
19944
|
}
|
|
@@ -19863,22 +20095,84 @@ function isExtMethodRequest(request) {
|
|
|
19863
20095
|
return request.method === "authentication/status" || request.method === "authentication/logout";
|
|
19864
20096
|
}
|
|
19865
20097
|
|
|
20098
|
+
// src/FastModeConfig.ts
|
|
20099
|
+
var FAST_MODE_CONFIG_ID = "fast-mode";
|
|
20100
|
+
var FAST_MODE_ON = "on";
|
|
20101
|
+
var FAST_MODE_OFF = "off";
|
|
20102
|
+
var FAST_MODE_DESCRIPTION = "1.5x speed, increased usage";
|
|
20103
|
+
function modelSupportsFast(model) {
|
|
20104
|
+
return model?.additionalSpeedTiers?.includes("fast") ?? false;
|
|
20105
|
+
}
|
|
20106
|
+
function resolveFastServiceTier(fastModeEnabled, currentModelSupportsFast) {
|
|
20107
|
+
return fastModeEnabled && currentModelSupportsFast ? "fast" : null;
|
|
20108
|
+
}
|
|
20109
|
+
function createFastModeConfigOption(fastModeEnabled) {
|
|
20110
|
+
return {
|
|
20111
|
+
id: FAST_MODE_CONFIG_ID,
|
|
20112
|
+
name: "Fast mode",
|
|
20113
|
+
description: FAST_MODE_DESCRIPTION,
|
|
20114
|
+
category: FAST_MODE_CONFIG_ID,
|
|
20115
|
+
type: "select",
|
|
20116
|
+
currentValue: fastModeEnabled ? FAST_MODE_ON : FAST_MODE_OFF,
|
|
20117
|
+
options: [
|
|
20118
|
+
{
|
|
20119
|
+
value: FAST_MODE_OFF,
|
|
20120
|
+
name: "Off",
|
|
20121
|
+
description: "Default speed, normal usage"
|
|
20122
|
+
},
|
|
20123
|
+
{
|
|
20124
|
+
value: FAST_MODE_ON,
|
|
20125
|
+
name: "On",
|
|
20126
|
+
description: FAST_MODE_DESCRIPTION
|
|
20127
|
+
}
|
|
20128
|
+
]
|
|
20129
|
+
};
|
|
20130
|
+
}
|
|
20131
|
+
|
|
20132
|
+
// src/JBUtils.ts
|
|
20133
|
+
function isJetBrains2026_1Client(clientInfo) {
|
|
20134
|
+
if (!clientInfo) {
|
|
20135
|
+
return false;
|
|
20136
|
+
}
|
|
20137
|
+
const platform2 = clientInfo._meta?.["platform"];
|
|
20138
|
+
const isIntelliJPlatform = platform2 === "intellij";
|
|
20139
|
+
const isJetBrainsClient = clientInfo.name.startsWith("JetBrains");
|
|
20140
|
+
return (isIntelliJPlatform || isJetBrainsClient) && clientInfo.version.startsWith("2026.1");
|
|
20141
|
+
}
|
|
20142
|
+
|
|
19866
20143
|
// src/CodexAcpServer.ts
|
|
19867
|
-
var CodexAcpServer = class {
|
|
20144
|
+
var CodexAcpServer = class _CodexAcpServer {
|
|
20145
|
+
static MODEL_NAME_TOKEN_OVERRIDES = {
|
|
20146
|
+
gpt: "GPT",
|
|
20147
|
+
mini: "Mini",
|
|
20148
|
+
codex: "Codex"
|
|
20149
|
+
};
|
|
19868
20150
|
codexAcpClient;
|
|
19869
20151
|
connection;
|
|
19870
20152
|
defaultAuthRequest;
|
|
19871
20153
|
getExitCode;
|
|
19872
20154
|
availableCommands;
|
|
20155
|
+
clientInfo;
|
|
19873
20156
|
sessions;
|
|
19874
20157
|
pendingMcpStartupSessions;
|
|
20158
|
+
pendingTurnStarts;
|
|
20159
|
+
activePrompts;
|
|
20160
|
+
closingSessions;
|
|
20161
|
+
sessionGenerations;
|
|
20162
|
+
sessionOpenGenerations;
|
|
19875
20163
|
constructor(connection, codexAcpClient, defaultAuthRequest, getExitCode) {
|
|
19876
20164
|
this.sessions = /* @__PURE__ */ new Map();
|
|
19877
20165
|
this.pendingMcpStartupSessions = /* @__PURE__ */ new Map();
|
|
20166
|
+
this.pendingTurnStarts = /* @__PURE__ */ new Map();
|
|
20167
|
+
this.activePrompts = /* @__PURE__ */ new Map();
|
|
20168
|
+
this.closingSessions = /* @__PURE__ */ new Map();
|
|
20169
|
+
this.sessionGenerations = /* @__PURE__ */ new Map();
|
|
20170
|
+
this.sessionOpenGenerations = /* @__PURE__ */ new Map();
|
|
19878
20171
|
this.connection = connection;
|
|
19879
20172
|
this.codexAcpClient = codexAcpClient;
|
|
19880
20173
|
this.defaultAuthRequest = defaultAuthRequest ?? null;
|
|
19881
20174
|
this.getExitCode = getExitCode ?? (() => null);
|
|
20175
|
+
this.clientInfo = null;
|
|
19882
20176
|
this.availableCommands = new CodexCommands(
|
|
19883
20177
|
connection,
|
|
19884
20178
|
codexAcpClient,
|
|
@@ -19887,22 +20181,31 @@ var CodexAcpServer = class {
|
|
|
19887
20181
|
}
|
|
19888
20182
|
async initialize(_params) {
|
|
19889
20183
|
logger.log("Initialize request received");
|
|
20184
|
+
this.clientInfo = _params.clientInfo ?? null;
|
|
19890
20185
|
await this.runWithProcessCheck(() => this.codexAcpClient.initialize(_params));
|
|
19891
20186
|
return {
|
|
19892
20187
|
protocolVersion: PROTOCOL_VERSION,
|
|
20188
|
+
agentInfo: {
|
|
20189
|
+
name: package_default.name,
|
|
20190
|
+
title: "Codex",
|
|
20191
|
+
version: package_default.version
|
|
20192
|
+
},
|
|
19893
20193
|
agentCapabilities: {
|
|
19894
20194
|
auth: {
|
|
19895
20195
|
logout: {}
|
|
19896
20196
|
},
|
|
19897
20197
|
loadSession: true,
|
|
19898
20198
|
promptCapabilities: {
|
|
20199
|
+
embeddedContext: true,
|
|
19899
20200
|
image: true
|
|
19900
20201
|
},
|
|
19901
20202
|
sessionCapabilities: {
|
|
19902
20203
|
resume: {},
|
|
19903
|
-
list: {}
|
|
20204
|
+
list: {},
|
|
20205
|
+
close: {}
|
|
19904
20206
|
},
|
|
19905
20207
|
mcpCapabilities: {
|
|
20208
|
+
acp: false,
|
|
19906
20209
|
http: true,
|
|
19907
20210
|
sse: false
|
|
19908
20211
|
}
|
|
@@ -19941,24 +20244,123 @@ var CodexAcpServer = class {
|
|
|
19941
20244
|
}
|
|
19942
20245
|
}
|
|
19943
20246
|
async getOrCreateSession(request) {
|
|
20247
|
+
try {
|
|
20248
|
+
return await this.tryCreateSession(request);
|
|
20249
|
+
} catch (e) {
|
|
20250
|
+
const error40 = e instanceof Error ? e : new Error(String(e));
|
|
20251
|
+
await this.handleError(error40);
|
|
20252
|
+
throw e;
|
|
20253
|
+
}
|
|
20254
|
+
}
|
|
20255
|
+
async handleError(e) {
|
|
20256
|
+
if (e.message.includes("log out")) {
|
|
20257
|
+
await this.runWithProcessCheck(() => this.codexAcpClient.logout());
|
|
20258
|
+
throw RequestError.internalError(`${e.message}
|
|
20259
|
+
|
|
20260
|
+
You have been logged out. Please try again.`);
|
|
20261
|
+
}
|
|
20262
|
+
}
|
|
20263
|
+
beginSessionOpen(sessionId) {
|
|
20264
|
+
const generation = this.getSessionGeneration(sessionId);
|
|
20265
|
+
if (this.sessionIsClosing(sessionId)) {
|
|
20266
|
+
throw RequestError.invalidRequest(`Session ${sessionId} is closing`);
|
|
20267
|
+
}
|
|
20268
|
+
this.sessionOpenGenerations.set(sessionId, generation);
|
|
20269
|
+
return generation;
|
|
20270
|
+
}
|
|
20271
|
+
sessionOpenCanInstall(sessionId, generation) {
|
|
20272
|
+
return !this.sessionIsClosing(sessionId) && this.getSessionGeneration(sessionId) === generation;
|
|
20273
|
+
}
|
|
20274
|
+
async cleanupStaleSessionOpen(sessionId, generation) {
|
|
20275
|
+
if (this.sessionOpenGenerations.get(sessionId) === generation) {
|
|
20276
|
+
if (!this.sessionIsClosing(sessionId)) {
|
|
20277
|
+
this.bumpSessionGeneration(sessionId);
|
|
20278
|
+
}
|
|
20279
|
+
this.beginSessionCloseFence(sessionId);
|
|
20280
|
+
try {
|
|
20281
|
+
await this.runWithProcessCheck(() => this.codexAcpClient.closeSession(sessionId));
|
|
20282
|
+
} catch (err) {
|
|
20283
|
+
logger.error(`Failed to close stale session open for ${sessionId}`, err);
|
|
20284
|
+
} finally {
|
|
20285
|
+
this.endSessionCloseFence(sessionId);
|
|
20286
|
+
}
|
|
20287
|
+
return true;
|
|
20288
|
+
}
|
|
20289
|
+
return false;
|
|
20290
|
+
}
|
|
20291
|
+
async closeStaleSessionOpen(sessionId, generation) {
|
|
20292
|
+
await this.cleanupStaleSessionOpen(sessionId, generation);
|
|
20293
|
+
throw RequestError.invalidRequest(`Session ${sessionId} is closing`);
|
|
20294
|
+
}
|
|
20295
|
+
sessionIsClosing(sessionId) {
|
|
20296
|
+
return (this.closingSessions.get(sessionId) ?? 0) > 0;
|
|
20297
|
+
}
|
|
20298
|
+
beginSessionCloseFence(sessionId) {
|
|
20299
|
+
this.closingSessions.set(sessionId, (this.closingSessions.get(sessionId) ?? 0) + 1);
|
|
20300
|
+
}
|
|
20301
|
+
endSessionCloseFence(sessionId) {
|
|
20302
|
+
const count = this.closingSessions.get(sessionId) ?? 0;
|
|
20303
|
+
if (count <= 1) {
|
|
20304
|
+
this.closingSessions.delete(sessionId);
|
|
20305
|
+
return;
|
|
20306
|
+
}
|
|
20307
|
+
this.closingSessions.set(sessionId, count - 1);
|
|
20308
|
+
}
|
|
20309
|
+
getSessionGeneration(sessionId) {
|
|
20310
|
+
return this.sessionGenerations.get(sessionId) ?? 0;
|
|
20311
|
+
}
|
|
20312
|
+
bumpSessionGeneration(sessionId) {
|
|
20313
|
+
const generation = this.getSessionGeneration(sessionId) + 1;
|
|
20314
|
+
this.sessionGenerations.set(sessionId, generation);
|
|
20315
|
+
return generation;
|
|
20316
|
+
}
|
|
20317
|
+
async tryCreateSession(request) {
|
|
20318
|
+
const requestedSessionGeneration = "sessionId" in request ? this.beginSessionOpen(request.sessionId) : null;
|
|
19944
20319
|
await this.checkAuthorization();
|
|
19945
20320
|
const requestedMcpServers = request.mcpServers ?? [];
|
|
19946
20321
|
const mcpServerStartupVersion = requestedMcpServers.length > 0 ? this.codexAcpClient.getMcpServerStartupVersion() : null;
|
|
19947
20322
|
let sessionMetadata;
|
|
20323
|
+
let resumeSubscribed = false;
|
|
19948
20324
|
if ("sessionId" in request) {
|
|
19949
20325
|
logger.log(`Resume existing session: ${request.sessionId}...`);
|
|
19950
|
-
|
|
20326
|
+
try {
|
|
20327
|
+
sessionMetadata = await this.runWithProcessCheck(
|
|
20328
|
+
() => this.codexAcpClient.resumeSession(request, () => {
|
|
20329
|
+
resumeSubscribed = true;
|
|
20330
|
+
})
|
|
20331
|
+
);
|
|
20332
|
+
} catch (err) {
|
|
20333
|
+
if (resumeSubscribed && requestedSessionGeneration !== null) {
|
|
20334
|
+
await this.cleanupStaleSessionOpen(request.sessionId, requestedSessionGeneration);
|
|
20335
|
+
}
|
|
20336
|
+
throw err;
|
|
20337
|
+
}
|
|
19951
20338
|
} else {
|
|
19952
20339
|
logger.log(`Create new session...`);
|
|
19953
20340
|
sessionMetadata = await this.runWithProcessCheck(() => this.codexAcpClient.newSession(request));
|
|
19954
20341
|
}
|
|
19955
|
-
const account = await this.getActiveAccount();
|
|
19956
20342
|
const { sessionId, currentModelId, models } = sessionMetadata;
|
|
20343
|
+
let account;
|
|
20344
|
+
try {
|
|
20345
|
+
account = await this.getActiveAccount();
|
|
20346
|
+
} catch (err) {
|
|
20347
|
+
if (resumeSubscribed && requestedSessionGeneration !== null) {
|
|
20348
|
+
await this.cleanupStaleSessionOpen(sessionId, requestedSessionGeneration);
|
|
20349
|
+
}
|
|
20350
|
+
throw err;
|
|
20351
|
+
}
|
|
20352
|
+
const sessionGeneration = requestedSessionGeneration ?? this.beginSessionOpen(sessionId);
|
|
20353
|
+
if (!this.sessionOpenCanInstall(sessionId, sessionGeneration)) {
|
|
20354
|
+
resumeSubscribed = false;
|
|
20355
|
+
await this.closeStaleSessionOpen(sessionId, sessionGeneration);
|
|
20356
|
+
}
|
|
19957
20357
|
const sessionMcpServers = this.resolveSessionMcpServers(requestedMcpServers, "sessionId" in request);
|
|
19958
20358
|
const currentModel = this.findCurrentModel(models, currentModelId);
|
|
20359
|
+
const currentModelSupportsFast = modelSupportsFast(currentModel);
|
|
19959
20360
|
const sessionState = {
|
|
19960
20361
|
sessionId,
|
|
19961
20362
|
currentModelId,
|
|
20363
|
+
availableModels: models,
|
|
19962
20364
|
supportedReasoningEfforts: currentModel?.supportedReasoningEfforts ?? [],
|
|
19963
20365
|
supportedInputModalities: currentModel?.inputModalities ?? ["text", "image"],
|
|
19964
20366
|
agentMode: AgentMode.getInitialAgentMode(),
|
|
@@ -19969,12 +20371,15 @@ var CodexAcpServer = class {
|
|
|
19969
20371
|
rateLimits: null,
|
|
19970
20372
|
account,
|
|
19971
20373
|
cwd: request.cwd,
|
|
20374
|
+
fastModeEnabled: sessionMetadata.currentServiceTier === "fast",
|
|
20375
|
+
currentModelSupportsFast,
|
|
19972
20376
|
sessionMcpServers
|
|
19973
20377
|
};
|
|
19974
20378
|
this.sessions.set(sessionId, sessionState);
|
|
20379
|
+
resumeSubscribed = false;
|
|
19975
20380
|
if (requestedMcpServers.length > 0 && mcpServerStartupVersion !== null) {
|
|
19976
20381
|
this.pendingMcpStartupSessions.set(sessionId, {
|
|
19977
|
-
requestedServers: new Set(requestedMcpServers
|
|
20382
|
+
requestedServers: new Set(getRequestedMcpServerNames(requestedMcpServers)),
|
|
19978
20383
|
afterVersion: mcpServerStartupVersion
|
|
19979
20384
|
});
|
|
19980
20385
|
this.publishMcpStartupStatusAsync(sessionId);
|
|
@@ -20007,7 +20412,8 @@ var CodexAcpServer = class {
|
|
|
20007
20412
|
});
|
|
20008
20413
|
return {
|
|
20009
20414
|
models: modelState,
|
|
20010
|
-
modes: modeState
|
|
20415
|
+
modes: modeState,
|
|
20416
|
+
...this.createSessionConfigOptionsResponse(this.getSessionState(sessionId))
|
|
20011
20417
|
};
|
|
20012
20418
|
}
|
|
20013
20419
|
async resumeSession(params) {
|
|
@@ -20020,7 +20426,8 @@ var CodexAcpServer = class {
|
|
|
20020
20426
|
});
|
|
20021
20427
|
return {
|
|
20022
20428
|
models: modelState,
|
|
20023
|
-
modes: modeState
|
|
20429
|
+
modes: modeState,
|
|
20430
|
+
...this.createSessionConfigOptionsResponse(this.getSessionState(sessionId))
|
|
20024
20431
|
};
|
|
20025
20432
|
}
|
|
20026
20433
|
async listSessions(params) {
|
|
@@ -20028,6 +20435,35 @@ var CodexAcpServer = class {
|
|
|
20028
20435
|
await this.checkAuthorization();
|
|
20029
20436
|
return await this.runWithProcessCheck(() => this.codexAcpClient.listSessions(params));
|
|
20030
20437
|
}
|
|
20438
|
+
async closeSession(params) {
|
|
20439
|
+
logger.log("Closing session...", { sessionId: params.sessionId });
|
|
20440
|
+
const closeGeneration = this.bumpSessionGeneration(params.sessionId);
|
|
20441
|
+
const sessionState = this.sessions.get(params.sessionId);
|
|
20442
|
+
this.beginSessionCloseFence(params.sessionId);
|
|
20443
|
+
try {
|
|
20444
|
+
if (sessionState) {
|
|
20445
|
+
await this.interruptSessionTurn(sessionState, "Close", true);
|
|
20446
|
+
} else {
|
|
20447
|
+
logger.log("Close request received for unknown local session", { sessionId: params.sessionId });
|
|
20448
|
+
}
|
|
20449
|
+
const activePrompt = this.activePrompts.get(params.sessionId);
|
|
20450
|
+
if (activePrompt) {
|
|
20451
|
+
activePrompt.requestClose();
|
|
20452
|
+
await activePrompt.completion;
|
|
20453
|
+
}
|
|
20454
|
+
await this.runWithProcessCheck(() => this.codexAcpClient.closeSession(params.sessionId));
|
|
20455
|
+
logger.log("Session closed", { sessionId: params.sessionId });
|
|
20456
|
+
} finally {
|
|
20457
|
+
if (this.getSessionGeneration(params.sessionId) === closeGeneration) {
|
|
20458
|
+
this.sessions.delete(params.sessionId);
|
|
20459
|
+
this.pendingMcpStartupSessions.delete(params.sessionId);
|
|
20460
|
+
this.pendingTurnStarts.delete(params.sessionId);
|
|
20461
|
+
this.activePrompts.delete(params.sessionId);
|
|
20462
|
+
}
|
|
20463
|
+
this.endSessionCloseFence(params.sessionId);
|
|
20464
|
+
}
|
|
20465
|
+
return {};
|
|
20466
|
+
}
|
|
20031
20467
|
async newSession(params) {
|
|
20032
20468
|
logger.log("Starting new session...");
|
|
20033
20469
|
const [sessionId, modelState, modeState] = await this.getOrCreateSession(params);
|
|
@@ -20039,7 +20475,8 @@ var CodexAcpServer = class {
|
|
|
20039
20475
|
return {
|
|
20040
20476
|
sessionId,
|
|
20041
20477
|
models: modelState,
|
|
20042
|
-
modes: modeState
|
|
20478
|
+
modes: modeState,
|
|
20479
|
+
...this.createSessionConfigOptionsResponse(this.getSessionState(sessionId))
|
|
20043
20480
|
};
|
|
20044
20481
|
}
|
|
20045
20482
|
async authenticate(_params) {
|
|
@@ -20064,12 +20501,75 @@ var CodexAcpServer = class {
|
|
|
20064
20501
|
});
|
|
20065
20502
|
const sessionState = this.sessions.get(_params.sessionId);
|
|
20066
20503
|
if (!sessionState) throw new Error(`Session ${_params.sessionId} not found`);
|
|
20067
|
-
|
|
20504
|
+
this.applyModeChange(sessionState, _params.modeId);
|
|
20505
|
+
return {};
|
|
20506
|
+
}
|
|
20507
|
+
async setSessionConfigOption(params) {
|
|
20508
|
+
logger.log("Set session config option requested", {
|
|
20509
|
+
sessionId: params.sessionId,
|
|
20510
|
+
configId: params.configId
|
|
20511
|
+
});
|
|
20512
|
+
const sessionState = this.sessions.get(params.sessionId);
|
|
20513
|
+
if (!sessionState) throw new Error(`Session ${params.sessionId} not found`);
|
|
20514
|
+
if (typeof params.value !== "string") {
|
|
20515
|
+
throw RequestError.invalidParams();
|
|
20516
|
+
}
|
|
20517
|
+
const value = params.value;
|
|
20518
|
+
switch (params.configId) {
|
|
20519
|
+
case FAST_MODE_CONFIG_ID:
|
|
20520
|
+
this.applyFastModeChange(sessionState, value);
|
|
20521
|
+
break;
|
|
20522
|
+
case MODE_CONFIG_ID:
|
|
20523
|
+
this.applyModeChange(sessionState, value);
|
|
20524
|
+
break;
|
|
20525
|
+
case MODEL_CONFIG_ID:
|
|
20526
|
+
this.applyModelChange(sessionState, value);
|
|
20527
|
+
break;
|
|
20528
|
+
case REASONING_EFFORT_CONFIG_ID:
|
|
20529
|
+
this.applyReasoningEffortChange(sessionState, value);
|
|
20530
|
+
break;
|
|
20531
|
+
default:
|
|
20532
|
+
throw RequestError.invalidParams();
|
|
20533
|
+
}
|
|
20534
|
+
return {
|
|
20535
|
+
configOptions: this.createSessionConfigOptions(sessionState)
|
|
20536
|
+
};
|
|
20537
|
+
}
|
|
20538
|
+
applyFastModeChange(sessionState, value) {
|
|
20539
|
+
if (value !== FAST_MODE_ON && value !== FAST_MODE_OFF) {
|
|
20540
|
+
throw RequestError.invalidParams();
|
|
20541
|
+
}
|
|
20542
|
+
sessionState.fastModeEnabled = value === FAST_MODE_ON;
|
|
20543
|
+
}
|
|
20544
|
+
applyModeChange(sessionState, value) {
|
|
20545
|
+
const newMode = AgentMode.find(value);
|
|
20068
20546
|
if (!newMode) {
|
|
20069
20547
|
throw RequestError.invalidParams();
|
|
20070
20548
|
}
|
|
20071
20549
|
sessionState.agentMode = newMode;
|
|
20072
|
-
|
|
20550
|
+
}
|
|
20551
|
+
applyModelChange(sessionState, value) {
|
|
20552
|
+
const model = sessionState.availableModels.find((m) => m.id === value);
|
|
20553
|
+
if (!model) {
|
|
20554
|
+
throw RequestError.invalidParams();
|
|
20555
|
+
}
|
|
20556
|
+
const currentEffort = ModelId.fromString(sessionState.currentModelId).effort;
|
|
20557
|
+
const effort = findSupportedEffort(model.supportedReasoningEfforts, currentEffort) ?? model.defaultReasoningEffort;
|
|
20558
|
+
this.applyModelAndEffort(sessionState, model, effort);
|
|
20559
|
+
}
|
|
20560
|
+
applyReasoningEffortChange(sessionState, value) {
|
|
20561
|
+
const effort = findSupportedEffort(sessionState.supportedReasoningEfforts, value);
|
|
20562
|
+
if (!effort) {
|
|
20563
|
+
throw RequestError.invalidParams();
|
|
20564
|
+
}
|
|
20565
|
+
const { model } = ModelId.fromString(sessionState.currentModelId);
|
|
20566
|
+
sessionState.currentModelId = ModelId.create(model, effort).toString();
|
|
20567
|
+
}
|
|
20568
|
+
applyModelAndEffort(sessionState, model, effort) {
|
|
20569
|
+
sessionState.currentModelId = ModelId.fromComponents(model, effort).toString();
|
|
20570
|
+
sessionState.supportedReasoningEfforts = model.supportedReasoningEfforts;
|
|
20571
|
+
sessionState.supportedInputModalities = model.inputModalities;
|
|
20572
|
+
sessionState.currentModelSupportsFast = modelSupportsFast(model);
|
|
20073
20573
|
}
|
|
20074
20574
|
async unstable_setSessionModel(params) {
|
|
20075
20575
|
logger.log("Set session model requested", {
|
|
@@ -20078,30 +20578,44 @@ var CodexAcpServer = class {
|
|
|
20078
20578
|
});
|
|
20079
20579
|
const sessionState = this.sessions.get(params.sessionId);
|
|
20080
20580
|
if (!sessionState) throw new Error(`Session ${params.sessionId} not found`);
|
|
20081
|
-
const
|
|
20082
|
-
const requestedModelName = requestedModelId.model;
|
|
20083
|
-
const requestedEffort = requestedModelId.effort;
|
|
20581
|
+
const { model: requestedModelName, effort: requestedEffort } = ModelId.fromString(params.modelId);
|
|
20084
20582
|
const models = await this.codexAcpClient.fetchAvailableModels();
|
|
20085
20583
|
const model = models.find((m) => m.id === requestedModelName);
|
|
20086
20584
|
if (!model) throw new Error(`Unknown model ${params.modelId}`);
|
|
20087
|
-
const requestedEffortValue = requestedEffort;
|
|
20088
20585
|
let reasoningEffort;
|
|
20089
|
-
if (
|
|
20090
|
-
const matchedEffort = model.supportedReasoningEfforts
|
|
20091
|
-
(option) => option.reasoningEffort === requestedEffortValue
|
|
20092
|
-
)?.reasoningEffort;
|
|
20586
|
+
if (requestedEffort) {
|
|
20587
|
+
const matchedEffort = findSupportedEffort(model.supportedReasoningEfforts, requestedEffort);
|
|
20093
20588
|
if (!matchedEffort) {
|
|
20094
|
-
throw new Error(`Unsupported reasoning effort ${
|
|
20589
|
+
throw new Error(`Unsupported reasoning effort ${requestedEffort} for model ${requestedModelName}`);
|
|
20095
20590
|
}
|
|
20096
20591
|
reasoningEffort = matchedEffort;
|
|
20097
20592
|
} else {
|
|
20098
20593
|
reasoningEffort = model.defaultReasoningEffort;
|
|
20099
20594
|
}
|
|
20100
|
-
sessionState.
|
|
20101
|
-
sessionState
|
|
20102
|
-
sessionState.supportedInputModalities = model.inputModalities;
|
|
20595
|
+
sessionState.availableModels = models;
|
|
20596
|
+
this.applyModelAndEffort(sessionState, model, reasoningEffort);
|
|
20103
20597
|
return {};
|
|
20104
20598
|
}
|
|
20599
|
+
createSessionConfigOptions(sessionState) {
|
|
20600
|
+
const currentModelId = ModelId.fromString(sessionState.currentModelId);
|
|
20601
|
+
return [
|
|
20602
|
+
sessionState.agentMode.toConfigOption(),
|
|
20603
|
+
createModelConfigOption(sessionState.availableModels, currentModelId.model),
|
|
20604
|
+
createReasoningEffortConfigOption(sessionState.supportedReasoningEfforts, currentModelId.effort),
|
|
20605
|
+
createFastModeConfigOption(sessionState.fastModeEnabled)
|
|
20606
|
+
];
|
|
20607
|
+
}
|
|
20608
|
+
createSessionConfigOptionsResponse(sessionState) {
|
|
20609
|
+
if (!this.isSessionConfigEnabled()) {
|
|
20610
|
+
return {};
|
|
20611
|
+
}
|
|
20612
|
+
return {
|
|
20613
|
+
configOptions: this.createSessionConfigOptions(sessionState)
|
|
20614
|
+
};
|
|
20615
|
+
}
|
|
20616
|
+
isSessionConfigEnabled() {
|
|
20617
|
+
return !isJetBrains2026_1Client(this.clientInfo);
|
|
20618
|
+
}
|
|
20105
20619
|
publishAvailableCommandsAsync(sessionId) {
|
|
20106
20620
|
void this.availableCommands.publish(sessionId);
|
|
20107
20621
|
}
|
|
@@ -20109,11 +20623,14 @@ var CodexAcpServer = class {
|
|
|
20109
20623
|
const modelId = ModelId.fromString(currentModelId);
|
|
20110
20624
|
return models.find((m) => m.id === modelId.model);
|
|
20111
20625
|
}
|
|
20626
|
+
normalizeModelDisplayName(displayName) {
|
|
20627
|
+
return displayName.split("-").map((token) => _CodexAcpServer.MODEL_NAME_TOKEN_OVERRIDES[token.toLowerCase()] ?? token).join("-");
|
|
20628
|
+
}
|
|
20112
20629
|
createModelState(availableModels, selectedModelId) {
|
|
20113
20630
|
const allowedModels = availableModels.flatMap(
|
|
20114
20631
|
(model) => model.supportedReasoningEfforts.map((effort) => ({
|
|
20115
20632
|
modelId: ModelId.fromComponents(model, effort.reasoningEffort).toString(),
|
|
20116
|
-
name: `${model.displayName} (${effort.reasoningEffort})`,
|
|
20633
|
+
name: `${this.normalizeModelDisplayName(model.displayName)} (${effort.reasoningEffort})`,
|
|
20117
20634
|
description: `${model.description} ${effort.description}`
|
|
20118
20635
|
}))
|
|
20119
20636
|
);
|
|
@@ -20123,20 +20640,46 @@ var CodexAcpServer = class {
|
|
|
20123
20640
|
};
|
|
20124
20641
|
}
|
|
20125
20642
|
async getOrCreateSessionWithHistory(request) {
|
|
20643
|
+
const requestedSessionGeneration = this.beginSessionOpen(request.sessionId);
|
|
20126
20644
|
await this.checkAuthorization();
|
|
20127
20645
|
const requestedMcpServers = request.mcpServers ?? [];
|
|
20128
20646
|
const mcpServerStartupVersion = requestedMcpServers.length > 0 ? this.codexAcpClient.getMcpServerStartupVersion() : null;
|
|
20129
20647
|
logger.log(`Load existing session: ${request.sessionId}...`);
|
|
20130
|
-
|
|
20131
|
-
|
|
20132
|
-
|
|
20133
|
-
|
|
20648
|
+
let subscribed = false;
|
|
20649
|
+
let sessionMetadata;
|
|
20650
|
+
try {
|
|
20651
|
+
sessionMetadata = await this.runWithProcessCheck(
|
|
20652
|
+
() => this.codexAcpClient.loadSession(request, () => {
|
|
20653
|
+
subscribed = true;
|
|
20654
|
+
})
|
|
20655
|
+
);
|
|
20656
|
+
} catch (err) {
|
|
20657
|
+
if (subscribed) {
|
|
20658
|
+
await this.cleanupStaleSessionOpen(request.sessionId, requestedSessionGeneration);
|
|
20659
|
+
}
|
|
20660
|
+
throw err;
|
|
20661
|
+
}
|
|
20134
20662
|
const { sessionId, currentModelId, models, thread } = sessionMetadata;
|
|
20663
|
+
let account;
|
|
20664
|
+
try {
|
|
20665
|
+
account = await this.getActiveAccount();
|
|
20666
|
+
} catch (err) {
|
|
20667
|
+
if (subscribed) {
|
|
20668
|
+
await this.cleanupStaleSessionOpen(request.sessionId, requestedSessionGeneration);
|
|
20669
|
+
}
|
|
20670
|
+
throw err;
|
|
20671
|
+
}
|
|
20672
|
+
if (!this.sessionOpenCanInstall(sessionId, requestedSessionGeneration)) {
|
|
20673
|
+
subscribed = false;
|
|
20674
|
+
await this.closeStaleSessionOpen(sessionId, requestedSessionGeneration);
|
|
20675
|
+
}
|
|
20135
20676
|
const sessionMcpServers = this.resolveSessionMcpServers(requestedMcpServers, true);
|
|
20136
20677
|
const currentModel = this.findCurrentModel(models, currentModelId);
|
|
20678
|
+
const currentModelSupportsFast = modelSupportsFast(currentModel);
|
|
20137
20679
|
const sessionState = {
|
|
20138
20680
|
sessionId,
|
|
20139
20681
|
currentModelId,
|
|
20682
|
+
availableModels: models,
|
|
20140
20683
|
supportedReasoningEfforts: currentModel?.supportedReasoningEfforts ?? [],
|
|
20141
20684
|
supportedInputModalities: currentModel?.inputModalities ?? ["text", "image"],
|
|
20142
20685
|
agentMode: AgentMode.getInitialAgentMode(),
|
|
@@ -20147,12 +20690,15 @@ var CodexAcpServer = class {
|
|
|
20147
20690
|
rateLimits: null,
|
|
20148
20691
|
account,
|
|
20149
20692
|
cwd: request.cwd,
|
|
20693
|
+
fastModeEnabled: sessionMetadata.currentServiceTier === "fast",
|
|
20694
|
+
currentModelSupportsFast,
|
|
20150
20695
|
sessionMcpServers
|
|
20151
20696
|
};
|
|
20152
20697
|
this.sessions.set(sessionId, sessionState);
|
|
20698
|
+
subscribed = false;
|
|
20153
20699
|
if (requestedMcpServers.length > 0 && mcpServerStartupVersion !== null) {
|
|
20154
20700
|
this.pendingMcpStartupSessions.set(sessionId, {
|
|
20155
|
-
requestedServers: new Set(requestedMcpServers
|
|
20701
|
+
requestedServers: new Set(getRequestedMcpServerNames(requestedMcpServers)),
|
|
20156
20702
|
afterVersion: mcpServerStartupVersion
|
|
20157
20703
|
});
|
|
20158
20704
|
this.publishMcpStartupStatusAsync(sessionId);
|
|
@@ -20398,11 +20944,16 @@ ${item.text}`
|
|
|
20398
20944
|
pendingStartup.afterVersion
|
|
20399
20945
|
)
|
|
20400
20946
|
);
|
|
20947
|
+
if (!this.sessions.has(sessionId) || this.sessionIsClosing(sessionId) || this.pendingMcpStartupSessions.get(sessionId) !== pendingStartup) {
|
|
20948
|
+
return;
|
|
20949
|
+
}
|
|
20401
20950
|
await this.publishMcpStartupStatus(sessionId, mcpStartup, pendingStartup.requestedServers);
|
|
20402
20951
|
} catch (err) {
|
|
20403
20952
|
logger.error(`Failed to publish MCP startup status for session ${sessionId}`, err);
|
|
20404
20953
|
} finally {
|
|
20405
|
-
this.pendingMcpStartupSessions.
|
|
20954
|
+
if (this.pendingMcpStartupSessions.get(sessionId) === pendingStartup) {
|
|
20955
|
+
this.pendingMcpStartupSessions.delete(sessionId);
|
|
20956
|
+
}
|
|
20406
20957
|
}
|
|
20407
20958
|
}
|
|
20408
20959
|
async publishMcpStartupStatus(sessionId, mcpStartup, requestedServers) {
|
|
@@ -20418,6 +20969,125 @@ ${item.text}`
|
|
|
20418
20969
|
});
|
|
20419
20970
|
}
|
|
20420
20971
|
}
|
|
20972
|
+
trackActivePrompt(sessionId) {
|
|
20973
|
+
let resolveCompletion = () => {
|
|
20974
|
+
};
|
|
20975
|
+
const completion = new Promise((resolve) => {
|
|
20976
|
+
resolveCompletion = resolve;
|
|
20977
|
+
});
|
|
20978
|
+
let resolveCloseSignal = () => {
|
|
20979
|
+
};
|
|
20980
|
+
const closeSignal = new Promise((resolve) => {
|
|
20981
|
+
resolveCloseSignal = resolve;
|
|
20982
|
+
});
|
|
20983
|
+
let completed = false;
|
|
20984
|
+
let closeRequested = false;
|
|
20985
|
+
const activePrompt = {
|
|
20986
|
+
completion,
|
|
20987
|
+
closeSignal,
|
|
20988
|
+
requestClose: () => {
|
|
20989
|
+
if (closeRequested) {
|
|
20990
|
+
return;
|
|
20991
|
+
}
|
|
20992
|
+
closeRequested = true;
|
|
20993
|
+
resolveCloseSignal(null);
|
|
20994
|
+
},
|
|
20995
|
+
complete: () => {
|
|
20996
|
+
if (completed) {
|
|
20997
|
+
return;
|
|
20998
|
+
}
|
|
20999
|
+
completed = true;
|
|
21000
|
+
if (this.activePrompts.get(sessionId) === activePrompt) {
|
|
21001
|
+
this.activePrompts.delete(sessionId);
|
|
21002
|
+
}
|
|
21003
|
+
resolveCompletion();
|
|
21004
|
+
}
|
|
21005
|
+
};
|
|
21006
|
+
this.activePrompts.set(sessionId, activePrompt);
|
|
21007
|
+
return activePrompt;
|
|
21008
|
+
}
|
|
21009
|
+
createPendingTurnStart() {
|
|
21010
|
+
let resolve = () => {
|
|
21011
|
+
};
|
|
21012
|
+
const promise2 = new Promise((innerResolve) => {
|
|
21013
|
+
resolve = innerResolve;
|
|
21014
|
+
});
|
|
21015
|
+
return { promise: promise2, resolve };
|
|
21016
|
+
}
|
|
21017
|
+
interruptLateStartedTurn(sessionId, turnId) {
|
|
21018
|
+
this.codexAcpClient.markTurnStale({
|
|
21019
|
+
threadId: sessionId,
|
|
21020
|
+
turnId
|
|
21021
|
+
});
|
|
21022
|
+
void this.runWithProcessCheck(() => this.codexAcpClient.turnInterrupt({
|
|
21023
|
+
threadId: sessionId,
|
|
21024
|
+
turnId
|
|
21025
|
+
})).catch((err) => {
|
|
21026
|
+
logger.error(`Close - late turnInterrupt failed`, err);
|
|
21027
|
+
}).finally(() => {
|
|
21028
|
+
this.codexAcpClient.resolveTurnInterrupted({
|
|
21029
|
+
threadId: sessionId,
|
|
21030
|
+
turnId
|
|
21031
|
+
});
|
|
21032
|
+
});
|
|
21033
|
+
}
|
|
21034
|
+
promptIsClosedOrStale(sessionId, activePrompt) {
|
|
21035
|
+
return this.activePrompts.get(sessionId) !== activePrompt || this.sessionIsClosing(sessionId);
|
|
21036
|
+
}
|
|
21037
|
+
async interruptSessionTurn(sessionState, requestName, resolveInterruptedTurn) {
|
|
21038
|
+
const turnId = await this.getInterruptibleTurnId(sessionState, requestName);
|
|
21039
|
+
if (!turnId) {
|
|
21040
|
+
return;
|
|
21041
|
+
}
|
|
21042
|
+
logger.log(`${requestName} session requested`, {
|
|
21043
|
+
sessionId: sessionState.sessionId,
|
|
21044
|
+
currentTurnId: turnId
|
|
21045
|
+
});
|
|
21046
|
+
if (resolveInterruptedTurn) {
|
|
21047
|
+
this.codexAcpClient.markTurnStale({
|
|
21048
|
+
threadId: sessionState.sessionId,
|
|
21049
|
+
turnId
|
|
21050
|
+
});
|
|
21051
|
+
}
|
|
21052
|
+
try {
|
|
21053
|
+
await this.runWithProcessCheck(() => this.codexAcpClient.turnInterrupt({
|
|
21054
|
+
threadId: sessionState.sessionId,
|
|
21055
|
+
turnId
|
|
21056
|
+
}));
|
|
21057
|
+
logger.log(`${requestName} - turnInterrupt succeeded`, {
|
|
21058
|
+
sessionId: sessionState.sessionId,
|
|
21059
|
+
currentTurnId: turnId
|
|
21060
|
+
});
|
|
21061
|
+
} catch (err) {
|
|
21062
|
+
logger.error(`${requestName} - turnInterrupt failed`, err);
|
|
21063
|
+
} finally {
|
|
21064
|
+
if (resolveInterruptedTurn) {
|
|
21065
|
+
this.codexAcpClient.resolveTurnInterrupted({
|
|
21066
|
+
threadId: sessionState.sessionId,
|
|
21067
|
+
turnId
|
|
21068
|
+
});
|
|
21069
|
+
}
|
|
21070
|
+
}
|
|
21071
|
+
}
|
|
21072
|
+
async getInterruptibleTurnId(sessionState, requestName) {
|
|
21073
|
+
if (sessionState.currentTurnId) {
|
|
21074
|
+
return sessionState.currentTurnId;
|
|
21075
|
+
}
|
|
21076
|
+
const pendingTurnStart = this.pendingTurnStarts.get(sessionState.sessionId);
|
|
21077
|
+
if (!pendingTurnStart) {
|
|
21078
|
+
logger.log(`${requestName} request rejected: no current turn`, { sessionId: sessionState.sessionId });
|
|
21079
|
+
return null;
|
|
21080
|
+
}
|
|
21081
|
+
if (requestName === "Close") {
|
|
21082
|
+
pendingTurnStart.resolve(null);
|
|
21083
|
+
return null;
|
|
21084
|
+
}
|
|
21085
|
+
const turnId = await pendingTurnStart.promise;
|
|
21086
|
+
if (!turnId) {
|
|
21087
|
+
logger.log(`${requestName} request rejected: no current turn`, { sessionId: sessionState.sessionId });
|
|
21088
|
+
}
|
|
21089
|
+
return turnId;
|
|
21090
|
+
}
|
|
20421
21091
|
async prompt(params) {
|
|
20422
21092
|
logger.log("Prompt received", {
|
|
20423
21093
|
sessionId: params.sessionId,
|
|
@@ -20426,6 +21096,8 @@ ${item.text}`
|
|
|
20426
21096
|
const sessionState = this.getSessionState(params.sessionId);
|
|
20427
21097
|
sessionState.currentTurnId = null;
|
|
20428
21098
|
sessionState.lastTokenUsage = null;
|
|
21099
|
+
const activePrompt = this.trackActivePrompt(params.sessionId);
|
|
21100
|
+
let pendingTurnStart = null;
|
|
20429
21101
|
try {
|
|
20430
21102
|
const eventHandler = new CodexEventHandler(this.connection, sessionState);
|
|
20431
21103
|
const approvalHandler = new CodexApprovalHandler(this.connection, sessionState);
|
|
@@ -20439,7 +21111,7 @@ ${item.text}`
|
|
|
20439
21111
|
approvalHandler,
|
|
20440
21112
|
elicitationHandler
|
|
20441
21113
|
);
|
|
20442
|
-
if (await this.availableCommands.
|
|
21114
|
+
if (await this.availableCommands.tryHandleCommand(params.prompt, sessionState)) {
|
|
20443
21115
|
logger.log("Prompt handled by a command");
|
|
20444
21116
|
return {
|
|
20445
21117
|
stopReason: "end_turn",
|
|
@@ -20447,6 +21119,13 @@ ${item.text}`
|
|
|
20447
21119
|
_meta: this.buildQuotaMeta(sessionState)
|
|
20448
21120
|
};
|
|
20449
21121
|
}
|
|
21122
|
+
if (this.sessionIsClosing(params.sessionId)) {
|
|
21123
|
+
return {
|
|
21124
|
+
stopReason: "cancelled",
|
|
21125
|
+
usage: this.buildPromptUsage(sessionState.lastTokenUsage),
|
|
21126
|
+
_meta: this.buildQuotaMeta(sessionState)
|
|
21127
|
+
};
|
|
21128
|
+
}
|
|
20450
21129
|
const modelId = ModelId.fromString(sessionState.currentModelId);
|
|
20451
21130
|
const modelLacksReasoning = sessionState.supportedReasoningEfforts.length > 0 && sessionState.supportedReasoningEfforts.every((e) => e.reasoningEffort === "none");
|
|
20452
21131
|
const disableSummary = sessionState.account?.type === "apiKey" || modelLacksReasoning;
|
|
@@ -20460,20 +21139,61 @@ ${item.text}`
|
|
|
20460
21139
|
throw RequestError.invalidRequest("The current model does not support image input");
|
|
20461
21140
|
}
|
|
20462
21141
|
const agentMode = sessionState.agentMode;
|
|
20463
|
-
const
|
|
20464
|
-
|
|
21142
|
+
const serviceTier = resolveFastServiceTier(
|
|
21143
|
+
sessionState.fastModeEnabled,
|
|
21144
|
+
sessionState.currentModelSupportsFast
|
|
20465
21145
|
);
|
|
21146
|
+
pendingTurnStart = this.createPendingTurnStart();
|
|
21147
|
+
this.pendingTurnStarts.set(params.sessionId, pendingTurnStart);
|
|
21148
|
+
const sendPromptPromise = this.runWithProcessCheck(
|
|
21149
|
+
() => this.codexAcpClient.sendPrompt(
|
|
21150
|
+
params,
|
|
21151
|
+
agentMode,
|
|
21152
|
+
modelId,
|
|
21153
|
+
serviceTier,
|
|
21154
|
+
disableSummary,
|
|
21155
|
+
sessionState.cwd,
|
|
21156
|
+
(turnId) => {
|
|
21157
|
+
if (this.promptIsClosedOrStale(params.sessionId, activePrompt)) {
|
|
21158
|
+
this.interruptLateStartedTurn(params.sessionId, turnId);
|
|
21159
|
+
return;
|
|
21160
|
+
}
|
|
21161
|
+
sessionState.currentTurnId = turnId;
|
|
21162
|
+
pendingTurnStart?.resolve(turnId);
|
|
21163
|
+
},
|
|
21164
|
+
() => this.promptIsClosedOrStale(params.sessionId, activePrompt)
|
|
21165
|
+
)
|
|
21166
|
+
);
|
|
21167
|
+
void sendPromptPromise.catch((err) => {
|
|
21168
|
+
if (this.activePrompts.get(params.sessionId) !== activePrompt) {
|
|
21169
|
+
logger.error(`Prompt for closed session ${params.sessionId} failed after close`, err);
|
|
21170
|
+
}
|
|
21171
|
+
});
|
|
21172
|
+
const turnCompleted = await Promise.race([
|
|
21173
|
+
sendPromptPromise,
|
|
21174
|
+
activePrompt.closeSignal
|
|
21175
|
+
]);
|
|
21176
|
+
if (turnCompleted === null) {
|
|
21177
|
+
return {
|
|
21178
|
+
stopReason: "cancelled",
|
|
21179
|
+
usage: this.buildPromptUsage(sessionState.lastTokenUsage),
|
|
21180
|
+
_meta: this.buildQuotaMeta(sessionState)
|
|
21181
|
+
};
|
|
21182
|
+
}
|
|
21183
|
+
await this.codexAcpClient.waitForSessionNotifications(params.sessionId);
|
|
20466
21184
|
if (turnCompleted.turn.status === "interrupted") {
|
|
20467
|
-
|
|
20468
|
-
|
|
20469
|
-
|
|
20470
|
-
|
|
20471
|
-
|
|
20472
|
-
|
|
20473
|
-
|
|
21185
|
+
if (!this.sessionIsClosing(params.sessionId) && this.sessions.has(params.sessionId)) {
|
|
21186
|
+
await this.connection.sessionUpdate({
|
|
21187
|
+
sessionId: params.sessionId,
|
|
21188
|
+
update: {
|
|
21189
|
+
sessionUpdate: "agent_message_chunk",
|
|
21190
|
+
content: {
|
|
21191
|
+
type: "text",
|
|
21192
|
+
text: "*Conversation interrupted*"
|
|
21193
|
+
}
|
|
20474
21194
|
}
|
|
20475
|
-
}
|
|
20476
|
-
}
|
|
21195
|
+
});
|
|
21196
|
+
}
|
|
20477
21197
|
return {
|
|
20478
21198
|
stopReason: "cancelled",
|
|
20479
21199
|
usage: this.buildPromptUsage(sessionState.lastTokenUsage),
|
|
@@ -20495,6 +21215,11 @@ ${item.text}`
|
|
|
20495
21215
|
} finally {
|
|
20496
21216
|
logger.log("Prompt completed", { sessionId: params.sessionId });
|
|
20497
21217
|
sessionState.currentTurnId = null;
|
|
21218
|
+
if (pendingTurnStart !== null && this.pendingTurnStarts.get(params.sessionId) === pendingTurnStart) {
|
|
21219
|
+
this.pendingTurnStarts.delete(params.sessionId);
|
|
21220
|
+
}
|
|
21221
|
+
pendingTurnStart?.resolve(null);
|
|
21222
|
+
activePrompt.complete();
|
|
20498
21223
|
}
|
|
20499
21224
|
}
|
|
20500
21225
|
buildQuotaMeta(sessionState) {
|
|
@@ -20535,30 +21260,11 @@ ${item.text}`
|
|
|
20535
21260
|
logger.log("Cancel request rejected: session not found", { sessionId: params.sessionId });
|
|
20536
21261
|
return;
|
|
20537
21262
|
}
|
|
20538
|
-
|
|
20539
|
-
logger.log("Cancel request rejected: no current turn", { sessionId: params.sessionId });
|
|
20540
|
-
return;
|
|
20541
|
-
}
|
|
20542
|
-
logger.log("Cancel session requested", {
|
|
20543
|
-
sessionId: params.sessionId,
|
|
20544
|
-
currentTurnId: sessionState.currentTurnId
|
|
20545
|
-
});
|
|
20546
|
-
try {
|
|
20547
|
-
await this.codexAcpClient.turnInterrupt({
|
|
20548
|
-
threadId: params.sessionId,
|
|
20549
|
-
turnId: sessionState.currentTurnId
|
|
20550
|
-
});
|
|
20551
|
-
logger.log("Cancel - turnInterrupt succeeded", {
|
|
20552
|
-
sessionId: params.sessionId,
|
|
20553
|
-
currentTurnId: sessionState.currentTurnId
|
|
20554
|
-
});
|
|
20555
|
-
} catch (err) {
|
|
20556
|
-
logger.error(`Cancel - turnInterrupt failed`, err);
|
|
20557
|
-
}
|
|
21263
|
+
await this.interruptSessionTurn(sessionState, "Cancel", false);
|
|
20558
21264
|
}
|
|
20559
21265
|
};
|
|
20560
21266
|
function getRequestedMcpServerNames(mcpServers) {
|
|
20561
|
-
return Array.from(new Set(mcpServers.map((server) => server.name)));
|
|
21267
|
+
return Array.from(new Set(mcpServers.map((server) => sanitizeMcpServerName(server.name))));
|
|
20562
21268
|
}
|
|
20563
21269
|
|
|
20564
21270
|
// src/CodexAppServerClient.ts
|
|
@@ -20575,6 +21281,7 @@ var CodexAppServerClient = class {
|
|
|
20575
21281
|
mcpServerStartupResolvers = [];
|
|
20576
21282
|
pendingTurnCompletionResolvers = /* @__PURE__ */ new Map();
|
|
20577
21283
|
turnCompletionCaptures = /* @__PURE__ */ new Map();
|
|
21284
|
+
staleTurnIds = /* @__PURE__ */ new Map();
|
|
20578
21285
|
constructor(connection) {
|
|
20579
21286
|
this.connection = connection;
|
|
20580
21287
|
this.connection.onUnhandledNotification((data) => {
|
|
@@ -20591,12 +21298,26 @@ var CodexAppServerClient = class {
|
|
|
20591
21298
|
if (isTurnCompletedNotification(serverNotification)) {
|
|
20592
21299
|
this.recordTurnCompleted(serverNotification.params);
|
|
20593
21300
|
}
|
|
21301
|
+
const routing = extractTurnRouting(serverNotification);
|
|
21302
|
+
const staleTurnNotification = this.isStaleTurn(routing.threadId, routing.turnId);
|
|
21303
|
+
if (staleTurnNotification) {
|
|
21304
|
+
if (isTurnCompletedNotification(serverNotification) && routing.threadId !== null && routing.turnId !== null) {
|
|
21305
|
+
this.clearStaleTurn(routing.threadId, routing.turnId);
|
|
21306
|
+
}
|
|
21307
|
+
for (const callback of this.codexEventHandlers) {
|
|
21308
|
+
callback({ eventType: "notification", ...serverNotification });
|
|
21309
|
+
}
|
|
21310
|
+
return;
|
|
21311
|
+
}
|
|
20594
21312
|
this.notify(serverNotification);
|
|
20595
21313
|
for (const callback of this.codexEventHandlers) {
|
|
20596
21314
|
callback({ eventType: "notification", ...serverNotification });
|
|
20597
21315
|
}
|
|
20598
21316
|
});
|
|
20599
21317
|
this.connection.onRequest(CommandExecutionApprovalRequest, async (params) => {
|
|
21318
|
+
if (this.isStaleTurn(params.threadId, params.turnId)) {
|
|
21319
|
+
return { decision: "cancel" };
|
|
21320
|
+
}
|
|
20600
21321
|
const handler = this.approvalHandlers.get(params.threadId);
|
|
20601
21322
|
if (!handler) {
|
|
20602
21323
|
return { decision: "cancel" };
|
|
@@ -20604,6 +21325,9 @@ var CodexAppServerClient = class {
|
|
|
20604
21325
|
return await handler.handleCommandExecution(params);
|
|
20605
21326
|
});
|
|
20606
21327
|
this.connection.onRequest(FileChangeApprovalRequest, async (params) => {
|
|
21328
|
+
if (this.isStaleTurn(params.threadId, params.turnId)) {
|
|
21329
|
+
return { decision: "cancel" };
|
|
21330
|
+
}
|
|
20607
21331
|
const handler = this.approvalHandlers.get(params.threadId);
|
|
20608
21332
|
if (!handler) {
|
|
20609
21333
|
return { decision: "cancel" };
|
|
@@ -20611,6 +21335,9 @@ var CodexAppServerClient = class {
|
|
|
20611
21335
|
return await handler.handleFileChange(params);
|
|
20612
21336
|
});
|
|
20613
21337
|
this.connection.onRequest(McpServerElicitationRequest, async (params) => {
|
|
21338
|
+
if (this.isStaleTurn(params.threadId, params.turnId)) {
|
|
21339
|
+
return { action: "cancel", content: null, _meta: null };
|
|
21340
|
+
}
|
|
20614
21341
|
const handler = this.elicitationHandlers.get(params.threadId);
|
|
20615
21342
|
if (!handler) {
|
|
20616
21343
|
return { action: "cancel", content: null, _meta: null };
|
|
@@ -20624,19 +21351,25 @@ var CodexAppServerClient = class {
|
|
|
20624
21351
|
onElicitationRequest(threadId, handler) {
|
|
20625
21352
|
this.elicitationHandlers.set(threadId, handler);
|
|
20626
21353
|
}
|
|
21354
|
+
clearThreadHandlers(threadId) {
|
|
21355
|
+
this.notificationHandlers.delete(threadId);
|
|
21356
|
+
this.approvalHandlers.delete(threadId);
|
|
21357
|
+
this.elicitationHandlers.delete(threadId);
|
|
21358
|
+
}
|
|
20627
21359
|
async initialize(params) {
|
|
20628
21360
|
return await this.sendRequest({ method: "initialize", params });
|
|
20629
21361
|
}
|
|
20630
21362
|
async turnStart(params) {
|
|
20631
21363
|
return await this.sendRequest({ method: "turn/start", params });
|
|
20632
21364
|
}
|
|
20633
|
-
async runTurn(params) {
|
|
21365
|
+
async runTurn(params, onTurnStarted) {
|
|
20634
21366
|
const capturedCompletions = [];
|
|
20635
21367
|
const releaseCapture = this.captureTurnCompletions(params.threadId, (event) => {
|
|
20636
21368
|
capturedCompletions.push(event);
|
|
20637
21369
|
});
|
|
20638
21370
|
try {
|
|
20639
21371
|
const turnStarted = await this.turnStart(params);
|
|
21372
|
+
onTurnStarted?.(turnStarted.turn.id);
|
|
20640
21373
|
const earlyCompletion = capturedCompletions.find((event) => event.turn.id === turnStarted.turn.id);
|
|
20641
21374
|
releaseCapture();
|
|
20642
21375
|
if (earlyCompletion) {
|
|
@@ -20650,6 +21383,11 @@ var CodexAppServerClient = class {
|
|
|
20650
21383
|
async turnInterrupt(params) {
|
|
20651
21384
|
return await this.sendRequest({ method: "turn/interrupt", params });
|
|
20652
21385
|
}
|
|
21386
|
+
markTurnStale(threadId, turnId) {
|
|
21387
|
+
const threadStaleTurns = this.staleTurnIds.get(threadId) ?? /* @__PURE__ */ new Set();
|
|
21388
|
+
threadStaleTurns.add(turnId);
|
|
21389
|
+
this.staleTurnIds.set(threadId, threadStaleTurns);
|
|
21390
|
+
}
|
|
20653
21391
|
async threadStart(params) {
|
|
20654
21392
|
return await this.sendRequest({ method: "thread/start", params });
|
|
20655
21393
|
}
|
|
@@ -20665,6 +21403,9 @@ var CodexAppServerClient = class {
|
|
|
20665
21403
|
async threadRead(params) {
|
|
20666
21404
|
return await this.sendRequest({ method: "thread/read", params });
|
|
20667
21405
|
}
|
|
21406
|
+
async threadUnsubscribe(params) {
|
|
21407
|
+
return await this.sendRequest({ method: "thread/unsubscribe", params });
|
|
21408
|
+
}
|
|
20668
21409
|
async listMcpServerStatus(params) {
|
|
20669
21410
|
return await this.sendRequest({ method: "mcpServerStatus/list", params });
|
|
20670
21411
|
}
|
|
@@ -20707,10 +21448,28 @@ var CodexAppServerClient = class {
|
|
|
20707
21448
|
threadResolvers.set(turnId, resolve);
|
|
20708
21449
|
});
|
|
20709
21450
|
}
|
|
20710
|
-
|
|
21451
|
+
resolveTurnInterrupted(threadId, turnId) {
|
|
21452
|
+
this.recordTurnCompleted({
|
|
21453
|
+
threadId,
|
|
21454
|
+
turn: {
|
|
21455
|
+
id: turnId,
|
|
21456
|
+
items: [],
|
|
21457
|
+
itemsView: "notLoaded",
|
|
21458
|
+
status: "interrupted",
|
|
21459
|
+
error: null,
|
|
21460
|
+
startedAt: null,
|
|
21461
|
+
completedAt: null,
|
|
21462
|
+
durationMs: null
|
|
21463
|
+
}
|
|
21464
|
+
});
|
|
21465
|
+
}
|
|
21466
|
+
async listModels(params) {
|
|
20711
21467
|
return await this.sendRequest({ method: "model/list", params });
|
|
20712
21468
|
}
|
|
20713
|
-
async
|
|
21469
|
+
async skillsExtraRootsSet(params) {
|
|
21470
|
+
return await this.sendRequest({ method: "skills/extraRoots/set", params });
|
|
21471
|
+
}
|
|
21472
|
+
async listSkills(params) {
|
|
20714
21473
|
return await this.sendRequest({ method: "skills/list", params });
|
|
20715
21474
|
}
|
|
20716
21475
|
/**
|
|
@@ -20757,6 +21516,22 @@ var CodexAppServerClient = class {
|
|
|
20757
21516
|
capture(event);
|
|
20758
21517
|
}
|
|
20759
21518
|
}
|
|
21519
|
+
isStaleTurn(threadId, turnId) {
|
|
21520
|
+
if (threadId === null || turnId === null) {
|
|
21521
|
+
return false;
|
|
21522
|
+
}
|
|
21523
|
+
return this.staleTurnIds.get(threadId)?.has(turnId) ?? false;
|
|
21524
|
+
}
|
|
21525
|
+
clearStaleTurn(threadId, turnId) {
|
|
21526
|
+
const threadStaleTurns = this.staleTurnIds.get(threadId);
|
|
21527
|
+
if (!threadStaleTurns) {
|
|
21528
|
+
return;
|
|
21529
|
+
}
|
|
21530
|
+
threadStaleTurns.delete(turnId);
|
|
21531
|
+
if (threadStaleTurns.size === 0) {
|
|
21532
|
+
this.staleTurnIds.delete(threadId);
|
|
21533
|
+
}
|
|
21534
|
+
}
|
|
20760
21535
|
getOrCreatePendingTurnCompletionResolvers(threadId) {
|
|
20761
21536
|
const existing = this.pendingTurnCompletionResolvers.get(threadId);
|
|
20762
21537
|
if (existing) {
|
|
@@ -20851,6 +21626,17 @@ function extractThreadId(notification) {
|
|
|
20851
21626
|
}
|
|
20852
21627
|
return null;
|
|
20853
21628
|
}
|
|
21629
|
+
function extractTurnRouting(notification) {
|
|
21630
|
+
const params = notification.params;
|
|
21631
|
+
const threadId = extractThreadId(notification);
|
|
21632
|
+
if (params && typeof params.turnId === "string") {
|
|
21633
|
+
return { threadId, turnId: params.turnId };
|
|
21634
|
+
}
|
|
21635
|
+
if (params && typeof params.turn?.id === "string") {
|
|
21636
|
+
return { threadId, turnId: params.turn.id };
|
|
21637
|
+
}
|
|
21638
|
+
return { threadId, turnId: null };
|
|
21639
|
+
}
|
|
20854
21640
|
|
|
20855
21641
|
// src/login.ts
|
|
20856
21642
|
function parseArgs(args) {
|
|
@@ -20955,6 +21741,34 @@ async function runLoginCommand(args) {
|
|
|
20955
21741
|
return login(options);
|
|
20956
21742
|
}
|
|
20957
21743
|
|
|
21744
|
+
// src/CodexCli.ts
|
|
21745
|
+
import { spawn as spawn2 } from "node:child_process";
|
|
21746
|
+
import { createRequire as createRequire2 } from "node:module";
|
|
21747
|
+
function runCodexCli(codexPath, args) {
|
|
21748
|
+
const child = spawnCodexCli(codexPath, args);
|
|
21749
|
+
return new Promise((resolve, reject) => {
|
|
21750
|
+
child.on("error", reject);
|
|
21751
|
+
child.on("exit", (code, signal) => {
|
|
21752
|
+
if (signal) {
|
|
21753
|
+
process.kill(process.pid, signal);
|
|
21754
|
+
return;
|
|
21755
|
+
}
|
|
21756
|
+
resolve(code ?? 1);
|
|
21757
|
+
});
|
|
21758
|
+
});
|
|
21759
|
+
}
|
|
21760
|
+
function spawnCodexCli(codexPath, args) {
|
|
21761
|
+
const options = {
|
|
21762
|
+
env: process.env,
|
|
21763
|
+
stdio: "inherit"
|
|
21764
|
+
};
|
|
21765
|
+
if (codexPath) {
|
|
21766
|
+
return spawn2(codexPath, args, { ...options, shell: process.platform === "win32" });
|
|
21767
|
+
}
|
|
21768
|
+
const bundledCodexPath = createRequire2(import.meta.url).resolve("@openai/codex/bin/codex.js");
|
|
21769
|
+
return spawn2(process.execPath, [bundledCodexPath, ...args], options);
|
|
21770
|
+
}
|
|
21771
|
+
|
|
20958
21772
|
// src/index.ts
|
|
20959
21773
|
if (process.argv.includes("--version")) {
|
|
20960
21774
|
console.log(`${package_default.name} ${package_default.version}`);
|
|
@@ -20966,6 +21780,12 @@ if (process.argv[2] === "login") {
|
|
|
20966
21780
|
console.error("Login error:", error40.message);
|
|
20967
21781
|
process.exit(1);
|
|
20968
21782
|
});
|
|
21783
|
+
} else if (process.argv[2] === "cli") {
|
|
21784
|
+
const args = process.argv.slice(3);
|
|
21785
|
+
runCodexCli(process.env["CODEX_PATH"], args).then((exitCode) => process.exit(exitCode)).catch((error40) => {
|
|
21786
|
+
console.error("Codex CLI error:", error40.message);
|
|
21787
|
+
process.exit(1);
|
|
21788
|
+
});
|
|
20969
21789
|
} else {
|
|
20970
21790
|
startAcpServer();
|
|
20971
21791
|
}
|