lody 0.69.0 → 0.70.1
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/chunks/{directory-handle-B28RRBM4.js → directory-handle-Ydn6ZTye.js} +1 -1
- package/dist/chunks/{index-DjSKImM-.js → index-BKfeSFHN.js} +694 -105
- package/dist/chunks/package-DqzNopZM.js +11 -0
- package/dist/chunks/{review-viewer-cjVseAUz.js → review-viewer-BHFYVB1-.js} +2 -2
- package/dist/chunks/{schemas-BunMNnz1.js → schemas-Dq_X20sw.js} +35 -24
- package/dist/claude-acp.js +54251 -51421
- package/dist/codex-acp.js +1 -1
- package/dist/file-index-scan-worker.js +2 -2
- package/dist/index.js +5128 -1763
- package/package.json +8 -8
|
@@ -2,6 +2,7 @@ import { createRequire } from "module";
|
|
|
2
2
|
import require$$1, { execFile as execFile$1, spawn } from "node:child_process";
|
|
3
3
|
import { createRequire as createRequire$1 } from "node:module";
|
|
4
4
|
import { Writable, Readable } from "node:stream";
|
|
5
|
+
import { StringDecoder } from "node:string_decoder";
|
|
5
6
|
import fs__default from "node:fs";
|
|
6
7
|
import path__default from "node:path";
|
|
7
8
|
import fs__default$1, { readFile, constants } from "node:fs/promises";
|
|
@@ -20651,8 +20652,9 @@ function createJSONRPCReader(readable) {
|
|
|
20651
20652
|
return {
|
|
20652
20653
|
listen(callback) {
|
|
20653
20654
|
let buf = "";
|
|
20655
|
+
const decoder = new StringDecoder("utf8");
|
|
20654
20656
|
const onData = (chunk) => {
|
|
20655
|
-
buf +=
|
|
20657
|
+
buf += decoder.write(chunk);
|
|
20656
20658
|
for (; ; ) {
|
|
20657
20659
|
const i = buf.indexOf("\n");
|
|
20658
20660
|
if (i < 0) break;
|
|
@@ -20801,6 +20803,22 @@ var LEGACY_SET_SESSION_MODEL_METHOD = "session/set_model";
|
|
|
20801
20803
|
var ACP_EXT_SESSION_USAGE_UPDATE_METHOD = "_acp_ext:session_usage_update";
|
|
20802
20804
|
var ACP_EXT_SESSION_RATE_LIMITS_METHOD = "_acp_ext:session_rate_limits";
|
|
20803
20805
|
var ACP_EXT_CODEX_PROPOSED_PLAN_METHOD = "_acp_ext:codex_proposed_plan";
|
|
20806
|
+
var CODEX_STEER_APPLIED_METHOD = "_codex/steerApplied";
|
|
20807
|
+
var CODEX_STEER_CAPABILITY = {
|
|
20808
|
+
version: 1,
|
|
20809
|
+
appliedNotification: CODEX_STEER_APPLIED_METHOD,
|
|
20810
|
+
upstreamTurn: "same",
|
|
20811
|
+
configPolicy: "active"
|
|
20812
|
+
};
|
|
20813
|
+
function getCodexSteerId(meta3) {
|
|
20814
|
+
if (typeof meta3 !== "object" || meta3 === null) return null;
|
|
20815
|
+
const codex = meta3["codex"];
|
|
20816
|
+
if (typeof codex !== "object" || codex === null) return null;
|
|
20817
|
+
const steer = codex["steer"];
|
|
20818
|
+
if (typeof steer !== "object" || steer === null) return null;
|
|
20819
|
+
const id = steer["id"];
|
|
20820
|
+
return typeof id === "string" && id.length > 0 ? id : null;
|
|
20821
|
+
}
|
|
20804
20822
|
function isExtMethodRequest(request) {
|
|
20805
20823
|
return request.method === "authentication/status" || request.method === "authentication/logout" || request.method === LEGACY_SET_SESSION_MODEL_METHOD;
|
|
20806
20824
|
}
|
|
@@ -21442,6 +21460,7 @@ function createTerminalOutputMeta(mode, terminalId, data) {
|
|
|
21442
21460
|
};
|
|
21443
21461
|
}
|
|
21444
21462
|
}
|
|
21463
|
+
var CONTEXT_COMPACTION_META = { contextCompaction: true };
|
|
21445
21464
|
function toAcpStatus(status) {
|
|
21446
21465
|
switch (status) {
|
|
21447
21466
|
case "inProgress":
|
|
@@ -21584,6 +21603,35 @@ function createImageGenerationUpdate(item, options) {
|
|
|
21584
21603
|
rawOutput: imageGenerationRawOutput(item)
|
|
21585
21604
|
};
|
|
21586
21605
|
}
|
|
21606
|
+
function createContextCompactionStartUpdate(item) {
|
|
21607
|
+
return {
|
|
21608
|
+
sessionUpdate: "tool_call",
|
|
21609
|
+
toolCallId: item.id,
|
|
21610
|
+
kind: "other",
|
|
21611
|
+
title: "Context compacting",
|
|
21612
|
+
status: "in_progress",
|
|
21613
|
+
_meta: CONTEXT_COMPACTION_META
|
|
21614
|
+
};
|
|
21615
|
+
}
|
|
21616
|
+
function createContextCompactionCompleteUpdate(item) {
|
|
21617
|
+
return {
|
|
21618
|
+
sessionUpdate: "tool_call_update",
|
|
21619
|
+
toolCallId: item.id,
|
|
21620
|
+
title: "Context compacted",
|
|
21621
|
+
status: "completed",
|
|
21622
|
+
_meta: CONTEXT_COMPACTION_META
|
|
21623
|
+
};
|
|
21624
|
+
}
|
|
21625
|
+
function createCompletedContextCompactionUpdate(item) {
|
|
21626
|
+
return {
|
|
21627
|
+
sessionUpdate: "tool_call",
|
|
21628
|
+
toolCallId: item.id,
|
|
21629
|
+
kind: "other",
|
|
21630
|
+
title: "Context compacted",
|
|
21631
|
+
status: "completed",
|
|
21632
|
+
_meta: CONTEXT_COMPACTION_META
|
|
21633
|
+
};
|
|
21634
|
+
}
|
|
21587
21635
|
async function createExecuteToolCallUpdate(item, title, rawInput, rawOutput) {
|
|
21588
21636
|
return {
|
|
21589
21637
|
sessionUpdate: "tool_call",
|
|
@@ -22063,6 +22111,69 @@ async function readFileContent(filePath) {
|
|
|
22063
22111
|
function recoverCorruptedDiff(diff) {
|
|
22064
22112
|
return diff.replace(/\n\nMoved to: .*$/, "");
|
|
22065
22113
|
}
|
|
22114
|
+
var COMPLETE_EMPTY_COMMENT = /^<!--\s*(?:\*\/\s*)?-->\s*$/u;
|
|
22115
|
+
var PARTIAL_COMMENT_BODY = /^\s*(?:\*\/?\s*)?$/u;
|
|
22116
|
+
var PARTIAL_COMMENT_CLOSE = /^\s*(?:\*\/\s*)?-{1,2}$/u;
|
|
22117
|
+
var isHorizontalWhitespace = (char) => char === " " || char === " ";
|
|
22118
|
+
var canBecomeEmptyComment = (text) => {
|
|
22119
|
+
if (text === "<" || text === "<!" || text === "<!-") {
|
|
22120
|
+
return true;
|
|
22121
|
+
}
|
|
22122
|
+
if (!text.startsWith("<!--")) {
|
|
22123
|
+
return false;
|
|
22124
|
+
}
|
|
22125
|
+
const tail = text.slice(4);
|
|
22126
|
+
return COMPLETE_EMPTY_COMMENT.test(text) || PARTIAL_COMMENT_BODY.test(tail) || PARTIAL_COMMENT_CLOSE.test(tail);
|
|
22127
|
+
};
|
|
22128
|
+
var ReasoningSummaryFilter = class {
|
|
22129
|
+
pending = "";
|
|
22130
|
+
lineHasContent = false;
|
|
22131
|
+
push(delta) {
|
|
22132
|
+
let output = "";
|
|
22133
|
+
const emit = (text) => {
|
|
22134
|
+
output += text;
|
|
22135
|
+
for (const char of text) {
|
|
22136
|
+
if (char === "\n" || char === "\r") {
|
|
22137
|
+
this.lineHasContent = false;
|
|
22138
|
+
} else if (!isHorizontalWhitespace(char)) {
|
|
22139
|
+
this.lineHasContent = true;
|
|
22140
|
+
}
|
|
22141
|
+
}
|
|
22142
|
+
};
|
|
22143
|
+
for (const char of delta) {
|
|
22144
|
+
if (this.pending) {
|
|
22145
|
+
this.pending += char;
|
|
22146
|
+
if (canBecomeEmptyComment(this.pending)) {
|
|
22147
|
+
continue;
|
|
22148
|
+
}
|
|
22149
|
+
emit(this.pending);
|
|
22150
|
+
this.pending = "";
|
|
22151
|
+
continue;
|
|
22152
|
+
}
|
|
22153
|
+
if (char === "<" && !this.lineHasContent) {
|
|
22154
|
+
this.pending = char;
|
|
22155
|
+
} else {
|
|
22156
|
+
emit(char);
|
|
22157
|
+
}
|
|
22158
|
+
}
|
|
22159
|
+
return output;
|
|
22160
|
+
}
|
|
22161
|
+
finish() {
|
|
22162
|
+
const output = COMPLETE_EMPTY_COMMENT.test(this.pending) ? "" : this.pending;
|
|
22163
|
+
this.pending = "";
|
|
22164
|
+
this.lineHasContent = false;
|
|
22165
|
+
return output;
|
|
22166
|
+
}
|
|
22167
|
+
};
|
|
22168
|
+
function stripEmptyReasoningComments(text) {
|
|
22169
|
+
const filter = new ReasoningSummaryFilter();
|
|
22170
|
+
return filter.push(text) + filter.finish();
|
|
22171
|
+
}
|
|
22172
|
+
function sanitizeReasoningParts(summary, content) {
|
|
22173
|
+
const useSummary = summary.length > 0;
|
|
22174
|
+
const parts = useSummary ? summary : content;
|
|
22175
|
+
return parts.map((part) => useSummary ? stripEmptyReasoningComments(part) : part).filter((part) => part.length > 0);
|
|
22176
|
+
}
|
|
22066
22177
|
function createCodexMessagePhaseMeta(phase) {
|
|
22067
22178
|
if (!phase) {
|
|
22068
22179
|
return void 0;
|
|
@@ -22129,6 +22240,7 @@ var CodexEventHandler = class {
|
|
|
22129
22240
|
activeImageGenerationItems = /* @__PURE__ */ new Set();
|
|
22130
22241
|
emittedImageViewItems = /* @__PURE__ */ new Set();
|
|
22131
22242
|
seenReasoningDeltaItemIds = /* @__PURE__ */ new Set();
|
|
22243
|
+
reasoningSummaryFilters = /* @__PURE__ */ new Map();
|
|
22132
22244
|
terminalCommandIds = /* @__PURE__ */ new Set();
|
|
22133
22245
|
terminalCommandOutputIds = /* @__PURE__ */ new Set();
|
|
22134
22246
|
proposedPlanMarkdown = "";
|
|
@@ -22142,6 +22254,10 @@ var CodexEventHandler = class {
|
|
|
22142
22254
|
return this.failure;
|
|
22143
22255
|
}
|
|
22144
22256
|
async handleNotification(notification) {
|
|
22257
|
+
if (notification.method === "account/rateLimits/updated") {
|
|
22258
|
+
await this.handleRateLimitsSnapshot(notification.params.rateLimits, true);
|
|
22259
|
+
return;
|
|
22260
|
+
}
|
|
22145
22261
|
const session = new ACPSessionConnection(this.connection, this.sessionState.sessionId);
|
|
22146
22262
|
const updateEvent = await this.createUpdateEvent(notification);
|
|
22147
22263
|
if (updateEvent) {
|
|
@@ -22170,6 +22286,8 @@ var CodexEventHandler = class {
|
|
|
22170
22286
|
case "thread/tokenUsage/updated":
|
|
22171
22287
|
return this.createUsageUpdate(notification.params);
|
|
22172
22288
|
case "thread/name/updated":
|
|
22289
|
+
this.sessionState.sessionTitle = notification.params.threadName ?? null;
|
|
22290
|
+
this.sessionState.sessionTitleSource = notification.params.threadName == null ? "unset" : "explicit";
|
|
22173
22291
|
return {
|
|
22174
22292
|
sessionUpdate: "session_info_update",
|
|
22175
22293
|
title: notification.params.threadName ?? null
|
|
@@ -22195,7 +22313,6 @@ var CodexEventHandler = class {
|
|
|
22195
22313
|
case "item/mcpToolCall/progress":
|
|
22196
22314
|
return this.createMcpToolProgressEvent(notification.params);
|
|
22197
22315
|
case "account/rateLimits/updated":
|
|
22198
|
-
this.handleRateLimitsUpdated(notification.params);
|
|
22199
22316
|
return null;
|
|
22200
22317
|
case "configWarning":
|
|
22201
22318
|
return await this.createConfigWarningEvent(notification.params);
|
|
@@ -22210,9 +22327,9 @@ var CodexEventHandler = class {
|
|
|
22210
22327
|
case "thread/compacted":
|
|
22211
22328
|
return this.createContextCompactedEvent();
|
|
22212
22329
|
case "item/reasoning/summaryTextDelta":
|
|
22213
|
-
return this.
|
|
22330
|
+
return this.createReasoningSummaryDeltaEvent(notification.params);
|
|
22214
22331
|
case "item/reasoning/textDelta":
|
|
22215
|
-
return this.
|
|
22332
|
+
return this.createRawReasoningDeltaEvent(notification.params);
|
|
22216
22333
|
case "item/reasoning/summaryPartAdded":
|
|
22217
22334
|
return this.createReasoningSectionBreakEvent(notification.params);
|
|
22218
22335
|
case "model/rerouted":
|
|
@@ -22277,12 +22394,6 @@ var CodexEventHandler = class {
|
|
|
22277
22394
|
this.createSessionUsageExtNotification(notification.params)
|
|
22278
22395
|
);
|
|
22279
22396
|
return;
|
|
22280
|
-
case "account/rateLimits/updated":
|
|
22281
|
-
await this.notifyExt(
|
|
22282
|
-
ACP_EXT_SESSION_RATE_LIMITS_METHOD,
|
|
22283
|
-
this.createSessionRateLimitsExtNotification(notification.params)
|
|
22284
|
-
);
|
|
22285
|
-
return;
|
|
22286
22397
|
case "item/plan/delta":
|
|
22287
22398
|
await this.emitCodexProposedPlanDelta(notification.params);
|
|
22288
22399
|
return;
|
|
@@ -22344,16 +22455,26 @@ var CodexEventHandler = class {
|
|
|
22344
22455
|
isLatest: true
|
|
22345
22456
|
};
|
|
22346
22457
|
}
|
|
22347
|
-
createSessionRateLimitsExtNotification(
|
|
22348
|
-
const
|
|
22458
|
+
createSessionRateLimitsExtNotification(rateLimits) {
|
|
22459
|
+
const windows = [rateLimits.primary, rateLimits.secondary].filter(
|
|
22460
|
+
(window) => window !== null
|
|
22461
|
+
);
|
|
22462
|
+
const fiveHour = windows.find((window) => window.windowDurationMins === 5 * 60) ?? null;
|
|
22463
|
+
const sevenDay = windows.find((window) => window.windowDurationMins === 7 * 24 * 60) ?? null;
|
|
22349
22464
|
return {
|
|
22465
|
+
schemaVersion: 2,
|
|
22350
22466
|
planName: rateLimits.planType,
|
|
22351
22467
|
limitName: rateLimits.limitName,
|
|
22352
22468
|
limitId: rateLimits.limitId,
|
|
22353
|
-
|
|
22354
|
-
|
|
22355
|
-
|
|
22356
|
-
|
|
22469
|
+
windows: windows.map((window) => ({
|
|
22470
|
+
usedPercent: window.usedPercent,
|
|
22471
|
+
windowDurationMins: window.windowDurationMins,
|
|
22472
|
+
resetsAt: window.resetsAt
|
|
22473
|
+
})),
|
|
22474
|
+
fiveHour: fiveHour?.usedPercent ?? null,
|
|
22475
|
+
sevenDay: sevenDay?.usedPercent ?? null,
|
|
22476
|
+
fiveHourResetAt: fiveHour?.resetsAt ?? null,
|
|
22477
|
+
sevenDayResetAt: sevenDay?.resetsAt ?? null
|
|
22357
22478
|
};
|
|
22358
22479
|
}
|
|
22359
22480
|
createCodexSessionInfoUpdate(codexMetadata) {
|
|
@@ -22415,13 +22536,34 @@ ${event.details}` : "";
|
|
|
22415
22536
|
sameThreadGoalSnapshot(left, right) {
|
|
22416
22537
|
return left !== null && left !== void 0 && left.objective === right.objective && left.status === right.status && left.tokenBudget === right.tokenBudget;
|
|
22417
22538
|
}
|
|
22418
|
-
|
|
22539
|
+
createReasoningSummaryDeltaEvent(event) {
|
|
22540
|
+
this.seenReasoningDeltaItemIds.add(event.itemId);
|
|
22541
|
+
let filter = this.reasoningSummaryFilters.get(event.itemId);
|
|
22542
|
+
if (!filter) {
|
|
22543
|
+
filter = new ReasoningSummaryFilter();
|
|
22544
|
+
this.reasoningSummaryFilters.set(event.itemId, filter);
|
|
22545
|
+
}
|
|
22546
|
+
const text = filter.push(event.delta);
|
|
22547
|
+
return text.length > 0 ? this.createAgentThoughtEvent(text, event.itemId) : null;
|
|
22548
|
+
}
|
|
22549
|
+
createRawReasoningDeltaEvent(event) {
|
|
22419
22550
|
this.seenReasoningDeltaItemIds.add(event.itemId);
|
|
22420
22551
|
return this.createAgentThoughtEvent(event.delta, event.itemId);
|
|
22421
22552
|
}
|
|
22422
22553
|
createReasoningSectionBreakEvent(event) {
|
|
22423
22554
|
this.seenReasoningDeltaItemIds.add(event.itemId);
|
|
22424
|
-
|
|
22555
|
+
const trailingText = this.finishReasoningSummaryFilter(event.itemId);
|
|
22556
|
+
return this.createAgentThoughtEvent(`${trailingText}
|
|
22557
|
+
|
|
22558
|
+
`, event.itemId);
|
|
22559
|
+
}
|
|
22560
|
+
finishReasoningSummaryFilter(itemId) {
|
|
22561
|
+
const filter = this.reasoningSummaryFilters.get(itemId);
|
|
22562
|
+
if (!filter) {
|
|
22563
|
+
return "";
|
|
22564
|
+
}
|
|
22565
|
+
this.reasoningSummaryFilters.delete(itemId);
|
|
22566
|
+
return filter.finish();
|
|
22425
22567
|
}
|
|
22426
22568
|
createAgentThoughtEvent(text, messageId) {
|
|
22427
22569
|
return createAgentTextThoughtChunk(text, messageId);
|
|
@@ -22456,6 +22598,8 @@ ${event.details}` : "";
|
|
|
22456
22598
|
case "agentMessage":
|
|
22457
22599
|
this.rememberAgentMessagePhase(event.item);
|
|
22458
22600
|
return null;
|
|
22601
|
+
case "contextCompaction":
|
|
22602
|
+
return createContextCompactionStartUpdate(event.item);
|
|
22459
22603
|
case "subAgentActivity":
|
|
22460
22604
|
case "sleep":
|
|
22461
22605
|
case "userMessage":
|
|
@@ -22463,7 +22607,6 @@ ${event.details}` : "";
|
|
|
22463
22607
|
case "reasoning":
|
|
22464
22608
|
case "enteredReviewMode":
|
|
22465
22609
|
case "exitedReviewMode":
|
|
22466
|
-
case "contextCompaction":
|
|
22467
22610
|
case "plan":
|
|
22468
22611
|
return null;
|
|
22469
22612
|
}
|
|
@@ -22499,7 +22642,8 @@ ${event.details}` : "";
|
|
|
22499
22642
|
return createImageGenerationUpdate(event.item, { terminalStatus: true });
|
|
22500
22643
|
case "reasoning":
|
|
22501
22644
|
if (this.seenReasoningDeltaItemIds.delete(event.item.id)) {
|
|
22502
|
-
|
|
22645
|
+
const trailingText = this.finishReasoningSummaryFilter(event.item.id);
|
|
22646
|
+
return trailingText.length > 0 ? this.createAgentThoughtEvent(trailingText, event.item.id) : null;
|
|
22503
22647
|
}
|
|
22504
22648
|
return this.createCompletedReasoningEvent(event.item);
|
|
22505
22649
|
case "webSearch":
|
|
@@ -22512,7 +22656,7 @@ ${event.details}` : "";
|
|
|
22512
22656
|
case "exitedReviewMode":
|
|
22513
22657
|
return this.createExitedReviewModeEvent(event.item);
|
|
22514
22658
|
case "contextCompaction":
|
|
22515
|
-
return
|
|
22659
|
+
return createContextCompactionCompleteUpdate(event.item);
|
|
22516
22660
|
//ignored types
|
|
22517
22661
|
case "subAgentActivity":
|
|
22518
22662
|
case "sleep":
|
|
@@ -22527,8 +22671,7 @@ ${event.details}` : "";
|
|
|
22527
22671
|
this.agentMessagePhases.set(item.id, item.phase);
|
|
22528
22672
|
}
|
|
22529
22673
|
createCompletedReasoningEvent(item) {
|
|
22530
|
-
const
|
|
22531
|
-
const text = parts.filter((part) => part.length > 0).join("\n\n");
|
|
22674
|
+
const text = sanitizeReasoningParts(item.summary, item.content).join("\n\n");
|
|
22532
22675
|
if (text.length === 0) {
|
|
22533
22676
|
return null;
|
|
22534
22677
|
}
|
|
@@ -22662,7 +22805,15 @@ ${event.stdin}
|
|
|
22662
22805
|
}
|
|
22663
22806
|
async createErrorEvent(params) {
|
|
22664
22807
|
const error48 = params.error.codexErrorInfo;
|
|
22665
|
-
if (
|
|
22808
|
+
if (params.willRetry) {
|
|
22809
|
+
return this.createCodexSessionInfoUpdate({
|
|
22810
|
+
error: {
|
|
22811
|
+
...params.error,
|
|
22812
|
+
turnId: params.turnId,
|
|
22813
|
+
willRetry: true
|
|
22814
|
+
}
|
|
22815
|
+
});
|
|
22816
|
+
} else if (error48 === "usageLimitExceeded") {
|
|
22666
22817
|
this.failure = RequestError.internalError(
|
|
22667
22818
|
this.createTurnErrorData(params.error)
|
|
22668
22819
|
);
|
|
@@ -22720,16 +22871,36 @@ ${event.stdin}
|
|
|
22720
22871
|
size
|
|
22721
22872
|
};
|
|
22722
22873
|
}
|
|
22723
|
-
|
|
22874
|
+
async handleRateLimitsSnapshot(rateLimits, sparse = false) {
|
|
22875
|
+
const merged = this.storeRateLimitsSnapshot(rateLimits, sparse);
|
|
22876
|
+
await this.notifyExt(
|
|
22877
|
+
ACP_EXT_SESSION_RATE_LIMITS_METHOD,
|
|
22878
|
+
this.createSessionRateLimitsExtNotification(merged)
|
|
22879
|
+
);
|
|
22880
|
+
}
|
|
22881
|
+
storeRateLimitsSnapshot(rateLimits, sparse) {
|
|
22724
22882
|
if (!this.sessionState.rateLimits) {
|
|
22725
22883
|
this.sessionState.rateLimits = /* @__PURE__ */ new Map();
|
|
22726
22884
|
}
|
|
22727
|
-
const
|
|
22885
|
+
const fallbackLimitId = this.sessionState.rateLimits.size === 1 ? this.sessionState.rateLimits.keys().next().value : null;
|
|
22886
|
+
const limitId = rateLimits.limitId ?? rateLimits.limitName ?? fallbackLimitId ?? "unknown";
|
|
22887
|
+
const existing = this.sessionState.rateLimits.get(limitId)?.snapshot;
|
|
22888
|
+
const snapshot = sparse && existing ? {
|
|
22889
|
+
limitId: rateLimits.limitId ?? existing.limitId,
|
|
22890
|
+
limitName: rateLimits.limitName ?? existing.limitName,
|
|
22891
|
+
primary: rateLimits.primary ?? existing.primary,
|
|
22892
|
+
secondary: rateLimits.secondary ?? existing.secondary,
|
|
22893
|
+
credits: rateLimits.credits ?? existing.credits,
|
|
22894
|
+
individualLimit: rateLimits.individualLimit ?? existing.individualLimit,
|
|
22895
|
+
planType: rateLimits.planType ?? existing.planType,
|
|
22896
|
+
rateLimitReachedType: rateLimits.rateLimitReachedType ?? existing.rateLimitReachedType
|
|
22897
|
+
} : rateLimits;
|
|
22728
22898
|
this.sessionState.rateLimits.set(limitId, {
|
|
22729
22899
|
limitId,
|
|
22730
|
-
limitName:
|
|
22731
|
-
snapshot
|
|
22900
|
+
limitName: snapshot.limitName ?? limitId,
|
|
22901
|
+
snapshot
|
|
22732
22902
|
});
|
|
22903
|
+
return snapshot;
|
|
22733
22904
|
}
|
|
22734
22905
|
handleFuzzyFileSearchSessionUpdated(params) {
|
|
22735
22906
|
const toolCallId = fuzzyFileSearchToolCallId(params.sessionId);
|
|
@@ -23084,6 +23255,7 @@ var ELICITATION_OPTIONS = [
|
|
|
23084
23255
|
{ optionId: "accept", name: "Accept", kind: "allow_once" },
|
|
23085
23256
|
{ optionId: "decline", name: "Decline", kind: "reject_once" }
|
|
23086
23257
|
];
|
|
23258
|
+
var USER_INPUT_OTHER_FIELD_SUFFIX = "__other";
|
|
23087
23259
|
function parsePersistOptions(meta3) {
|
|
23088
23260
|
const result = /* @__PURE__ */ new Set();
|
|
23089
23261
|
if (!meta3 || typeof meta3 !== "object") return result;
|
|
@@ -23219,6 +23391,27 @@ function elicitationResponseMeta(response, context, persist = void 0) {
|
|
|
23219
23391
|
}
|
|
23220
23392
|
return Object.keys(meta3).length === 0 ? null : meta3;
|
|
23221
23393
|
}
|
|
23394
|
+
function userInputOtherFieldId(questionId, questionIds) {
|
|
23395
|
+
const base = `${questionId}${USER_INPUT_OTHER_FIELD_SUFFIX}`;
|
|
23396
|
+
if (!questionIds.has(base)) {
|
|
23397
|
+
return base;
|
|
23398
|
+
}
|
|
23399
|
+
let index = 1;
|
|
23400
|
+
while (questionIds.has(`${base}${index}`)) {
|
|
23401
|
+
index += 1;
|
|
23402
|
+
}
|
|
23403
|
+
return `${base}${index}`;
|
|
23404
|
+
}
|
|
23405
|
+
function userInputResponseValue(content, fieldId) {
|
|
23406
|
+
const value = content[fieldId];
|
|
23407
|
+
if (typeof value === "string" && value.trim() === "") {
|
|
23408
|
+
return void 0;
|
|
23409
|
+
}
|
|
23410
|
+
if (Array.isArray(value) && value.length === 0) {
|
|
23411
|
+
return void 0;
|
|
23412
|
+
}
|
|
23413
|
+
return value;
|
|
23414
|
+
}
|
|
23222
23415
|
function buildToolApprovalOptions(persistOptions) {
|
|
23223
23416
|
const options = [
|
|
23224
23417
|
{ optionId: McpApprovalOptionId.AllowOnce, name: "Allow", kind: "allow_once" }
|
|
@@ -23315,8 +23508,68 @@ var CodexElicitationHandler = class {
|
|
|
23315
23508
|
return { action: "cancel", content: null, _meta: null };
|
|
23316
23509
|
}
|
|
23317
23510
|
}
|
|
23318
|
-
|
|
23319
|
-
|
|
23511
|
+
async handleUserInput(params) {
|
|
23512
|
+
if (!clientSupportsFormElicitation(this.clientCapabilities)) {
|
|
23513
|
+
return { answers: {} };
|
|
23514
|
+
}
|
|
23515
|
+
try {
|
|
23516
|
+
const response = await this.requestUserInputElicitation(params);
|
|
23517
|
+
if (response === null) {
|
|
23518
|
+
return { answers: {} };
|
|
23519
|
+
}
|
|
23520
|
+
return this.convertUserInputResponse(response, params);
|
|
23521
|
+
} catch (error48) {
|
|
23522
|
+
logger.error("Error handling Codex user input request", error48);
|
|
23523
|
+
return { answers: {} };
|
|
23524
|
+
}
|
|
23525
|
+
}
|
|
23526
|
+
requestOptions(cancellationSignal = this.cancellationSignal) {
|
|
23527
|
+
return cancellationSignal ? { cancellationSignal } : void 0;
|
|
23528
|
+
}
|
|
23529
|
+
async requestUserInputElicitation(params) {
|
|
23530
|
+
const request = this.buildUserInputRequest(params);
|
|
23531
|
+
if (params.autoResolutionMs === null) {
|
|
23532
|
+
return await this.connection.request(
|
|
23533
|
+
methods.client.elicitation.create,
|
|
23534
|
+
request,
|
|
23535
|
+
this.requestOptions()
|
|
23536
|
+
);
|
|
23537
|
+
}
|
|
23538
|
+
const abortController = new AbortController();
|
|
23539
|
+
let timeout;
|
|
23540
|
+
let removeAbortListener;
|
|
23541
|
+
const timeoutPromise = new Promise((resolve) => {
|
|
23542
|
+
const resolveWithoutInput = () => {
|
|
23543
|
+
abortController.abort();
|
|
23544
|
+
resolve(null);
|
|
23545
|
+
};
|
|
23546
|
+
timeout = setTimeout(resolveWithoutInput, Math.max(0, params.autoResolutionMs ?? 0));
|
|
23547
|
+
if (this.cancellationSignal?.aborted) {
|
|
23548
|
+
resolveWithoutInput();
|
|
23549
|
+
return;
|
|
23550
|
+
}
|
|
23551
|
+
if (this.cancellationSignal) {
|
|
23552
|
+
this.cancellationSignal.addEventListener("abort", resolveWithoutInput, { once: true });
|
|
23553
|
+
removeAbortListener = () => {
|
|
23554
|
+
this.cancellationSignal?.removeEventListener("abort", resolveWithoutInput);
|
|
23555
|
+
};
|
|
23556
|
+
}
|
|
23557
|
+
});
|
|
23558
|
+
const requestPromise = Promise.resolve(this.connection.request(
|
|
23559
|
+
methods.client.elicitation.create,
|
|
23560
|
+
request,
|
|
23561
|
+
this.requestOptions(abortController.signal)
|
|
23562
|
+
));
|
|
23563
|
+
void requestPromise.catch(() => {
|
|
23564
|
+
});
|
|
23565
|
+
try {
|
|
23566
|
+
return await Promise.race([requestPromise, timeoutPromise]);
|
|
23567
|
+
} finally {
|
|
23568
|
+
if (timeout) {
|
|
23569
|
+
clearTimeout(timeout);
|
|
23570
|
+
}
|
|
23571
|
+
removeAbortListener?.();
|
|
23572
|
+
}
|
|
23320
23573
|
}
|
|
23321
23574
|
createMcpElicitationContext(params) {
|
|
23322
23575
|
const isToolApproval = isMcpToolCallApproval(params._meta);
|
|
@@ -23362,6 +23615,72 @@ var CodexElicitationHandler = class {
|
|
|
23362
23615
|
};
|
|
23363
23616
|
}
|
|
23364
23617
|
}
|
|
23618
|
+
buildUserInputRequest(params) {
|
|
23619
|
+
const properties = {};
|
|
23620
|
+
const required2 = [];
|
|
23621
|
+
const questionIds = new Set(params.questions.map((question) => question.id));
|
|
23622
|
+
for (const question of params.questions) {
|
|
23623
|
+
const options = question.options ?? [];
|
|
23624
|
+
const hasOptions = options.length > 0;
|
|
23625
|
+
const hasOtherAnswer = question.isOther && hasOptions;
|
|
23626
|
+
const base = {
|
|
23627
|
+
title: question.header || question.id,
|
|
23628
|
+
description: question.question,
|
|
23629
|
+
_meta: {
|
|
23630
|
+
codex: {
|
|
23631
|
+
isOther: question.isOther,
|
|
23632
|
+
isSecret: question.isSecret
|
|
23633
|
+
}
|
|
23634
|
+
}
|
|
23635
|
+
};
|
|
23636
|
+
if (!hasOtherAnswer) {
|
|
23637
|
+
required2.push(question.id);
|
|
23638
|
+
}
|
|
23639
|
+
properties[question.id] = hasOptions ? {
|
|
23640
|
+
...base,
|
|
23641
|
+
type: "string",
|
|
23642
|
+
oneOf: options.map((option) => ({
|
|
23643
|
+
const: option.label,
|
|
23644
|
+
title: option.label,
|
|
23645
|
+
description: option.description
|
|
23646
|
+
}))
|
|
23647
|
+
} : {
|
|
23648
|
+
...base,
|
|
23649
|
+
type: "string"
|
|
23650
|
+
};
|
|
23651
|
+
if (hasOtherAnswer) {
|
|
23652
|
+
properties[userInputOtherFieldId(question.id, questionIds)] = {
|
|
23653
|
+
type: "string",
|
|
23654
|
+
title: "Other",
|
|
23655
|
+
description: "Type your own answer instead of choosing an option above.",
|
|
23656
|
+
_meta: {
|
|
23657
|
+
codex: {
|
|
23658
|
+
questionId: question.id,
|
|
23659
|
+
isOtherAnswer: true,
|
|
23660
|
+
isSecret: question.isSecret
|
|
23661
|
+
}
|
|
23662
|
+
}
|
|
23663
|
+
};
|
|
23664
|
+
}
|
|
23665
|
+
}
|
|
23666
|
+
const firstQuestion = params.questions[0];
|
|
23667
|
+
return {
|
|
23668
|
+
sessionId: this.sessionState.sessionId,
|
|
23669
|
+
toolCallId: params.itemId,
|
|
23670
|
+
mode: "form",
|
|
23671
|
+
message: params.questions.length === 1 && firstQuestion ? firstQuestion.question : "Input requested",
|
|
23672
|
+
requestedSchema: {
|
|
23673
|
+
type: "object",
|
|
23674
|
+
properties,
|
|
23675
|
+
required: required2
|
|
23676
|
+
},
|
|
23677
|
+
_meta: {
|
|
23678
|
+
codex: {
|
|
23679
|
+
autoResolutionMs: params.autoResolutionMs
|
|
23680
|
+
}
|
|
23681
|
+
}
|
|
23682
|
+
};
|
|
23683
|
+
}
|
|
23365
23684
|
buildPermissionRequest(params, context) {
|
|
23366
23685
|
const sessionId = this.sessionState.sessionId;
|
|
23367
23686
|
const messageContent = {
|
|
@@ -23459,6 +23778,24 @@ var CodexElicitationHandler = class {
|
|
|
23459
23778
|
}
|
|
23460
23779
|
return { action: "cancel", content: null, _meta: null };
|
|
23461
23780
|
}
|
|
23781
|
+
convertUserInputResponse(response, params) {
|
|
23782
|
+
if (!CreateElicitationResponse.isAccept(response)) {
|
|
23783
|
+
return { answers: {} };
|
|
23784
|
+
}
|
|
23785
|
+
const answers = {};
|
|
23786
|
+
const content = contentRecord(response.content);
|
|
23787
|
+
const questionIds = new Set(params.questions.map((question) => question.id));
|
|
23788
|
+
for (const question of params.questions) {
|
|
23789
|
+
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);
|
|
23790
|
+
if (value === void 0) {
|
|
23791
|
+
continue;
|
|
23792
|
+
}
|
|
23793
|
+
answers[question.id] = {
|
|
23794
|
+
answers: Array.isArray(value) ? value.map(String) : [String(value)]
|
|
23795
|
+
};
|
|
23796
|
+
}
|
|
23797
|
+
return { answers };
|
|
23798
|
+
}
|
|
23462
23799
|
async publishAcceptedMcpToolApproval(context, accepted) {
|
|
23463
23800
|
if (!accepted || context.correlatedCallId === void 0) {
|
|
23464
23801
|
return;
|
|
@@ -24245,7 +24582,7 @@ var package_default = {
|
|
|
24245
24582
|
publishConfig: {
|
|
24246
24583
|
access: "public"
|
|
24247
24584
|
},
|
|
24248
|
-
version: "1.1
|
|
24585
|
+
version: "1.2.1",
|
|
24249
24586
|
description: "An ACP-compatible coding agent powered by Codex",
|
|
24250
24587
|
main: "dist/index.js",
|
|
24251
24588
|
bin: {
|
|
@@ -24311,13 +24648,17 @@ var package_default = {
|
|
|
24311
24648
|
},
|
|
24312
24649
|
dependencies: {
|
|
24313
24650
|
"@agentclientprotocol/sdk": "^1.2.1",
|
|
24314
|
-
"@openai/codex": "^0.144.
|
|
24651
|
+
"@openai/codex": "^0.144.4",
|
|
24315
24652
|
diff: "^9.0.0",
|
|
24316
24653
|
open: "^11.0.0",
|
|
24317
24654
|
"vscode-jsonrpc": "^9.0.1",
|
|
24318
24655
|
zod: "^4.0.0"
|
|
24319
24656
|
}
|
|
24320
24657
|
};
|
|
24658
|
+
var CUSTOM_GATEWAY_PROVIDER_ID = "custom-gateway";
|
|
24659
|
+
var SUPPORTED_GATEWAY_PROTOCOLS = {
|
|
24660
|
+
openai: "responses"
|
|
24661
|
+
};
|
|
24321
24662
|
var CodexAcpClient = class {
|
|
24322
24663
|
codexClient;
|
|
24323
24664
|
config;
|
|
@@ -24355,6 +24696,7 @@ var CodexAcpClient = class {
|
|
|
24355
24696
|
if (!isCodexAuthRequest(authRequest)) {
|
|
24356
24697
|
throw RequestError.invalidRequest();
|
|
24357
24698
|
}
|
|
24699
|
+
this.gatewayConfig = null;
|
|
24358
24700
|
switch (authRequest.methodId) {
|
|
24359
24701
|
case "api-key": {
|
|
24360
24702
|
const apiKey = authRequest._meta?.["api-key"]?.apiKey ?? this.readApiKeyFromEnv();
|
|
@@ -24363,7 +24705,6 @@ var CodexAcpClient = class {
|
|
|
24363
24705
|
case "chat-gpt": {
|
|
24364
24706
|
const accountResponse = await this.codexClient.accountRead({ refreshToken: true });
|
|
24365
24707
|
if (accountResponse.account?.type === "chatgpt") {
|
|
24366
|
-
this.gatewayConfig = null;
|
|
24367
24708
|
return true;
|
|
24368
24709
|
}
|
|
24369
24710
|
const loginCompletedPromise = this.awaitNextLoginCompleted();
|
|
@@ -24371,7 +24712,6 @@ var CodexAcpClient = class {
|
|
|
24371
24712
|
if (loginResponse.type == "chatgpt") {
|
|
24372
24713
|
await open_default(loginResponse.authUrl);
|
|
24373
24714
|
}
|
|
24374
|
-
this.gatewayConfig = null;
|
|
24375
24715
|
const result = await loginCompletedPromise;
|
|
24376
24716
|
return result.success;
|
|
24377
24717
|
}
|
|
@@ -24379,25 +24719,14 @@ var CodexAcpClient = class {
|
|
|
24379
24719
|
if (!authRequest._meta) throw RequestError.invalidRequest();
|
|
24380
24720
|
const gatewaySettings = authRequest._meta["gateway"];
|
|
24381
24721
|
if (!gatewaySettings) throw RequestError.invalidRequest();
|
|
24382
|
-
|
|
24383
|
-
|
|
24384
|
-
|
|
24385
|
-
|
|
24386
|
-
|
|
24387
|
-
};
|
|
24388
|
-
this.gatewayConfig = {
|
|
24389
|
-
modelProvider: "custom-gateway",
|
|
24390
|
-
config: {
|
|
24391
|
-
name: providerName,
|
|
24392
|
-
base_url: baseUrl,
|
|
24393
|
-
http_headers: headers,
|
|
24394
|
-
wire_api: "responses"
|
|
24395
|
-
}
|
|
24396
|
-
};
|
|
24722
|
+
this.applyGatewayConfig({
|
|
24723
|
+
baseUrl: gatewaySettings.baseUrl,
|
|
24724
|
+
apiType: GatewayAuthMethod._meta.gateway.protocol,
|
|
24725
|
+
headers: gatewaySettings.headers,
|
|
24726
|
+
providerName: gatewaySettings.providerName
|
|
24727
|
+
});
|
|
24397
24728
|
return true;
|
|
24398
24729
|
}
|
|
24399
|
-
this.gatewayConfig = null;
|
|
24400
|
-
return false;
|
|
24401
24730
|
}
|
|
24402
24731
|
async authenticateWithApiKey(apiKey) {
|
|
24403
24732
|
const loginCompletedPromise = this.awaitNextLoginCompleted();
|
|
@@ -24405,7 +24734,6 @@ var CodexAcpClient = class {
|
|
|
24405
24734
|
type: "apiKey",
|
|
24406
24735
|
apiKey
|
|
24407
24736
|
});
|
|
24408
|
-
this.gatewayConfig = null;
|
|
24409
24737
|
const result = await loginCompletedPromise;
|
|
24410
24738
|
return result.success;
|
|
24411
24739
|
}
|
|
@@ -24472,12 +24800,90 @@ var CodexAcpClient = class {
|
|
|
24472
24800
|
const response = await this.codexClient.accountRead({ refreshToken: false });
|
|
24473
24801
|
return response.requiresOpenaiAuth && !response.account;
|
|
24474
24802
|
}
|
|
24475
|
-
|
|
24476
|
-
|
|
24803
|
+
/**
|
|
24804
|
+
* Validates and stores custom gateway routing. Shared by the `gateway` auth
|
|
24805
|
+
* method and the ACP `providers/set` method. Throws `invalid_params` for an
|
|
24806
|
+
* unsupported protocol or a malformed base URL.
|
|
24807
|
+
*/
|
|
24808
|
+
applyGatewayConfig(params) {
|
|
24809
|
+
const apiType = params.apiType;
|
|
24810
|
+
const wireApi = SUPPORTED_GATEWAY_PROTOCOLS[apiType];
|
|
24811
|
+
if (!wireApi) {
|
|
24812
|
+
throw RequestError.invalidParams(
|
|
24813
|
+
{ apiType },
|
|
24814
|
+
`Unsupported provider apiType "${apiType}"; supported: ${Object.keys(SUPPORTED_GATEWAY_PROTOCOLS).join(", ")}`
|
|
24815
|
+
);
|
|
24816
|
+
}
|
|
24817
|
+
if (typeof params.baseUrl !== "string" || params.baseUrl.trim().length === 0) {
|
|
24818
|
+
throw RequestError.invalidParams(void 0, "baseUrl must be a non-empty string");
|
|
24819
|
+
}
|
|
24820
|
+
const providerName = typeof params.providerName === "string" && params.providerName.trim().length > 0 ? params.providerName : "User-provided gateway";
|
|
24821
|
+
const headers = {
|
|
24822
|
+
"X-Client-Feature-ID": "codex",
|
|
24823
|
+
...params.headers
|
|
24824
|
+
};
|
|
24825
|
+
this.gatewayConfig = {
|
|
24826
|
+
modelProvider: CUSTOM_GATEWAY_PROVIDER_ID,
|
|
24827
|
+
config: {
|
|
24828
|
+
name: providerName,
|
|
24829
|
+
base_url: params.baseUrl,
|
|
24830
|
+
http_headers: headers,
|
|
24831
|
+
wire_api: wireApi
|
|
24832
|
+
}
|
|
24833
|
+
};
|
|
24834
|
+
}
|
|
24835
|
+
/**
|
|
24836
|
+
* `providers/list`: returns the single client-configurable custom gateway
|
|
24837
|
+
* provider. `current` carries only non-secret routing (never headers), and is
|
|
24838
|
+
* `null` when the provider is not configured/disabled.
|
|
24839
|
+
*/
|
|
24840
|
+
listProviders() {
|
|
24841
|
+
const gatewayConfig = this.gatewayConfig;
|
|
24842
|
+
const current = gatewayConfig ? {
|
|
24843
|
+
apiType: gatewayApiTypeFromConfig(gatewayConfig),
|
|
24844
|
+
baseUrl: gatewayConfig.config.base_url
|
|
24845
|
+
} : null;
|
|
24846
|
+
return [
|
|
24847
|
+
{
|
|
24848
|
+
providerId: CUSTOM_GATEWAY_PROVIDER_ID,
|
|
24849
|
+
supported: Object.keys(SUPPORTED_GATEWAY_PROTOCOLS),
|
|
24850
|
+
required: false,
|
|
24851
|
+
current
|
|
24852
|
+
}
|
|
24853
|
+
];
|
|
24854
|
+
}
|
|
24855
|
+
/**
|
|
24856
|
+
* `providers/set`: replaces the full configuration for the custom gateway
|
|
24857
|
+
* provider. Rejects unknown provider ids with `invalid_params`.
|
|
24858
|
+
*/
|
|
24859
|
+
setProvider(request) {
|
|
24860
|
+
if (request.providerId !== CUSTOM_GATEWAY_PROVIDER_ID) {
|
|
24861
|
+
throw RequestError.invalidParams(
|
|
24862
|
+
{ providerId: request.providerId },
|
|
24863
|
+
`Unknown providerId "${request.providerId}"; only "${CUSTOM_GATEWAY_PROVIDER_ID}" is configurable`
|
|
24864
|
+
);
|
|
24865
|
+
}
|
|
24866
|
+
this.applyGatewayConfig({
|
|
24867
|
+
apiType: request.apiType,
|
|
24868
|
+
baseUrl: request.baseUrl,
|
|
24869
|
+
headers: request.headers
|
|
24870
|
+
});
|
|
24871
|
+
}
|
|
24872
|
+
/**
|
|
24873
|
+
* `providers/disable`: disables the custom gateway provider. Disabling an
|
|
24874
|
+
* unknown provider id is idempotent success (RFD behavior §7).
|
|
24875
|
+
*/
|
|
24876
|
+
disableProvider(request) {
|
|
24877
|
+
if (request.providerId === CUSTOM_GATEWAY_PROVIDER_ID) {
|
|
24878
|
+
this.gatewayConfig = null;
|
|
24879
|
+
}
|
|
24477
24880
|
}
|
|
24478
24881
|
async getAccount() {
|
|
24479
24882
|
return this.codexClient.accountRead({ refreshToken: false });
|
|
24480
24883
|
}
|
|
24884
|
+
async getRateLimits() {
|
|
24885
|
+
return this.codexClient.accountRateLimitsRead();
|
|
24886
|
+
}
|
|
24481
24887
|
async resumeSession(request, onSubscribed) {
|
|
24482
24888
|
const additionalDirectories = readAdditionalDirectories(request.cwd, request.additionalDirectories, request._meta);
|
|
24483
24889
|
await this.refreshSkills(request.cwd, additionalDirectories);
|
|
@@ -24715,6 +25121,10 @@ var CodexAcpClient = class {
|
|
|
24715
25121
|
handleElicitation: async (params) => {
|
|
24716
25122
|
await this.waitForSessionNotifications(sessionId);
|
|
24717
25123
|
return await elicitationHandler.handleElicitation(params);
|
|
25124
|
+
},
|
|
25125
|
+
handleUserInput: async (params) => {
|
|
25126
|
+
await this.waitForSessionNotifications(sessionId);
|
|
25127
|
+
return await elicitationHandler.handleUserInput(params);
|
|
24718
25128
|
}
|
|
24719
25129
|
});
|
|
24720
25130
|
}
|
|
@@ -24764,6 +25174,15 @@ var CodexAcpClient = class {
|
|
|
24764
25174
|
}
|
|
24765
25175
|
return await this.codexClient.runTurn(params, onTurnStarted);
|
|
24766
25176
|
}
|
|
25177
|
+
async sendSteer(request, expectedTurnId, steerId) {
|
|
25178
|
+
const response = await this.codexClient.turnSteer({
|
|
25179
|
+
threadId: request.sessionId,
|
|
25180
|
+
input: buildPromptItems(request.prompt),
|
|
25181
|
+
expectedTurnId,
|
|
25182
|
+
clientUserMessageId: steerId
|
|
25183
|
+
});
|
|
25184
|
+
return response.turnId;
|
|
25185
|
+
}
|
|
24767
25186
|
resolveTurnInterrupted(params) {
|
|
24768
25187
|
this.codexClient.resolveTurnInterrupted(params.threadId, params.turnId);
|
|
24769
25188
|
}
|
|
@@ -24881,7 +25300,7 @@ var CodexAcpClient = class {
|
|
|
24881
25300
|
const [allProviders, archivedAllProviders, customGateway] = await Promise.all([
|
|
24882
25301
|
this.codexClient.threadList({}),
|
|
24883
25302
|
this.codexClient.threadList({ archived: true }),
|
|
24884
|
-
this.codexClient.threadList({ modelProviders: [
|
|
25303
|
+
this.codexClient.threadList({ modelProviders: [CUSTOM_GATEWAY_PROVIDER_ID] })
|
|
24885
25304
|
]);
|
|
24886
25305
|
return {
|
|
24887
25306
|
allProviders: {
|
|
@@ -25034,6 +25453,11 @@ function arraysEqual(left, right) {
|
|
|
25034
25453
|
function isJsonObject(value) {
|
|
25035
25454
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
25036
25455
|
}
|
|
25456
|
+
function gatewayApiTypeFromConfig(gatewayConfig) {
|
|
25457
|
+
const wireApi = gatewayConfig.config.wire_api;
|
|
25458
|
+
const match = Object.entries(SUPPORTED_GATEWAY_PROTOCOLS).find(([, wire]) => wire === wireApi);
|
|
25459
|
+
return match?.[0] ?? "openai";
|
|
25460
|
+
}
|
|
25037
25461
|
function mergeGatewayConfig(config2, gatewayConfig) {
|
|
25038
25462
|
if (gatewayConfig !== null) {
|
|
25039
25463
|
const newConfig = { ...config2 };
|
|
@@ -25050,6 +25474,9 @@ function mergeGatewayConfig(config2, gatewayConfig) {
|
|
|
25050
25474
|
}
|
|
25051
25475
|
var MODEL_CONFIG_ID = "model";
|
|
25052
25476
|
var REASONING_EFFORT_CONFIG_ID = "reasoning_effort";
|
|
25477
|
+
function capitalize(value) {
|
|
25478
|
+
return value.charAt(0).toUpperCase() + value.slice(1);
|
|
25479
|
+
}
|
|
25053
25480
|
function findSupportedEffort(options, effort) {
|
|
25054
25481
|
if (!effort) return void 0;
|
|
25055
25482
|
return options.find((o) => o.reasoningEffort === effort)?.reasoningEffort;
|
|
@@ -25087,7 +25514,7 @@ function createReasoningEffortConfigOption(supportedReasoningEfforts, currentEff
|
|
|
25087
25514
|
currentValue: currentEffort,
|
|
25088
25515
|
options: supportedReasoningEfforts.map((option) => ({
|
|
25089
25516
|
value: option.reasoningEffort,
|
|
25090
|
-
name: option.reasoningEffort,
|
|
25517
|
+
name: capitalize(option.reasoningEffort),
|
|
25091
25518
|
description: option.description
|
|
25092
25519
|
}))
|
|
25093
25520
|
};
|
|
@@ -25288,8 +25715,7 @@ var CodexCommands = class {
|
|
|
25288
25715
|
return { handled: true };
|
|
25289
25716
|
}
|
|
25290
25717
|
default:
|
|
25291
|
-
|
|
25292
|
-
return { handled: true };
|
|
25718
|
+
return { handled: false };
|
|
25293
25719
|
}
|
|
25294
25720
|
}
|
|
25295
25721
|
async runReviewCommand(sessionState, target, options) {
|
|
@@ -25371,17 +25797,6 @@ var CodexCommands = class {
|
|
|
25371
25797
|
const session = new ACPSessionConnection(this.connection, sessionId);
|
|
25372
25798
|
await session.update(createAgentTextMessageChunk(text));
|
|
25373
25799
|
}
|
|
25374
|
-
async sendUnknownCommandMessage(name, sessionId) {
|
|
25375
|
-
const lines = this.getBuiltinCommands().map((command) => `- /${command.name}: ${command.description}`);
|
|
25376
|
-
const text = [
|
|
25377
|
-
`Unknown command "/${name}".`,
|
|
25378
|
-
"Available commands:"
|
|
25379
|
-
];
|
|
25380
|
-
if (lines.length > 0) {
|
|
25381
|
-
text.push(...lines);
|
|
25382
|
-
}
|
|
25383
|
-
await this.sendCommandMessage(text.join("\n"), sessionId);
|
|
25384
|
-
}
|
|
25385
25800
|
buildStatusMessage(sessionState) {
|
|
25386
25801
|
const agentMode = sessionState.agentMode;
|
|
25387
25802
|
const accountText = this.formatAccountInfo(sessionState.account);
|
|
@@ -25645,6 +26060,7 @@ function toolCallIdFromThreadItem(item) {
|
|
|
25645
26060
|
case "webSearch":
|
|
25646
26061
|
case "imageView":
|
|
25647
26062
|
case "imageGeneration":
|
|
26063
|
+
case "contextCompaction":
|
|
25648
26064
|
return item.id;
|
|
25649
26065
|
case "userMessage":
|
|
25650
26066
|
case "hookPrompt":
|
|
@@ -25654,7 +26070,6 @@ function toolCallIdFromThreadItem(item) {
|
|
|
25654
26070
|
case "subAgentActivity":
|
|
25655
26071
|
case "enteredReviewMode":
|
|
25656
26072
|
case "exitedReviewMode":
|
|
25657
|
-
case "contextCompaction":
|
|
25658
26073
|
case "sleep":
|
|
25659
26074
|
return null;
|
|
25660
26075
|
}
|
|
@@ -25737,9 +26152,13 @@ function createAgentReasoningEventUpdates(payload) {
|
|
|
25737
26152
|
if (text === null || text.length === 0) {
|
|
25738
26153
|
return [];
|
|
25739
26154
|
}
|
|
26155
|
+
const sanitizedText = stripEmptyReasoningComments(text);
|
|
26156
|
+
if (sanitizedText.length === 0) {
|
|
26157
|
+
return [];
|
|
26158
|
+
}
|
|
25740
26159
|
return [{
|
|
25741
26160
|
sessionUpdate: "agent_thought_chunk",
|
|
25742
|
-
content: { type: "text", text }
|
|
26161
|
+
content: { type: "text", text: sanitizedText }
|
|
25743
26162
|
}];
|
|
25744
26163
|
}
|
|
25745
26164
|
function imageBlocks(images) {
|
|
@@ -25776,11 +26195,7 @@ function contentBlocksFromResponseContent(content) {
|
|
|
25776
26195
|
});
|
|
25777
26196
|
}
|
|
25778
26197
|
function createReasoningUpdates(item) {
|
|
25779
|
-
|
|
25780
|
-
if (parts.length === 0) {
|
|
25781
|
-
parts.push(...textParts(item["content"]));
|
|
25782
|
-
}
|
|
25783
|
-
return parts.map((text) => ({
|
|
26198
|
+
return sanitizeReasoningParts(textParts(item["summary"]), textParts(item["content"])).map((text) => ({
|
|
25784
26199
|
sessionUpdate: "agent_thought_chunk",
|
|
25785
26200
|
content: { type: "text", text }
|
|
25786
26201
|
}));
|
|
@@ -26571,6 +26986,7 @@ var CodexAcpServer = class _CodexAcpServer {
|
|
|
26571
26986
|
pendingMcpStartupSessions;
|
|
26572
26987
|
pendingTurnStarts;
|
|
26573
26988
|
activePrompts;
|
|
26989
|
+
pendingSteers;
|
|
26574
26990
|
closingSessions;
|
|
26575
26991
|
sessionGenerations;
|
|
26576
26992
|
sessionOpenGenerations;
|
|
@@ -26579,6 +26995,7 @@ var CodexAcpServer = class _CodexAcpServer {
|
|
|
26579
26995
|
this.pendingMcpStartupSessions = /* @__PURE__ */ new Map();
|
|
26580
26996
|
this.pendingTurnStarts = /* @__PURE__ */ new Map();
|
|
26581
26997
|
this.activePrompts = /* @__PURE__ */ new Map();
|
|
26998
|
+
this.pendingSteers = /* @__PURE__ */ new Map();
|
|
26582
26999
|
this.closingSessions = /* @__PURE__ */ new Map();
|
|
26583
27000
|
this.sessionGenerations = /* @__PURE__ */ new Map();
|
|
26584
27001
|
this.sessionOpenGenerations = /* @__PURE__ */ new Map();
|
|
@@ -26616,6 +27033,7 @@ var CodexAcpServer = class _CodexAcpServer {
|
|
|
26616
27033
|
auth: {
|
|
26617
27034
|
logout: {}
|
|
26618
27035
|
},
|
|
27036
|
+
providers: {},
|
|
26619
27037
|
loadSession: true,
|
|
26620
27038
|
promptCapabilities: {
|
|
26621
27039
|
embeddedContext: true,
|
|
@@ -26632,6 +27050,11 @@ var CodexAcpServer = class _CodexAcpServer {
|
|
|
26632
27050
|
acp: false,
|
|
26633
27051
|
http: true,
|
|
26634
27052
|
sse: false
|
|
27053
|
+
},
|
|
27054
|
+
_meta: {
|
|
27055
|
+
codex: {
|
|
27056
|
+
steer: CODEX_STEER_CAPABILITY
|
|
27057
|
+
}
|
|
26635
27058
|
}
|
|
26636
27059
|
},
|
|
26637
27060
|
authMethods: getCodexAuthMethods(_params.clientCapabilities)
|
|
@@ -26807,9 +27230,12 @@ You have been logged out. Please try again.`);
|
|
|
26807
27230
|
planModeEnabled: false,
|
|
26808
27231
|
planModeExplicitlySet: false,
|
|
26809
27232
|
sessionMcpServers,
|
|
26810
|
-
terminalOutputMode: this.terminalOutputMode
|
|
27233
|
+
terminalOutputMode: this.terminalOutputMode,
|
|
27234
|
+
sessionTitle: null,
|
|
27235
|
+
sessionTitleSource: "sessionId" in request ? "unknown" : "unset"
|
|
26811
27236
|
};
|
|
26812
27237
|
this.sessions.set(sessionId, sessionState);
|
|
27238
|
+
this.publishRateLimitsAsync(sessionState);
|
|
26813
27239
|
resumeSubscribed = false;
|
|
26814
27240
|
if (requestedMcpServers.length > 0 && mcpServerStartupVersion !== null) {
|
|
26815
27241
|
this.pendingMcpStartupSessions.set(sessionId, {
|
|
@@ -26845,6 +27271,27 @@ You have been logged out. Please try again.`);
|
|
|
26845
27271
|
}
|
|
26846
27272
|
return a === b;
|
|
26847
27273
|
}
|
|
27274
|
+
publishRateLimitsAsync(sessionState) {
|
|
27275
|
+
if (!sessionState.authConfigured || !this.authProviderUsesOpenAiAccount(sessionState.authProvider)) {
|
|
27276
|
+
return;
|
|
27277
|
+
}
|
|
27278
|
+
void this.codexAcpClient.getRateLimits().then(async (response) => {
|
|
27279
|
+
if (this.sessions.get(sessionState.sessionId) !== sessionState) {
|
|
27280
|
+
return;
|
|
27281
|
+
}
|
|
27282
|
+
if (!response?.rateLimits) {
|
|
27283
|
+
return;
|
|
27284
|
+
}
|
|
27285
|
+
const rateLimitsById = Object.values(response.rateLimitsByLimitId ?? {}).filter((snapshot) => snapshot !== void 0);
|
|
27286
|
+
const snapshots = rateLimitsById.length > 0 ? rateLimitsById : [response.rateLimits];
|
|
27287
|
+
const handler = new CodexEventHandler(this.connection, sessionState);
|
|
27288
|
+
for (const snapshot of snapshots) {
|
|
27289
|
+
await handler.handleRateLimitsSnapshot(snapshot);
|
|
27290
|
+
}
|
|
27291
|
+
}).catch((err) => {
|
|
27292
|
+
logger.error(`Failed to read rate limits for session ${sessionState.sessionId}`, err);
|
|
27293
|
+
});
|
|
27294
|
+
}
|
|
26848
27295
|
getAuthProviderForAuthenticateRequest(request) {
|
|
26849
27296
|
if (isCodexAuthRequest(request) && request.methodId === "gateway") {
|
|
26850
27297
|
return "custom-gateway";
|
|
@@ -26988,6 +27435,17 @@ You have been logged out. Please try again.`);
|
|
|
26988
27435
|
await this.refreshSessionsAuthState(null);
|
|
26989
27436
|
logger.log("Logout request completed");
|
|
26990
27437
|
}
|
|
27438
|
+
listProviders(_params) {
|
|
27439
|
+
return { providers: this.codexAcpClient.listProviders() };
|
|
27440
|
+
}
|
|
27441
|
+
setProvider(params) {
|
|
27442
|
+
this.codexAcpClient.setProvider(params);
|
|
27443
|
+
return {};
|
|
27444
|
+
}
|
|
27445
|
+
disableProvider(params) {
|
|
27446
|
+
this.codexAcpClient.disableProvider(params);
|
|
27447
|
+
return {};
|
|
27448
|
+
}
|
|
26991
27449
|
async refreshSessionsAuthState(authProvider) {
|
|
26992
27450
|
if (this.sessions.size === 0) return;
|
|
26993
27451
|
const sessionsToRefresh = [...this.sessions.values()].filter((sessionState) => this.authProvidersMatch(sessionState.authProvider, authProvider));
|
|
@@ -26996,6 +27454,7 @@ You have been logged out. Please try again.`);
|
|
|
26996
27454
|
for (const sessionState of sessionsToRefresh) {
|
|
26997
27455
|
sessionState.account = authState.account;
|
|
26998
27456
|
sessionState.authConfigured = authState.authConfigured;
|
|
27457
|
+
this.publishRateLimitsAsync(sessionState);
|
|
26999
27458
|
}
|
|
27000
27459
|
}
|
|
27001
27460
|
async setSessionMode(_params) {
|
|
@@ -27259,9 +27718,12 @@ You have been logged out. Please try again.`);
|
|
|
27259
27718
|
planModeEnabled: false,
|
|
27260
27719
|
planModeExplicitlySet: false,
|
|
27261
27720
|
sessionMcpServers,
|
|
27262
|
-
terminalOutputMode: this.terminalOutputMode
|
|
27721
|
+
terminalOutputMode: this.terminalOutputMode,
|
|
27722
|
+
sessionTitle: null,
|
|
27723
|
+
sessionTitleSource: "unset"
|
|
27263
27724
|
};
|
|
27264
27725
|
this.sessions.set(sessionId, sessionState);
|
|
27726
|
+
this.publishRateLimitsAsync(sessionState);
|
|
27265
27727
|
subscribed = false;
|
|
27266
27728
|
if (requestedMcpServers.length > 0 && mcpServerStartupVersion !== null) {
|
|
27267
27729
|
this.pendingMcpStartupSessions.set(sessionId, {
|
|
@@ -27283,6 +27745,7 @@ You have been logged out. Please try again.`);
|
|
|
27283
27745
|
async streamThreadHistory(sessionId, thread) {
|
|
27284
27746
|
const session = new ACPSessionConnection(this.connection, sessionId);
|
|
27285
27747
|
const sessionState = this.getSessionState(sessionId);
|
|
27748
|
+
await this.publishThreadHistoryTitle(session, sessionState, thread);
|
|
27286
27749
|
const responseItemFallbackUpdates = await createResponseItemHistoryFallbackUpdates(
|
|
27287
27750
|
thread,
|
|
27288
27751
|
sessionState.terminalOutputMode
|
|
@@ -27299,6 +27762,47 @@ You have been logged out. Please try again.`);
|
|
|
27299
27762
|
await session.update(update);
|
|
27300
27763
|
}
|
|
27301
27764
|
}
|
|
27765
|
+
async publishThreadHistoryTitle(session, sessionState, thread) {
|
|
27766
|
+
const explicitTitle = this.normalizeSessionTitle(thread.name);
|
|
27767
|
+
if (explicitTitle) {
|
|
27768
|
+
sessionState.sessionTitle = explicitTitle;
|
|
27769
|
+
sessionState.sessionTitleSource = "explicit";
|
|
27770
|
+
await session.update({
|
|
27771
|
+
sessionUpdate: "session_info_update",
|
|
27772
|
+
title: explicitTitle
|
|
27773
|
+
});
|
|
27774
|
+
return;
|
|
27775
|
+
}
|
|
27776
|
+
const historyTitle = this.findFirstUserMessageTitle(thread) ?? this.normalizeSessionTitle(thread.preview);
|
|
27777
|
+
await this.publishFallbackSessionTitle(sessionState, historyTitle);
|
|
27778
|
+
}
|
|
27779
|
+
findFirstUserMessageTitle(thread) {
|
|
27780
|
+
for (const turn of thread.turns) {
|
|
27781
|
+
for (const item of turn.items) {
|
|
27782
|
+
if (item.type !== "userMessage") continue;
|
|
27783
|
+
const title = this.normalizeSessionTitle(item.content.filter((input) => input.type === "text").map((input) => input.text).join(" "));
|
|
27784
|
+
if (title) return title;
|
|
27785
|
+
}
|
|
27786
|
+
}
|
|
27787
|
+
return null;
|
|
27788
|
+
}
|
|
27789
|
+
async publishFallbackSessionTitle(sessionState, title) {
|
|
27790
|
+
if (sessionState.sessionTitleSource !== "unset" || !title) return;
|
|
27791
|
+
sessionState.sessionTitle = title;
|
|
27792
|
+
sessionState.sessionTitleSource = "fallback";
|
|
27793
|
+
const session = new ACPSessionConnection(this.connection, sessionState.sessionId);
|
|
27794
|
+
await session.update({
|
|
27795
|
+
sessionUpdate: "session_info_update",
|
|
27796
|
+
title
|
|
27797
|
+
});
|
|
27798
|
+
}
|
|
27799
|
+
createPromptFallbackTitle(prompt) {
|
|
27800
|
+
return this.normalizeSessionTitle(prompt.filter((block) => block.type === "text").map((block) => block.text).join(" "));
|
|
27801
|
+
}
|
|
27802
|
+
normalizeSessionTitle(title) {
|
|
27803
|
+
const normalized = title?.replace(/\s+/g, " ").trim() ?? "";
|
|
27804
|
+
return normalized.length > 0 ? normalized : null;
|
|
27805
|
+
}
|
|
27302
27806
|
async createHistoryUpdates(item, sessionState) {
|
|
27303
27807
|
switch (item.type) {
|
|
27304
27808
|
case "userMessage":
|
|
@@ -27345,7 +27849,7 @@ You have been logged out. Please try again.`);
|
|
|
27345
27849
|
case "exitedReviewMode":
|
|
27346
27850
|
return [this.createReviewModeUpdate(item, false)];
|
|
27347
27851
|
case "contextCompaction":
|
|
27348
|
-
return [
|
|
27852
|
+
return [createCompletedContextCompactionUpdate(item)];
|
|
27349
27853
|
case "plan":
|
|
27350
27854
|
return [this.createPlanUpdate(item)];
|
|
27351
27855
|
}
|
|
@@ -27362,9 +27866,8 @@ You have been logged out. Please try again.`);
|
|
|
27362
27866
|
return updates;
|
|
27363
27867
|
}
|
|
27364
27868
|
createReasoningUpdates(item) {
|
|
27365
|
-
const parts = item.summary.length > 0 ? item.summary : item.content;
|
|
27366
27869
|
const messageId = item.id;
|
|
27367
|
-
return
|
|
27870
|
+
return sanitizeReasoningParts(item.summary, item.content).map((text) => createAgentTextThoughtChunk(text, messageId));
|
|
27368
27871
|
}
|
|
27369
27872
|
createWebSearchUpdate(item) {
|
|
27370
27873
|
return {
|
|
@@ -27388,15 +27891,6 @@ You have been logged out. Please try again.`);
|
|
|
27388
27891
|
}
|
|
27389
27892
|
};
|
|
27390
27893
|
}
|
|
27391
|
-
createContextCompactionUpdate() {
|
|
27392
|
-
return {
|
|
27393
|
-
sessionUpdate: "agent_message_chunk",
|
|
27394
|
-
content: {
|
|
27395
|
-
type: "text",
|
|
27396
|
-
text: "Context compacted."
|
|
27397
|
-
}
|
|
27398
|
-
};
|
|
27399
|
-
}
|
|
27400
27894
|
createPlanUpdate(item) {
|
|
27401
27895
|
return {
|
|
27402
27896
|
sessionUpdate: "agent_message_chunk",
|
|
@@ -27516,6 +28010,7 @@ ${item.text}`
|
|
|
27516
28010
|
cancelSignal,
|
|
27517
28011
|
signal: abortController.signal,
|
|
27518
28012
|
currentTurn: null,
|
|
28013
|
+
outcome: null,
|
|
27519
28014
|
requestCancel: () => {
|
|
27520
28015
|
if (abortController.signal.aborted) {
|
|
27521
28016
|
return;
|
|
@@ -27539,12 +28034,78 @@ ${item.text}`
|
|
|
27539
28034
|
if (this.activePrompts.get(sessionId) === activePrompt) {
|
|
27540
28035
|
this.activePrompts.delete(sessionId);
|
|
27541
28036
|
}
|
|
28037
|
+
this.clearPendingSteers(sessionId, activePrompt);
|
|
27542
28038
|
resolveCompletion();
|
|
27543
28039
|
}
|
|
27544
28040
|
};
|
|
27545
28041
|
this.activePrompts.set(sessionId, activePrompt);
|
|
27546
28042
|
return activePrompt;
|
|
27547
28043
|
}
|
|
28044
|
+
clearPendingSteers(sessionId, activePrompt) {
|
|
28045
|
+
const pending = this.pendingSteers.get(sessionId);
|
|
28046
|
+
if (!pending) return;
|
|
28047
|
+
for (const [steerId, steer] of pending) {
|
|
28048
|
+
if (steer.activePrompt === activePrompt) pending.delete(steerId);
|
|
28049
|
+
}
|
|
28050
|
+
if (pending.size === 0) this.pendingSteers.delete(sessionId);
|
|
28051
|
+
}
|
|
28052
|
+
async handleSteerAppliedNotification(sessionId, event, activePrompt) {
|
|
28053
|
+
if (event.method !== "item/completed" || event.params.item.type !== "userMessage") return;
|
|
28054
|
+
const steerId = event.params.item.clientId;
|
|
28055
|
+
if (!steerId) return;
|
|
28056
|
+
const pending = this.pendingSteers.get(sessionId);
|
|
28057
|
+
if (!pending) return;
|
|
28058
|
+
const steer = pending.get(steerId);
|
|
28059
|
+
if (!steer || steer.activePrompt !== activePrompt || steer.turnId !== event.params.turnId) return;
|
|
28060
|
+
pending.delete(steerId);
|
|
28061
|
+
if (pending.size === 0) this.pendingSteers.delete(sessionId);
|
|
28062
|
+
await this.connection.notify(CODEX_STEER_APPLIED_METHOD, { sessionId, steerId });
|
|
28063
|
+
}
|
|
28064
|
+
async steerPrompt(params) {
|
|
28065
|
+
const steerId = getCodexSteerId(params._meta);
|
|
28066
|
+
if (!steerId) throw RequestError.invalidRequest("Missing Codex steer id");
|
|
28067
|
+
const firstText = params.prompt[0]?.type === "text" ? params.prompt[0].text : "";
|
|
28068
|
+
if (firstText.startsWith("/")) {
|
|
28069
|
+
throw RequestError.invalidRequest("Slash commands cannot steer an active Codex turn");
|
|
28070
|
+
}
|
|
28071
|
+
let activePrompt = this.activePrompts.get(params.sessionId);
|
|
28072
|
+
if (!activePrompt) throw RequestError.invalidRequest("No active Codex turn to steer");
|
|
28073
|
+
if (!activePrompt.currentTurn) {
|
|
28074
|
+
await this.pendingTurnStarts.get(params.sessionId)?.promise;
|
|
28075
|
+
activePrompt = this.activePrompts.get(params.sessionId);
|
|
28076
|
+
}
|
|
28077
|
+
const turn = activePrompt?.currentTurn;
|
|
28078
|
+
if (!activePrompt || !turn || activePrompt.signal.aborted) {
|
|
28079
|
+
throw RequestError.invalidRequest("No active Codex turn to steer");
|
|
28080
|
+
}
|
|
28081
|
+
const pending = this.pendingSteers.get(params.sessionId) ?? /* @__PURE__ */ new Map();
|
|
28082
|
+
if (pending.has(steerId)) {
|
|
28083
|
+
throw RequestError.invalidRequest(`Duplicate Codex steer id: ${steerId}`);
|
|
28084
|
+
}
|
|
28085
|
+
pending.set(steerId, { activePrompt, turnId: turn.turnId });
|
|
28086
|
+
this.pendingSteers.set(params.sessionId, pending);
|
|
28087
|
+
try {
|
|
28088
|
+
const steeredTurnId = await this.runWithProcessCheck(
|
|
28089
|
+
() => this.codexAcpClient.sendSteer(params, turn.turnId, steerId)
|
|
28090
|
+
);
|
|
28091
|
+
if (steeredTurnId !== turn.turnId) {
|
|
28092
|
+
throw RequestError.internalError(
|
|
28093
|
+
void 0,
|
|
28094
|
+
`Codex steered unexpected turn ${steeredTurnId}; expected ${turn.turnId}`
|
|
28095
|
+
);
|
|
28096
|
+
}
|
|
28097
|
+
} catch (error48) {
|
|
28098
|
+
if (pending.get(steerId)?.activePrompt === activePrompt) {
|
|
28099
|
+
pending.delete(steerId);
|
|
28100
|
+
if (pending.size === 0) this.pendingSteers.delete(params.sessionId);
|
|
28101
|
+
}
|
|
28102
|
+
throw error48;
|
|
28103
|
+
}
|
|
28104
|
+
if (!activePrompt.outcome) {
|
|
28105
|
+
throw RequestError.internalError(void 0, "Active Codex prompt has no tracked outcome");
|
|
28106
|
+
}
|
|
28107
|
+
return await activePrompt.outcome;
|
|
28108
|
+
}
|
|
27548
28109
|
cancelBeforeTurnStarted(activePrompt) {
|
|
27549
28110
|
return activePrompt.cancelSignal.then(() => {
|
|
27550
28111
|
if (activePrompt.currentTurn === null) {
|
|
@@ -27676,6 +28237,22 @@ ${item.text}`
|
|
|
27676
28237
|
return turnId;
|
|
27677
28238
|
}
|
|
27678
28239
|
async prompt(params, signal) {
|
|
28240
|
+
if (getCodexSteerId(params._meta)) {
|
|
28241
|
+
return await this.steerPrompt(params);
|
|
28242
|
+
}
|
|
28243
|
+
if (this.activePrompts.has(params.sessionId)) {
|
|
28244
|
+
throw RequestError.invalidRequest(
|
|
28245
|
+
"A Codex prompt is already active; use the advertised steer extension"
|
|
28246
|
+
);
|
|
28247
|
+
}
|
|
28248
|
+
const outcome = this.runPrompt(params, signal);
|
|
28249
|
+
const activePrompt = this.activePrompts.get(params.sessionId);
|
|
28250
|
+
if (activePrompt) {
|
|
28251
|
+
activePrompt.outcome = outcome;
|
|
28252
|
+
}
|
|
28253
|
+
return await outcome;
|
|
28254
|
+
}
|
|
28255
|
+
async runPrompt(params, signal) {
|
|
27679
28256
|
logger.log("Prompt received", {
|
|
27680
28257
|
sessionId: params.sessionId,
|
|
27681
28258
|
prompt: params.prompt
|
|
@@ -27684,14 +28261,8 @@ ${item.text}`
|
|
|
27684
28261
|
sessionState.currentTurnId = null;
|
|
27685
28262
|
sessionState.lastTokenUsage = null;
|
|
27686
28263
|
const activePrompt = this.trackActivePrompt(params.sessionId);
|
|
27687
|
-
|
|
27688
|
-
|
|
27689
|
-
if (pendingTurnStart === null) {
|
|
27690
|
-
pendingTurnStart = this.createPendingTurnStart();
|
|
27691
|
-
this.pendingTurnStarts.set(params.sessionId, pendingTurnStart);
|
|
27692
|
-
}
|
|
27693
|
-
return pendingTurnStart;
|
|
27694
|
-
};
|
|
28264
|
+
const pendingTurnStart = this.createPendingTurnStart();
|
|
28265
|
+
this.pendingTurnStarts.set(params.sessionId, pendingTurnStart);
|
|
27695
28266
|
const disposePromptRequestCancellation = this.observePromptRequestCancellation(signal, sessionState, activePrompt);
|
|
27696
28267
|
try {
|
|
27697
28268
|
const eventHandler = new CodexEventHandler(this.connection, sessionState);
|
|
@@ -27705,6 +28276,7 @@ ${item.text}`
|
|
|
27705
28276
|
await this.codexAcpClient.subscribeToSessionEvents(
|
|
27706
28277
|
params.sessionId,
|
|
27707
28278
|
async (event) => {
|
|
28279
|
+
await this.handleSteerAppliedNotification(params.sessionId, event, activePrompt);
|
|
27708
28280
|
await elicitationHandler.handleNotification(event);
|
|
27709
28281
|
return eventHandler.handleNotification(event);
|
|
27710
28282
|
},
|
|
@@ -27715,9 +28287,6 @@ ${item.text}`
|
|
|
27715
28287
|
return this.cancelledPromptResponse(sessionState);
|
|
27716
28288
|
}
|
|
27717
28289
|
const commandPromise = this.availableCommands.tryHandleCommand(params.prompt, sessionState, {
|
|
27718
|
-
onTurnStartPending: () => {
|
|
27719
|
-
ensurePendingTurnStart();
|
|
27720
|
-
},
|
|
27721
28290
|
onTurnStarted: (turnId, threadId) => {
|
|
27722
28291
|
const turn = { threadId, turnId };
|
|
27723
28292
|
activePrompt.currentTurn = turn;
|
|
@@ -27726,7 +28295,7 @@ ${item.text}`
|
|
|
27726
28295
|
return;
|
|
27727
28296
|
}
|
|
27728
28297
|
sessionState.currentTurnId = turnId;
|
|
27729
|
-
pendingTurnStart
|
|
28298
|
+
pendingTurnStart.resolve(turnId);
|
|
27730
28299
|
}
|
|
27731
28300
|
});
|
|
27732
28301
|
void commandPromise.catch((err) => {
|
|
@@ -27780,7 +28349,6 @@ ${item.text}`
|
|
|
27780
28349
|
sessionState.currentModelSupportsFast
|
|
27781
28350
|
);
|
|
27782
28351
|
const collaborationMode = this.createPlanModeCollaborationMode(sessionState, modelId);
|
|
27783
|
-
ensurePendingTurnStart();
|
|
27784
28352
|
const sendPromptPromise = this.runWithProcessCheck(
|
|
27785
28353
|
() => this.codexAcpClient.sendPrompt(
|
|
27786
28354
|
params,
|
|
@@ -27799,7 +28367,7 @@ ${item.text}`
|
|
|
27799
28367
|
return;
|
|
27800
28368
|
}
|
|
27801
28369
|
sessionState.currentTurnId = turnId;
|
|
27802
|
-
pendingTurnStart
|
|
28370
|
+
pendingTurnStart.resolve(turnId);
|
|
27803
28371
|
},
|
|
27804
28372
|
() => this.promptShouldStop(params.sessionId, activePrompt)
|
|
27805
28373
|
)
|
|
@@ -27826,6 +28394,10 @@ ${item.text}`
|
|
|
27826
28394
|
if (error48) {
|
|
27827
28395
|
throw error48;
|
|
27828
28396
|
}
|
|
28397
|
+
await this.publishFallbackSessionTitle(
|
|
28398
|
+
sessionState,
|
|
28399
|
+
this.createPromptFallbackTitle(params.prompt)
|
|
28400
|
+
);
|
|
27829
28401
|
return {
|
|
27830
28402
|
stopReason: "end_turn",
|
|
27831
28403
|
usage: this.buildPromptUsage(sessionState.lastTokenUsage),
|
|
@@ -27978,6 +28550,7 @@ var CommandExecutionApprovalRequest = new import_node2.RequestType("item/command
|
|
|
27978
28550
|
var FileChangeApprovalRequest = new import_node2.RequestType("item/fileChange/requestApproval");
|
|
27979
28551
|
var PermissionsApprovalRequest = new import_node2.RequestType("item/permissions/requestApproval");
|
|
27980
28552
|
var McpServerElicitationRequest = new import_node2.RequestType("mcpServer/elicitation/request");
|
|
28553
|
+
var ToolRequestUserInputRequest = new import_node2.RequestType("item/tool/requestUserInput");
|
|
27981
28554
|
var GOAL_RUNTIME_EFFECTS_GRACE_MS = 1e3;
|
|
27982
28555
|
var CodexAppServerClient = class {
|
|
27983
28556
|
connection;
|
|
@@ -28075,6 +28648,16 @@ var CodexAppServerClient = class {
|
|
|
28075
28648
|
}
|
|
28076
28649
|
return await handler.handleElicitation(params);
|
|
28077
28650
|
});
|
|
28651
|
+
this.connection.onRequest(ToolRequestUserInputRequest, async (params) => {
|
|
28652
|
+
if (this.isStaleTurn(params.threadId, params.turnId)) {
|
|
28653
|
+
return { answers: {} };
|
|
28654
|
+
}
|
|
28655
|
+
const handler = this.elicitationHandlers.get(params.threadId);
|
|
28656
|
+
if (!handler) {
|
|
28657
|
+
return { answers: {} };
|
|
28658
|
+
}
|
|
28659
|
+
return await handler.handleUserInput(params);
|
|
28660
|
+
});
|
|
28078
28661
|
}
|
|
28079
28662
|
onApprovalRequest(threadId, handler) {
|
|
28080
28663
|
this.approvalHandlers.set(threadId, handler);
|
|
@@ -28093,6 +28676,9 @@ var CodexAppServerClient = class {
|
|
|
28093
28676
|
async turnStart(params) {
|
|
28094
28677
|
return await this.sendRequest({ method: "turn/start", params });
|
|
28095
28678
|
}
|
|
28679
|
+
async turnSteer(params) {
|
|
28680
|
+
return await this.sendRequest({ method: "turn/steer", params });
|
|
28681
|
+
}
|
|
28096
28682
|
async runTurn(params, onTurnStarted) {
|
|
28097
28683
|
const capturedCompletions = [];
|
|
28098
28684
|
const releaseCapture = this.captureTurnCompletions(params.threadId, (event) => {
|
|
@@ -28378,6 +28964,9 @@ var CodexAppServerClient = class {
|
|
|
28378
28964
|
async accountRead(params) {
|
|
28379
28965
|
return await this.sendRequest({ method: "account/read", params });
|
|
28380
28966
|
}
|
|
28967
|
+
async accountRateLimitsRead() {
|
|
28968
|
+
return await this.sendRequest({ method: "account/rateLimits/read", params: void 0 });
|
|
28969
|
+
}
|
|
28381
28970
|
//TODO create type-safe helper
|
|
28382
28971
|
async awaitTurnCompleted(threadId, turnId) {
|
|
28383
28972
|
return await new Promise((resolve) => {
|
|
@@ -28932,5 +29521,5 @@ function startAcpServer() {
|
|
|
28932
29521
|
codexAcpServer = null;
|
|
28933
29522
|
}
|
|
28934
29523
|
});
|
|
28935
|
-
}).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);
|
|
29524
|
+
}).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)).connect(acpJsonStream);
|
|
28936
29525
|
}
|