@agentclientprotocol/codex-acp 1.1.7 → 1.1.8
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 +306 -15
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -23585,7 +23585,9 @@ function sameThreadGoalSnapshot(left, right) {
|
|
|
23585
23585
|
var CodexEventHandler = class {
|
|
23586
23586
|
connection;
|
|
23587
23587
|
sessionState;
|
|
23588
|
+
supportsPlanUpdates;
|
|
23588
23589
|
failure = null;
|
|
23590
|
+
completedPlan = null;
|
|
23589
23591
|
activeFuzzyFileSearchSessions = /* @__PURE__ */ new Set();
|
|
23590
23592
|
activeGuardianApprovalReviews = /* @__PURE__ */ new Set();
|
|
23591
23593
|
activeImageGenerationItems = /* @__PURE__ */ new Set();
|
|
@@ -23596,13 +23598,19 @@ var CodexEventHandler = class {
|
|
|
23596
23598
|
terminalCommandOutputIds = /* @__PURE__ */ new Set();
|
|
23597
23599
|
agentMessagePhases = /* @__PURE__ */ new Map();
|
|
23598
23600
|
activeSubAgentActivities = /* @__PURE__ */ new Set();
|
|
23599
|
-
constructor(connection, sessionState) {
|
|
23601
|
+
constructor(connection, sessionState, supportsPlanUpdates = false) {
|
|
23600
23602
|
this.connection = connection;
|
|
23601
23603
|
this.sessionState = sessionState;
|
|
23604
|
+
this.supportsPlanUpdates = supportsPlanUpdates;
|
|
23602
23605
|
}
|
|
23603
23606
|
getFailure() {
|
|
23604
23607
|
return this.failure;
|
|
23605
23608
|
}
|
|
23609
|
+
takeCompletedPlan() {
|
|
23610
|
+
const plan = this.completedPlan;
|
|
23611
|
+
this.completedPlan = null;
|
|
23612
|
+
return plan;
|
|
23613
|
+
}
|
|
23606
23614
|
async handleNotification(notification) {
|
|
23607
23615
|
const session = new ACPSessionConnection(this.connection, this.sessionState.sessionId);
|
|
23608
23616
|
const updateEvent = await this.createUpdateEvent(notification);
|
|
@@ -23796,8 +23804,9 @@ ${event.details}` : "";
|
|
|
23796
23804
|
return null;
|
|
23797
23805
|
}
|
|
23798
23806
|
const text = this.planDeltaTextByItemId.get(event.itemId) ?? "";
|
|
23799
|
-
|
|
23800
|
-
|
|
23807
|
+
const updatedText = text + event.delta;
|
|
23808
|
+
this.planDeltaTextByItemId.set(event.itemId, updatedText);
|
|
23809
|
+
return this.supportsPlanUpdates ? this.createPlanUpdateEvent(updatedText, event.itemId) : null;
|
|
23801
23810
|
}
|
|
23802
23811
|
createReasoningSectionBreakEvent(event) {
|
|
23803
23812
|
this.seenReasoningDeltaItemIds.add(event.itemId);
|
|
@@ -23929,7 +23938,18 @@ ${event.details}` : "";
|
|
|
23929
23938
|
if (text.length === 0) {
|
|
23930
23939
|
return null;
|
|
23931
23940
|
}
|
|
23932
|
-
|
|
23941
|
+
this.completedPlan = { itemId: item.id, text };
|
|
23942
|
+
return this.supportsPlanUpdates ? this.createPlanUpdateEvent(text, item.id) : this.createPlanTextEvent(text, item.id);
|
|
23943
|
+
}
|
|
23944
|
+
createPlanUpdateEvent(text, planId) {
|
|
23945
|
+
return {
|
|
23946
|
+
sessionUpdate: "plan_update",
|
|
23947
|
+
plan: {
|
|
23948
|
+
type: "markdown",
|
|
23949
|
+
planId,
|
|
23950
|
+
content: text
|
|
23951
|
+
}
|
|
23952
|
+
};
|
|
23933
23953
|
}
|
|
23934
23954
|
createPlanTextEvent(text, messageId) {
|
|
23935
23955
|
return createAgentTextMessageChunk(
|
|
@@ -24182,12 +24202,17 @@ var ApprovalOptionId = {
|
|
|
24182
24202
|
};
|
|
24183
24203
|
|
|
24184
24204
|
// src/CodexApprovalHandler.ts
|
|
24185
|
-
function permissionOption(optionId, name, kind, codexMeta) {
|
|
24205
|
+
function permissionOption(optionId, name, kind, codexMeta, permission) {
|
|
24186
24206
|
return {
|
|
24187
24207
|
optionId,
|
|
24188
24208
|
name,
|
|
24189
24209
|
kind,
|
|
24190
|
-
...codexMeta
|
|
24210
|
+
...codexMeta || permission ? {
|
|
24211
|
+
_meta: {
|
|
24212
|
+
...permission ? { permission } : {},
|
|
24213
|
+
...codexMeta ? { codex: codexMeta } : {}
|
|
24214
|
+
}
|
|
24215
|
+
} : {}
|
|
24191
24216
|
};
|
|
24192
24217
|
}
|
|
24193
24218
|
var CodexApprovalHandler = class {
|
|
@@ -24294,13 +24319,15 @@ var CodexApprovalHandler = class {
|
|
|
24294
24319
|
ApprovalOptionId.AllowPermissionsForSession,
|
|
24295
24320
|
"Allow for Session",
|
|
24296
24321
|
"allow_always",
|
|
24297
|
-
{ decision: "allowPermissionsForSession", permissions: params.permissions }
|
|
24322
|
+
{ decision: "allowPermissionsForSession", permissions: params.permissions },
|
|
24323
|
+
this.permissionGrantMetadata(params.permissions, "session")
|
|
24298
24324
|
),
|
|
24299
24325
|
permissionOption(
|
|
24300
24326
|
ApprovalOptionId.AllowPermissionsForTurn,
|
|
24301
24327
|
"Allow Once",
|
|
24302
24328
|
"allow_once",
|
|
24303
|
-
{ decision: "allowPermissionsForTurn", permissions: params.permissions }
|
|
24329
|
+
{ decision: "allowPermissionsForTurn", permissions: params.permissions },
|
|
24330
|
+
this.permissionGrantMetadata(params.permissions, "turn")
|
|
24304
24331
|
),
|
|
24305
24332
|
permissionOption(
|
|
24306
24333
|
ApprovalOptionId.RejectPermissions,
|
|
@@ -24362,7 +24389,24 @@ var CodexApprovalHandler = class {
|
|
|
24362
24389
|
ApprovalOptionId.AllowAlways,
|
|
24363
24390
|
params.networkApprovalContext ? "Allow Host for Session" : "Allow for Session",
|
|
24364
24391
|
"allow_always",
|
|
24365
|
-
{ decision: "acceptForSession" }
|
|
24392
|
+
{ decision: "acceptForSession" },
|
|
24393
|
+
params.networkApprovalContext ? {
|
|
24394
|
+
version: 1,
|
|
24395
|
+
changes: [{
|
|
24396
|
+
type: "grant",
|
|
24397
|
+
operation: "grant",
|
|
24398
|
+
description: `Allow access to ${params.networkApprovalContext.host} for this session`,
|
|
24399
|
+
lifetime: { scope: "session" },
|
|
24400
|
+
targets: [{
|
|
24401
|
+
type: "network",
|
|
24402
|
+
matcher: {
|
|
24403
|
+
type: "host",
|
|
24404
|
+
host: params.networkApprovalContext.host,
|
|
24405
|
+
protocol: params.networkApprovalContext.protocol
|
|
24406
|
+
}
|
|
24407
|
+
}]
|
|
24408
|
+
}]
|
|
24409
|
+
} : void 0
|
|
24366
24410
|
),
|
|
24367
24411
|
decision: "acceptForSession"
|
|
24368
24412
|
}
|
|
@@ -24376,6 +24420,22 @@ var CodexApprovalHandler = class {
|
|
|
24376
24420
|
{
|
|
24377
24421
|
decision: "acceptWithExecpolicyAmendment",
|
|
24378
24422
|
execpolicyAmendment: params.proposedExecpolicyAmendment
|
|
24423
|
+
},
|
|
24424
|
+
{
|
|
24425
|
+
version: 1,
|
|
24426
|
+
changes: [{
|
|
24427
|
+
type: "policy_rule",
|
|
24428
|
+
operation: "add",
|
|
24429
|
+
ruleBehavior: "allow",
|
|
24430
|
+
description: `Allow commands starting with ${params.proposedExecpolicyAmendment.join(" ")}`,
|
|
24431
|
+
targets: [{
|
|
24432
|
+
type: "command",
|
|
24433
|
+
matcher: {
|
|
24434
|
+
type: "argv_prefix",
|
|
24435
|
+
argv: params.proposedExecpolicyAmendment
|
|
24436
|
+
}
|
|
24437
|
+
}]
|
|
24438
|
+
}]
|
|
24379
24439
|
}
|
|
24380
24440
|
),
|
|
24381
24441
|
decision: {
|
|
@@ -24394,6 +24454,22 @@ var CodexApprovalHandler = class {
|
|
|
24394
24454
|
{
|
|
24395
24455
|
decision: "applyNetworkPolicyAmendment",
|
|
24396
24456
|
networkPolicyAmendment: amendment
|
|
24457
|
+
},
|
|
24458
|
+
{
|
|
24459
|
+
version: 1,
|
|
24460
|
+
changes: [{
|
|
24461
|
+
type: "policy_rule",
|
|
24462
|
+
operation: "add",
|
|
24463
|
+
ruleBehavior: amendment.action,
|
|
24464
|
+
description: amendment.action === "allow" ? `Allow access to ${amendment.host}` : `Block access to ${amendment.host}`,
|
|
24465
|
+
targets: [{
|
|
24466
|
+
type: "network",
|
|
24467
|
+
matcher: {
|
|
24468
|
+
type: "host",
|
|
24469
|
+
host: amendment.host
|
|
24470
|
+
}
|
|
24471
|
+
}]
|
|
24472
|
+
}]
|
|
24397
24473
|
}
|
|
24398
24474
|
),
|
|
24399
24475
|
decision: {
|
|
@@ -24420,7 +24496,21 @@ var CodexApprovalHandler = class {
|
|
|
24420
24496
|
ApprovalOptionId.AllowAlways,
|
|
24421
24497
|
params.grantRoot ? "Allow Root for Session" : "Allow for Session",
|
|
24422
24498
|
"allow_always",
|
|
24423
|
-
{ decision: "acceptForSession", grantRoot: params.grantRoot ?? null }
|
|
24499
|
+
{ decision: "acceptForSession", grantRoot: params.grantRoot ?? null },
|
|
24500
|
+
params.grantRoot ? {
|
|
24501
|
+
version: 1,
|
|
24502
|
+
changes: [{
|
|
24503
|
+
type: "grant",
|
|
24504
|
+
operation: "grant",
|
|
24505
|
+
description: `Allow writes under ${params.grantRoot} for this session`,
|
|
24506
|
+
lifetime: { scope: "session" },
|
|
24507
|
+
targets: [{
|
|
24508
|
+
type: "filesystem",
|
|
24509
|
+
access: ["write"],
|
|
24510
|
+
matcher: { type: "directory", path: params.grantRoot }
|
|
24511
|
+
}]
|
|
24512
|
+
}]
|
|
24513
|
+
} : void 0
|
|
24424
24514
|
),
|
|
24425
24515
|
decision: "acceptForSession"
|
|
24426
24516
|
},
|
|
@@ -24443,6 +24533,68 @@ var CodexApprovalHandler = class {
|
|
|
24443
24533
|
...permissions.fileSystem ? { fileSystem: permissions.fileSystem } : {}
|
|
24444
24534
|
};
|
|
24445
24535
|
}
|
|
24536
|
+
permissionGrantMetadata(permissions, scope) {
|
|
24537
|
+
const changes = [];
|
|
24538
|
+
const lifetime = { scope };
|
|
24539
|
+
const suffix = scope === "session" ? " for this session" : " for this turn";
|
|
24540
|
+
if (permissions.network?.enabled !== null && permissions.network?.enabled !== void 0) {
|
|
24541
|
+
const allowed = permissions.network.enabled;
|
|
24542
|
+
changes.push({
|
|
24543
|
+
type: allowed ? "grant" : "policy_rule",
|
|
24544
|
+
operation: allowed ? "grant" : "add",
|
|
24545
|
+
...allowed ? {} : { ruleBehavior: "deny" },
|
|
24546
|
+
description: `${allowed ? "Allow" : "Deny"} network access${suffix}`,
|
|
24547
|
+
lifetime,
|
|
24548
|
+
targets: [{ type: "network", matcher: { type: "any" } }]
|
|
24549
|
+
});
|
|
24550
|
+
}
|
|
24551
|
+
const fileSystem = permissions.fileSystem;
|
|
24552
|
+
for (const path6 of fileSystem?.read ?? []) {
|
|
24553
|
+
changes.push(this.fileSystemGrantChange(path6, "read", lifetime, suffix));
|
|
24554
|
+
}
|
|
24555
|
+
for (const path6 of fileSystem?.write ?? []) {
|
|
24556
|
+
changes.push(this.fileSystemGrantChange(path6, "write", lifetime, suffix));
|
|
24557
|
+
}
|
|
24558
|
+
for (const entry of fileSystem?.entries ?? []) {
|
|
24559
|
+
const matcher = (() => {
|
|
24560
|
+
switch (entry.path.type) {
|
|
24561
|
+
case "path":
|
|
24562
|
+
return { type: "exact_path", path: entry.path.path };
|
|
24563
|
+
case "glob_pattern":
|
|
24564
|
+
return { type: "glob", pattern: entry.path.pattern };
|
|
24565
|
+
case "special":
|
|
24566
|
+
return { type: "special", provider: "codex", value: entry.path.value };
|
|
24567
|
+
}
|
|
24568
|
+
})();
|
|
24569
|
+
const pathDescription = entry.path.type === "path" ? entry.path.path : entry.path.type === "glob_pattern" ? entry.path.pattern : JSON.stringify(entry.path.value);
|
|
24570
|
+
changes.push({
|
|
24571
|
+
type: entry.access === "deny" ? "policy_rule" : "grant",
|
|
24572
|
+
operation: entry.access === "deny" ? "add" : "grant",
|
|
24573
|
+
...entry.access === "deny" ? { ruleBehavior: "deny" } : {},
|
|
24574
|
+
description: entry.access === "deny" ? `Deny filesystem access to ${pathDescription}${suffix}` : `Allow ${entry.access} access to ${pathDescription}${suffix}`,
|
|
24575
|
+
lifetime,
|
|
24576
|
+
targets: [{
|
|
24577
|
+
type: "filesystem",
|
|
24578
|
+
...entry.access === "deny" ? {} : { access: [entry.access] },
|
|
24579
|
+
matcher
|
|
24580
|
+
}]
|
|
24581
|
+
});
|
|
24582
|
+
}
|
|
24583
|
+
return changes.length > 0 ? { version: 1, changes } : void 0;
|
|
24584
|
+
}
|
|
24585
|
+
fileSystemGrantChange(path6, access, lifetime, suffix) {
|
|
24586
|
+
return {
|
|
24587
|
+
type: "grant",
|
|
24588
|
+
operation: "grant",
|
|
24589
|
+
description: `Allow ${access} access to ${path6}${suffix}`,
|
|
24590
|
+
lifetime,
|
|
24591
|
+
targets: [{
|
|
24592
|
+
type: "filesystem",
|
|
24593
|
+
access: [access],
|
|
24594
|
+
matcher: { type: "exact_path", path: path6 }
|
|
24595
|
+
}]
|
|
24596
|
+
};
|
|
24597
|
+
}
|
|
24446
24598
|
networkPolicyAmendmentOptionId(index) {
|
|
24447
24599
|
return `${ApprovalOptionId.ApplyNetworkPolicyAmendment}:${index}`;
|
|
24448
24600
|
}
|
|
@@ -25913,7 +26065,7 @@ var package_default = {
|
|
|
25913
26065
|
publishConfig: {
|
|
25914
26066
|
access: "public"
|
|
25915
26067
|
},
|
|
25916
|
-
version: "1.1.
|
|
26068
|
+
version: "1.1.8",
|
|
25917
26069
|
description: "",
|
|
25918
26070
|
main: "dist/index.js",
|
|
25919
26071
|
bin: {
|
|
@@ -28413,7 +28565,14 @@ function isJetBrains2026_1Client(clientInfo) {
|
|
|
28413
28565
|
return (isIntelliJPlatform || isJetBrainsClient) && clientInfo.version.startsWith("2026.1");
|
|
28414
28566
|
}
|
|
28415
28567
|
|
|
28568
|
+
// src/PlanCapabilities.ts
|
|
28569
|
+
function clientSupportsPlanUpdates(clientCapabilities) {
|
|
28570
|
+
return clientCapabilities?.plan != null;
|
|
28571
|
+
}
|
|
28572
|
+
|
|
28416
28573
|
// src/CodexAcpServer.ts
|
|
28574
|
+
var IMPLEMENT_PLAN_OPTION_ID = "implement_plan";
|
|
28575
|
+
var REVISE_PLAN_OPTION_ID = "revise_plan";
|
|
28417
28576
|
var CodexAcpServer = class _CodexAcpServer {
|
|
28418
28577
|
static MODEL_NAME_TOKEN_OVERRIDES = {
|
|
28419
28578
|
gpt: "GPT",
|
|
@@ -29532,7 +29691,7 @@ Check ${configPath} and project .codex directories, especially their config.toml
|
|
|
29532
29691
|
case "contextCompaction":
|
|
29533
29692
|
return [createCompletedContextCompactionUpdate(item)];
|
|
29534
29693
|
case "plan":
|
|
29535
|
-
return [this.
|
|
29694
|
+
return item.text.length > 0 ? [this.createPlanHistoryUpdate(item)] : [];
|
|
29536
29695
|
}
|
|
29537
29696
|
}
|
|
29538
29697
|
createUserMessageUpdates(item) {
|
|
@@ -29573,7 +29732,17 @@ Check ${configPath} and project .codex directories, especially their config.toml
|
|
|
29573
29732
|
}
|
|
29574
29733
|
};
|
|
29575
29734
|
}
|
|
29576
|
-
|
|
29735
|
+
createPlanHistoryUpdate(item) {
|
|
29736
|
+
if (clientSupportsPlanUpdates(this.clientCapabilities)) {
|
|
29737
|
+
return {
|
|
29738
|
+
sessionUpdate: "plan_update",
|
|
29739
|
+
plan: {
|
|
29740
|
+
type: "markdown",
|
|
29741
|
+
planId: item.id,
|
|
29742
|
+
content: item.text
|
|
29743
|
+
}
|
|
29744
|
+
};
|
|
29745
|
+
}
|
|
29577
29746
|
return createAgentTextMessageChunk(
|
|
29578
29747
|
item.text,
|
|
29579
29748
|
item.id,
|
|
@@ -29867,7 +30036,11 @@ Check ${configPath} and project .codex directories, especially their config.toml
|
|
|
29867
30036
|
};
|
|
29868
30037
|
const disposePromptRequestCancellation = this.observePromptRequestCancellation(signal, sessionState, activePrompt);
|
|
29869
30038
|
try {
|
|
29870
|
-
const eventHandler = new CodexEventHandler(
|
|
30039
|
+
const eventHandler = new CodexEventHandler(
|
|
30040
|
+
this.connection,
|
|
30041
|
+
sessionState,
|
|
30042
|
+
clientSupportsPlanUpdates(this.clientCapabilities)
|
|
30043
|
+
);
|
|
29871
30044
|
const approvalHandler = new CodexApprovalHandler(this.connection, sessionState, activePrompt.signal);
|
|
29872
30045
|
const elicitationHandler = new CodexElicitationHandler(
|
|
29873
30046
|
this.connection,
|
|
@@ -29994,7 +30167,7 @@ Check ${configPath} and project .codex directories, especially their config.toml
|
|
|
29994
30167
|
logger.error(`Prompt for cancelled session ${params.sessionId} failed after prompt returned`, err);
|
|
29995
30168
|
}
|
|
29996
30169
|
});
|
|
29997
|
-
|
|
30170
|
+
let turnCompleted = await Promise.race([
|
|
29998
30171
|
sendPromptPromise,
|
|
29999
30172
|
activePrompt.closeSignal,
|
|
30000
30173
|
this.cancelBeforeTurnStarted(activePrompt)
|
|
@@ -30011,6 +30184,73 @@ Check ${configPath} and project .codex directories, especially their config.toml
|
|
|
30011
30184
|
if (error51) {
|
|
30012
30185
|
throw error51;
|
|
30013
30186
|
}
|
|
30187
|
+
const completedPlan = eventHandler.takeCompletedPlan();
|
|
30188
|
+
if (completedPlan !== null && sessionState.collaborationMode === PLAN_COLLABORATION_MODE && !this.promptShouldStop(params.sessionId, activePrompt)) {
|
|
30189
|
+
const approved = await this.requestPlanImplementationPermission(
|
|
30190
|
+
sessionState,
|
|
30191
|
+
completedPlan,
|
|
30192
|
+
activePrompt.signal
|
|
30193
|
+
);
|
|
30194
|
+
if (this.promptShouldStop(params.sessionId, activePrompt)) {
|
|
30195
|
+
return this.cancelledPromptResponse(sessionState);
|
|
30196
|
+
}
|
|
30197
|
+
if (approved && !this.promptShouldStop(params.sessionId, activePrompt)) {
|
|
30198
|
+
await this.applyCollaborationModeChange(sessionState, DEFAULT_COLLABORATION_MODE);
|
|
30199
|
+
const session = new ACPSessionConnection(this.connection, sessionState.sessionId);
|
|
30200
|
+
await session.update({
|
|
30201
|
+
sessionUpdate: "config_option_update",
|
|
30202
|
+
configOptions: this.createSessionConfigOptions(sessionState)
|
|
30203
|
+
});
|
|
30204
|
+
const implementationRequest = {
|
|
30205
|
+
sessionId: params.sessionId,
|
|
30206
|
+
prompt: [{ type: "text", text: "Implement the approved plan." }]
|
|
30207
|
+
};
|
|
30208
|
+
activePrompt.currentTurn = null;
|
|
30209
|
+
const implementationPromise = this.runWithProcessCheck(
|
|
30210
|
+
() => this.codexAcpClient.sendPrompt(
|
|
30211
|
+
implementationRequest,
|
|
30212
|
+
agentMode,
|
|
30213
|
+
modelId,
|
|
30214
|
+
serviceTier,
|
|
30215
|
+
disableSummary,
|
|
30216
|
+
sessionState.cwd,
|
|
30217
|
+
sessionState.additionalDirectories,
|
|
30218
|
+
(turnId) => {
|
|
30219
|
+
const turn = { threadId: params.sessionId, turnId };
|
|
30220
|
+
activePrompt.currentTurn = turn;
|
|
30221
|
+
if (this.promptShouldStop(params.sessionId, activePrompt)) {
|
|
30222
|
+
this.interruptLateStartedTurn(turn);
|
|
30223
|
+
return;
|
|
30224
|
+
}
|
|
30225
|
+
sessionState.currentTurnId = turnId;
|
|
30226
|
+
},
|
|
30227
|
+
() => this.promptShouldStop(params.sessionId, activePrompt)
|
|
30228
|
+
)
|
|
30229
|
+
);
|
|
30230
|
+
void implementationPromise.catch((err) => {
|
|
30231
|
+
if (this.activePrompts.get(params.sessionId) !== activePrompt) {
|
|
30232
|
+
logger.error(`Implementation turn for cancelled prompt ${params.sessionId} failed after prompt returned`, err);
|
|
30233
|
+
}
|
|
30234
|
+
});
|
|
30235
|
+
turnCompleted = await Promise.race([
|
|
30236
|
+
implementationPromise,
|
|
30237
|
+
activePrompt.closeSignal,
|
|
30238
|
+
this.cancelBeforeTurnStarted(activePrompt)
|
|
30239
|
+
]);
|
|
30240
|
+
if (turnCompleted === null) {
|
|
30241
|
+
return this.cancelledPromptResponse(sessionState);
|
|
30242
|
+
}
|
|
30243
|
+
await this.codexAcpClient.waitForSessionNotifications(params.sessionId);
|
|
30244
|
+
if (turnCompleted.turn.status === "interrupted") {
|
|
30245
|
+
await this.notifyConversationInterrupted(params.sessionId);
|
|
30246
|
+
return this.cancelledPromptResponse(sessionState);
|
|
30247
|
+
}
|
|
30248
|
+
const implementationError = eventHandler.getFailure();
|
|
30249
|
+
if (implementationError) {
|
|
30250
|
+
throw implementationError;
|
|
30251
|
+
}
|
|
30252
|
+
}
|
|
30253
|
+
}
|
|
30014
30254
|
await this.publishFallbackSessionTitle(
|
|
30015
30255
|
sessionState,
|
|
30016
30256
|
this.createPromptFallbackTitle(params.prompt)
|
|
@@ -30035,6 +30275,57 @@ Check ${configPath} and project .codex directories, especially their config.toml
|
|
|
30035
30275
|
activePrompt.complete();
|
|
30036
30276
|
}
|
|
30037
30277
|
}
|
|
30278
|
+
async requestPlanImplementationPermission(sessionState, plan, cancellationSignal) {
|
|
30279
|
+
const toolCallId = `plan-review:${plan.itemId}`;
|
|
30280
|
+
try {
|
|
30281
|
+
const response = await this.connection.request(
|
|
30282
|
+
methods.client.session.requestPermission,
|
|
30283
|
+
{
|
|
30284
|
+
sessionId: sessionState.sessionId,
|
|
30285
|
+
toolCall: {
|
|
30286
|
+
toolCallId,
|
|
30287
|
+
title: "Implement this plan?",
|
|
30288
|
+
kind: "switch_mode",
|
|
30289
|
+
status: "pending",
|
|
30290
|
+
rawInput: { plan: plan.text }
|
|
30291
|
+
},
|
|
30292
|
+
options: [
|
|
30293
|
+
{
|
|
30294
|
+
optionId: IMPLEMENT_PLAN_OPTION_ID,
|
|
30295
|
+
name: "Yes, implement this plan",
|
|
30296
|
+
kind: "allow_once"
|
|
30297
|
+
},
|
|
30298
|
+
{
|
|
30299
|
+
optionId: REVISE_PLAN_OPTION_ID,
|
|
30300
|
+
name: "No, and tell Codex what to do differently",
|
|
30301
|
+
kind: "reject_once"
|
|
30302
|
+
}
|
|
30303
|
+
],
|
|
30304
|
+
_meta: {
|
|
30305
|
+
codex: {
|
|
30306
|
+
kind: "plan_review",
|
|
30307
|
+
planItemId: plan.itemId
|
|
30308
|
+
}
|
|
30309
|
+
}
|
|
30310
|
+
},
|
|
30311
|
+
{ cancellationSignal }
|
|
30312
|
+
);
|
|
30313
|
+
const approved = response.outcome.outcome === "selected" && response.outcome.optionId === IMPLEMENT_PLAN_OPTION_ID;
|
|
30314
|
+
await this.connection.notify(methods.client.session.update, {
|
|
30315
|
+
sessionId: sessionState.sessionId,
|
|
30316
|
+
update: {
|
|
30317
|
+
sessionUpdate: "tool_call_update",
|
|
30318
|
+
toolCallId,
|
|
30319
|
+
status: "completed",
|
|
30320
|
+
rawOutput: approved ? "User approved the plan." : "User kept the session in plan mode."
|
|
30321
|
+
}
|
|
30322
|
+
});
|
|
30323
|
+
return approved;
|
|
30324
|
+
} catch (error51) {
|
|
30325
|
+
logger.error("Error requesting plan implementation permission", error51);
|
|
30326
|
+
return false;
|
|
30327
|
+
}
|
|
30328
|
+
}
|
|
30038
30329
|
cancelledPromptResponse(sessionState) {
|
|
30039
30330
|
return {
|
|
30040
30331
|
stopReason: "cancelled",
|