@agentclientprotocol/codex-acp 1.1.1 → 1.1.4
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 +1 -0
- package/dist/index.js +702 -88
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -12,6 +12,7 @@ Use [OpenAI Codex](https://github.com/openai/codex) from [Agent Client Protocol]
|
|
|
12
12
|
- Model, reasoning effort, fast mode, approval, and sandbox mode configuration.
|
|
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
|
+
- Subagent launches as standard ACP tool calls, with Codex thread identity and activity details in namespaced `_meta.codex.subagent` metadata.
|
|
15
16
|
- Client-provided MCP servers over command-based stdio config and HTTP transport.
|
|
16
17
|
- Slash commands: `/status`, `/mcp`, `/skills`, `/review`, `/review-branch`, `/review-commit`, `/compact`, and `/logout`, as well as configured skills.
|
|
17
18
|
|
package/dist/index.js
CHANGED
|
@@ -22592,6 +22592,7 @@ function createTerminalOutputMeta(mode, terminalId, data) {
|
|
|
22592
22592
|
}
|
|
22593
22593
|
|
|
22594
22594
|
// src/CodexToolCallMapper.ts
|
|
22595
|
+
var CONTEXT_COMPACTION_META = { contextCompaction: true };
|
|
22595
22596
|
function toAcpStatus(status) {
|
|
22596
22597
|
switch (status) {
|
|
22597
22598
|
case "inProgress":
|
|
@@ -22734,6 +22735,35 @@ function createImageGenerationUpdate(item, options) {
|
|
|
22734
22735
|
rawOutput: imageGenerationRawOutput(item)
|
|
22735
22736
|
};
|
|
22736
22737
|
}
|
|
22738
|
+
function createContextCompactionStartUpdate(item) {
|
|
22739
|
+
return {
|
|
22740
|
+
sessionUpdate: "tool_call",
|
|
22741
|
+
toolCallId: item.id,
|
|
22742
|
+
kind: "other",
|
|
22743
|
+
title: "Context compacting",
|
|
22744
|
+
status: "in_progress",
|
|
22745
|
+
_meta: CONTEXT_COMPACTION_META
|
|
22746
|
+
};
|
|
22747
|
+
}
|
|
22748
|
+
function createContextCompactionCompleteUpdate(item) {
|
|
22749
|
+
return {
|
|
22750
|
+
sessionUpdate: "tool_call_update",
|
|
22751
|
+
toolCallId: item.id,
|
|
22752
|
+
title: "Context compacted",
|
|
22753
|
+
status: "completed",
|
|
22754
|
+
_meta: CONTEXT_COMPACTION_META
|
|
22755
|
+
};
|
|
22756
|
+
}
|
|
22757
|
+
function createCompletedContextCompactionUpdate(item) {
|
|
22758
|
+
return {
|
|
22759
|
+
sessionUpdate: "tool_call",
|
|
22760
|
+
toolCallId: item.id,
|
|
22761
|
+
kind: "other",
|
|
22762
|
+
title: "Context compacted",
|
|
22763
|
+
status: "completed",
|
|
22764
|
+
_meta: CONTEXT_COMPACTION_META
|
|
22765
|
+
};
|
|
22766
|
+
}
|
|
22737
22767
|
async function createExecuteToolCallUpdate(item, title, rawInput, rawOutput) {
|
|
22738
22768
|
return {
|
|
22739
22769
|
sessionUpdate: "tool_call",
|
|
@@ -22847,7 +22877,8 @@ function createCollabAgentToolCallUpdate(item) {
|
|
|
22847
22877
|
kind: "other",
|
|
22848
22878
|
title: item.tool,
|
|
22849
22879
|
status: toAcpStatus(item.status),
|
|
22850
|
-
rawInput: createCollabAgentToolCallRawInput(item)
|
|
22880
|
+
rawInput: createCollabAgentToolCallRawInput(item),
|
|
22881
|
+
_meta: createCollabAgentToolCallMeta(item)
|
|
22851
22882
|
};
|
|
22852
22883
|
}
|
|
22853
22884
|
function createCollabAgentToolCallCompleteUpdate(item) {
|
|
@@ -22856,7 +22887,8 @@ function createCollabAgentToolCallCompleteUpdate(item) {
|
|
|
22856
22887
|
toolCallId: item.id,
|
|
22857
22888
|
title: item.tool,
|
|
22858
22889
|
status: toAcpStatus(item.status),
|
|
22859
|
-
rawInput: createCollabAgentToolCallRawInput(item)
|
|
22890
|
+
rawInput: createCollabAgentToolCallRawInput(item),
|
|
22891
|
+
_meta: createCollabAgentToolCallMeta(item)
|
|
22860
22892
|
};
|
|
22861
22893
|
}
|
|
22862
22894
|
function createCollabAgentToolCallRawInput(item) {
|
|
@@ -22865,9 +22897,66 @@ function createCollabAgentToolCallRawInput(item) {
|
|
|
22865
22897
|
senderThreadId: item.senderThreadId,
|
|
22866
22898
|
receiverThreadIds: item.receiverThreadIds,
|
|
22867
22899
|
agentsStates: item.agentsStates,
|
|
22900
|
+
model: item.model,
|
|
22901
|
+
reasoningEffort: item.reasoningEffort,
|
|
22868
22902
|
status: item.status
|
|
22869
22903
|
};
|
|
22870
22904
|
}
|
|
22905
|
+
function createCollabAgentToolCallMeta(item) {
|
|
22906
|
+
return {
|
|
22907
|
+
codex: {
|
|
22908
|
+
collaboration: {
|
|
22909
|
+
tool: item.tool,
|
|
22910
|
+
senderThreadId: item.senderThreadId,
|
|
22911
|
+
receiverThreadIds: item.receiverThreadIds
|
|
22912
|
+
}
|
|
22913
|
+
}
|
|
22914
|
+
};
|
|
22915
|
+
}
|
|
22916
|
+
function createSubAgentActivityUpdate(item, status, sessionUpdate) {
|
|
22917
|
+
const name = item.agentPath.split("/").filter(Boolean).at(-1) ?? "subagent";
|
|
22918
|
+
const title = formatSubAgentActivityTitle(item.kind, name);
|
|
22919
|
+
const common = {
|
|
22920
|
+
toolCallId: item.id,
|
|
22921
|
+
status,
|
|
22922
|
+
rawInput: {
|
|
22923
|
+
agentThreadId: item.agentThreadId,
|
|
22924
|
+
agentPath: item.agentPath,
|
|
22925
|
+
activityKind: item.kind
|
|
22926
|
+
},
|
|
22927
|
+
_meta: {
|
|
22928
|
+
codex: {
|
|
22929
|
+
subagent: {
|
|
22930
|
+
threadId: item.agentThreadId,
|
|
22931
|
+
path: item.agentPath,
|
|
22932
|
+
activity: item.kind
|
|
22933
|
+
}
|
|
22934
|
+
}
|
|
22935
|
+
}
|
|
22936
|
+
};
|
|
22937
|
+
if (sessionUpdate === "tool_call") {
|
|
22938
|
+
return {
|
|
22939
|
+
sessionUpdate,
|
|
22940
|
+
title,
|
|
22941
|
+
kind: "other",
|
|
22942
|
+
...common
|
|
22943
|
+
};
|
|
22944
|
+
}
|
|
22945
|
+
return {
|
|
22946
|
+
sessionUpdate,
|
|
22947
|
+
...common
|
|
22948
|
+
};
|
|
22949
|
+
}
|
|
22950
|
+
function formatSubAgentActivityTitle(kind, name) {
|
|
22951
|
+
switch (kind) {
|
|
22952
|
+
case "started":
|
|
22953
|
+
return `Start subagent ${name}`;
|
|
22954
|
+
case "interacted":
|
|
22955
|
+
return `Interact with subagent ${name}`;
|
|
22956
|
+
case "interrupted":
|
|
22957
|
+
return `Interrupt subagent ${name}`;
|
|
22958
|
+
}
|
|
22959
|
+
}
|
|
22871
22960
|
function formatWebSearchTitle(item) {
|
|
22872
22961
|
const action = item.action;
|
|
22873
22962
|
if (!action) {
|
|
@@ -23273,6 +23362,30 @@ function createAgentTextThoughtChunk(text, messageId, meta3) {
|
|
|
23273
23362
|
return createAgentThoughtChunk({ type: "text", text }, messageId, meta3);
|
|
23274
23363
|
}
|
|
23275
23364
|
|
|
23365
|
+
// src/AcpExtensions.ts
|
|
23366
|
+
var LEGACY_SET_SESSION_MODEL_METHOD = "session/set_model";
|
|
23367
|
+
var GOAL_CONTROL_METHOD = "_codex/session/goal_control";
|
|
23368
|
+
function isExtMethodRequest(request) {
|
|
23369
|
+
return request.method === "authentication/status" || request.method === "authentication/logout" || request.method === LEGACY_SET_SESSION_MODEL_METHOD || request.method === GOAL_CONTROL_METHOD;
|
|
23370
|
+
}
|
|
23371
|
+
|
|
23372
|
+
// src/ThreadGoalSnapshot.ts
|
|
23373
|
+
function toThreadGoalSnapshot(goal) {
|
|
23374
|
+
return {
|
|
23375
|
+
objective: goal.objective.trim(),
|
|
23376
|
+
status: goal.status,
|
|
23377
|
+
tokenBudget: goal.tokenBudget,
|
|
23378
|
+
timeUsedSeconds: goal.timeUsedSeconds,
|
|
23379
|
+
createdAt: goal.createdAt,
|
|
23380
|
+
controlMethod: GOAL_CONTROL_METHOD
|
|
23381
|
+
};
|
|
23382
|
+
}
|
|
23383
|
+
function sameThreadGoalSnapshot(left, right) {
|
|
23384
|
+
if (left === void 0) return false;
|
|
23385
|
+
if (left === null || right === null) return left === right;
|
|
23386
|
+
return left.objective === right.objective && left.status === right.status && left.tokenBudget === right.tokenBudget && left.createdAt === right.createdAt;
|
|
23387
|
+
}
|
|
23388
|
+
|
|
23276
23389
|
// src/CodexEventHandler.ts
|
|
23277
23390
|
var CodexEventHandler = class {
|
|
23278
23391
|
connection;
|
|
@@ -23286,6 +23399,7 @@ var CodexEventHandler = class {
|
|
|
23286
23399
|
terminalCommandIds = /* @__PURE__ */ new Set();
|
|
23287
23400
|
terminalCommandOutputIds = /* @__PURE__ */ new Set();
|
|
23288
23401
|
agentMessagePhases = /* @__PURE__ */ new Map();
|
|
23402
|
+
activeSubAgentActivities = /* @__PURE__ */ new Set();
|
|
23289
23403
|
constructor(connection, sessionState) {
|
|
23290
23404
|
this.connection = connection;
|
|
23291
23405
|
this.sessionState = sessionState;
|
|
@@ -23321,6 +23435,8 @@ var CodexEventHandler = class {
|
|
|
23321
23435
|
case "thread/tokenUsage/updated":
|
|
23322
23436
|
return this.createUsageUpdate(notification.params);
|
|
23323
23437
|
case "thread/name/updated":
|
|
23438
|
+
this.sessionState.sessionTitle = notification.params.threadName ?? null;
|
|
23439
|
+
this.sessionState.sessionTitleSource = notification.params.threadName == null ? "unset" : "explicit";
|
|
23324
23440
|
return {
|
|
23325
23441
|
sessionUpdate: "session_info_update",
|
|
23326
23442
|
title: notification.params.threadName ?? null
|
|
@@ -23451,8 +23567,9 @@ ${event.details}` : "";
|
|
|
23451
23567
|
`);
|
|
23452
23568
|
}
|
|
23453
23569
|
createThreadGoalUpdatedEvent(event) {
|
|
23454
|
-
|
|
23455
|
-
|
|
23570
|
+
this.sessionState.goalRevision += 1;
|
|
23571
|
+
const goalSnapshot = toThreadGoalSnapshot(event.goal);
|
|
23572
|
+
if (sameThreadGoalSnapshot(this.sessionState.currentGoal, goalSnapshot)) {
|
|
23456
23573
|
return null;
|
|
23457
23574
|
}
|
|
23458
23575
|
this.sessionState.currentGoal = goalSnapshot;
|
|
@@ -23461,6 +23578,7 @@ ${event.details}` : "";
|
|
|
23461
23578
|
});
|
|
23462
23579
|
}
|
|
23463
23580
|
createThreadGoalClearedEvent(_event) {
|
|
23581
|
+
this.sessionState.goalRevision += 1;
|
|
23464
23582
|
if (this.sessionState.currentGoal === null) {
|
|
23465
23583
|
return null;
|
|
23466
23584
|
}
|
|
@@ -23469,16 +23587,6 @@ ${event.details}` : "";
|
|
|
23469
23587
|
goal: null
|
|
23470
23588
|
});
|
|
23471
23589
|
}
|
|
23472
|
-
createThreadGoalSnapshot(event) {
|
|
23473
|
-
return {
|
|
23474
|
-
objective: event.goal.objective.trim(),
|
|
23475
|
-
status: event.goal.status,
|
|
23476
|
-
tokenBudget: event.goal.tokenBudget
|
|
23477
|
-
};
|
|
23478
|
-
}
|
|
23479
|
-
sameThreadGoalSnapshot(left, right) {
|
|
23480
|
-
return left !== null && left !== void 0 && left.objective === right.objective && left.status === right.status && left.tokenBudget === right.tokenBudget;
|
|
23481
|
-
}
|
|
23482
23590
|
createReasoningDeltaEvent(event) {
|
|
23483
23591
|
this.seenReasoningDeltaItemIds.add(event.itemId);
|
|
23484
23592
|
return this.createAgentThoughtEvent(event.delta, event.itemId);
|
|
@@ -23520,14 +23628,17 @@ ${event.details}` : "";
|
|
|
23520
23628
|
case "agentMessage":
|
|
23521
23629
|
this.rememberAgentMessagePhase(event.item);
|
|
23522
23630
|
return null;
|
|
23631
|
+
case "contextCompaction":
|
|
23632
|
+
return createContextCompactionStartUpdate(event.item);
|
|
23523
23633
|
case "subAgentActivity":
|
|
23634
|
+
this.activeSubAgentActivities.add(event.item.id);
|
|
23635
|
+
return createSubAgentActivityUpdate(event.item, "in_progress", "tool_call");
|
|
23524
23636
|
case "sleep":
|
|
23525
23637
|
case "userMessage":
|
|
23526
23638
|
case "hookPrompt":
|
|
23527
23639
|
case "reasoning":
|
|
23528
23640
|
case "enteredReviewMode":
|
|
23529
23641
|
case "exitedReviewMode":
|
|
23530
|
-
case "contextCompaction":
|
|
23531
23642
|
case "plan":
|
|
23532
23643
|
return null;
|
|
23533
23644
|
}
|
|
@@ -23576,9 +23687,12 @@ ${event.details}` : "";
|
|
|
23576
23687
|
case "exitedReviewMode":
|
|
23577
23688
|
return this.createExitedReviewModeEvent(event.item);
|
|
23578
23689
|
case "contextCompaction":
|
|
23579
|
-
return
|
|
23690
|
+
return createContextCompactionCompleteUpdate(event.item);
|
|
23580
23691
|
//ignored types
|
|
23581
|
-
case "subAgentActivity":
|
|
23692
|
+
case "subAgentActivity": {
|
|
23693
|
+
const sessionUpdate = this.activeSubAgentActivities.delete(event.item.id) ? "tool_call_update" : "tool_call";
|
|
23694
|
+
return createSubAgentActivityUpdate(event.item, "completed", sessionUpdate);
|
|
23695
|
+
}
|
|
23582
23696
|
case "sleep":
|
|
23583
23697
|
case "userMessage":
|
|
23584
23698
|
case "hookPrompt":
|
|
@@ -23726,7 +23840,15 @@ ${event.stdin}
|
|
|
23726
23840
|
}
|
|
23727
23841
|
async createErrorEvent(params) {
|
|
23728
23842
|
const error51 = params.error.codexErrorInfo;
|
|
23729
|
-
if (
|
|
23843
|
+
if (params.willRetry) {
|
|
23844
|
+
return this.createCodexSessionInfoUpdate({
|
|
23845
|
+
error: {
|
|
23846
|
+
...params.error,
|
|
23847
|
+
turnId: params.turnId,
|
|
23848
|
+
willRetry: true
|
|
23849
|
+
}
|
|
23850
|
+
});
|
|
23851
|
+
} else if (error51 === "usageLimitExceeded") {
|
|
23730
23852
|
this.failure = RequestError.internalError(
|
|
23731
23853
|
this.createTurnErrorData(params.error)
|
|
23732
23854
|
);
|
|
@@ -24158,6 +24280,7 @@ var ELICITATION_OPTIONS = [
|
|
|
24158
24280
|
{ optionId: "accept", name: "Accept", kind: "allow_once" },
|
|
24159
24281
|
{ optionId: "decline", name: "Decline", kind: "reject_once" }
|
|
24160
24282
|
];
|
|
24283
|
+
var USER_INPUT_OTHER_FIELD_SUFFIX = "__other";
|
|
24161
24284
|
function parsePersistOptions(meta3) {
|
|
24162
24285
|
const result = /* @__PURE__ */ new Set();
|
|
24163
24286
|
if (!meta3 || typeof meta3 !== "object") return result;
|
|
@@ -24293,6 +24416,27 @@ function elicitationResponseMeta(response, context, persist = void 0) {
|
|
|
24293
24416
|
}
|
|
24294
24417
|
return Object.keys(meta3).length === 0 ? null : meta3;
|
|
24295
24418
|
}
|
|
24419
|
+
function userInputOtherFieldId(questionId, questionIds) {
|
|
24420
|
+
const base = `${questionId}${USER_INPUT_OTHER_FIELD_SUFFIX}`;
|
|
24421
|
+
if (!questionIds.has(base)) {
|
|
24422
|
+
return base;
|
|
24423
|
+
}
|
|
24424
|
+
let index = 1;
|
|
24425
|
+
while (questionIds.has(`${base}${index}`)) {
|
|
24426
|
+
index += 1;
|
|
24427
|
+
}
|
|
24428
|
+
return `${base}${index}`;
|
|
24429
|
+
}
|
|
24430
|
+
function userInputResponseValue(content, fieldId) {
|
|
24431
|
+
const value = content[fieldId];
|
|
24432
|
+
if (typeof value === "string" && value.trim() === "") {
|
|
24433
|
+
return void 0;
|
|
24434
|
+
}
|
|
24435
|
+
if (Array.isArray(value) && value.length === 0) {
|
|
24436
|
+
return void 0;
|
|
24437
|
+
}
|
|
24438
|
+
return value;
|
|
24439
|
+
}
|
|
24296
24440
|
function buildToolApprovalOptions(persistOptions) {
|
|
24297
24441
|
const options = [
|
|
24298
24442
|
{ optionId: McpApprovalOptionId.AllowOnce, name: "Allow", kind: "allow_once" }
|
|
@@ -24389,8 +24533,68 @@ var CodexElicitationHandler = class {
|
|
|
24389
24533
|
return { action: "cancel", content: null, _meta: null };
|
|
24390
24534
|
}
|
|
24391
24535
|
}
|
|
24392
|
-
|
|
24393
|
-
|
|
24536
|
+
async handleUserInput(params) {
|
|
24537
|
+
if (!clientSupportsFormElicitation(this.clientCapabilities)) {
|
|
24538
|
+
return { answers: {} };
|
|
24539
|
+
}
|
|
24540
|
+
try {
|
|
24541
|
+
const response = await this.requestUserInputElicitation(params);
|
|
24542
|
+
if (response === null) {
|
|
24543
|
+
return { answers: {} };
|
|
24544
|
+
}
|
|
24545
|
+
return this.convertUserInputResponse(response, params);
|
|
24546
|
+
} catch (error51) {
|
|
24547
|
+
logger.error("Error handling Codex user input request", error51);
|
|
24548
|
+
return { answers: {} };
|
|
24549
|
+
}
|
|
24550
|
+
}
|
|
24551
|
+
requestOptions(cancellationSignal = this.cancellationSignal) {
|
|
24552
|
+
return cancellationSignal ? { cancellationSignal } : void 0;
|
|
24553
|
+
}
|
|
24554
|
+
async requestUserInputElicitation(params) {
|
|
24555
|
+
const request = this.buildUserInputRequest(params);
|
|
24556
|
+
if (params.autoResolutionMs === null) {
|
|
24557
|
+
return await this.connection.request(
|
|
24558
|
+
methods.client.elicitation.create,
|
|
24559
|
+
request,
|
|
24560
|
+
this.requestOptions()
|
|
24561
|
+
);
|
|
24562
|
+
}
|
|
24563
|
+
const abortController = new AbortController();
|
|
24564
|
+
let timeout;
|
|
24565
|
+
let removeAbortListener;
|
|
24566
|
+
const timeoutPromise = new Promise((resolve) => {
|
|
24567
|
+
const resolveWithoutInput = () => {
|
|
24568
|
+
abortController.abort();
|
|
24569
|
+
resolve(null);
|
|
24570
|
+
};
|
|
24571
|
+
timeout = setTimeout(resolveWithoutInput, Math.max(0, params.autoResolutionMs ?? 0));
|
|
24572
|
+
if (this.cancellationSignal?.aborted) {
|
|
24573
|
+
resolveWithoutInput();
|
|
24574
|
+
return;
|
|
24575
|
+
}
|
|
24576
|
+
if (this.cancellationSignal) {
|
|
24577
|
+
this.cancellationSignal.addEventListener("abort", resolveWithoutInput, { once: true });
|
|
24578
|
+
removeAbortListener = () => {
|
|
24579
|
+
this.cancellationSignal?.removeEventListener("abort", resolveWithoutInput);
|
|
24580
|
+
};
|
|
24581
|
+
}
|
|
24582
|
+
});
|
|
24583
|
+
const requestPromise = Promise.resolve(this.connection.request(
|
|
24584
|
+
methods.client.elicitation.create,
|
|
24585
|
+
request,
|
|
24586
|
+
this.requestOptions(abortController.signal)
|
|
24587
|
+
));
|
|
24588
|
+
void requestPromise.catch(() => {
|
|
24589
|
+
});
|
|
24590
|
+
try {
|
|
24591
|
+
return await Promise.race([requestPromise, timeoutPromise]);
|
|
24592
|
+
} finally {
|
|
24593
|
+
if (timeout) {
|
|
24594
|
+
clearTimeout(timeout);
|
|
24595
|
+
}
|
|
24596
|
+
removeAbortListener?.();
|
|
24597
|
+
}
|
|
24394
24598
|
}
|
|
24395
24599
|
createMcpElicitationContext(params) {
|
|
24396
24600
|
const isToolApproval = isMcpToolCallApproval(params._meta);
|
|
@@ -24436,6 +24640,72 @@ var CodexElicitationHandler = class {
|
|
|
24436
24640
|
};
|
|
24437
24641
|
}
|
|
24438
24642
|
}
|
|
24643
|
+
buildUserInputRequest(params) {
|
|
24644
|
+
const properties = {};
|
|
24645
|
+
const required2 = [];
|
|
24646
|
+
const questionIds = new Set(params.questions.map((question) => question.id));
|
|
24647
|
+
for (const question of params.questions) {
|
|
24648
|
+
const options = question.options ?? [];
|
|
24649
|
+
const hasOptions = options.length > 0;
|
|
24650
|
+
const hasOtherAnswer = question.isOther && hasOptions;
|
|
24651
|
+
const base = {
|
|
24652
|
+
title: question.header || question.id,
|
|
24653
|
+
description: question.question,
|
|
24654
|
+
_meta: {
|
|
24655
|
+
codex: {
|
|
24656
|
+
isOther: question.isOther,
|
|
24657
|
+
isSecret: question.isSecret
|
|
24658
|
+
}
|
|
24659
|
+
}
|
|
24660
|
+
};
|
|
24661
|
+
if (!hasOtherAnswer) {
|
|
24662
|
+
required2.push(question.id);
|
|
24663
|
+
}
|
|
24664
|
+
properties[question.id] = hasOptions ? {
|
|
24665
|
+
...base,
|
|
24666
|
+
type: "string",
|
|
24667
|
+
oneOf: options.map((option) => ({
|
|
24668
|
+
const: option.label,
|
|
24669
|
+
title: option.label,
|
|
24670
|
+
description: option.description
|
|
24671
|
+
}))
|
|
24672
|
+
} : {
|
|
24673
|
+
...base,
|
|
24674
|
+
type: "string"
|
|
24675
|
+
};
|
|
24676
|
+
if (hasOtherAnswer) {
|
|
24677
|
+
properties[userInputOtherFieldId(question.id, questionIds)] = {
|
|
24678
|
+
type: "string",
|
|
24679
|
+
title: "Other",
|
|
24680
|
+
description: "Type your own answer instead of choosing an option above.",
|
|
24681
|
+
_meta: {
|
|
24682
|
+
codex: {
|
|
24683
|
+
questionId: question.id,
|
|
24684
|
+
isOtherAnswer: true,
|
|
24685
|
+
isSecret: question.isSecret
|
|
24686
|
+
}
|
|
24687
|
+
}
|
|
24688
|
+
};
|
|
24689
|
+
}
|
|
24690
|
+
}
|
|
24691
|
+
const firstQuestion = params.questions[0];
|
|
24692
|
+
return {
|
|
24693
|
+
sessionId: this.sessionState.sessionId,
|
|
24694
|
+
toolCallId: params.itemId,
|
|
24695
|
+
mode: "form",
|
|
24696
|
+
message: params.questions.length === 1 && firstQuestion ? firstQuestion.question : "Input requested",
|
|
24697
|
+
requestedSchema: {
|
|
24698
|
+
type: "object",
|
|
24699
|
+
properties,
|
|
24700
|
+
required: required2
|
|
24701
|
+
},
|
|
24702
|
+
_meta: {
|
|
24703
|
+
codex: {
|
|
24704
|
+
autoResolutionMs: params.autoResolutionMs
|
|
24705
|
+
}
|
|
24706
|
+
}
|
|
24707
|
+
};
|
|
24708
|
+
}
|
|
24439
24709
|
buildPermissionRequest(params, context) {
|
|
24440
24710
|
const sessionId = this.sessionState.sessionId;
|
|
24441
24711
|
const messageContent = {
|
|
@@ -24533,6 +24803,24 @@ var CodexElicitationHandler = class {
|
|
|
24533
24803
|
}
|
|
24534
24804
|
return { action: "cancel", content: null, _meta: null };
|
|
24535
24805
|
}
|
|
24806
|
+
convertUserInputResponse(response, params) {
|
|
24807
|
+
if (!CreateElicitationResponse.isAccept(response)) {
|
|
24808
|
+
return { answers: {} };
|
|
24809
|
+
}
|
|
24810
|
+
const answers = {};
|
|
24811
|
+
const content = contentRecord(response.content);
|
|
24812
|
+
const questionIds = new Set(params.questions.map((question) => question.id));
|
|
24813
|
+
for (const question of params.questions) {
|
|
24814
|
+
const value = question.isOther && question.options != null && question.options.length > 0 ? userInputResponseValue(content, userInputOtherFieldId(question.id, questionIds)) ?? userInputResponseValue(content, question.id) : userInputResponseValue(content, question.id);
|
|
24815
|
+
if (value === void 0) {
|
|
24816
|
+
continue;
|
|
24817
|
+
}
|
|
24818
|
+
answers[question.id] = {
|
|
24819
|
+
answers: Array.isArray(value) ? value.map(String) : [String(value)]
|
|
24820
|
+
};
|
|
24821
|
+
}
|
|
24822
|
+
return { answers };
|
|
24823
|
+
}
|
|
24536
24824
|
async publishAcceptedMcpToolApproval(context, accepted) {
|
|
24537
24825
|
if (!accepted || context.correlatedCallId === void 0) {
|
|
24538
24826
|
return;
|
|
@@ -25399,7 +25687,7 @@ var package_default = {
|
|
|
25399
25687
|
publishConfig: {
|
|
25400
25688
|
access: "public"
|
|
25401
25689
|
},
|
|
25402
|
-
version: "1.1.
|
|
25690
|
+
version: "1.1.4",
|
|
25403
25691
|
description: "",
|
|
25404
25692
|
main: "dist/index.js",
|
|
25405
25693
|
bin: {
|
|
@@ -25458,7 +25746,7 @@ var package_default = {
|
|
|
25458
25746
|
},
|
|
25459
25747
|
dependencies: {
|
|
25460
25748
|
"@agentclientprotocol/sdk": "^1.2.1",
|
|
25461
|
-
"@openai/codex": "^0.
|
|
25749
|
+
"@openai/codex": "^0.144.4",
|
|
25462
25750
|
diff: "^9.0.0",
|
|
25463
25751
|
open: "^11.0.0",
|
|
25464
25752
|
"vscode-jsonrpc": "^9.0.1",
|
|
@@ -25466,7 +25754,46 @@ var package_default = {
|
|
|
25466
25754
|
}
|
|
25467
25755
|
};
|
|
25468
25756
|
|
|
25757
|
+
// src/CollaborationModeConfig.ts
|
|
25758
|
+
var COLLABORATION_MODE_CONFIG_ID = "collaboration_mode";
|
|
25759
|
+
var DEFAULT_COLLABORATION_MODE = "default";
|
|
25760
|
+
var PLAN_COLLABORATION_MODE = "plan";
|
|
25761
|
+
function createCollaborationModeConfigOption(currentValue) {
|
|
25762
|
+
return {
|
|
25763
|
+
id: COLLABORATION_MODE_CONFIG_ID,
|
|
25764
|
+
name: "Collaboration mode",
|
|
25765
|
+
description: "How Codex collaborates for subsequent turns",
|
|
25766
|
+
category: "collaboration_mode",
|
|
25767
|
+
type: "select",
|
|
25768
|
+
currentValue,
|
|
25769
|
+
options: [
|
|
25770
|
+
{ value: DEFAULT_COLLABORATION_MODE, name: "Default" },
|
|
25771
|
+
{ value: PLAN_COLLABORATION_MODE, name: "Plan", description: "Plan before making changes" }
|
|
25772
|
+
]
|
|
25773
|
+
};
|
|
25774
|
+
}
|
|
25775
|
+
function parseCollaborationMode(value) {
|
|
25776
|
+
if (value === DEFAULT_COLLABORATION_MODE) return DEFAULT_COLLABORATION_MODE;
|
|
25777
|
+
if (value === PLAN_COLLABORATION_MODE) return PLAN_COLLABORATION_MODE;
|
|
25778
|
+
return null;
|
|
25779
|
+
}
|
|
25780
|
+
function createCodexCollaborationMode(mode, currentModelId) {
|
|
25781
|
+
const modelId = ModelId.fromString(currentModelId);
|
|
25782
|
+
return {
|
|
25783
|
+
mode,
|
|
25784
|
+
settings: {
|
|
25785
|
+
model: modelId.model,
|
|
25786
|
+
reasoning_effort: modelId.effort,
|
|
25787
|
+
developer_instructions: null
|
|
25788
|
+
}
|
|
25789
|
+
};
|
|
25790
|
+
}
|
|
25791
|
+
|
|
25469
25792
|
// src/CodexAcpClient.ts
|
|
25793
|
+
var CUSTOM_GATEWAY_PROVIDER_ID = "custom-gateway";
|
|
25794
|
+
var SUPPORTED_GATEWAY_PROTOCOLS = {
|
|
25795
|
+
openai: "responses"
|
|
25796
|
+
};
|
|
25470
25797
|
var CodexAcpClient = class {
|
|
25471
25798
|
codexClient;
|
|
25472
25799
|
config;
|
|
@@ -25489,7 +25816,10 @@ var CodexAcpClient = class {
|
|
|
25489
25816
|
};
|
|
25490
25817
|
async initialize(request) {
|
|
25491
25818
|
await this.codexClient.initialize({
|
|
25492
|
-
capabilities:
|
|
25819
|
+
capabilities: {
|
|
25820
|
+
experimentalApi: true,
|
|
25821
|
+
requestAttestation: false
|
|
25822
|
+
},
|
|
25493
25823
|
clientInfo: {
|
|
25494
25824
|
name: request.clientInfo?.name ?? this.defaultClientInfo.name,
|
|
25495
25825
|
version: request.clientInfo?.version ?? this.defaultClientInfo.version,
|
|
@@ -25501,6 +25831,7 @@ var CodexAcpClient = class {
|
|
|
25501
25831
|
if (!isCodexAuthRequest(authRequest)) {
|
|
25502
25832
|
throw RequestError.invalidRequest();
|
|
25503
25833
|
}
|
|
25834
|
+
this.gatewayConfig = null;
|
|
25504
25835
|
switch (authRequest.methodId) {
|
|
25505
25836
|
case "api-key": {
|
|
25506
25837
|
const apiKey = authRequest._meta?.["api-key"]?.apiKey ?? this.readApiKeyFromEnv();
|
|
@@ -25509,7 +25840,6 @@ var CodexAcpClient = class {
|
|
|
25509
25840
|
case "chat-gpt": {
|
|
25510
25841
|
const accountResponse = await this.codexClient.accountRead({ refreshToken: true });
|
|
25511
25842
|
if (accountResponse.account?.type === "chatgpt") {
|
|
25512
|
-
this.gatewayConfig = null;
|
|
25513
25843
|
return true;
|
|
25514
25844
|
}
|
|
25515
25845
|
const loginCompletedPromise = this.awaitNextLoginCompleted();
|
|
@@ -25517,7 +25847,6 @@ var CodexAcpClient = class {
|
|
|
25517
25847
|
if (loginResponse.type == "chatgpt") {
|
|
25518
25848
|
await open_default(loginResponse.authUrl);
|
|
25519
25849
|
}
|
|
25520
|
-
this.gatewayConfig = null;
|
|
25521
25850
|
const result = await loginCompletedPromise;
|
|
25522
25851
|
return result.success;
|
|
25523
25852
|
}
|
|
@@ -25525,25 +25854,14 @@ var CodexAcpClient = class {
|
|
|
25525
25854
|
if (!authRequest._meta) throw RequestError.invalidRequest();
|
|
25526
25855
|
const gatewaySettings = authRequest._meta["gateway"];
|
|
25527
25856
|
if (!gatewaySettings) throw RequestError.invalidRequest();
|
|
25528
|
-
|
|
25529
|
-
|
|
25530
|
-
|
|
25531
|
-
|
|
25532
|
-
|
|
25533
|
-
};
|
|
25534
|
-
this.gatewayConfig = {
|
|
25535
|
-
modelProvider: "custom-gateway",
|
|
25536
|
-
config: {
|
|
25537
|
-
name: providerName,
|
|
25538
|
-
base_url: baseUrl,
|
|
25539
|
-
http_headers: headers,
|
|
25540
|
-
wire_api: "responses"
|
|
25541
|
-
}
|
|
25542
|
-
};
|
|
25857
|
+
this.applyGatewayConfig({
|
|
25858
|
+
baseUrl: gatewaySettings.baseUrl,
|
|
25859
|
+
apiType: GatewayAuthMethod._meta.gateway.protocol,
|
|
25860
|
+
headers: gatewaySettings.headers,
|
|
25861
|
+
providerName: gatewaySettings.providerName
|
|
25862
|
+
});
|
|
25543
25863
|
return true;
|
|
25544
25864
|
}
|
|
25545
|
-
this.gatewayConfig = null;
|
|
25546
|
-
return false;
|
|
25547
25865
|
}
|
|
25548
25866
|
async authenticateWithApiKey(apiKey) {
|
|
25549
25867
|
const loginCompletedPromise = this.awaitNextLoginCompleted();
|
|
@@ -25551,7 +25869,6 @@ var CodexAcpClient = class {
|
|
|
25551
25869
|
type: "apiKey",
|
|
25552
25870
|
apiKey
|
|
25553
25871
|
});
|
|
25554
|
-
this.gatewayConfig = null;
|
|
25555
25872
|
const result = await loginCompletedPromise;
|
|
25556
25873
|
return result.success;
|
|
25557
25874
|
}
|
|
@@ -25618,8 +25935,83 @@ var CodexAcpClient = class {
|
|
|
25618
25935
|
const response = await this.codexClient.accountRead({ refreshToken: false });
|
|
25619
25936
|
return response.requiresOpenaiAuth && !response.account;
|
|
25620
25937
|
}
|
|
25621
|
-
|
|
25622
|
-
|
|
25938
|
+
/**
|
|
25939
|
+
* Validates and stores custom gateway routing. Shared by the `gateway` auth
|
|
25940
|
+
* method and the ACP `providers/set` method. Throws `invalid_params` for an
|
|
25941
|
+
* unsupported protocol or a malformed base URL.
|
|
25942
|
+
*/
|
|
25943
|
+
applyGatewayConfig(params) {
|
|
25944
|
+
const apiType = params.apiType;
|
|
25945
|
+
const wireApi = SUPPORTED_GATEWAY_PROTOCOLS[apiType];
|
|
25946
|
+
if (!wireApi) {
|
|
25947
|
+
throw RequestError.invalidParams(
|
|
25948
|
+
{ apiType },
|
|
25949
|
+
`Unsupported provider apiType "${apiType}"; supported: ${Object.keys(SUPPORTED_GATEWAY_PROTOCOLS).join(", ")}`
|
|
25950
|
+
);
|
|
25951
|
+
}
|
|
25952
|
+
if (typeof params.baseUrl !== "string" || params.baseUrl.trim().length === 0) {
|
|
25953
|
+
throw RequestError.invalidParams(void 0, "baseUrl must be a non-empty string");
|
|
25954
|
+
}
|
|
25955
|
+
const providerName = typeof params.providerName === "string" && params.providerName.trim().length > 0 ? params.providerName : "User-provided gateway";
|
|
25956
|
+
const headers = {
|
|
25957
|
+
"X-Client-Feature-ID": "codex",
|
|
25958
|
+
...params.headers
|
|
25959
|
+
};
|
|
25960
|
+
this.gatewayConfig = {
|
|
25961
|
+
modelProvider: CUSTOM_GATEWAY_PROVIDER_ID,
|
|
25962
|
+
config: {
|
|
25963
|
+
name: providerName,
|
|
25964
|
+
base_url: params.baseUrl,
|
|
25965
|
+
http_headers: headers,
|
|
25966
|
+
wire_api: wireApi
|
|
25967
|
+
}
|
|
25968
|
+
};
|
|
25969
|
+
}
|
|
25970
|
+
/**
|
|
25971
|
+
* `providers/list`: returns the single client-configurable custom gateway
|
|
25972
|
+
* provider. `current` carries only non-secret routing (never headers), and is
|
|
25973
|
+
* `null` when the provider is not configured/disabled.
|
|
25974
|
+
*/
|
|
25975
|
+
listProviders() {
|
|
25976
|
+
const gatewayConfig = this.gatewayConfig;
|
|
25977
|
+
const current = gatewayConfig ? {
|
|
25978
|
+
apiType: gatewayApiTypeFromConfig(gatewayConfig),
|
|
25979
|
+
baseUrl: gatewayConfig.config.base_url
|
|
25980
|
+
} : null;
|
|
25981
|
+
return [
|
|
25982
|
+
{
|
|
25983
|
+
providerId: CUSTOM_GATEWAY_PROVIDER_ID,
|
|
25984
|
+
supported: Object.keys(SUPPORTED_GATEWAY_PROTOCOLS),
|
|
25985
|
+
required: false,
|
|
25986
|
+
current
|
|
25987
|
+
}
|
|
25988
|
+
];
|
|
25989
|
+
}
|
|
25990
|
+
/**
|
|
25991
|
+
* `providers/set`: replaces the full configuration for the custom gateway
|
|
25992
|
+
* provider. Rejects unknown provider ids with `invalid_params`.
|
|
25993
|
+
*/
|
|
25994
|
+
setProvider(request) {
|
|
25995
|
+
if (request.providerId !== CUSTOM_GATEWAY_PROVIDER_ID) {
|
|
25996
|
+
throw RequestError.invalidParams(
|
|
25997
|
+
{ providerId: request.providerId },
|
|
25998
|
+
`Unknown providerId "${request.providerId}"; only "${CUSTOM_GATEWAY_PROVIDER_ID}" is configurable`
|
|
25999
|
+
);
|
|
26000
|
+
}
|
|
26001
|
+
this.applyGatewayConfig({
|
|
26002
|
+
apiType: request.apiType,
|
|
26003
|
+
baseUrl: request.baseUrl,
|
|
26004
|
+
headers: request.headers
|
|
26005
|
+
});
|
|
26006
|
+
}
|
|
26007
|
+
/**
|
|
26008
|
+
* `providers/disable`: disables the custom gateway provider. Disabling an
|
|
26009
|
+
* unknown provider id is idempotent success (RFD behavior §7).
|
|
26010
|
+
*/
|
|
26011
|
+
disableProvider(request) {
|
|
26012
|
+
if (request.providerId === CUSTOM_GATEWAY_PROVIDER_ID) {
|
|
26013
|
+
this.gatewayConfig = null;
|
|
26014
|
+
}
|
|
25623
26015
|
}
|
|
25624
26016
|
async getAccount() {
|
|
25625
26017
|
return this.codexClient.accountRead({ refreshToken: false });
|
|
@@ -25640,6 +26032,7 @@ var CodexAcpClient = class {
|
|
|
25640
26032
|
sessionId: request.sessionId,
|
|
25641
26033
|
currentModelId,
|
|
25642
26034
|
models: codexModels,
|
|
26035
|
+
collaborationMode: this.getCollaborationMode(response.thread.id),
|
|
25643
26036
|
modelProvider: response.modelProvider,
|
|
25644
26037
|
currentServiceTier: response.serviceTier ?? null,
|
|
25645
26038
|
additionalDirectories
|
|
@@ -25665,6 +26058,7 @@ var CodexAcpClient = class {
|
|
|
25665
26058
|
sessionId: request.sessionId,
|
|
25666
26059
|
currentModelId,
|
|
25667
26060
|
models: codexModels,
|
|
26061
|
+
collaborationMode: this.getCollaborationMode(response.thread.id),
|
|
25668
26062
|
modelProvider: response.modelProvider,
|
|
25669
26063
|
currentServiceTier: response.serviceTier ?? null,
|
|
25670
26064
|
thread: historyResponse.thread,
|
|
@@ -25688,6 +26082,7 @@ var CodexAcpClient = class {
|
|
|
25688
26082
|
sessionId: response.thread.id,
|
|
25689
26083
|
currentModelId,
|
|
25690
26084
|
models: codexModels,
|
|
26085
|
+
collaborationMode: this.getCollaborationMode(response.thread.id),
|
|
25691
26086
|
modelProvider: response.modelProvider,
|
|
25692
26087
|
currentServiceTier: response.serviceTier ?? null,
|
|
25693
26088
|
additionalDirectories
|
|
@@ -25713,6 +26108,10 @@ var CodexAcpClient = class {
|
|
|
25713
26108
|
async runCompact(sessionId) {
|
|
25714
26109
|
await this.codexClient.runCompact({ threadId: sessionId });
|
|
25715
26110
|
}
|
|
26111
|
+
async getGoal(sessionId) {
|
|
26112
|
+
const response = await this.codexClient.threadGoalGet({ threadId: sessionId });
|
|
26113
|
+
return response?.goal ?? null;
|
|
26114
|
+
}
|
|
25716
26115
|
async setGoal(sessionId, objective, onTurnStarted) {
|
|
25717
26116
|
return await this.codexClient.runGoalSet({
|
|
25718
26117
|
threadId: sessionId,
|
|
@@ -25721,10 +26120,17 @@ var CodexAcpClient = class {
|
|
|
25721
26120
|
}, onTurnStarted);
|
|
25722
26121
|
}
|
|
25723
26122
|
async setGoalStatus(sessionId, status) {
|
|
26123
|
+
let updatedGoal = null;
|
|
25724
26124
|
await this.codexClient.runGoalSet({
|
|
25725
26125
|
threadId: sessionId,
|
|
25726
26126
|
status
|
|
26127
|
+
}, void 0, void 0, (goal) => {
|
|
26128
|
+
updatedGoal = goal;
|
|
25727
26129
|
});
|
|
26130
|
+
if (updatedGoal === null) {
|
|
26131
|
+
throw new Error(`Goal update for session ${sessionId} returned no goal`);
|
|
26132
|
+
}
|
|
26133
|
+
return updatedGoal;
|
|
25728
26134
|
}
|
|
25729
26135
|
async resumeGoal(sessionId, onTurnStarted) {
|
|
25730
26136
|
return await this.codexClient.runGoalSet({
|
|
@@ -25861,6 +26267,10 @@ var CodexAcpClient = class {
|
|
|
25861
26267
|
handleElicitation: async (params) => {
|
|
25862
26268
|
await this.waitForSessionNotifications(sessionId);
|
|
25863
26269
|
return await elicitationHandler.handleElicitation(params);
|
|
26270
|
+
},
|
|
26271
|
+
handleUserInput: async (params) => {
|
|
26272
|
+
await this.waitForSessionNotifications(sessionId);
|
|
26273
|
+
return await elicitationHandler.handleUserInput(params);
|
|
25864
26274
|
}
|
|
25865
26275
|
});
|
|
25866
26276
|
}
|
|
@@ -25906,6 +26316,15 @@ var CodexAcpClient = class {
|
|
|
25906
26316
|
serviceTier
|
|
25907
26317
|
}, onTurnStarted);
|
|
25908
26318
|
}
|
|
26319
|
+
async setCollaborationMode(sessionId, mode, currentModelId) {
|
|
26320
|
+
await this.codexClient.threadSettingsUpdate({
|
|
26321
|
+
threadId: sessionId,
|
|
26322
|
+
collaborationMode: createCodexCollaborationMode(mode, currentModelId)
|
|
26323
|
+
});
|
|
26324
|
+
}
|
|
26325
|
+
getCollaborationMode(sessionId) {
|
|
26326
|
+
return this.codexClient.getThreadSettings(sessionId)?.collaborationMode.mode ?? "default";
|
|
26327
|
+
}
|
|
25909
26328
|
resolveTurnInterrupted(params) {
|
|
25910
26329
|
this.codexClient.resolveTurnInterrupted(params.threadId, params.turnId);
|
|
25911
26330
|
}
|
|
@@ -26023,7 +26442,7 @@ var CodexAcpClient = class {
|
|
|
26023
26442
|
const [allProviders, archivedAllProviders, customGateway] = await Promise.all([
|
|
26024
26443
|
this.codexClient.threadList({}),
|
|
26025
26444
|
this.codexClient.threadList({ archived: true }),
|
|
26026
|
-
this.codexClient.threadList({ modelProviders: [
|
|
26445
|
+
this.codexClient.threadList({ modelProviders: [CUSTOM_GATEWAY_PROVIDER_ID] })
|
|
26027
26446
|
]);
|
|
26028
26447
|
return {
|
|
26029
26448
|
allProviders: {
|
|
@@ -26176,6 +26595,11 @@ function arraysEqual(left, right) {
|
|
|
26176
26595
|
function isJsonObject(value) {
|
|
26177
26596
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
26178
26597
|
}
|
|
26598
|
+
function gatewayApiTypeFromConfig(gatewayConfig) {
|
|
26599
|
+
const wireApi = gatewayConfig.config.wire_api;
|
|
26600
|
+
const match = Object.entries(SUPPORTED_GATEWAY_PROTOCOLS).find(([, wire]) => wire === wireApi);
|
|
26601
|
+
return match?.[0] ?? "openai";
|
|
26602
|
+
}
|
|
26179
26603
|
function mergeGatewayConfig(config2, gatewayConfig) {
|
|
26180
26604
|
if (gatewayConfig !== null) {
|
|
26181
26605
|
const newConfig = { ...config2 };
|
|
@@ -26194,6 +26618,9 @@ function mergeGatewayConfig(config2, gatewayConfig) {
|
|
|
26194
26618
|
// src/ModelConfigOption.ts
|
|
26195
26619
|
var MODEL_CONFIG_ID = "model";
|
|
26196
26620
|
var REASONING_EFFORT_CONFIG_ID = "reasoning_effort";
|
|
26621
|
+
function capitalize(value) {
|
|
26622
|
+
return value.charAt(0).toUpperCase() + value.slice(1);
|
|
26623
|
+
}
|
|
26197
26624
|
function findSupportedEffort(options, effort) {
|
|
26198
26625
|
if (!effort) return void 0;
|
|
26199
26626
|
return options.find((o) => o.reasoningEffort === effort)?.reasoningEffort;
|
|
@@ -26231,7 +26658,7 @@ function createReasoningEffortConfigOption(supportedReasoningEfforts, currentEff
|
|
|
26231
26658
|
currentValue: currentEffort,
|
|
26232
26659
|
options: supportedReasoningEfforts.map((option) => ({
|
|
26233
26660
|
value: option.reasoningEffort,
|
|
26234
|
-
name: option.reasoningEffort,
|
|
26661
|
+
name: capitalize(option.reasoningEffort),
|
|
26235
26662
|
description: option.description
|
|
26236
26663
|
}))
|
|
26237
26664
|
};
|
|
@@ -26295,6 +26722,20 @@ var CodexCommands = class {
|
|
|
26295
26722
|
*/
|
|
26296
26723
|
getBuiltinCommands() {
|
|
26297
26724
|
return [
|
|
26725
|
+
{
|
|
26726
|
+
name: "plan",
|
|
26727
|
+
description: "Turn plan mode on.",
|
|
26728
|
+
input: null,
|
|
26729
|
+
_meta: {
|
|
26730
|
+
commandAction: {
|
|
26731
|
+
kind: "setConfigOption",
|
|
26732
|
+
configId: COLLABORATION_MODE_CONFIG_ID,
|
|
26733
|
+
value: PLAN_COLLABORATION_MODE,
|
|
26734
|
+
resetValue: DEFAULT_COLLABORATION_MODE,
|
|
26735
|
+
presentation: "state"
|
|
26736
|
+
}
|
|
26737
|
+
}
|
|
26738
|
+
},
|
|
26298
26739
|
{
|
|
26299
26740
|
name: "mcp",
|
|
26300
26741
|
description: "List configured Model Context Protocol (MCP) tools.",
|
|
@@ -26332,8 +26773,14 @@ var CodexCommands = class {
|
|
|
26332
26773
|
},
|
|
26333
26774
|
{
|
|
26334
26775
|
name: "goal",
|
|
26335
|
-
description: "Set
|
|
26336
|
-
input: { hint: "[<objective>|clear|pause|resume]" }
|
|
26776
|
+
description: "Set a goal to keep pursuing.",
|
|
26777
|
+
input: { hint: "[<objective>|clear|pause|resume]" },
|
|
26778
|
+
_meta: {
|
|
26779
|
+
commandAction: {
|
|
26780
|
+
kind: "prefixPrompt",
|
|
26781
|
+
presentation: "state"
|
|
26782
|
+
}
|
|
26783
|
+
}
|
|
26337
26784
|
},
|
|
26338
26785
|
{
|
|
26339
26786
|
name: "logout",
|
|
@@ -26363,6 +26810,15 @@ var CodexCommands = class {
|
|
|
26363
26810
|
if (commandName.startsWith("$")) return { handled: false };
|
|
26364
26811
|
const sessionId = sessionState.sessionId;
|
|
26365
26812
|
switch (commandName) {
|
|
26813
|
+
case "plan": {
|
|
26814
|
+
if (command.rest.length > 0) {
|
|
26815
|
+
await this.sendCommandUsageMessage(commandName, "no arguments", sessionId);
|
|
26816
|
+
return { handled: true };
|
|
26817
|
+
}
|
|
26818
|
+
const mode = sessionState.collaborationMode === PLAN_COLLABORATION_MODE ? DEFAULT_COLLABORATION_MODE : PLAN_COLLABORATION_MODE;
|
|
26819
|
+
await options.setConfigOption?.(COLLABORATION_MODE_CONFIG_ID, mode);
|
|
26820
|
+
return { handled: options.setConfigOption !== void 0 };
|
|
26821
|
+
}
|
|
26366
26822
|
case "compact": {
|
|
26367
26823
|
await this.runWithProcessCheck(() => this.codexAcpClient.runCompact(sessionId));
|
|
26368
26824
|
return { handled: true };
|
|
@@ -26438,8 +26894,7 @@ var CodexCommands = class {
|
|
|
26438
26894
|
return { handled: true };
|
|
26439
26895
|
}
|
|
26440
26896
|
default:
|
|
26441
|
-
|
|
26442
|
-
return { handled: true };
|
|
26897
|
+
return { handled: false };
|
|
26443
26898
|
}
|
|
26444
26899
|
}
|
|
26445
26900
|
async runReviewCommand(sessionState, target, options) {
|
|
@@ -26518,18 +26973,6 @@ var CodexCommands = class {
|
|
|
26518
26973
|
const session = new ACPSessionConnection(this.connection, sessionId);
|
|
26519
26974
|
await session.update(createAgentTextMessageChunk(`Command "/${name}" requires ${inputHint}.`));
|
|
26520
26975
|
}
|
|
26521
|
-
async sendUnknownCommandMessage(name, sessionId) {
|
|
26522
|
-
const lines = this.getBuiltinCommands().map((command) => `- /${command.name}: ${command.description}`);
|
|
26523
|
-
const text = [
|
|
26524
|
-
`Unknown command "/${name}".`,
|
|
26525
|
-
"Available commands:"
|
|
26526
|
-
];
|
|
26527
|
-
if (lines.length > 0) {
|
|
26528
|
-
text.push(...lines);
|
|
26529
|
-
}
|
|
26530
|
-
const session = new ACPSessionConnection(this.connection, sessionId);
|
|
26531
|
-
await session.update(createAgentTextMessageChunk(text.join("\n")));
|
|
26532
|
-
}
|
|
26533
26976
|
buildStatusMessage(sessionState) {
|
|
26534
26977
|
const agentMode = sessionState.agentMode;
|
|
26535
26978
|
const accountText = this.formatAccountInfo(sessionState.account);
|
|
@@ -26799,6 +27242,7 @@ function toolCallIdFromThreadItem(item) {
|
|
|
26799
27242
|
case "webSearch":
|
|
26800
27243
|
case "imageView":
|
|
26801
27244
|
case "imageGeneration":
|
|
27245
|
+
case "contextCompaction":
|
|
26802
27246
|
return item.id;
|
|
26803
27247
|
case "userMessage":
|
|
26804
27248
|
case "hookPrompt":
|
|
@@ -26808,7 +27252,6 @@ function toolCallIdFromThreadItem(item) {
|
|
|
26808
27252
|
case "subAgentActivity":
|
|
26809
27253
|
case "enteredReviewMode":
|
|
26810
27254
|
case "exitedReviewMode":
|
|
26811
|
-
case "contextCompaction":
|
|
26812
27255
|
case "sleep":
|
|
26813
27256
|
return null;
|
|
26814
27257
|
}
|
|
@@ -27625,12 +28068,6 @@ function numberValue(value) {
|
|
|
27625
28068
|
return typeof value === "number" && Number.isFinite(value) ? value : null;
|
|
27626
28069
|
}
|
|
27627
28070
|
|
|
27628
|
-
// src/AcpExtensions.ts
|
|
27629
|
-
var LEGACY_SET_SESSION_MODEL_METHOD = "session/set_model";
|
|
27630
|
-
function isExtMethodRequest(request) {
|
|
27631
|
-
return request.method === "authentication/status" || request.method === "authentication/logout" || request.method === LEGACY_SET_SESSION_MODEL_METHOD;
|
|
27632
|
-
}
|
|
27633
|
-
|
|
27634
28071
|
// src/FastModeConfig.ts
|
|
27635
28072
|
var FAST_MODE_CONFIG_ID = "fast-mode";
|
|
27636
28073
|
var FAST_MODE_CATEGORY = "model_config";
|
|
@@ -27756,6 +28193,7 @@ var CodexAcpServer = class _CodexAcpServer {
|
|
|
27756
28193
|
auth: {
|
|
27757
28194
|
logout: {}
|
|
27758
28195
|
},
|
|
28196
|
+
providers: {},
|
|
27759
28197
|
loadSession: true,
|
|
27760
28198
|
promptCapabilities: {
|
|
27761
28199
|
embeddedContext: true,
|
|
@@ -27791,6 +28229,25 @@ var CodexAcpServer = class _CodexAcpServer {
|
|
|
27791
28229
|
}
|
|
27792
28230
|
case LEGACY_SET_SESSION_MODEL_METHOD:
|
|
27793
28231
|
return await this.unstable_setSessionModel(this.parseLegacySetSessionModelParams(methodRequest.params));
|
|
28232
|
+
case GOAL_CONTROL_METHOD: {
|
|
28233
|
+
const sessionState = this.sessions.get(methodRequest.params.sessionId);
|
|
28234
|
+
if (!sessionState) {
|
|
28235
|
+
throw RequestError.invalidParams(void 0, `Unknown session: ${methodRequest.params.sessionId}`);
|
|
28236
|
+
}
|
|
28237
|
+
const sessionGeneration = this.getSessionGeneration(sessionState.sessionId);
|
|
28238
|
+
if (methodRequest.params.action === "pause") {
|
|
28239
|
+
const goal = await this.runWithProcessCheck(() => this.codexAcpClient.setGoalStatus(sessionState.sessionId, "paused"));
|
|
28240
|
+
if (this.goalPublishIsCurrent(sessionState, sessionGeneration)) {
|
|
28241
|
+
await this.publishGoalSnapshot(sessionState, toThreadGoalSnapshot(goal), false);
|
|
28242
|
+
}
|
|
28243
|
+
} else if (methodRequest.params.action === "clear") {
|
|
28244
|
+
await this.runWithProcessCheck(() => this.codexAcpClient.clearGoal(sessionState.sessionId));
|
|
28245
|
+
if (this.goalPublishIsCurrent(sessionState, sessionGeneration)) {
|
|
28246
|
+
await this.publishGoalSnapshot(sessionState, null, false);
|
|
28247
|
+
}
|
|
28248
|
+
}
|
|
28249
|
+
return {};
|
|
28250
|
+
}
|
|
27794
28251
|
}
|
|
27795
28252
|
}
|
|
27796
28253
|
async checkAuthorization() {
|
|
@@ -27932,6 +28389,7 @@ You have been logged out. Please try again.`);
|
|
|
27932
28389
|
supportedReasoningEfforts: currentModel?.supportedReasoningEfforts ?? [],
|
|
27933
28390
|
supportedInputModalities: currentModel?.inputModalities ?? ["text", "image"],
|
|
27934
28391
|
agentMode: AgentMode.getInitialAgentMode(),
|
|
28392
|
+
collaborationMode: sessionMetadata.collaborationMode,
|
|
27935
28393
|
currentTurnId: null,
|
|
27936
28394
|
lastTokenUsage: null,
|
|
27937
28395
|
totalTokenUsage: null,
|
|
@@ -27945,7 +28403,10 @@ You have been logged out. Please try again.`);
|
|
|
27945
28403
|
fastModeEnabled: sessionMetadata.currentServiceTier === "fast",
|
|
27946
28404
|
currentModelSupportsFast,
|
|
27947
28405
|
sessionMcpServers,
|
|
27948
|
-
terminalOutputMode: this.terminalOutputMode
|
|
28406
|
+
terminalOutputMode: this.terminalOutputMode,
|
|
28407
|
+
goalRevision: 0,
|
|
28408
|
+
sessionTitle: null,
|
|
28409
|
+
sessionTitleSource: "sessionId" in request ? "unknown" : "unset"
|
|
27949
28410
|
};
|
|
27950
28411
|
this.sessions.set(sessionId, sessionState);
|
|
27951
28412
|
resumeSubscribed = false;
|
|
@@ -27957,6 +28418,9 @@ You have been logged out. Please try again.`);
|
|
|
27957
28418
|
this.publishMcpStartupStatusAsync(sessionId);
|
|
27958
28419
|
}
|
|
27959
28420
|
this.publishAvailableCommandsAsync(sessionState);
|
|
28421
|
+
if ("sessionId" in request) {
|
|
28422
|
+
this.publishCurrentGoalAsync(sessionState, sessionGeneration);
|
|
28423
|
+
}
|
|
27960
28424
|
const sessionModelState = this.createModelState(models, currentModelId);
|
|
27961
28425
|
const sessionModeState = sessionState.agentMode.toSessionModeState();
|
|
27962
28426
|
return [sessionId, sessionModelState, sessionModeState];
|
|
@@ -28126,6 +28590,17 @@ You have been logged out. Please try again.`);
|
|
|
28126
28590
|
await this.refreshSessionsAuthState(null);
|
|
28127
28591
|
logger.log("Logout request completed");
|
|
28128
28592
|
}
|
|
28593
|
+
listProviders(_params) {
|
|
28594
|
+
return { providers: this.codexAcpClient.listProviders() };
|
|
28595
|
+
}
|
|
28596
|
+
setProvider(params) {
|
|
28597
|
+
this.codexAcpClient.setProvider(params);
|
|
28598
|
+
return {};
|
|
28599
|
+
}
|
|
28600
|
+
disableProvider(params) {
|
|
28601
|
+
this.codexAcpClient.disableProvider(params);
|
|
28602
|
+
return {};
|
|
28603
|
+
}
|
|
28129
28604
|
async refreshSessionsAuthState(authProvider) {
|
|
28130
28605
|
if (this.sessions.size === 0) return;
|
|
28131
28606
|
const sessionsToRefresh = [...this.sessions.values()].filter((sessionState) => this.authProvidersMatch(sessionState.authProvider, authProvider));
|
|
@@ -28153,6 +28628,12 @@ You have been logged out. Please try again.`);
|
|
|
28153
28628
|
});
|
|
28154
28629
|
const sessionState = this.sessions.get(params.sessionId);
|
|
28155
28630
|
if (!sessionState) throw new Error(`Session ${params.sessionId} not found`);
|
|
28631
|
+
await this.applySessionConfigOption(sessionState, params);
|
|
28632
|
+
return {
|
|
28633
|
+
configOptions: this.createSessionConfigOptions(sessionState)
|
|
28634
|
+
};
|
|
28635
|
+
}
|
|
28636
|
+
async applySessionConfigOption(sessionState, params) {
|
|
28156
28637
|
switch (params.configId) {
|
|
28157
28638
|
case FAST_MODE_CONFIG_ID:
|
|
28158
28639
|
this.applyFastModeChange(sessionState, params);
|
|
@@ -28160,6 +28641,9 @@ You have been logged out. Please try again.`);
|
|
|
28160
28641
|
case MODE_CONFIG_ID:
|
|
28161
28642
|
this.applyModeChange(sessionState, this.stringConfigValue(params));
|
|
28162
28643
|
break;
|
|
28644
|
+
case COLLABORATION_MODE_CONFIG_ID:
|
|
28645
|
+
await this.applyCollaborationModeChange(sessionState, this.stringConfigValue(params));
|
|
28646
|
+
break;
|
|
28163
28647
|
case MODEL_CONFIG_ID:
|
|
28164
28648
|
this.applyModelChange(sessionState, this.stringConfigValue(params));
|
|
28165
28649
|
break;
|
|
@@ -28169,9 +28653,6 @@ You have been logged out. Please try again.`);
|
|
|
28169
28653
|
default:
|
|
28170
28654
|
throw RequestError.invalidParams();
|
|
28171
28655
|
}
|
|
28172
|
-
return {
|
|
28173
|
-
configOptions: this.createSessionConfigOptions(sessionState)
|
|
28174
|
-
};
|
|
28175
28656
|
}
|
|
28176
28657
|
applyFastModeChange(sessionState, params) {
|
|
28177
28658
|
const value = params.value;
|
|
@@ -28197,6 +28678,14 @@ You have been logged out. Please try again.`);
|
|
|
28197
28678
|
}
|
|
28198
28679
|
sessionState.agentMode = newMode;
|
|
28199
28680
|
}
|
|
28681
|
+
async applyCollaborationModeChange(sessionState, value) {
|
|
28682
|
+
const mode = parseCollaborationMode(value);
|
|
28683
|
+
if (mode === null) {
|
|
28684
|
+
throw RequestError.invalidParams();
|
|
28685
|
+
}
|
|
28686
|
+
await this.codexAcpClient.setCollaborationMode(sessionState.sessionId, mode, sessionState.currentModelId);
|
|
28687
|
+
sessionState.collaborationMode = mode;
|
|
28688
|
+
}
|
|
28200
28689
|
applyModelChange(sessionState, value) {
|
|
28201
28690
|
const model = sessionState.availableModels.find((m) => m.id === value);
|
|
28202
28691
|
if (!model) {
|
|
@@ -28264,6 +28753,7 @@ You have been logged out. Please try again.`);
|
|
|
28264
28753
|
const currentModelId = ModelId.fromString(sessionState.currentModelId);
|
|
28265
28754
|
const configOptions = [
|
|
28266
28755
|
sessionState.agentMode.toConfigOption(),
|
|
28756
|
+
createCollaborationModeConfigOption(sessionState.collaborationMode),
|
|
28267
28757
|
createModelConfigOption(sessionState.availableModels, currentModelId.model)
|
|
28268
28758
|
];
|
|
28269
28759
|
if (sessionState.supportedReasoningEfforts.length > 0) {
|
|
@@ -28293,6 +28783,46 @@ You have been logged out. Please try again.`);
|
|
|
28293
28783
|
publishAvailableCommandsAsync(sessionState) {
|
|
28294
28784
|
void this.availableCommands.publish(sessionState);
|
|
28295
28785
|
}
|
|
28786
|
+
publishCurrentGoalAsync(sessionState, sessionGeneration) {
|
|
28787
|
+
void this.publishCurrentGoalBestEffort(sessionState, sessionGeneration, true);
|
|
28788
|
+
}
|
|
28789
|
+
async publishCurrentGoalBestEffort(sessionState, sessionGeneration, force) {
|
|
28790
|
+
try {
|
|
28791
|
+
await this.publishCurrentGoal(sessionState, sessionGeneration, force);
|
|
28792
|
+
} catch (err) {
|
|
28793
|
+
logger.error(`Failed to publish current goal for session ${sessionState.sessionId}`, err);
|
|
28794
|
+
}
|
|
28795
|
+
}
|
|
28796
|
+
async publishCurrentGoal(sessionState, sessionGeneration, force) {
|
|
28797
|
+
const requestRevision = ++sessionState.goalRevision;
|
|
28798
|
+
const goal = await this.runWithProcessCheck(() => this.codexAcpClient.getGoal(sessionState.sessionId));
|
|
28799
|
+
const snapshot = goal === null ? null : toThreadGoalSnapshot(goal);
|
|
28800
|
+
if (!this.goalPublishIsCurrent(sessionState, sessionGeneration) || sessionState.goalRevision !== requestRevision) {
|
|
28801
|
+
return;
|
|
28802
|
+
}
|
|
28803
|
+
await this.publishGoalSnapshot(sessionState, snapshot, force, false);
|
|
28804
|
+
}
|
|
28805
|
+
goalPublishIsCurrent(sessionState, sessionGeneration) {
|
|
28806
|
+
return this.sessions.get(sessionState.sessionId) === sessionState && this.getSessionGeneration(sessionState.sessionId) === sessionGeneration && !this.sessionIsClosing(sessionState.sessionId);
|
|
28807
|
+
}
|
|
28808
|
+
async publishGoalSnapshot(sessionState, snapshot, force, incrementRevision = true) {
|
|
28809
|
+
if (incrementRevision) {
|
|
28810
|
+
sessionState.goalRevision += 1;
|
|
28811
|
+
}
|
|
28812
|
+
if (!force && sameThreadGoalSnapshot(sessionState.currentGoal, snapshot)) {
|
|
28813
|
+
return;
|
|
28814
|
+
}
|
|
28815
|
+
sessionState.currentGoal = snapshot;
|
|
28816
|
+
const session = new ACPSessionConnection(this.connection, sessionState.sessionId);
|
|
28817
|
+
await session.update({
|
|
28818
|
+
sessionUpdate: "session_info_update",
|
|
28819
|
+
_meta: {
|
|
28820
|
+
codex: {
|
|
28821
|
+
goal: snapshot
|
|
28822
|
+
}
|
|
28823
|
+
}
|
|
28824
|
+
});
|
|
28825
|
+
}
|
|
28296
28826
|
findCurrentModel(models, currentModelId) {
|
|
28297
28827
|
const modelId = ModelId.fromString(currentModelId);
|
|
28298
28828
|
return models.find((m) => m.id === modelId.model);
|
|
@@ -28358,6 +28888,7 @@ You have been logged out. Please try again.`);
|
|
|
28358
28888
|
supportedReasoningEfforts: currentModel?.supportedReasoningEfforts ?? [],
|
|
28359
28889
|
supportedInputModalities: currentModel?.inputModalities ?? ["text", "image"],
|
|
28360
28890
|
agentMode: AgentMode.getInitialAgentMode(),
|
|
28891
|
+
collaborationMode: sessionMetadata.collaborationMode,
|
|
28361
28892
|
currentTurnId: null,
|
|
28362
28893
|
lastTokenUsage: null,
|
|
28363
28894
|
totalTokenUsage: null,
|
|
@@ -28371,7 +28902,10 @@ You have been logged out. Please try again.`);
|
|
|
28371
28902
|
fastModeEnabled: sessionMetadata.currentServiceTier === "fast",
|
|
28372
28903
|
currentModelSupportsFast,
|
|
28373
28904
|
sessionMcpServers,
|
|
28374
|
-
terminalOutputMode: this.terminalOutputMode
|
|
28905
|
+
terminalOutputMode: this.terminalOutputMode,
|
|
28906
|
+
goalRevision: 0,
|
|
28907
|
+
sessionTitle: null,
|
|
28908
|
+
sessionTitleSource: "unset"
|
|
28375
28909
|
};
|
|
28376
28910
|
this.sessions.set(sessionId, sessionState);
|
|
28377
28911
|
subscribed = false;
|
|
@@ -28383,6 +28917,7 @@ You have been logged out. Please try again.`);
|
|
|
28383
28917
|
this.publishMcpStartupStatusAsync(sessionId);
|
|
28384
28918
|
}
|
|
28385
28919
|
await this.availableCommands.publish(sessionState);
|
|
28920
|
+
await this.publishCurrentGoalBestEffort(sessionState, requestedSessionGeneration, true);
|
|
28386
28921
|
const sessionModelState = this.createModelState(models, currentModelId);
|
|
28387
28922
|
const sessionModeState = sessionState.agentMode.toSessionModeState();
|
|
28388
28923
|
return {
|
|
@@ -28395,6 +28930,7 @@ You have been logged out. Please try again.`);
|
|
|
28395
28930
|
async streamThreadHistory(sessionId, thread) {
|
|
28396
28931
|
const session = new ACPSessionConnection(this.connection, sessionId);
|
|
28397
28932
|
const sessionState = this.getSessionState(sessionId);
|
|
28933
|
+
await this.publishThreadHistoryTitle(session, sessionState, thread);
|
|
28398
28934
|
const responseItemFallbackUpdates = await createResponseItemHistoryFallbackUpdates(
|
|
28399
28935
|
thread,
|
|
28400
28936
|
sessionState.terminalOutputMode
|
|
@@ -28411,14 +28947,56 @@ You have been logged out. Please try again.`);
|
|
|
28411
28947
|
await session.update(update);
|
|
28412
28948
|
}
|
|
28413
28949
|
}
|
|
28950
|
+
async publishThreadHistoryTitle(session, sessionState, thread) {
|
|
28951
|
+
const explicitTitle = this.normalizeSessionTitle(thread.name);
|
|
28952
|
+
if (explicitTitle) {
|
|
28953
|
+
sessionState.sessionTitle = explicitTitle;
|
|
28954
|
+
sessionState.sessionTitleSource = "explicit";
|
|
28955
|
+
await session.update({
|
|
28956
|
+
sessionUpdate: "session_info_update",
|
|
28957
|
+
title: explicitTitle
|
|
28958
|
+
});
|
|
28959
|
+
return;
|
|
28960
|
+
}
|
|
28961
|
+
const historyTitle = this.findFirstUserMessageTitle(thread) ?? this.normalizeSessionTitle(thread.preview);
|
|
28962
|
+
await this.publishFallbackSessionTitle(sessionState, historyTitle);
|
|
28963
|
+
}
|
|
28964
|
+
findFirstUserMessageTitle(thread) {
|
|
28965
|
+
for (const turn of thread.turns) {
|
|
28966
|
+
for (const item of turn.items) {
|
|
28967
|
+
if (item.type !== "userMessage") continue;
|
|
28968
|
+
const title = this.normalizeSessionTitle(item.content.filter((input) => input.type === "text").map((input) => input.text).join(" "));
|
|
28969
|
+
if (title) return title;
|
|
28970
|
+
}
|
|
28971
|
+
}
|
|
28972
|
+
return null;
|
|
28973
|
+
}
|
|
28974
|
+
async publishFallbackSessionTitle(sessionState, title) {
|
|
28975
|
+
if (sessionState.sessionTitleSource !== "unset" || !title) return;
|
|
28976
|
+
sessionState.sessionTitle = title;
|
|
28977
|
+
sessionState.sessionTitleSource = "fallback";
|
|
28978
|
+
const session = new ACPSessionConnection(this.connection, sessionState.sessionId);
|
|
28979
|
+
await session.update({
|
|
28980
|
+
sessionUpdate: "session_info_update",
|
|
28981
|
+
title
|
|
28982
|
+
});
|
|
28983
|
+
}
|
|
28984
|
+
createPromptFallbackTitle(prompt) {
|
|
28985
|
+
return this.normalizeSessionTitle(prompt.filter((block) => block.type === "text").map((block) => block.text).join(" "));
|
|
28986
|
+
}
|
|
28987
|
+
normalizeSessionTitle(title) {
|
|
28988
|
+
const normalized = title?.replace(/\s+/g, " ").trim() ?? "";
|
|
28989
|
+
return normalized.length > 0 ? normalized : null;
|
|
28990
|
+
}
|
|
28414
28991
|
async createHistoryUpdates(item, sessionState) {
|
|
28415
28992
|
switch (item.type) {
|
|
28416
28993
|
case "userMessage":
|
|
28417
28994
|
return this.createUserMessageUpdates(item);
|
|
28418
28995
|
case "hookPrompt":
|
|
28419
|
-
case "subAgentActivity":
|
|
28420
28996
|
case "sleep":
|
|
28421
28997
|
return [];
|
|
28998
|
+
case "subAgentActivity":
|
|
28999
|
+
return [createSubAgentActivityUpdate(item, "completed", "tool_call")];
|
|
28422
29000
|
case "agentMessage": {
|
|
28423
29001
|
const meta3 = createCodexMessagePhaseMeta(item.phase);
|
|
28424
29002
|
return [{
|
|
@@ -28457,7 +29035,7 @@ You have been logged out. Please try again.`);
|
|
|
28457
29035
|
case "exitedReviewMode":
|
|
28458
29036
|
return [this.createReviewModeUpdate(item, false)];
|
|
28459
29037
|
case "contextCompaction":
|
|
28460
|
-
return [
|
|
29038
|
+
return [createCompletedContextCompactionUpdate(item)];
|
|
28461
29039
|
case "plan":
|
|
28462
29040
|
return [this.createPlanUpdate(item)];
|
|
28463
29041
|
}
|
|
@@ -28500,15 +29078,6 @@ You have been logged out. Please try again.`);
|
|
|
28500
29078
|
}
|
|
28501
29079
|
};
|
|
28502
29080
|
}
|
|
28503
|
-
createContextCompactionUpdate() {
|
|
28504
|
-
return {
|
|
28505
|
-
sessionUpdate: "agent_message_chunk",
|
|
28506
|
-
content: {
|
|
28507
|
-
type: "text",
|
|
28508
|
-
text: "Context compacted."
|
|
28509
|
-
}
|
|
28510
|
-
};
|
|
28511
|
-
}
|
|
28512
29081
|
createPlanUpdate(item) {
|
|
28513
29082
|
return {
|
|
28514
29083
|
sessionUpdate: "agent_message_chunk",
|
|
@@ -28839,6 +29408,18 @@ ${item.text}`
|
|
|
28839
29408
|
}
|
|
28840
29409
|
sessionState.currentTurnId = turnId;
|
|
28841
29410
|
pendingTurnStart?.resolve(turnId);
|
|
29411
|
+
},
|
|
29412
|
+
setConfigOption: async (configId, value) => {
|
|
29413
|
+
await this.applySessionConfigOption(sessionState, {
|
|
29414
|
+
sessionId: sessionState.sessionId,
|
|
29415
|
+
configId,
|
|
29416
|
+
value
|
|
29417
|
+
});
|
|
29418
|
+
const session = new ACPSessionConnection(this.connection, sessionState.sessionId);
|
|
29419
|
+
await session.update({
|
|
29420
|
+
sessionUpdate: "config_option_update",
|
|
29421
|
+
configOptions: this.createSessionConfigOptions(sessionState)
|
|
29422
|
+
});
|
|
28842
29423
|
}
|
|
28843
29424
|
});
|
|
28844
29425
|
void commandPromise.catch((err) => {
|
|
@@ -28936,6 +29517,10 @@ ${item.text}`
|
|
|
28936
29517
|
if (error51) {
|
|
28937
29518
|
throw error51;
|
|
28938
29519
|
}
|
|
29520
|
+
await this.publishFallbackSessionTitle(
|
|
29521
|
+
sessionState,
|
|
29522
|
+
this.createPromptFallbackTitle(params.prompt)
|
|
29523
|
+
);
|
|
28939
29524
|
return {
|
|
28940
29525
|
stopReason: "end_turn",
|
|
28941
29526
|
usage: this.buildPromptUsage(sessionState.lastTokenUsage),
|
|
@@ -29090,6 +29675,7 @@ var CommandExecutionApprovalRequest = new import_node2.RequestType("item/command
|
|
|
29090
29675
|
var FileChangeApprovalRequest = new import_node2.RequestType("item/fileChange/requestApproval");
|
|
29091
29676
|
var PermissionsApprovalRequest = new import_node2.RequestType("item/permissions/requestApproval");
|
|
29092
29677
|
var McpServerElicitationRequest = new import_node2.RequestType("mcpServer/elicitation/request");
|
|
29678
|
+
var ToolRequestUserInputRequest = new import_node2.RequestType("item/tool/requestUserInput");
|
|
29093
29679
|
var GOAL_RUNTIME_EFFECTS_GRACE_MS = 1e3;
|
|
29094
29680
|
var CodexAppServerClient = class {
|
|
29095
29681
|
connection;
|
|
@@ -29105,6 +29691,7 @@ var CodexAppServerClient = class {
|
|
|
29105
29691
|
threadStatusCaptures = /* @__PURE__ */ new Map();
|
|
29106
29692
|
threadGoalUpdateCaptures = /* @__PURE__ */ new Map();
|
|
29107
29693
|
threadGoalClearedCaptures = /* @__PURE__ */ new Map();
|
|
29694
|
+
threadSettings = /* @__PURE__ */ new Map();
|
|
29108
29695
|
staleTurnIds = /* @__PURE__ */ new Map();
|
|
29109
29696
|
constructor(connection) {
|
|
29110
29697
|
this.connection = connection;
|
|
@@ -29134,6 +29721,9 @@ var CodexAppServerClient = class {
|
|
|
29134
29721
|
if (isThreadGoalClearedNotification(serverNotification)) {
|
|
29135
29722
|
this.recordThreadGoalCleared(serverNotification.params);
|
|
29136
29723
|
}
|
|
29724
|
+
if (serverNotification.method === "thread/settings/updated") {
|
|
29725
|
+
this.threadSettings.set(serverNotification.params.threadId, serverNotification.params.threadSettings);
|
|
29726
|
+
}
|
|
29137
29727
|
const routing = extractTurnRouting(serverNotification);
|
|
29138
29728
|
if (this.handleStaleTurnNotification(serverNotification, routing)) {
|
|
29139
29729
|
return;
|
|
@@ -29187,6 +29777,16 @@ var CodexAppServerClient = class {
|
|
|
29187
29777
|
}
|
|
29188
29778
|
return await handler.handleElicitation(params);
|
|
29189
29779
|
});
|
|
29780
|
+
this.connection.onRequest(ToolRequestUserInputRequest, async (params) => {
|
|
29781
|
+
if (this.isStaleTurn(params.threadId, params.turnId)) {
|
|
29782
|
+
return { answers: {} };
|
|
29783
|
+
}
|
|
29784
|
+
const handler = this.elicitationHandlers.get(params.threadId);
|
|
29785
|
+
if (!handler) {
|
|
29786
|
+
return { answers: {} };
|
|
29787
|
+
}
|
|
29788
|
+
return await handler.handleUserInput(params);
|
|
29789
|
+
});
|
|
29190
29790
|
}
|
|
29191
29791
|
onApprovalRequest(threadId, handler) {
|
|
29192
29792
|
this.approvalHandlers.set(threadId, handler);
|
|
@@ -29241,7 +29841,7 @@ var CodexAppServerClient = class {
|
|
|
29241
29841
|
releaseCapture();
|
|
29242
29842
|
}
|
|
29243
29843
|
}
|
|
29244
|
-
async runGoalSet(params, onTurnStarted, runtimeEffectsGraceMs = GOAL_RUNTIME_EFFECTS_GRACE_MS) {
|
|
29844
|
+
async runGoalSet(params, onTurnStarted, runtimeEffectsGraceMs = GOAL_RUNTIME_EFFECTS_GRACE_MS, onGoalSet) {
|
|
29245
29845
|
let goalTurnId = null;
|
|
29246
29846
|
const capturedCompletions = [];
|
|
29247
29847
|
let resolveGoalTurnCompleted = () => {
|
|
@@ -29294,6 +29894,7 @@ var CodexAppServerClient = class {
|
|
|
29294
29894
|
try {
|
|
29295
29895
|
const goalSetResponse = await this.threadGoalSet(params);
|
|
29296
29896
|
expectedGoal = goalSetResponse.goal;
|
|
29897
|
+
onGoalSet?.(expectedGoal);
|
|
29297
29898
|
if (capturedGoalUpdates.some((event) => goalsMatch(event.goal, expectedGoal))) {
|
|
29298
29899
|
goalUpdateHandled = true;
|
|
29299
29900
|
resolveGoalUpdateHandled();
|
|
@@ -29431,6 +30032,12 @@ var CodexAppServerClient = class {
|
|
|
29431
30032
|
async threadResume(params) {
|
|
29432
30033
|
return await this.sendRequest({ method: "thread/resume", params });
|
|
29433
30034
|
}
|
|
30035
|
+
getThreadSettings(threadId) {
|
|
30036
|
+
return this.threadSettings.get(threadId);
|
|
30037
|
+
}
|
|
30038
|
+
async threadSettingsUpdate(params) {
|
|
30039
|
+
await this.connection.sendRequest("thread/settings/update", params);
|
|
30040
|
+
}
|
|
29434
30041
|
async threadList(params) {
|
|
29435
30042
|
return await this.sendRequest({ method: "thread/list", params });
|
|
29436
30043
|
}
|
|
@@ -29452,6 +30059,9 @@ var CodexAppServerClient = class {
|
|
|
29452
30059
|
async threadGoalSet(params) {
|
|
29453
30060
|
return await this.sendRequest({ method: "thread/goal/set", params });
|
|
29454
30061
|
}
|
|
30062
|
+
async threadGoalGet(params) {
|
|
30063
|
+
return await this.sendRequest({ method: "thread/goal/get", params });
|
|
30064
|
+
}
|
|
29455
30065
|
async threadGoalClear(params) {
|
|
29456
30066
|
return await this.sendRequest({ method: "thread/goal/clear", params });
|
|
29457
30067
|
}
|
|
@@ -29981,6 +30591,10 @@ var legacySetSessionModelParamsParser = external_exports.object({
|
|
|
29981
30591
|
sessionId: external_exports.string(),
|
|
29982
30592
|
modelId: external_exports.string()
|
|
29983
30593
|
}).passthrough();
|
|
30594
|
+
var goalControlParamsParser = external_exports.object({
|
|
30595
|
+
sessionId: external_exports.string(),
|
|
30596
|
+
action: external_exports.enum(["pause", "clear"])
|
|
30597
|
+
}).passthrough();
|
|
29984
30598
|
if (process.argv.includes("--version")) {
|
|
29985
30599
|
console.log(`${package_default.name} ${package_default.version}`);
|
|
29986
30600
|
process.exit(0);
|
|
@@ -30053,5 +30667,5 @@ function startAcpServer() {
|
|
|
30053
30667
|
codexAcpServer = null;
|
|
30054
30668
|
}
|
|
30055
30669
|
});
|
|
30056
|
-
}).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.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)).connect(acpJsonStream);
|
|
30670
|
+
}).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(GOAL_CONTROL_METHOD, goalControlParamsParser, (ctx) => getAgent().extMethod(GOAL_CONTROL_METHOD, ctx.params)).connect(acpJsonStream);
|
|
30057
30671
|
}
|
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.4",
|
|
7
7
|
"description": "",
|
|
8
8
|
"main": "dist/index.js",
|
|
9
9
|
"bin": {
|
|
@@ -62,7 +62,7 @@
|
|
|
62
62
|
},
|
|
63
63
|
"dependencies": {
|
|
64
64
|
"@agentclientprotocol/sdk": "^1.2.1",
|
|
65
|
-
"@openai/codex": "^0.
|
|
65
|
+
"@openai/codex": "^0.144.4",
|
|
66
66
|
"diff": "^9.0.0",
|
|
67
67
|
"open": "^11.0.0",
|
|
68
68
|
"vscode-jsonrpc": "^9.0.1",
|