@agentclientprotocol/codex-acp 1.1.8 → 1.1.10
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/README.md +2 -1
- package/dist/index.js +226 -78
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -13,8 +13,9 @@ Use [OpenAI Codex](https://github.com/openai/codex) from [Agent Client Protocol]
|
|
|
13
13
|
- Text prompts, embedded context, images, resource links, and additional workspace directories.
|
|
14
14
|
- Shell command, file change, permission request, MCP tool call, terminal output, reasoning, plan, web search, image generation, image view, token usage, and review events.
|
|
15
15
|
- Subagent launches as standard ACP tool calls, with Codex thread identity and activity details in namespaced `_meta.codex.subagent` metadata.
|
|
16
|
+
- Session-scoped long-running goals through the provider-neutral [goal extension](docs/goal-extension.md).
|
|
16
17
|
- Client-provided MCP servers over command-based stdio config and HTTP transport.
|
|
17
|
-
- Slash commands: `/status`, `/mcp`, `/skills`, `/review`, `/review-branch`, `/review-commit`, `/compact`, and `/logout`, as well as configured skills.
|
|
18
|
+
- Slash commands: `/status`, `/mcp`, `/skills`, `/goal`, `/review`, `/review-branch`, `/review-commit`, `/compact`, and `/logout`, as well as configured skills.
|
|
18
19
|
|
|
19
20
|
## Installation
|
|
20
21
|
|
package/dist/index.js
CHANGED
|
@@ -23556,22 +23556,37 @@ function createAgentTextThoughtChunk(text, messageId, meta3) {
|
|
|
23556
23556
|
return createAgentThoughtChunk({ type: "text", text }, messageId, meta3);
|
|
23557
23557
|
}
|
|
23558
23558
|
|
|
23559
|
-
// src/
|
|
23560
|
-
var
|
|
23561
|
-
var
|
|
23562
|
-
var
|
|
23563
|
-
|
|
23564
|
-
return request.method === "authentication/status" || request.method === "authentication/logout" || request.method === LEGACY_SET_SESSION_MODEL_METHOD || request.method === GOAL_CONTROL_METHOD || request.method === SESSION_STEERING_METHOD;
|
|
23565
|
-
}
|
|
23559
|
+
// src/GoalExtension.ts
|
|
23560
|
+
var GOAL_EXTENSION_VERSION = 1;
|
|
23561
|
+
var GOAL_CONTROL_METHOD = "_session/goal";
|
|
23562
|
+
var LEGACY_GOAL_CONTROL_METHOD = "_codex/session/goal_control";
|
|
23563
|
+
var GOAL_CONTROL_ACTIONS = ["pause", "clear"];
|
|
23566
23564
|
|
|
23567
23565
|
// src/ThreadGoalSnapshot.ts
|
|
23566
|
+
function toGoalStatus(status) {
|
|
23567
|
+
switch (status) {
|
|
23568
|
+
case "active":
|
|
23569
|
+
case "paused":
|
|
23570
|
+
case "blocked":
|
|
23571
|
+
case "complete":
|
|
23572
|
+
return status;
|
|
23573
|
+
case "usageLimited":
|
|
23574
|
+
case "budgetLimited":
|
|
23575
|
+
return "limited";
|
|
23576
|
+
}
|
|
23577
|
+
}
|
|
23578
|
+
function toUnixMilliseconds(timestampSeconds) {
|
|
23579
|
+
return timestampSeconds * 1e3;
|
|
23580
|
+
}
|
|
23568
23581
|
function toThreadGoalSnapshot(goal) {
|
|
23569
23582
|
return {
|
|
23570
23583
|
objective: goal.objective.trim(),
|
|
23571
|
-
status: goal.status,
|
|
23584
|
+
status: toGoalStatus(goal.status),
|
|
23572
23585
|
tokenBudget: goal.tokenBudget,
|
|
23586
|
+
tokensUsed: goal.tokensUsed,
|
|
23573
23587
|
timeUsedSeconds: goal.timeUsedSeconds,
|
|
23574
|
-
createdAt: goal.createdAt,
|
|
23588
|
+
createdAt: toUnixMilliseconds(goal.createdAt),
|
|
23589
|
+
updatedAt: toUnixMilliseconds(goal.updatedAt),
|
|
23575
23590
|
controlMethod: GOAL_CONTROL_METHOD
|
|
23576
23591
|
};
|
|
23577
23592
|
}
|
|
@@ -23582,8 +23597,8 @@ function sameThreadGoalSnapshot(left, right) {
|
|
|
23582
23597
|
}
|
|
23583
23598
|
|
|
23584
23599
|
// src/CodexEventHandler.ts
|
|
23585
|
-
var CodexEventHandler = class {
|
|
23586
|
-
|
|
23600
|
+
var CodexEventHandler = class _CodexEventHandler {
|
|
23601
|
+
static PLAN_UPDATE_INTERVAL_MS = 150;
|
|
23587
23602
|
sessionState;
|
|
23588
23603
|
supportsPlanUpdates;
|
|
23589
23604
|
failure = null;
|
|
@@ -23593,15 +23608,21 @@ var CodexEventHandler = class {
|
|
|
23593
23608
|
activeImageGenerationItems = /* @__PURE__ */ new Set();
|
|
23594
23609
|
emittedImageViewItems = /* @__PURE__ */ new Set();
|
|
23595
23610
|
planDeltaTextByItemId = /* @__PURE__ */ new Map();
|
|
23611
|
+
pendingPlanItemIds = /* @__PURE__ */ new Set();
|
|
23612
|
+
lastEmittedPlanTextByItemId = /* @__PURE__ */ new Map();
|
|
23613
|
+
session;
|
|
23614
|
+
planUpdateTimer = null;
|
|
23615
|
+
planUpdateChain = Promise.resolve();
|
|
23616
|
+
disposed = false;
|
|
23596
23617
|
seenReasoningDeltaItemIds = /* @__PURE__ */ new Set();
|
|
23597
23618
|
terminalCommandIds = /* @__PURE__ */ new Set();
|
|
23598
23619
|
terminalCommandOutputIds = /* @__PURE__ */ new Set();
|
|
23599
23620
|
agentMessagePhases = /* @__PURE__ */ new Map();
|
|
23600
23621
|
activeSubAgentActivities = /* @__PURE__ */ new Set();
|
|
23601
23622
|
constructor(connection, sessionState, supportsPlanUpdates = false) {
|
|
23602
|
-
this.connection = connection;
|
|
23603
23623
|
this.sessionState = sessionState;
|
|
23604
23624
|
this.supportsPlanUpdates = supportsPlanUpdates;
|
|
23625
|
+
this.session = new ACPSessionConnection(connection, sessionState.sessionId);
|
|
23605
23626
|
}
|
|
23606
23627
|
getFailure() {
|
|
23607
23628
|
return this.failure;
|
|
@@ -23612,12 +23633,32 @@ var CodexEventHandler = class {
|
|
|
23612
23633
|
return plan;
|
|
23613
23634
|
}
|
|
23614
23635
|
async handleNotification(notification) {
|
|
23615
|
-
const session = new ACPSessionConnection(this.connection, this.sessionState.sessionId);
|
|
23616
23636
|
const updateEvent = await this.createUpdateEvent(notification);
|
|
23617
23637
|
if (updateEvent) {
|
|
23618
|
-
await session.update(updateEvent);
|
|
23638
|
+
await this.session.update(updateEvent);
|
|
23619
23639
|
}
|
|
23620
23640
|
}
|
|
23641
|
+
async flushPendingPlanUpdates() {
|
|
23642
|
+
this.cancelPlanUpdateTimer();
|
|
23643
|
+
do {
|
|
23644
|
+
const itemIds = [...this.pendingPlanItemIds];
|
|
23645
|
+
this.pendingPlanItemIds.clear();
|
|
23646
|
+
await Promise.all(itemIds.map((itemId) => {
|
|
23647
|
+
const text = this.planDeltaTextByItemId.get(itemId) ?? "";
|
|
23648
|
+
return text.length > 0 ? this.enqueuePlanSnapshot(itemId, text) : Promise.resolve();
|
|
23649
|
+
}));
|
|
23650
|
+
await this.planUpdateChain;
|
|
23651
|
+
} while (this.pendingPlanItemIds.size > 0);
|
|
23652
|
+
}
|
|
23653
|
+
async dispose() {
|
|
23654
|
+
if (this.disposed) return;
|
|
23655
|
+
await this.flushPendingPlanUpdates();
|
|
23656
|
+
this.disposed = true;
|
|
23657
|
+
this.cancelPlanUpdateTimer();
|
|
23658
|
+
this.pendingPlanItemIds.clear();
|
|
23659
|
+
this.planDeltaTextByItemId.clear();
|
|
23660
|
+
this.lastEmittedPlanTextByItemId.clear();
|
|
23661
|
+
}
|
|
23621
23662
|
async createUpdateEvent(notification) {
|
|
23622
23663
|
switch (notification.method) {
|
|
23623
23664
|
case "item/agentMessage/delta":
|
|
@@ -23636,6 +23677,8 @@ var CodexEventHandler = class {
|
|
|
23636
23677
|
this.sessionState.currentTurnId = notification.params.turn.id;
|
|
23637
23678
|
return null;
|
|
23638
23679
|
case "turn/completed":
|
|
23680
|
+
await this.flushPendingPlanUpdates();
|
|
23681
|
+
this.clearPlanTurnState();
|
|
23639
23682
|
this.sessionState.currentTurnId = null;
|
|
23640
23683
|
return null;
|
|
23641
23684
|
case "thread/tokenUsage/updated":
|
|
@@ -23781,9 +23824,7 @@ ${event.details}` : "";
|
|
|
23781
23824
|
return null;
|
|
23782
23825
|
}
|
|
23783
23826
|
this.sessionState.currentGoal = goalSnapshot;
|
|
23784
|
-
return this.
|
|
23785
|
-
goal: goalSnapshot
|
|
23786
|
-
});
|
|
23827
|
+
return this.createGoalSessionInfoUpdate(goalSnapshot);
|
|
23787
23828
|
}
|
|
23788
23829
|
createThreadGoalClearedEvent(_event) {
|
|
23789
23830
|
this.sessionState.goalRevision += 1;
|
|
@@ -23791,9 +23832,13 @@ ${event.details}` : "";
|
|
|
23791
23832
|
return null;
|
|
23792
23833
|
}
|
|
23793
23834
|
this.sessionState.currentGoal = null;
|
|
23794
|
-
return this.
|
|
23795
|
-
|
|
23796
|
-
|
|
23835
|
+
return this.createGoalSessionInfoUpdate(null);
|
|
23836
|
+
}
|
|
23837
|
+
createGoalSessionInfoUpdate(goal) {
|
|
23838
|
+
return {
|
|
23839
|
+
sessionUpdate: "session_info_update",
|
|
23840
|
+
_meta: { goal }
|
|
23841
|
+
};
|
|
23797
23842
|
}
|
|
23798
23843
|
createReasoningDeltaEvent(event) {
|
|
23799
23844
|
this.seenReasoningDeltaItemIds.add(event.itemId);
|
|
@@ -23806,7 +23851,11 @@ ${event.details}` : "";
|
|
|
23806
23851
|
const text = this.planDeltaTextByItemId.get(event.itemId) ?? "";
|
|
23807
23852
|
const updatedText = text + event.delta;
|
|
23808
23853
|
this.planDeltaTextByItemId.set(event.itemId, updatedText);
|
|
23809
|
-
|
|
23854
|
+
if (this.supportsPlanUpdates) {
|
|
23855
|
+
this.pendingPlanItemIds.add(event.itemId);
|
|
23856
|
+
this.schedulePlanUpdate();
|
|
23857
|
+
}
|
|
23858
|
+
return null;
|
|
23810
23859
|
}
|
|
23811
23860
|
createReasoningSectionBreakEvent(event) {
|
|
23812
23861
|
this.seenReasoningDeltaItemIds.add(event.itemId);
|
|
@@ -23903,8 +23952,7 @@ ${event.details}` : "";
|
|
|
23903
23952
|
return null;
|
|
23904
23953
|
case "plan": {
|
|
23905
23954
|
const deltaText = this.planDeltaTextByItemId.get(event.item.id) ?? "";
|
|
23906
|
-
this.
|
|
23907
|
-
return this.createCompletedPlanEvent(event.item, deltaText);
|
|
23955
|
+
return await this.createCompletedPlanEvent(event.item, deltaText);
|
|
23908
23956
|
}
|
|
23909
23957
|
case "exitedReviewMode":
|
|
23910
23958
|
return this.createExitedReviewModeEvent(event.item);
|
|
@@ -23933,13 +23981,53 @@ ${event.details}` : "";
|
|
|
23933
23981
|
}
|
|
23934
23982
|
return this.createAgentThoughtEvent(text, item.id);
|
|
23935
23983
|
}
|
|
23936
|
-
createCompletedPlanEvent(item, deltaText) {
|
|
23984
|
+
async createCompletedPlanEvent(item, deltaText) {
|
|
23937
23985
|
const text = item.text.length > 0 ? item.text : deltaText;
|
|
23986
|
+
this.pendingPlanItemIds.delete(item.id);
|
|
23987
|
+
if (this.pendingPlanItemIds.size === 0) {
|
|
23988
|
+
this.cancelPlanUpdateTimer();
|
|
23989
|
+
}
|
|
23990
|
+
this.planDeltaTextByItemId.delete(item.id);
|
|
23938
23991
|
if (text.length === 0) {
|
|
23939
23992
|
return null;
|
|
23940
23993
|
}
|
|
23941
23994
|
this.completedPlan = { itemId: item.id, text };
|
|
23942
|
-
|
|
23995
|
+
if (this.supportsPlanUpdates) {
|
|
23996
|
+
await this.enqueuePlanSnapshot(item.id, text);
|
|
23997
|
+
return null;
|
|
23998
|
+
}
|
|
23999
|
+
return this.createPlanTextEvent(text, item.id);
|
|
24000
|
+
}
|
|
24001
|
+
schedulePlanUpdate() {
|
|
24002
|
+
if (this.disposed || this.planUpdateTimer !== null) return;
|
|
24003
|
+
this.planUpdateTimer = setTimeout(() => {
|
|
24004
|
+
this.planUpdateTimer = null;
|
|
24005
|
+
void this.flushPendingPlanUpdates().catch((error51) => {
|
|
24006
|
+
logger.error("Failed to flush throttled plan updates", error51);
|
|
24007
|
+
});
|
|
24008
|
+
}, _CodexEventHandler.PLAN_UPDATE_INTERVAL_MS);
|
|
24009
|
+
}
|
|
24010
|
+
cancelPlanUpdateTimer() {
|
|
24011
|
+
if (this.planUpdateTimer === null) return;
|
|
24012
|
+
clearTimeout(this.planUpdateTimer);
|
|
24013
|
+
this.planUpdateTimer = null;
|
|
24014
|
+
}
|
|
24015
|
+
enqueuePlanSnapshot(itemId, text) {
|
|
24016
|
+
const send = async () => {
|
|
24017
|
+
if (this.lastEmittedPlanTextByItemId.get(itemId) === text) return;
|
|
24018
|
+
await this.session.update(this.createPlanUpdateEvent(text, itemId));
|
|
24019
|
+
this.lastEmittedPlanTextByItemId.set(itemId, text);
|
|
24020
|
+
};
|
|
24021
|
+
const result = this.planUpdateChain.then(send);
|
|
24022
|
+
this.planUpdateChain = result.catch(() => {
|
|
24023
|
+
});
|
|
24024
|
+
return result;
|
|
24025
|
+
}
|
|
24026
|
+
clearPlanTurnState() {
|
|
24027
|
+
this.cancelPlanUpdateTimer();
|
|
24028
|
+
this.pendingPlanItemIds.clear();
|
|
24029
|
+
this.planDeltaTextByItemId.clear();
|
|
24030
|
+
this.lastEmittedPlanTextByItemId.clear();
|
|
23943
24031
|
}
|
|
23944
24032
|
createPlanUpdateEvent(text, planId) {
|
|
23945
24033
|
return {
|
|
@@ -25279,6 +25367,11 @@ var ChatGptAuthMethod = {
|
|
|
25279
25367
|
name: "ChatGPT",
|
|
25280
25368
|
description: "Use ChatGPT to authenticate"
|
|
25281
25369
|
};
|
|
25370
|
+
var ChatGptDeviceCodeAuthMethod = {
|
|
25371
|
+
id: "chat-gpt-device-code",
|
|
25372
|
+
name: "ChatGPT (device code)",
|
|
25373
|
+
description: "Sign in to ChatGPT by opening a verification page and entering a one-time code"
|
|
25374
|
+
};
|
|
25282
25375
|
var GatewayAuthMethod = {
|
|
25283
25376
|
id: "gateway",
|
|
25284
25377
|
name: "Custom model gateway",
|
|
@@ -25295,6 +25388,9 @@ function getCodexAuthMethods(clientCapabilities, env = process.env) {
|
|
|
25295
25388
|
if (!env["NO_BROWSER"]) {
|
|
25296
25389
|
authMethods.push(ChatGptAuthMethod);
|
|
25297
25390
|
}
|
|
25391
|
+
if (clientSupportsUrlElicitation(clientCapabilities)) {
|
|
25392
|
+
authMethods.push(ChatGptDeviceCodeAuthMethod);
|
|
25393
|
+
}
|
|
25298
25394
|
const supportsGatewayAuth = clientCapabilities?.auth?._meta?.["gateway"] === true;
|
|
25299
25395
|
if (supportsGatewayAuth) {
|
|
25300
25396
|
authMethods.push(GatewayAuthMethod);
|
|
@@ -25302,7 +25398,7 @@ function getCodexAuthMethods(clientCapabilities, env = process.env) {
|
|
|
25302
25398
|
return authMethods;
|
|
25303
25399
|
}
|
|
25304
25400
|
function isCodexAuthRequest(request) {
|
|
25305
|
-
return request.methodId === "api-key" || request.methodId === "chat-gpt" || request.methodId === "gateway";
|
|
25401
|
+
return request.methodId === "api-key" || request.methodId === "chat-gpt" || request.methodId === "chat-gpt-device-code" || request.methodId === "gateway";
|
|
25306
25402
|
}
|
|
25307
25403
|
|
|
25308
25404
|
// node_modules/open/index.js
|
|
@@ -26065,7 +26161,7 @@ var package_default = {
|
|
|
26065
26161
|
publishConfig: {
|
|
26066
26162
|
access: "public"
|
|
26067
26163
|
},
|
|
26068
|
-
version: "1.1.
|
|
26164
|
+
version: "1.1.10",
|
|
26069
26165
|
description: "",
|
|
26070
26166
|
main: "dist/index.js",
|
|
26071
26167
|
bin: {
|
|
@@ -26126,7 +26222,7 @@ var package_default = {
|
|
|
26126
26222
|
},
|
|
26127
26223
|
dependencies: {
|
|
26128
26224
|
"@agentclientprotocol/sdk": "^1.3.0",
|
|
26129
|
-
"@openai/codex": "^0.
|
|
26225
|
+
"@openai/codex": "^0.146.1",
|
|
26130
26226
|
diff: "^9.0.0",
|
|
26131
26227
|
open: "^11.0.0",
|
|
26132
26228
|
"vscode-jsonrpc": "^9.0.1",
|
|
@@ -26212,43 +26308,24 @@ var CodexAcpClient = class {
|
|
|
26212
26308
|
getHomePath() {
|
|
26213
26309
|
return this.configPath;
|
|
26214
26310
|
}
|
|
26215
|
-
async authenticate(authRequest) {
|
|
26311
|
+
async authenticate(authRequest, urlElicitationRequester) {
|
|
26216
26312
|
if (!isCodexAuthRequest(authRequest)) {
|
|
26217
26313
|
throw RequestError.invalidRequest();
|
|
26218
26314
|
}
|
|
26219
26315
|
this.gatewayConfig = null;
|
|
26220
26316
|
switch (authRequest.methodId) {
|
|
26221
|
-
case "api-key":
|
|
26222
|
-
|
|
26223
|
-
|
|
26224
|
-
|
|
26225
|
-
case "chat-gpt":
|
|
26226
|
-
|
|
26227
|
-
if (accountResponse.account?.type === "chatgpt") {
|
|
26228
|
-
return true;
|
|
26229
|
-
}
|
|
26230
|
-
const loginCompletedPromise = this.awaitNextLoginCompleted();
|
|
26231
|
-
const loginResponse = await this.codexClient.accountLogin({ type: "chatgpt" });
|
|
26232
|
-
if (loginResponse.type == "chatgpt") {
|
|
26233
|
-
await open_default(loginResponse.authUrl);
|
|
26234
|
-
}
|
|
26235
|
-
const result = await loginCompletedPromise;
|
|
26236
|
-
return result.success;
|
|
26237
|
-
}
|
|
26317
|
+
case "api-key":
|
|
26318
|
+
return await this.authenticateWithApiKey(authRequest);
|
|
26319
|
+
case "chat-gpt":
|
|
26320
|
+
return await this.authenticateWithChatGpt();
|
|
26321
|
+
case "chat-gpt-device-code":
|
|
26322
|
+
return await this.authenticateWithChatGptDeviceCode(urlElicitationRequester);
|
|
26238
26323
|
case "gateway":
|
|
26239
|
-
|
|
26240
|
-
const gatewaySettings = authRequest._meta["gateway"];
|
|
26241
|
-
if (!gatewaySettings) throw RequestError.invalidRequest();
|
|
26242
|
-
this.applyGatewayConfig({
|
|
26243
|
-
baseUrl: gatewaySettings.baseUrl,
|
|
26244
|
-
apiType: GatewayAuthMethod._meta.gateway.protocol,
|
|
26245
|
-
headers: gatewaySettings.headers,
|
|
26246
|
-
providerName: gatewaySettings.providerName
|
|
26247
|
-
});
|
|
26248
|
-
return true;
|
|
26324
|
+
return this.authenticateWithGateway(authRequest);
|
|
26249
26325
|
}
|
|
26250
26326
|
}
|
|
26251
|
-
async authenticateWithApiKey(
|
|
26327
|
+
async authenticateWithApiKey(authRequest) {
|
|
26328
|
+
const apiKey = authRequest._meta?.["api-key"]?.apiKey ?? this.readApiKeyFromEnv();
|
|
26252
26329
|
const loginCompletedPromise = this.awaitNextLoginCompleted();
|
|
26253
26330
|
await this.codexClient.accountLogin({
|
|
26254
26331
|
type: "apiKey",
|
|
@@ -26257,6 +26334,56 @@ var CodexAcpClient = class {
|
|
|
26257
26334
|
const result = await loginCompletedPromise;
|
|
26258
26335
|
return result.success;
|
|
26259
26336
|
}
|
|
26337
|
+
async authenticateWithChatGpt() {
|
|
26338
|
+
const accountResponse = await this.codexClient.accountRead({ refreshToken: true });
|
|
26339
|
+
if (accountResponse.account?.type === "chatgpt") {
|
|
26340
|
+
return true;
|
|
26341
|
+
}
|
|
26342
|
+
const loginCompletedPromise = this.awaitNextLoginCompleted();
|
|
26343
|
+
const loginResponse = await this.codexClient.accountLogin({ type: "chatgpt" });
|
|
26344
|
+
if (loginResponse.type == "chatgpt") {
|
|
26345
|
+
await open_default(loginResponse.authUrl);
|
|
26346
|
+
}
|
|
26347
|
+
const result = await loginCompletedPromise;
|
|
26348
|
+
return result.success;
|
|
26349
|
+
}
|
|
26350
|
+
async authenticateWithChatGptDeviceCode(urlElicitationRequester) {
|
|
26351
|
+
const accountResponse = await this.codexClient.accountRead({ refreshToken: true });
|
|
26352
|
+
if (accountResponse.account?.type === "chatgpt") {
|
|
26353
|
+
return true;
|
|
26354
|
+
}
|
|
26355
|
+
if (!urlElicitationRequester) {
|
|
26356
|
+
throw RequestError.invalidRequest(void 0, "Device code authentication requires URL elicitation support");
|
|
26357
|
+
}
|
|
26358
|
+
const loginCompletedPromise = this.awaitNextLoginCompleted();
|
|
26359
|
+
const loginResponse = await this.codexClient.accountLogin({ type: "chatgptDeviceCode" });
|
|
26360
|
+
if (loginResponse.type !== "chatgptDeviceCode") {
|
|
26361
|
+
return false;
|
|
26362
|
+
}
|
|
26363
|
+
const elicitationResponse = await urlElicitationRequester.elicitUrl({
|
|
26364
|
+
url: loginResponse.verificationUrl,
|
|
26365
|
+
message: `Sign in to ChatGPT and enter this code: ${loginResponse.userCode}`,
|
|
26366
|
+
elicitationId: loginResponse.loginId
|
|
26367
|
+
});
|
|
26368
|
+
if (!CreateElicitationResponse.isAccept(elicitationResponse)) {
|
|
26369
|
+
await this.codexClient.accountLoginCancel({ loginId: loginResponse.loginId });
|
|
26370
|
+
return false;
|
|
26371
|
+
}
|
|
26372
|
+
const result = await loginCompletedPromise;
|
|
26373
|
+
return result.success;
|
|
26374
|
+
}
|
|
26375
|
+
authenticateWithGateway(authRequest) {
|
|
26376
|
+
if (!authRequest._meta) throw RequestError.invalidRequest();
|
|
26377
|
+
const gatewaySettings = authRequest._meta["gateway"];
|
|
26378
|
+
if (!gatewaySettings) throw RequestError.invalidRequest();
|
|
26379
|
+
this.applyGatewayConfig({
|
|
26380
|
+
baseUrl: gatewaySettings.baseUrl,
|
|
26381
|
+
apiType: GatewayAuthMethod._meta.gateway.protocol,
|
|
26382
|
+
headers: gatewaySettings.headers,
|
|
26383
|
+
providerName: gatewaySettings.providerName
|
|
26384
|
+
});
|
|
26385
|
+
return true;
|
|
26386
|
+
}
|
|
26260
26387
|
readApiKeyFromEnv() {
|
|
26261
26388
|
for (const envVar of [CODEX_API_KEY_ENV_VAR, OPENAI_API_KEY_ENV_VAR]) {
|
|
26262
26389
|
const value = process.env[envVar]?.trim();
|
|
@@ -28506,6 +28633,13 @@ function numberValue(value) {
|
|
|
28506
28633
|
return typeof value === "number" && Number.isFinite(value) ? value : null;
|
|
28507
28634
|
}
|
|
28508
28635
|
|
|
28636
|
+
// src/AcpExtensions.ts
|
|
28637
|
+
var LEGACY_SET_SESSION_MODEL_METHOD = "session/set_model";
|
|
28638
|
+
var SESSION_STEERING_METHOD = "_session/steering";
|
|
28639
|
+
function isExtMethodRequest(request) {
|
|
28640
|
+
return request.method === "authentication/status" || request.method === "authentication/logout" || request.method === LEGACY_SET_SESSION_MODEL_METHOD || request.method === GOAL_CONTROL_METHOD || request.method === LEGACY_GOAL_CONTROL_METHOD || request.method === SESSION_STEERING_METHOD;
|
|
28641
|
+
}
|
|
28642
|
+
|
|
28509
28643
|
// src/FastModeConfig.ts
|
|
28510
28644
|
var FAST_MODE_CONFIG_ID = "fast-mode";
|
|
28511
28645
|
var FAST_MODE_CATEGORY = "model_config";
|
|
@@ -28663,6 +28797,11 @@ var CodexAcpServer = class _CodexAcpServer {
|
|
|
28663
28797
|
_meta: {
|
|
28664
28798
|
steering: {
|
|
28665
28799
|
supported: true
|
|
28800
|
+
},
|
|
28801
|
+
goal: {
|
|
28802
|
+
version: GOAL_EXTENSION_VERSION,
|
|
28803
|
+
controlMethod: GOAL_CONTROL_METHOD,
|
|
28804
|
+
actions: [...GOAL_CONTROL_ACTIONS]
|
|
28666
28805
|
}
|
|
28667
28806
|
}
|
|
28668
28807
|
};
|
|
@@ -28683,7 +28822,8 @@ var CodexAcpServer = class _CodexAcpServer {
|
|
|
28683
28822
|
return await this.unstable_setSessionModel(this.parseLegacySetSessionModelParams(methodRequest.params));
|
|
28684
28823
|
case SESSION_STEERING_METHOD:
|
|
28685
28824
|
return await this.executeOrQueueSteeringRequest(this.parseSessionSteerParams(methodRequest.params));
|
|
28686
|
-
case GOAL_CONTROL_METHOD:
|
|
28825
|
+
case GOAL_CONTROL_METHOD:
|
|
28826
|
+
case LEGACY_GOAL_CONTROL_METHOD: {
|
|
28687
28827
|
const sessionState = this.sessions.get(methodRequest.params.sessionId);
|
|
28688
28828
|
if (!sessionState) {
|
|
28689
28829
|
throw RequestError.invalidParams(void 0, `Unknown session: ${methodRequest.params.sessionId}`);
|
|
@@ -29034,9 +29174,10 @@ Check ${configPath} and project .codex directories, especially their config.toml
|
|
|
29034
29174
|
...this.createSessionConfigOptionsResponse(this.getSessionState(sessionId))
|
|
29035
29175
|
};
|
|
29036
29176
|
}
|
|
29037
|
-
async authenticate(_params) {
|
|
29177
|
+
async authenticate(_params, requestId) {
|
|
29038
29178
|
logger.log("Authenticate request received");
|
|
29039
|
-
const
|
|
29179
|
+
const elicitationRequester = this.createUrlElicitationRequester(requestId);
|
|
29180
|
+
const isAuthenticated = await this.runWithProcessCheck(() => this.codexAcpClient.authenticate(_params, elicitationRequester));
|
|
29040
29181
|
if (!isAuthenticated) {
|
|
29041
29182
|
logger.log("Authenticate request failed");
|
|
29042
29183
|
throw RequestError.invalidParams();
|
|
@@ -29045,6 +29186,18 @@ Check ${configPath} and project .codex directories, especially their config.toml
|
|
|
29045
29186
|
logger.log("Authenticate request completed");
|
|
29046
29187
|
return {};
|
|
29047
29188
|
}
|
|
29189
|
+
createUrlElicitationRequester(requestId) {
|
|
29190
|
+
if (requestId == null || !clientSupportsUrlElicitation(this.clientCapabilities)) {
|
|
29191
|
+
return void 0;
|
|
29192
|
+
}
|
|
29193
|
+
return {
|
|
29194
|
+
elicitUrl: (request) => this.connection.request(methods.client.elicitation.create, {
|
|
29195
|
+
mode: "url",
|
|
29196
|
+
requestId,
|
|
29197
|
+
...request
|
|
29198
|
+
})
|
|
29199
|
+
};
|
|
29200
|
+
}
|
|
29048
29201
|
async logout(_params) {
|
|
29049
29202
|
logger.log("Logout request received");
|
|
29050
29203
|
await this.runWithProcessCheck(() => this.codexAcpClient.logout());
|
|
@@ -29471,9 +29624,7 @@ Check ${configPath} and project .codex directories, especially their config.toml
|
|
|
29471
29624
|
await session.update({
|
|
29472
29625
|
sessionUpdate: "session_info_update",
|
|
29473
29626
|
_meta: {
|
|
29474
|
-
|
|
29475
|
-
goal: snapshot
|
|
29476
|
-
}
|
|
29627
|
+
goal: snapshot
|
|
29477
29628
|
}
|
|
29478
29629
|
});
|
|
29479
29630
|
}
|
|
@@ -30035,12 +30186,14 @@ Check ${configPath} and project .codex directories, especially their config.toml
|
|
|
30035
30186
|
return pendingTurnStart;
|
|
30036
30187
|
};
|
|
30037
30188
|
const disposePromptRequestCancellation = this.observePromptRequestCancellation(signal, sessionState, activePrompt);
|
|
30189
|
+
let eventHandler = null;
|
|
30038
30190
|
try {
|
|
30039
|
-
const
|
|
30191
|
+
const promptEventHandler = new CodexEventHandler(
|
|
30040
30192
|
this.connection,
|
|
30041
30193
|
sessionState,
|
|
30042
30194
|
clientSupportsPlanUpdates(this.clientCapabilities)
|
|
30043
30195
|
);
|
|
30196
|
+
eventHandler = promptEventHandler;
|
|
30044
30197
|
const approvalHandler = new CodexApprovalHandler(this.connection, sessionState, activePrompt.signal);
|
|
30045
30198
|
const elicitationHandler = new CodexElicitationHandler(
|
|
30046
30199
|
this.connection,
|
|
@@ -30052,7 +30205,7 @@ Check ${configPath} and project .codex directories, especially their config.toml
|
|
|
30052
30205
|
params.sessionId,
|
|
30053
30206
|
async (event) => {
|
|
30054
30207
|
await elicitationHandler.handleNotification(event);
|
|
30055
|
-
return
|
|
30208
|
+
return promptEventHandler.handleNotification(event);
|
|
30056
30209
|
},
|
|
30057
30210
|
approvalHandler,
|
|
30058
30211
|
elicitationHandler
|
|
@@ -30105,7 +30258,6 @@ Check ${configPath} and project .codex directories, especially their config.toml
|
|
|
30105
30258
|
logger.log("Prompt handled by a command");
|
|
30106
30259
|
await this.codexAcpClient.waitForSessionNotifications(params.sessionId);
|
|
30107
30260
|
if (commandResult.turnCompleted?.turn.status === "interrupted") {
|
|
30108
|
-
await this.notifyConversationInterrupted(params.sessionId);
|
|
30109
30261
|
return this.cancelledPromptResponse(sessionState);
|
|
30110
30262
|
}
|
|
30111
30263
|
const error52 = eventHandler.getFailure();
|
|
@@ -30177,13 +30329,14 @@ Check ${configPath} and project .codex directories, especially their config.toml
|
|
|
30177
30329
|
}
|
|
30178
30330
|
await this.codexAcpClient.waitForSessionNotifications(params.sessionId);
|
|
30179
30331
|
if (turnCompleted.turn.status === "interrupted") {
|
|
30180
|
-
await
|
|
30332
|
+
await eventHandler.flushPendingPlanUpdates();
|
|
30181
30333
|
return this.cancelledPromptResponse(sessionState);
|
|
30182
30334
|
}
|
|
30183
30335
|
const error51 = eventHandler.getFailure();
|
|
30184
30336
|
if (error51) {
|
|
30185
30337
|
throw error51;
|
|
30186
30338
|
}
|
|
30339
|
+
await eventHandler.flushPendingPlanUpdates();
|
|
30187
30340
|
const completedPlan = eventHandler.takeCompletedPlan();
|
|
30188
30341
|
if (completedPlan !== null && sessionState.collaborationMode === PLAN_COLLABORATION_MODE && !this.promptShouldStop(params.sessionId, activePrompt)) {
|
|
30189
30342
|
const approved = await this.requestPlanImplementationPermission(
|
|
@@ -30242,7 +30395,7 @@ Check ${configPath} and project .codex directories, especially their config.toml
|
|
|
30242
30395
|
}
|
|
30243
30396
|
await this.codexAcpClient.waitForSessionNotifications(params.sessionId);
|
|
30244
30397
|
if (turnCompleted.turn.status === "interrupted") {
|
|
30245
|
-
await
|
|
30398
|
+
await eventHandler.flushPendingPlanUpdates();
|
|
30246
30399
|
return this.cancelledPromptResponse(sessionState);
|
|
30247
30400
|
}
|
|
30248
30401
|
const implementationError = eventHandler.getFailure();
|
|
@@ -30265,6 +30418,7 @@ Check ${configPath} and project .codex directories, especially their config.toml
|
|
|
30265
30418
|
throw err;
|
|
30266
30419
|
} finally {
|
|
30267
30420
|
logger.log("Prompt completed", { sessionId: params.sessionId });
|
|
30421
|
+
await eventHandler?.dispose();
|
|
30268
30422
|
disposePromptRequestCancellation();
|
|
30269
30423
|
sessionState.currentTurnId = null;
|
|
30270
30424
|
const registeredPendingTurnStart = this.pendingTurnStarts.get(params.sessionId);
|
|
@@ -30333,15 +30487,6 @@ Check ${configPath} and project .codex directories, especially their config.toml
|
|
|
30333
30487
|
_meta: this.buildQuotaMeta(sessionState)
|
|
30334
30488
|
};
|
|
30335
30489
|
}
|
|
30336
|
-
async notifyConversationInterrupted(sessionId) {
|
|
30337
|
-
if (this.sessionIsClosing(sessionId) || !this.sessions.has(sessionId)) {
|
|
30338
|
-
return;
|
|
30339
|
-
}
|
|
30340
|
-
await this.connection.notify(methods.client.session.update, {
|
|
30341
|
-
sessionId,
|
|
30342
|
-
update: createAgentTextMessageChunk("*Conversation interrupted*")
|
|
30343
|
-
});
|
|
30344
|
-
}
|
|
30345
30490
|
buildQuotaMeta(sessionState) {
|
|
30346
30491
|
const lastTokenUsage = sessionState.lastTokenUsage;
|
|
30347
30492
|
const modelName = sessionState.currentModelId.replace(/\[.*?]$/, "");
|
|
@@ -30859,6 +31004,9 @@ var CodexAppServerClient = class {
|
|
|
30859
31004
|
async accountLogin(params) {
|
|
30860
31005
|
return await this.sendRequest({ method: "account/login/start", params });
|
|
30861
31006
|
}
|
|
31007
|
+
async accountLoginCancel(params) {
|
|
31008
|
+
return await this.sendRequest({ method: "account/login/cancel", params });
|
|
31009
|
+
}
|
|
30862
31010
|
async accountLogout() {
|
|
30863
31011
|
return await this.sendRequest({ method: "account/logout", params: void 0 });
|
|
30864
31012
|
}
|
|
@@ -31459,5 +31607,5 @@ function startAcpServer() {
|
|
|
31459
31607
|
codexAcpServer = null;
|
|
31460
31608
|
}
|
|
31461
31609
|
});
|
|
31462
|
-
}).onRequest(methods.agent.initialize, (ctx) => getAgent().initialize(ctx.params)).onRequest(methods.agent.session.new, (ctx) => getAgent().newSession(ctx.params)).onRequest(methods.agent.session.load, (ctx) => getAgent().loadSession(ctx.params)).onRequest(methods.agent.session.list, (ctx) => getAgent().listSessions(ctx.params)).onRequest(methods.agent.session.delete, (ctx) => getAgent().deleteSession(ctx.params)).onRequest(methods.agent.session.resume, (ctx) => getAgent().resumeSession(ctx.params)).onRequest(methods.agent.session.close, (ctx) => getAgent().closeSession(ctx.params)).onRequest(methods.agent.session.setMode, (ctx) => getAgent().setSessionMode(ctx.params)).onRequest(methods.agent.session.setConfigOption, (ctx) => getAgent().setSessionConfigOption(ctx.params)).onRequest(methods.agent.authenticate, (ctx) => getAgent().authenticate(ctx.params)).onRequest(methods.agent.logout, (ctx) => getAgent().logout(ctx.params)).onRequest(methods.agent.providers.list, (ctx) => getAgent().listProviders(ctx.params)).onRequest(methods.agent.providers.set, (ctx) => getAgent().setProvider(ctx.params)).onRequest(methods.agent.providers.disable, (ctx) => getAgent().disableProvider(ctx.params)).onRequest(methods.agent.session.prompt, (ctx) => getAgent().prompt(ctx.params, ctx.signal)).onNotification(methods.agent.session.cancel, (ctx) => getAgent().cancel(ctx.params)).onRequest("authentication/status", emptyExtensionParamsParser, (ctx) => getAgent().extMethod("authentication/status", ctx.params)).onRequest("authentication/logout", emptyExtensionParamsParser, (ctx) => getAgent().extMethod("authentication/logout", ctx.params)).onRequest(LEGACY_SET_SESSION_MODEL_METHOD, legacySetSessionModelParamsParser, (ctx) => getAgent().extMethod(LEGACY_SET_SESSION_MODEL_METHOD, ctx.params)).onRequest(SESSION_STEERING_METHOD, sessionSteerParamsParser, (ctx) => getAgent().extMethod(SESSION_STEERING_METHOD, ctx.params)).onRequest(GOAL_CONTROL_METHOD, goalControlParamsParser, (ctx) => getAgent().extMethod(GOAL_CONTROL_METHOD, ctx.params)).connect(acpJsonStream);
|
|
31610
|
+
}).onRequest(methods.agent.initialize, (ctx) => getAgent().initialize(ctx.params)).onRequest(methods.agent.session.new, (ctx) => getAgent().newSession(ctx.params)).onRequest(methods.agent.session.load, (ctx) => getAgent().loadSession(ctx.params)).onRequest(methods.agent.session.list, (ctx) => getAgent().listSessions(ctx.params)).onRequest(methods.agent.session.delete, (ctx) => getAgent().deleteSession(ctx.params)).onRequest(methods.agent.session.resume, (ctx) => getAgent().resumeSession(ctx.params)).onRequest(methods.agent.session.close, (ctx) => getAgent().closeSession(ctx.params)).onRequest(methods.agent.session.setMode, (ctx) => getAgent().setSessionMode(ctx.params)).onRequest(methods.agent.session.setConfigOption, (ctx) => getAgent().setSessionConfigOption(ctx.params)).onRequest(methods.agent.authenticate, (ctx) => getAgent().authenticate(ctx.params, ctx.requestId)).onRequest(methods.agent.logout, (ctx) => getAgent().logout(ctx.params)).onRequest(methods.agent.providers.list, (ctx) => getAgent().listProviders(ctx.params)).onRequest(methods.agent.providers.set, (ctx) => getAgent().setProvider(ctx.params)).onRequest(methods.agent.providers.disable, (ctx) => getAgent().disableProvider(ctx.params)).onRequest(methods.agent.session.prompt, (ctx) => getAgent().prompt(ctx.params, ctx.signal)).onNotification(methods.agent.session.cancel, (ctx) => getAgent().cancel(ctx.params)).onRequest("authentication/status", emptyExtensionParamsParser, (ctx) => getAgent().extMethod("authentication/status", ctx.params)).onRequest("authentication/logout", emptyExtensionParamsParser, (ctx) => getAgent().extMethod("authentication/logout", ctx.params)).onRequest(LEGACY_SET_SESSION_MODEL_METHOD, legacySetSessionModelParamsParser, (ctx) => getAgent().extMethod(LEGACY_SET_SESSION_MODEL_METHOD, ctx.params)).onRequest(SESSION_STEERING_METHOD, sessionSteerParamsParser, (ctx) => getAgent().extMethod(SESSION_STEERING_METHOD, ctx.params)).onRequest(GOAL_CONTROL_METHOD, goalControlParamsParser, (ctx) => getAgent().extMethod(GOAL_CONTROL_METHOD, ctx.params)).connect(acpJsonStream);
|
|
31463
31611
|
}
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"publishConfig": {
|
|
4
4
|
"access": "public"
|
|
5
5
|
},
|
|
6
|
-
"version": "1.1.
|
|
6
|
+
"version": "1.1.10",
|
|
7
7
|
"description": "",
|
|
8
8
|
"main": "dist/index.js",
|
|
9
9
|
"bin": {
|
|
@@ -64,7 +64,7 @@
|
|
|
64
64
|
},
|
|
65
65
|
"dependencies": {
|
|
66
66
|
"@agentclientprotocol/sdk": "^1.3.0",
|
|
67
|
-
"@openai/codex": "^0.
|
|
67
|
+
"@openai/codex": "^0.146.1",
|
|
68
68
|
"diff": "^9.0.0",
|
|
69
69
|
"open": "^11.0.0",
|
|
70
70
|
"vscode-jsonrpc": "^9.0.1",
|