@alas-ide/codex-acp 2.5.0-alas.5 → 2.5.0-alas.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +680 -595
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -32121,6 +32121,17 @@ var CODEX_NETWORK_PERMISSION_TITLE = "Allow network access?";
|
|
|
32121
32121
|
var CODEX_FILE_CHANGE_PERMISSION_TITLE = "Make edits?";
|
|
32122
32122
|
var CODEX_ADDITIONAL_PERMISSIONS_TITLE = "Grant permissions?";
|
|
32123
32123
|
var PERMISSION_PROMPT_META_KEY = "permission_prompt";
|
|
32124
|
+
var NEUTRAL_PERMISSION_PRESENTATION_META_KEY = "permissionPresentation";
|
|
32125
|
+
var NEUTRAL_QUESTION_CUSTOM_ANSWER_META_KEY = "questionCustomAnswer";
|
|
32126
|
+
function neutralPresentationCapability() {
|
|
32127
|
+
return { version: 1 };
|
|
32128
|
+
}
|
|
32129
|
+
function clientRequestsNeutralPresentation(capabilities, key) {
|
|
32130
|
+
const declared = capabilities?._meta?.[key];
|
|
32131
|
+
if (declared === null || typeof declared !== "object" || Array.isArray(declared)) return false;
|
|
32132
|
+
const version2 = declared["version"];
|
|
32133
|
+
return typeof version2 === "number" && Number.isInteger(version2) && version2 >= 1;
|
|
32134
|
+
}
|
|
32124
32135
|
function requestPermissionMeta(capabilities, title, reason) {
|
|
32125
32136
|
const description = nonBlank(reason);
|
|
32126
32137
|
const permission = {
|
|
@@ -32130,6 +32141,7 @@ function requestPermissionMeta(capabilities, title, reason) {
|
|
|
32130
32141
|
};
|
|
32131
32142
|
const meta3 = {
|
|
32132
32143
|
...airOnlyMeta(capabilities.airClient, AIR_PERMISSION_KEY, permission),
|
|
32144
|
+
...capabilities.neutralPermissionPresentation ? { [NEUTRAL_PERMISSION_PRESENTATION_META_KEY]: permission } : {},
|
|
32133
32145
|
...capabilities.permissionPromptFields ? { [PERMISSION_PROMPT_META_KEY]: permission } : {}
|
|
32134
32146
|
};
|
|
32135
32147
|
return Object.keys(meta3).length > 0 ? { _meta: meta3 } : {};
|
|
@@ -32141,11 +32153,15 @@ function readPermissionMeta(meta3) {
|
|
|
32141
32153
|
if (typeof title !== "string") return void 0;
|
|
32142
32154
|
return { version: 1, title, ...typeof description === "string" ? { description } : {} };
|
|
32143
32155
|
}
|
|
32144
|
-
function optionPermissionMeta(
|
|
32156
|
+
function optionPermissionMeta(capabilities, description) {
|
|
32145
32157
|
const normalized = nonBlank(description);
|
|
32146
32158
|
if (!normalized) return void 0;
|
|
32147
32159
|
const permission = { version: 1, description: normalized };
|
|
32148
|
-
|
|
32160
|
+
const meta3 = {
|
|
32161
|
+
...airOnlyMeta(capabilities.airClient, AIR_PERMISSION_KEY, permission),
|
|
32162
|
+
...capabilities.neutralPermissionPresentation ? { [NEUTRAL_PERMISSION_PRESENTATION_META_KEY]: permission } : {}
|
|
32163
|
+
};
|
|
32164
|
+
return Object.keys(meta3).length > 0 ? meta3 : void 0;
|
|
32149
32165
|
}
|
|
32150
32166
|
function nonBlank(value) {
|
|
32151
32167
|
const normalized = value?.trim();
|
|
@@ -34722,195 +34738,553 @@ var NeutralSessionFailureLedger = class {
|
|
|
34722
34738
|
}
|
|
34723
34739
|
};
|
|
34724
34740
|
|
|
34725
|
-
// src/
|
|
34726
|
-
|
|
34727
|
-
|
|
34728
|
-
|
|
34729
|
-
|
|
34730
|
-
|
|
34731
|
-
|
|
34732
|
-
|
|
34733
|
-
|
|
34734
|
-
|
|
34735
|
-
|
|
34736
|
-
|
|
34737
|
-
|
|
34738
|
-
|
|
34739
|
-
|
|
34740
|
-
|
|
34741
|
-
|
|
34742
|
-
|
|
34743
|
-
airToolCallContract;
|
|
34744
|
-
/** The client is AIR or declares `_meta.goal`. */
|
|
34745
|
-
goal;
|
|
34746
|
-
/** AIR declares its versioned asyncTasks capability; other clients opt in with literal true. */
|
|
34747
|
-
asyncTasks;
|
|
34748
|
-
/** The client declares `_meta.terminal_output`, the Zed convention for command output chunks. */
|
|
34749
|
-
terminalOutput;
|
|
34750
|
-
/** The client declares `_meta.terminal_output_delta` and appends the output chunks. */
|
|
34751
|
-
terminalOutputDelta;
|
|
34752
|
-
/** The client shows `plan_update`. Other clients get the plan as agent message text. */
|
|
34753
|
-
planUpdates;
|
|
34754
|
-
air;
|
|
34755
|
-
diffPatchFormat;
|
|
34756
|
-
sessionFailureFormat;
|
|
34757
|
-
/** A permission request has its own `title` and `description` (ACP v2). */
|
|
34758
|
-
permissionPromptFields;
|
|
34759
|
-
constructor(values) {
|
|
34760
|
-
this.airClient = values.airClient;
|
|
34761
|
-
this.airToolCallContract = values.airToolCallContract;
|
|
34762
|
-
this.goal = values.goal;
|
|
34763
|
-
this.asyncTasks = values.asyncTasks;
|
|
34764
|
-
this.terminalOutput = values.terminalOutput;
|
|
34765
|
-
this.terminalOutputDelta = values.terminalOutputDelta;
|
|
34766
|
-
this.planUpdates = values.planUpdates;
|
|
34767
|
-
this.air = values.air;
|
|
34768
|
-
this.diffPatchFormat = values.diffPatchFormat;
|
|
34769
|
-
this.sessionFailureFormat = values.sessionFailureFormat;
|
|
34770
|
-
this.permissionPromptFields = values.permissionPromptFields;
|
|
34771
|
-
}
|
|
34772
|
-
static from(capabilities) {
|
|
34773
|
-
const airClient = isAirClient(capabilities);
|
|
34774
|
-
const diffPatch = clientSupportsAirCapability(capabilities, AIR_DIFF_PATCH_KEY);
|
|
34775
|
-
const goal = capabilities?._meta?.["goal"];
|
|
34776
|
-
return new _ClientCapabilities({
|
|
34777
|
-
airClient,
|
|
34778
|
-
airToolCallContract: airClient,
|
|
34779
|
-
goal: airClient || goal !== null && typeof goal === "object" && !Array.isArray(goal),
|
|
34780
|
-
asyncTasks: airClient ? clientSupportsAirCapability(capabilities, AIR_ASYNC_TASKS_KEY) : capabilities?._meta?.["async-tasks"] === true,
|
|
34781
|
-
terminalOutput: capabilities?._meta?.["terminal_output"] === true,
|
|
34782
|
-
terminalOutputDelta: capabilities?._meta?.["terminal_output_delta"] === true,
|
|
34783
|
-
planUpdates: capabilities?.plan != null,
|
|
34784
|
-
air: {
|
|
34785
|
-
rawInputRendering: clientSupportsAirCapability(capabilities, AIR_RAW_INPUT_RENDERING_KEY),
|
|
34786
|
-
planContentDelta: clientSupportsAirCapability(capabilities, AIR_PLAN_CONTENT_DELTA_KEY),
|
|
34787
|
-
diffPatch
|
|
34788
|
-
},
|
|
34789
|
-
// A client that declares both forms gets only the client-neutral one.
|
|
34790
|
-
diffPatchFormat: clientRequestsNeutralDiffPatch(capabilities) ? "neutral" : diffPatch ? "air" : "none",
|
|
34791
|
-
// Likewise, and the client-neutral form selects the whole typed failure lane.
|
|
34792
|
-
sessionFailureFormat: clientRequestsNeutralSessionFailure(capabilities) ? "neutral" : clientSupportsAirCapability(capabilities, AIR_SESSION_FAILURE_KEY) ? "air" : "none",
|
|
34793
|
-
permissionPromptFields: false
|
|
34794
|
-
});
|
|
34795
|
-
}
|
|
34796
|
-
/**
|
|
34797
|
-
* The capabilities of an ACP v2 client, from the v1 view of its capabilities (`toV1ClientCapabilitiesView`).
|
|
34798
|
-
*
|
|
34799
|
-
* Every v2 client gets the standard tool call reports, also AIR: v2 has its own terminal and diff updates.
|
|
34800
|
-
* A shell command streams its output into its terminal. A read, search or list command has no terminal,
|
|
34801
|
-
* so its output goes to `content` at the end. A diff carries a Git patch. A permission request has its own title.
|
|
34802
|
-
* Plan updates need no capability on v2.
|
|
34803
|
-
*/
|
|
34804
|
-
static fromV2(capabilities) {
|
|
34805
|
-
return new _ClientCapabilities({
|
|
34806
|
-
airClient: isAirClient(capabilities),
|
|
34807
|
-
airToolCallContract: false,
|
|
34808
|
-
goal: isAirClient(capabilities),
|
|
34809
|
-
asyncTasks: clientSupportsAirCapability(capabilities, AIR_ASYNC_TASKS_KEY),
|
|
34810
|
-
terminalOutput: true,
|
|
34811
|
-
terminalOutputDelta: false,
|
|
34812
|
-
planUpdates: true,
|
|
34813
|
-
air: { rawInputRendering: false, planContentDelta: false, diffPatch: false },
|
|
34814
|
-
diffPatchFormat: "acpV2",
|
|
34815
|
-
// ACP v2 has its own terminal failure state, so it ignores the client-neutral opt-in.
|
|
34816
|
-
sessionFailureFormat: clientSupportsAirCapability(capabilities, AIR_SESSION_FAILURE_KEY) ? "air" : "none",
|
|
34817
|
-
permissionPromptFields: true
|
|
34818
|
-
});
|
|
34819
|
-
}
|
|
34820
|
-
/**
|
|
34821
|
-
* The key of the output chunks of a command, or `null` when the client has no chunk channel for it.
|
|
34822
|
-
* A client that declares `terminal_output_delta` gets appends for every command.
|
|
34823
|
-
* A client that declares `terminal_output` (Zed) gets `terminal_output` for a command that shows a terminal,
|
|
34824
|
-
* and no chunks for a read, search or list command.
|
|
34825
|
-
* Every other client that is not AIR gets `terminal_output_delta`, as before the tool call contract.
|
|
34826
|
-
* AIR without either capability gets no chunks.
|
|
34827
|
-
* A command sends its output once: as chunks when the key is not `null`, and in `rawOutput` otherwise.
|
|
34828
|
-
*/
|
|
34829
|
-
terminalOutputKey(terminal) {
|
|
34830
|
-
if (this.terminalOutputDelta) return "terminal_output_delta";
|
|
34831
|
-
if (this.terminalOutput) return terminal ? "terminal_output" : null;
|
|
34832
|
-
return this.airToolCallContract ? null : "terminal_output_delta";
|
|
34833
|
-
}
|
|
34834
|
-
};
|
|
34835
|
-
|
|
34836
|
-
// src/ServiceErrorMessage.ts
|
|
34837
|
-
var SERVICE_ERROR_TYPES = /* @__PURE__ */ new Set([
|
|
34838
|
-
"invalid_request_error",
|
|
34839
|
-
"server_error",
|
|
34840
|
-
"rate_limit_error",
|
|
34841
|
-
"insufficient_quota",
|
|
34842
|
-
"authentication_error",
|
|
34843
|
-
"permission_error",
|
|
34844
|
-
"not_found_error",
|
|
34845
|
-
"conflict_error",
|
|
34846
|
-
"overloaded_error"
|
|
34847
|
-
]);
|
|
34848
|
-
var INVALID_ENCRYPTED_CONTENT_CODE = "invalid_encrypted_content";
|
|
34849
|
-
var INVALID_ENCRYPTED_CONTENT_MESSAGE = "The current provider can't read this thread's earlier reasoning, which another provider or account encrypted. This happens after the provider changes in a thread. Switch back to the previous provider or start a new thread.";
|
|
34850
|
-
function workspaceRoutingUnavailableMessage(text) {
|
|
34851
|
-
return `Codex can't reach chatgpt.com to look up your ChatGPT workspace. Check your network connection and any proxy, VPN, or firewall that blocks chatgpt.com, then try again. (${text})`;
|
|
34741
|
+
// src/AgentFileChangeReport.ts
|
|
34742
|
+
import fs2 from "node:fs";
|
|
34743
|
+
import path5 from "node:path";
|
|
34744
|
+
var AGENT_FILE_CHANGE_REPORT_VERSION = 1;
|
|
34745
|
+
var AGENT_FILE_CHANGE_REPORT_MAX_PATHS = 1024;
|
|
34746
|
+
var AGENT_FILE_CHANGE_REPORT_MAX_PATH_LENGTH = 4096;
|
|
34747
|
+
var AGENT_FILE_CHANGE_REPORT_MAX_TOTAL_BYTES = 256 * 1024;
|
|
34748
|
+
var AGENT_FILE_CHANGE_REPORT_MAX_DIFF_BYTES = 8 * 1024 * 1024;
|
|
34749
|
+
var NEUTRAL_AGENT_FILE_CHANGE_REPORT_META_KEY = "agentFileChangeReport";
|
|
34750
|
+
var NEUTRAL_AGENT_FILE_CHANGE_REPORT_REQUEST_META_KEY = "agentFileChangeReportRequest";
|
|
34751
|
+
var TURN_DIFF_UNCERTAINTY = "Codex turn diffs may omit same-content renames and changes made outside apply_patch, including shell commands, version-control commands, generators, and child processes.";
|
|
34752
|
+
function captureAgentFileChangeWorkspace(cwd, additionalDirectories) {
|
|
34753
|
+
const lexicalCwd = parseWorkspaceRoot(cwd);
|
|
34754
|
+
return {
|
|
34755
|
+
cwd,
|
|
34756
|
+
additionalDirectories: [...additionalDirectories],
|
|
34757
|
+
diffRoot: lexicalCwd === null ? cwd : findDiffDisplayRoot(lexicalCwd).value
|
|
34758
|
+
};
|
|
34852
34759
|
}
|
|
34853
|
-
function
|
|
34854
|
-
|
|
34855
|
-
const value = parseJson(text);
|
|
34856
|
-
if (value === void 0) return text;
|
|
34857
|
-
if (isInvalidEncryptedContentError(value)) return INVALID_ENCRYPTED_CONTENT_MESSAGE;
|
|
34858
|
-
if (!isObject2(value) || Object.keys(value).some((key) => !["type", "status", "error"].includes(key)) || value["type"] !== "error" || typeof value["status"] !== "number" || !Number.isInteger(value["status"]) || value["status"] < 400 || value["status"] > 599 || !isObject2(value["error"])) return text;
|
|
34859
|
-
const error62 = value["error"];
|
|
34860
|
-
if (Object.keys(error62).some((key) => !["type", "message", "code", "param"].includes(key)) || typeof error62["type"] !== "string" || !SERVICE_ERROR_TYPES.has(error62["type"]) || typeof error62["message"] !== "string" || error62["message"].trim().length === 0 || ["code", "param"].some((key) => key in error62 && error62[key] !== null && typeof error62[key] !== "string")) return text;
|
|
34861
|
-
return error62["message"];
|
|
34760
|
+
function neutralAgentFileChangeReportCapability() {
|
|
34761
|
+
return { version: AGENT_FILE_CHANGE_REPORT_VERSION };
|
|
34862
34762
|
}
|
|
34863
|
-
function
|
|
34864
|
-
|
|
34865
|
-
const
|
|
34866
|
-
|
|
34867
|
-
const metadata = error62["metadata"];
|
|
34868
|
-
if (!isObject2(metadata)) return false;
|
|
34869
|
-
return metadata["provider_error_code"] === INVALID_ENCRYPTED_CONTENT_CODE || typeof metadata["raw"] === "string" && isInvalidEncryptedContentError(parseJson(metadata["raw"]));
|
|
34763
|
+
function clientRequestsNeutralAgentFileChangeReport(capabilities) {
|
|
34764
|
+
const declared = asRecord2(capabilities?._meta?.[NEUTRAL_AGENT_FILE_CHANGE_REPORT_META_KEY]);
|
|
34765
|
+
const version2 = declared?.["version"];
|
|
34766
|
+
return typeof version2 === "number" && Number.isInteger(version2) && version2 >= 1;
|
|
34870
34767
|
}
|
|
34871
|
-
function
|
|
34872
|
-
|
|
34873
|
-
|
|
34874
|
-
|
|
34875
|
-
|
|
34768
|
+
function parseAgentFileChangeReportRequest(meta3) {
|
|
34769
|
+
const jetbrains = asRecord2(meta3?.[JETBRAINS_META_KEY]);
|
|
34770
|
+
const air = asRecord2(jetbrains?.[AIR_META_KEY]);
|
|
34771
|
+
return validateAgentFileChangeReportRequest(air?.[AIR_AGENT_FILE_CHANGE_REPORT_REQUEST_KEY]);
|
|
34772
|
+
}
|
|
34773
|
+
function parseNeutralAgentFileChangeReportRequest(meta3) {
|
|
34774
|
+
return validateAgentFileChangeReportRequest(meta3?.[NEUTRAL_AGENT_FILE_CHANGE_REPORT_REQUEST_META_KEY]);
|
|
34775
|
+
}
|
|
34776
|
+
function agentFileChangeReportRequestFor(format, meta3) {
|
|
34777
|
+
switch (format) {
|
|
34778
|
+
case "none":
|
|
34779
|
+
return null;
|
|
34780
|
+
case "air":
|
|
34781
|
+
return parseAgentFileChangeReportRequest(meta3);
|
|
34782
|
+
case "neutral":
|
|
34783
|
+
return parseNeutralAgentFileChangeReportRequest(meta3);
|
|
34876
34784
|
}
|
|
34877
34785
|
}
|
|
34878
|
-
function
|
|
34879
|
-
|
|
34786
|
+
function agentFileChangeReportMeta(format, report) {
|
|
34787
|
+
if (format === "neutral") {
|
|
34788
|
+
return { [NEUTRAL_AGENT_FILE_CHANGE_REPORT_META_KEY]: report };
|
|
34789
|
+
}
|
|
34790
|
+
return {
|
|
34791
|
+
[JETBRAINS_META_KEY]: {
|
|
34792
|
+
[AIR_META_KEY]: {
|
|
34793
|
+
[AIR_EXTENSION_VERSION_KEY]: AIR_EXTENSION_VERSION,
|
|
34794
|
+
[AIR_AGENT_FILE_CHANGE_REPORT_KEY]: report
|
|
34795
|
+
}
|
|
34796
|
+
}
|
|
34797
|
+
};
|
|
34880
34798
|
}
|
|
34881
|
-
|
|
34882
|
-
|
|
34883
|
-
|
|
34884
|
-
|
|
34885
|
-
|
|
34799
|
+
function validateAgentFileChangeReportRequest(value) {
|
|
34800
|
+
const request = asRecord2(value);
|
|
34801
|
+
if (request === null || !hasOnlyKeys(request, ["version", "requestId"]) || request["version"] !== AGENT_FILE_CHANGE_REPORT_VERSION) {
|
|
34802
|
+
return null;
|
|
34803
|
+
}
|
|
34804
|
+
const requestId = request["requestId"];
|
|
34805
|
+
if (typeof requestId !== "string" || !/^[A-Za-z0-9._:-]{1,128}$/.test(requestId)) {
|
|
34806
|
+
return null;
|
|
34807
|
+
}
|
|
34808
|
+
return { version: AGENT_FILE_CHANGE_REPORT_VERSION, requestId };
|
|
34886
34809
|
}
|
|
34887
|
-
function
|
|
34888
|
-
if (
|
|
34889
|
-
|
|
34810
|
+
function createReportedAgentFileChangeReport(requestId, diff, workspace) {
|
|
34811
|
+
if (Buffer.byteLength(diff, "utf8") > AGENT_FILE_CHANGE_REPORT_MAX_DIFF_BYTES) {
|
|
34812
|
+
throw new AgentFileChangeReportError("invalidOutput", "The turn diff exceeds the parser input limit");
|
|
34890
34813
|
}
|
|
34891
|
-
const
|
|
34892
|
-
|
|
34893
|
-
return
|
|
34814
|
+
const parsedReport = parseTurnDiff(diff);
|
|
34815
|
+
const normalized = normalizeFileChangeReport(parsedReport, workspace);
|
|
34816
|
+
return fitReportedAgentFileChangeReport({
|
|
34817
|
+
version: AGENT_FILE_CHANGE_REPORT_VERSION,
|
|
34818
|
+
requestId,
|
|
34819
|
+
status: "reported",
|
|
34820
|
+
...normalized
|
|
34821
|
+
});
|
|
34894
34822
|
}
|
|
34895
|
-
|
|
34896
|
-
|
|
34897
|
-
|
|
34898
|
-
|
|
34823
|
+
function createUnavailableAgentFileChangeReport(requestId, reason) {
|
|
34824
|
+
return {
|
|
34825
|
+
version: AGENT_FILE_CHANGE_REPORT_VERSION,
|
|
34826
|
+
requestId,
|
|
34827
|
+
status: "unavailable",
|
|
34828
|
+
reason
|
|
34829
|
+
};
|
|
34830
|
+
}
|
|
34831
|
+
var AgentFileChangeReportError = class extends Error {
|
|
34832
|
+
reason;
|
|
34833
|
+
constructor(reason, message) {
|
|
34834
|
+
super(message);
|
|
34835
|
+
this.name = "AgentFileChangeReportError";
|
|
34836
|
+
this.reason = reason;
|
|
34899
34837
|
}
|
|
34900
34838
|
};
|
|
34901
|
-
|
|
34902
|
-
|
|
34903
|
-
|
|
34904
|
-
this.name = "ThreadRefusedError";
|
|
34839
|
+
function parseTurnDiff(diff) {
|
|
34840
|
+
if (diff.trim() === "") {
|
|
34841
|
+
return { paths: [], complete: false, uncertainty: TURN_DIFF_UNCERTAINTY };
|
|
34905
34842
|
}
|
|
34906
|
-
|
|
34907
|
-
|
|
34908
|
-
|
|
34909
|
-
|
|
34910
|
-
|
|
34911
|
-
|
|
34843
|
+
let patches;
|
|
34844
|
+
try {
|
|
34845
|
+
patches = parsePatch(diff);
|
|
34846
|
+
} catch (error62) {
|
|
34847
|
+
throw new AgentFileChangeReportError(
|
|
34848
|
+
"invalidOutput",
|
|
34849
|
+
`The turn diff is not valid unified diff: ${error62 instanceof Error ? error62.message : String(error62)}`
|
|
34912
34850
|
);
|
|
34913
|
-
|
|
34851
|
+
}
|
|
34852
|
+
if (patches.length === 0) {
|
|
34853
|
+
throw new AgentFileChangeReportError("invalidOutput", "The turn diff contains no parseable file patches");
|
|
34854
|
+
}
|
|
34855
|
+
const rawFileHeaders = extractRawFileHeaders(diff);
|
|
34856
|
+
const paths = [];
|
|
34857
|
+
for (const [index, patch] of patches.entries()) {
|
|
34858
|
+
const rawHeaders = rawFileHeaders[index];
|
|
34859
|
+
const oldPath = normalizeDiffPath(selectLosslessFileName(rawHeaders?.oldFileName, patch.oldFileName));
|
|
34860
|
+
const newPath = normalizeDiffPath(selectLosslessFileName(rawHeaders?.newFileName, patch.newFileName));
|
|
34861
|
+
if (oldPath === null && newPath === null) {
|
|
34862
|
+
throw new AgentFileChangeReportError("invalidOutput", "The turn diff contains a patch without a file path");
|
|
34863
|
+
}
|
|
34864
|
+
if (oldPath !== null) paths.push(oldPath);
|
|
34865
|
+
if (newPath !== null) paths.push(newPath);
|
|
34866
|
+
}
|
|
34867
|
+
return { paths, complete: false, uncertainty: TURN_DIFF_UNCERTAINTY };
|
|
34868
|
+
}
|
|
34869
|
+
function extractRawFileHeaders(diff) {
|
|
34870
|
+
return diff.split(/(?=^diff --git )/m).filter((section) => section.trim() !== "").map((section) => {
|
|
34871
|
+
const lines = section.split(/\r?\n/);
|
|
34872
|
+
for (let index = 0; index < lines.length; index += 1) {
|
|
34873
|
+
const line = lines[index];
|
|
34874
|
+
if (line?.startsWith("@@ ")) return null;
|
|
34875
|
+
const nextLine = lines[index + 1];
|
|
34876
|
+
if (line?.startsWith("--- ") && nextLine?.startsWith("+++ ")) {
|
|
34877
|
+
return {
|
|
34878
|
+
oldFileName: line.slice(4),
|
|
34879
|
+
newFileName: nextLine.slice(4)
|
|
34880
|
+
};
|
|
34881
|
+
}
|
|
34882
|
+
}
|
|
34883
|
+
return null;
|
|
34884
|
+
});
|
|
34885
|
+
}
|
|
34886
|
+
function selectLosslessFileName(rawFileName, parsedFileName) {
|
|
34887
|
+
return rawFileName === void 0 || rawFileName.startsWith('"') ? parsedFileName : rawFileName;
|
|
34888
|
+
}
|
|
34889
|
+
function normalizeDiffPath(value) {
|
|
34890
|
+
if (value === void 0 || value === "/dev/null") return null;
|
|
34891
|
+
return value.startsWith("a/") || value.startsWith("b/") ? value.slice(2) : value;
|
|
34892
|
+
}
|
|
34893
|
+
function fitReportedAgentFileChangeReport(report) {
|
|
34894
|
+
const paths = [...report.paths];
|
|
34895
|
+
let truncated = report.truncated;
|
|
34896
|
+
let fitted = report;
|
|
34897
|
+
while (Buffer.byteLength(JSON.stringify(fitted), "utf8") > AGENT_FILE_CHANGE_REPORT_MAX_TOTAL_BYTES) {
|
|
34898
|
+
if (paths.length === 0) {
|
|
34899
|
+
throw new AgentFileChangeReportError("invalidOutput", "The audit report exceeds the wire limit");
|
|
34900
|
+
}
|
|
34901
|
+
paths.pop();
|
|
34902
|
+
truncated = true;
|
|
34903
|
+
fitted = {
|
|
34904
|
+
...report,
|
|
34905
|
+
paths: [...paths],
|
|
34906
|
+
declaredComplete: false,
|
|
34907
|
+
truncated
|
|
34908
|
+
};
|
|
34909
|
+
}
|
|
34910
|
+
return fitted;
|
|
34911
|
+
}
|
|
34912
|
+
function normalizeFileChangeReport(report, workspace) {
|
|
34913
|
+
const lexicalCwd = parseWorkspaceRoot(workspace.cwd);
|
|
34914
|
+
if (lexicalCwd === null) {
|
|
34915
|
+
throw new AgentFileChangeReportError("providerError", "The session working directory is not absolute");
|
|
34916
|
+
}
|
|
34917
|
+
const cwd = canonicalizeWorkspaceRoot(lexicalCwd);
|
|
34918
|
+
const diffRoot = parseWorkspaceRoot(workspace.diffRoot);
|
|
34919
|
+
if (diffRoot === null || diffRoot.flavor !== cwd.flavor) {
|
|
34920
|
+
throw new AgentFileChangeReportError("providerError", "The captured turn-diff root is invalid");
|
|
34921
|
+
}
|
|
34922
|
+
const roots = [cwd, ...workspace.additionalDirectories.flatMap((directory) => {
|
|
34923
|
+
const root = normalizeWorkspaceRoot(directory);
|
|
34924
|
+
return root === null || root.flavor !== cwd.flavor ? [] : [root];
|
|
34925
|
+
})];
|
|
34926
|
+
const paths = [];
|
|
34927
|
+
const seen = /* @__PURE__ */ new Set();
|
|
34928
|
+
let totalBytes = 0;
|
|
34929
|
+
let truncated = false;
|
|
34930
|
+
for (const reportedPath of report.paths) {
|
|
34931
|
+
if (reportedPath.length > AGENT_FILE_CHANGE_REPORT_MAX_PATH_LENGTH) {
|
|
34932
|
+
truncated = true;
|
|
34933
|
+
continue;
|
|
34934
|
+
}
|
|
34935
|
+
const normalized = normalizeReportedPath(reportedPath, diffRoot, roots);
|
|
34936
|
+
if (normalized === null || normalized.value.length > AGENT_FILE_CHANGE_REPORT_MAX_PATH_LENGTH) {
|
|
34937
|
+
truncated = true;
|
|
34938
|
+
continue;
|
|
34939
|
+
}
|
|
34940
|
+
const key = normalized.flavor === "windows" ? normalized.value.toLowerCase() : normalized.value;
|
|
34941
|
+
if (seen.has(key)) {
|
|
34942
|
+
continue;
|
|
34943
|
+
}
|
|
34944
|
+
const bytes = Buffer.byteLength(normalized.value, "utf8");
|
|
34945
|
+
if (paths.length >= AGENT_FILE_CHANGE_REPORT_MAX_PATHS || totalBytes + bytes > AGENT_FILE_CHANGE_REPORT_MAX_TOTAL_BYTES) {
|
|
34946
|
+
truncated = true;
|
|
34947
|
+
continue;
|
|
34948
|
+
}
|
|
34949
|
+
seen.add(key);
|
|
34950
|
+
paths.push(normalized.value);
|
|
34951
|
+
totalBytes += bytes;
|
|
34952
|
+
}
|
|
34953
|
+
return {
|
|
34954
|
+
paths,
|
|
34955
|
+
declaredComplete: report.complete && !truncated,
|
|
34956
|
+
truncated,
|
|
34957
|
+
...report.uncertainty ? { uncertainty: report.uncertainty } : {}
|
|
34958
|
+
};
|
|
34959
|
+
}
|
|
34960
|
+
function normalizeWorkspaceRoot(value) {
|
|
34961
|
+
const root = parseWorkspaceRoot(value);
|
|
34962
|
+
return root === null ? null : canonicalizeWorkspaceRoot(root);
|
|
34963
|
+
}
|
|
34964
|
+
function parseWorkspaceRoot(value) {
|
|
34965
|
+
const trimmed = value.trim();
|
|
34966
|
+
if (!isValidPathText(trimmed)) {
|
|
34967
|
+
return null;
|
|
34968
|
+
}
|
|
34969
|
+
if (isWindowsAbsolutePath(trimmed)) {
|
|
34970
|
+
return {
|
|
34971
|
+
value: path5.win32.normalize(trimmed.replace(/\//g, "\\")),
|
|
34972
|
+
flavor: "windows"
|
|
34973
|
+
};
|
|
34974
|
+
}
|
|
34975
|
+
if (path5.posix.isAbsolute(trimmed)) {
|
|
34976
|
+
return {
|
|
34977
|
+
value: path5.posix.normalize(trimmed.replace(/\\/g, "/")),
|
|
34978
|
+
flavor: "posix"
|
|
34979
|
+
};
|
|
34980
|
+
}
|
|
34981
|
+
return null;
|
|
34982
|
+
}
|
|
34983
|
+
function normalizeReportedPath(value, relativeRoot, roots) {
|
|
34984
|
+
if (!isValidPathText(value) || /^[A-Za-z]:[^\\/]/.test(value) || /^\\\\[?.]\\/.test(value) || /^(?:\\\\|\/\/)/.test(value) && !isWindowsAbsolutePath(value) || relativeRoot.flavor === "windows" && /^\\(?!\\)/.test(value) || /^[A-Za-z][A-Za-z0-9+.-]*:\/\//.test(value)) {
|
|
34985
|
+
return null;
|
|
34986
|
+
}
|
|
34987
|
+
let candidate;
|
|
34988
|
+
if (isWindowsAbsolutePath(value)) {
|
|
34989
|
+
candidate = { value: path5.win32.normalize(value.replace(/\//g, "\\")), flavor: "windows" };
|
|
34990
|
+
} else if (path5.posix.isAbsolute(value)) {
|
|
34991
|
+
candidate = { value: path5.posix.normalize(value.replace(/\\/g, "/")), flavor: "posix" };
|
|
34992
|
+
} else if (relativeRoot.flavor === "windows") {
|
|
34993
|
+
candidate = {
|
|
34994
|
+
value: path5.win32.resolve(relativeRoot.value, value.replace(/\//g, "\\")),
|
|
34995
|
+
flavor: "windows"
|
|
34996
|
+
};
|
|
34997
|
+
} else {
|
|
34998
|
+
candidate = {
|
|
34999
|
+
value: path5.posix.resolve(relativeRoot.value, value.replace(/\\/g, "/")),
|
|
35000
|
+
flavor: "posix"
|
|
35001
|
+
};
|
|
35002
|
+
}
|
|
35003
|
+
candidate = canonicalizeReportedPath(candidate);
|
|
35004
|
+
return roots.some((root) => pathIsStrictlyInside(root, candidate)) ? candidate : null;
|
|
35005
|
+
}
|
|
35006
|
+
function findDiffDisplayRoot(cwd) {
|
|
35007
|
+
if (!isNativePathFlavor(cwd.flavor)) return cwd;
|
|
35008
|
+
const pathImplementation = cwd.flavor === "windows" ? path5.win32 : path5.posix;
|
|
35009
|
+
let current = cwd.value;
|
|
35010
|
+
while (true) {
|
|
35011
|
+
if (fs2.existsSync(pathImplementation.join(current, ".git"))) {
|
|
35012
|
+
return canonicalizeWorkspaceRoot({ value: current, flavor: cwd.flavor });
|
|
35013
|
+
}
|
|
35014
|
+
const parent = pathImplementation.dirname(current);
|
|
35015
|
+
if (parent === current) return cwd;
|
|
35016
|
+
current = parent;
|
|
35017
|
+
}
|
|
35018
|
+
}
|
|
35019
|
+
function canonicalizeWorkspaceRoot(root) {
|
|
35020
|
+
if (!isNativePathFlavor(root.flavor)) {
|
|
35021
|
+
return root;
|
|
35022
|
+
}
|
|
35023
|
+
return { ...root, value: canonicalizeFromExistingAncestor(root.value) };
|
|
35024
|
+
}
|
|
35025
|
+
function canonicalizeReportedPath(candidate) {
|
|
35026
|
+
if (!isNativePathFlavor(candidate.flavor)) {
|
|
35027
|
+
return candidate;
|
|
35028
|
+
}
|
|
35029
|
+
const parent = canonicalizeFromExistingAncestor(path5.dirname(candidate.value));
|
|
35030
|
+
return { ...candidate, value: path5.resolve(parent, path5.basename(candidate.value)) };
|
|
35031
|
+
}
|
|
35032
|
+
function canonicalizeFromExistingAncestor(value) {
|
|
35033
|
+
const original = path5.resolve(value);
|
|
35034
|
+
let current = original;
|
|
35035
|
+
const missingSegments = [];
|
|
35036
|
+
while (true) {
|
|
35037
|
+
try {
|
|
35038
|
+
const canonical = fs2.realpathSync.native(current);
|
|
35039
|
+
return path5.resolve(canonical, ...missingSegments.reverse());
|
|
35040
|
+
} catch (error62) {
|
|
35041
|
+
if (!isMissingPathError(error62)) return original;
|
|
35042
|
+
}
|
|
35043
|
+
const parent = path5.dirname(current);
|
|
35044
|
+
if (parent === current) return original;
|
|
35045
|
+
missingSegments.push(path5.basename(current));
|
|
35046
|
+
current = parent;
|
|
35047
|
+
}
|
|
35048
|
+
}
|
|
35049
|
+
function isMissingPathError(error62) {
|
|
35050
|
+
if (typeof error62 !== "object" || error62 === null || !("code" in error62)) return false;
|
|
35051
|
+
return error62.code === "ENOENT" || error62.code === "ENOTDIR";
|
|
35052
|
+
}
|
|
35053
|
+
function isNativePathFlavor(flavor) {
|
|
35054
|
+
return process.platform === "win32" ? flavor === "windows" : flavor === "posix";
|
|
35055
|
+
}
|
|
35056
|
+
function pathIsStrictlyInside(root, candidate) {
|
|
35057
|
+
if (root.flavor !== candidate.flavor) {
|
|
35058
|
+
return false;
|
|
35059
|
+
}
|
|
35060
|
+
const pathImplementation = root.flavor === "windows" ? path5.win32 : path5.posix;
|
|
35061
|
+
const relative = pathImplementation.relative(root.value, candidate.value);
|
|
35062
|
+
return relative.length > 0 && !pathImplementation.isAbsolute(relative) && relative !== ".." && !relative.startsWith(`..${pathImplementation.sep}`);
|
|
35063
|
+
}
|
|
35064
|
+
function isWindowsAbsolutePath(value) {
|
|
35065
|
+
const portable = value.replace(/\\/g, "/");
|
|
35066
|
+
return /^[A-Za-z]:\//.test(portable) || /^\/\/[^/]+\/[^/]+(?:\/|$)/.test(portable);
|
|
35067
|
+
}
|
|
35068
|
+
function isValidPathText(value) {
|
|
35069
|
+
return value.length > 0 && !/[\u0000-\u001F\u007F-\u009F]/.test(value);
|
|
35070
|
+
}
|
|
35071
|
+
function asRecord2(value) {
|
|
35072
|
+
return typeof value === "object" && value !== null && !Array.isArray(value) ? value : null;
|
|
35073
|
+
}
|
|
35074
|
+
function hasOnlyKeys(value, allowed) {
|
|
35075
|
+
const allowedKeys = new Set(allowed);
|
|
35076
|
+
return Object.keys(value).every((key) => allowedKeys.has(key));
|
|
35077
|
+
}
|
|
35078
|
+
|
|
35079
|
+
// src/tool-calls/ClientCapabilities.ts
|
|
35080
|
+
var ClientCapabilities = class _ClientCapabilities {
|
|
35081
|
+
static DEFAULT = new _ClientCapabilities({
|
|
35082
|
+
airClient: false,
|
|
35083
|
+
airToolCallContract: false,
|
|
35084
|
+
goal: false,
|
|
35085
|
+
asyncTasks: false,
|
|
35086
|
+
terminalOutput: false,
|
|
35087
|
+
terminalOutputDelta: false,
|
|
35088
|
+
planUpdates: false,
|
|
35089
|
+
air: { rawInputRendering: false, planContentDelta: false, diffPatch: false },
|
|
35090
|
+
diffPatchFormat: "none",
|
|
35091
|
+
sessionFailureFormat: "none",
|
|
35092
|
+
agentFileChangeReportFormat: "none",
|
|
35093
|
+
permissionPromptFields: false,
|
|
35094
|
+
neutralPermissionPresentation: false,
|
|
35095
|
+
neutralQuestionCustomAnswer: false
|
|
35096
|
+
});
|
|
35097
|
+
/** The client declares `_meta.jetbrains.air`. */
|
|
35098
|
+
airClient;
|
|
35099
|
+
/** The client gets the tool call reports of the AIR tool call contract. Only AIR on ACP v1 does. */
|
|
35100
|
+
airToolCallContract;
|
|
35101
|
+
/** The client is AIR or declares `_meta.goal`. */
|
|
35102
|
+
goal;
|
|
35103
|
+
/** AIR declares its versioned asyncTasks capability; other clients opt in with literal true. */
|
|
35104
|
+
asyncTasks;
|
|
35105
|
+
/** The client declares `_meta.terminal_output`, the Zed convention for command output chunks. */
|
|
35106
|
+
terminalOutput;
|
|
35107
|
+
/** The client declares `_meta.terminal_output_delta` and appends the output chunks. */
|
|
35108
|
+
terminalOutputDelta;
|
|
35109
|
+
/** The client shows `plan_update`. Other clients get the plan as agent message text. */
|
|
35110
|
+
planUpdates;
|
|
35111
|
+
air;
|
|
35112
|
+
diffPatchFormat;
|
|
35113
|
+
sessionFailureFormat;
|
|
35114
|
+
agentFileChangeReportFormat;
|
|
35115
|
+
/** A permission request has its own `title` and `description` (ACP v2). */
|
|
35116
|
+
permissionPromptFields;
|
|
35117
|
+
/** The client gets the permission presentation in `_meta.permissionPresentation`. Only ACP v1 reads the opt-in. */
|
|
35118
|
+
neutralPermissionPresentation;
|
|
35119
|
+
/** A question's note field carries `_meta.questionCustomAnswer`. Only ACP v1 reads the opt-in. */
|
|
35120
|
+
neutralQuestionCustomAnswer;
|
|
35121
|
+
constructor(values) {
|
|
35122
|
+
this.airClient = values.airClient;
|
|
35123
|
+
this.airToolCallContract = values.airToolCallContract;
|
|
35124
|
+
this.goal = values.goal;
|
|
35125
|
+
this.asyncTasks = values.asyncTasks;
|
|
35126
|
+
this.terminalOutput = values.terminalOutput;
|
|
35127
|
+
this.terminalOutputDelta = values.terminalOutputDelta;
|
|
35128
|
+
this.planUpdates = values.planUpdates;
|
|
35129
|
+
this.air = values.air;
|
|
35130
|
+
this.diffPatchFormat = values.diffPatchFormat;
|
|
35131
|
+
this.sessionFailureFormat = values.sessionFailureFormat;
|
|
35132
|
+
this.agentFileChangeReportFormat = values.agentFileChangeReportFormat;
|
|
35133
|
+
this.permissionPromptFields = values.permissionPromptFields;
|
|
35134
|
+
this.neutralPermissionPresentation = values.neutralPermissionPresentation;
|
|
35135
|
+
this.neutralQuestionCustomAnswer = values.neutralQuestionCustomAnswer;
|
|
35136
|
+
}
|
|
35137
|
+
static from(capabilities) {
|
|
35138
|
+
const airClient = isAirClient(capabilities);
|
|
35139
|
+
const diffPatch = clientSupportsAirCapability(capabilities, AIR_DIFF_PATCH_KEY);
|
|
35140
|
+
const goal = capabilities?._meta?.["goal"];
|
|
35141
|
+
return new _ClientCapabilities({
|
|
35142
|
+
airClient,
|
|
35143
|
+
airToolCallContract: airClient,
|
|
35144
|
+
goal: airClient || goal !== null && typeof goal === "object" && !Array.isArray(goal),
|
|
35145
|
+
asyncTasks: airClient ? clientSupportsAirCapability(capabilities, AIR_ASYNC_TASKS_KEY) : capabilities?._meta?.["async-tasks"] === true,
|
|
35146
|
+
terminalOutput: capabilities?._meta?.["terminal_output"] === true,
|
|
35147
|
+
terminalOutputDelta: capabilities?._meta?.["terminal_output_delta"] === true,
|
|
35148
|
+
planUpdates: capabilities?.plan != null,
|
|
35149
|
+
air: {
|
|
35150
|
+
rawInputRendering: clientSupportsAirCapability(capabilities, AIR_RAW_INPUT_RENDERING_KEY),
|
|
35151
|
+
planContentDelta: clientSupportsAirCapability(capabilities, AIR_PLAN_CONTENT_DELTA_KEY),
|
|
35152
|
+
diffPatch
|
|
35153
|
+
},
|
|
35154
|
+
// A client that declares both forms gets only the client-neutral one.
|
|
35155
|
+
diffPatchFormat: clientRequestsNeutralDiffPatch(capabilities) ? "neutral" : diffPatch ? "air" : "none",
|
|
35156
|
+
// Likewise, and the client-neutral form selects the whole typed failure lane.
|
|
35157
|
+
sessionFailureFormat: clientRequestsNeutralSessionFailure(capabilities) ? "neutral" : clientSupportsAirCapability(capabilities, AIR_SESSION_FAILURE_KEY) ? "air" : "none",
|
|
35158
|
+
// Likewise. The request and the report use the selected form.
|
|
35159
|
+
agentFileChangeReportFormat: clientRequestsNeutralAgentFileChangeReport(capabilities) ? "neutral" : clientSupportsAirCapability(capabilities, AIR_AGENT_FILE_CHANGE_REPORT_KEY) ? "air" : "none",
|
|
35160
|
+
permissionPromptFields: false,
|
|
35161
|
+
neutralPermissionPresentation: clientRequestsNeutralPresentation(capabilities, NEUTRAL_PERMISSION_PRESENTATION_META_KEY),
|
|
35162
|
+
neutralQuestionCustomAnswer: clientRequestsNeutralPresentation(capabilities, NEUTRAL_QUESTION_CUSTOM_ANSWER_META_KEY)
|
|
35163
|
+
});
|
|
35164
|
+
}
|
|
35165
|
+
/**
|
|
35166
|
+
* The capabilities of an ACP v2 client, from the v1 view of its capabilities (`toV1ClientCapabilitiesView`).
|
|
35167
|
+
*
|
|
35168
|
+
* Every v2 client gets the standard tool call reports, also AIR: v2 has its own terminal and diff updates.
|
|
35169
|
+
* A shell command streams its output into its terminal. A read, search or list command has no terminal,
|
|
35170
|
+
* so its output goes to `content` at the end. A diff carries a Git patch. A permission request has its own title.
|
|
35171
|
+
* Plan updates need no capability on v2.
|
|
35172
|
+
*/
|
|
35173
|
+
static fromV2(capabilities) {
|
|
35174
|
+
return new _ClientCapabilities({
|
|
35175
|
+
airClient: isAirClient(capabilities),
|
|
35176
|
+
airToolCallContract: false,
|
|
35177
|
+
goal: isAirClient(capabilities),
|
|
35178
|
+
asyncTasks: clientSupportsAirCapability(capabilities, AIR_ASYNC_TASKS_KEY),
|
|
35179
|
+
terminalOutput: true,
|
|
35180
|
+
terminalOutputDelta: false,
|
|
35181
|
+
planUpdates: true,
|
|
35182
|
+
air: { rawInputRendering: false, planContentDelta: false, diffPatch: false },
|
|
35183
|
+
diffPatchFormat: "acpV2",
|
|
35184
|
+
// ACP v2 has its own terminal failure state, so it ignores the client-neutral opt-in.
|
|
35185
|
+
sessionFailureFormat: clientSupportsAirCapability(capabilities, AIR_SESSION_FAILURE_KEY) ? "air" : "none",
|
|
35186
|
+
// The client-neutral report is an ACP v1 extension, so v2 ignores its opt-in.
|
|
35187
|
+
agentFileChangeReportFormat: clientSupportsAirCapability(capabilities, AIR_AGENT_FILE_CHANGE_REPORT_KEY) ? "air" : "none",
|
|
35188
|
+
permissionPromptFields: true,
|
|
35189
|
+
// A v2 request has its own title and description, so v2 ignores both client-neutral opt-ins.
|
|
35190
|
+
neutralPermissionPresentation: false,
|
|
35191
|
+
neutralQuestionCustomAnswer: false
|
|
35192
|
+
});
|
|
35193
|
+
}
|
|
35194
|
+
/**
|
|
35195
|
+
* The key of the output chunks of a command, or `null` when the client has no chunk channel for it.
|
|
35196
|
+
* A client that declares `terminal_output_delta` gets appends for every command.
|
|
35197
|
+
* A client that declares `terminal_output` (Zed) gets `terminal_output` for a command that shows a terminal,
|
|
35198
|
+
* and no chunks for a read, search or list command.
|
|
35199
|
+
* Every other client that is not AIR gets `terminal_output_delta`, as before the tool call contract.
|
|
35200
|
+
* AIR without either capability gets no chunks.
|
|
35201
|
+
* A command sends its output once: as chunks when the key is not `null`, and in `rawOutput` otherwise.
|
|
35202
|
+
*/
|
|
35203
|
+
terminalOutputKey(terminal) {
|
|
35204
|
+
if (this.terminalOutputDelta) return "terminal_output_delta";
|
|
35205
|
+
if (this.terminalOutput) return terminal ? "terminal_output" : null;
|
|
35206
|
+
return this.airToolCallContract ? null : "terminal_output_delta";
|
|
35207
|
+
}
|
|
35208
|
+
};
|
|
35209
|
+
|
|
35210
|
+
// src/ServiceErrorMessage.ts
|
|
35211
|
+
var SERVICE_ERROR_TYPES = /* @__PURE__ */ new Set([
|
|
35212
|
+
"invalid_request_error",
|
|
35213
|
+
"server_error",
|
|
35214
|
+
"rate_limit_error",
|
|
35215
|
+
"insufficient_quota",
|
|
35216
|
+
"authentication_error",
|
|
35217
|
+
"permission_error",
|
|
35218
|
+
"not_found_error",
|
|
35219
|
+
"conflict_error",
|
|
35220
|
+
"overloaded_error"
|
|
35221
|
+
]);
|
|
35222
|
+
var INVALID_ENCRYPTED_CONTENT_CODE = "invalid_encrypted_content";
|
|
35223
|
+
var INVALID_ENCRYPTED_CONTENT_MESSAGE = "The current provider can't read this thread's earlier reasoning, which another provider or account encrypted. This happens after the provider changes in a thread. Switch back to the previous provider or start a new thread.";
|
|
35224
|
+
function workspaceRoutingUnavailableMessage(text) {
|
|
35225
|
+
return `Codex can't reach chatgpt.com to look up your ChatGPT workspace. Check your network connection and any proxy, VPN, or firewall that blocks chatgpt.com, then try again. (${text})`;
|
|
35226
|
+
}
|
|
35227
|
+
function readableServiceErrorMessage(text) {
|
|
35228
|
+
if (isWorkspaceRoutingUnavailableMessage(text)) return workspaceRoutingUnavailableMessage(text);
|
|
35229
|
+
const value = parseJson(text);
|
|
35230
|
+
if (value === void 0) return text;
|
|
35231
|
+
if (isInvalidEncryptedContentError(value)) return INVALID_ENCRYPTED_CONTENT_MESSAGE;
|
|
35232
|
+
if (!isObject2(value) || Object.keys(value).some((key) => !["type", "status", "error"].includes(key)) || value["type"] !== "error" || typeof value["status"] !== "number" || !Number.isInteger(value["status"]) || value["status"] < 400 || value["status"] > 599 || !isObject2(value["error"])) return text;
|
|
35233
|
+
const error62 = value["error"];
|
|
35234
|
+
if (Object.keys(error62).some((key) => !["type", "message", "code", "param"].includes(key)) || typeof error62["type"] !== "string" || !SERVICE_ERROR_TYPES.has(error62["type"]) || typeof error62["message"] !== "string" || error62["message"].trim().length === 0 || ["code", "param"].some((key) => key in error62 && error62[key] !== null && typeof error62[key] !== "string")) return text;
|
|
35235
|
+
return error62["message"];
|
|
35236
|
+
}
|
|
35237
|
+
function isInvalidEncryptedContentError(value) {
|
|
35238
|
+
if (!isObject2(value) || !isObject2(value["error"])) return false;
|
|
35239
|
+
const error62 = value["error"];
|
|
35240
|
+
if (error62["code"] === INVALID_ENCRYPTED_CONTENT_CODE) return true;
|
|
35241
|
+
const metadata = error62["metadata"];
|
|
35242
|
+
if (!isObject2(metadata)) return false;
|
|
35243
|
+
return metadata["provider_error_code"] === INVALID_ENCRYPTED_CONTENT_CODE || typeof metadata["raw"] === "string" && isInvalidEncryptedContentError(parseJson(metadata["raw"]));
|
|
35244
|
+
}
|
|
35245
|
+
function parseJson(text) {
|
|
35246
|
+
try {
|
|
35247
|
+
return JSON.parse(text);
|
|
35248
|
+
} catch {
|
|
35249
|
+
return void 0;
|
|
35250
|
+
}
|
|
35251
|
+
}
|
|
35252
|
+
function isObject2(value) {
|
|
35253
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
35254
|
+
}
|
|
35255
|
+
|
|
35256
|
+
// src/app-server-recovery/AppServerExit.ts
|
|
35257
|
+
var CODEX_PROCESS_EXITED_ERROR_CODE = 1001;
|
|
35258
|
+
function likelyOutOfMemory(exit) {
|
|
35259
|
+
return exit.signal === "SIGKILL" || exit.code === 137;
|
|
35260
|
+
}
|
|
35261
|
+
function describeExit(exit) {
|
|
35262
|
+
if (exit.error !== void 0) {
|
|
35263
|
+
return exit.pid === void 0 ? `could not be started (${exit.error})` : `stopped responding (${exit.error})`;
|
|
35264
|
+
}
|
|
35265
|
+
const oom = likelyOutOfMemory(exit) ? ", which usually means it ran out of memory" : "";
|
|
35266
|
+
if (exit.signal !== null) return `was killed by ${exit.signal}${oom}`;
|
|
35267
|
+
return `exited with code ${exit.code ?? "unknown"}${oom}`;
|
|
35268
|
+
}
|
|
35269
|
+
var AppServerUnavailableError = class extends RequestError {
|
|
35270
|
+
constructor(message, data) {
|
|
35271
|
+
super(CODEX_PROCESS_EXITED_ERROR_CODE, message, data);
|
|
35272
|
+
this.name = "AppServerUnavailableError";
|
|
35273
|
+
}
|
|
35274
|
+
};
|
|
35275
|
+
var ThreadRefusedError = class extends AppServerUnavailableError {
|
|
35276
|
+
constructor(message, data) {
|
|
35277
|
+
super(message, data);
|
|
35278
|
+
this.name = "ThreadRefusedError";
|
|
35279
|
+
}
|
|
35280
|
+
};
|
|
35281
|
+
var SessionReplacedError = class extends AppServerUnavailableError {
|
|
35282
|
+
constructor(sessionId) {
|
|
35283
|
+
super(
|
|
35284
|
+
`Session ${sessionId} was closed or opened again while the agent reopened it after an app-server restart.`,
|
|
35285
|
+
{ exitCode: null, signal: null, restartable: true }
|
|
35286
|
+
);
|
|
35287
|
+
this.name = "SessionReplacedError";
|
|
34914
35288
|
}
|
|
34915
35289
|
};
|
|
34916
35290
|
var UnpersistedSessionLostError = class extends AppServerUnavailableError {
|
|
@@ -36484,413 +36858,114 @@ var StandardSubagentEventRouter = class {
|
|
|
36484
36858
|
}
|
|
36485
36859
|
await this.publishCancellation(child);
|
|
36486
36860
|
}
|
|
36487
|
-
/** Historical state bypasses the current foreground cache and grants no runtime ownership. */
|
|
36488
|
-
async replayTurnOutcome(threadId, turn) {
|
|
36489
|
-
const child = this.children.get(threadId);
|
|
36490
|
-
const state = turnEndState(turn);
|
|
36491
|
-
if (!child || state === void 0 || this.retired) return;
|
|
36492
|
-
await this.ensureAnnounced(child);
|
|
36493
|
-
if (this.retired) return;
|
|
36494
|
-
await this.session.updateSubagentState(child.sessionId, child.parentSessionId, state);
|
|
36495
|
-
}
|
|
36496
|
-
childSessionIds() {
|
|
36497
|
-
return [...this.children.values()].map((child) => child.sessionId);
|
|
36498
|
-
}
|
|
36499
|
-
isNativeSubagentThread(threadId) {
|
|
36500
|
-
return this.children.has(threadId);
|
|
36501
|
-
}
|
|
36502
|
-
shouldIgnore() {
|
|
36503
|
-
return false;
|
|
36504
|
-
}
|
|
36505
|
-
notificationSessionId(notification) {
|
|
36506
|
-
const threadId = notification.params.threadId;
|
|
36507
|
-
return typeof threadId === "string" ? this.children.get(threadId)?.sessionId ?? this.rootSessionId : this.rootSessionId;
|
|
36508
|
-
}
|
|
36509
|
-
takeBufferedNotifications() {
|
|
36510
|
-
return this.replayQueue.splice(0);
|
|
36511
|
-
}
|
|
36512
|
-
async waitForMaterializedSession(threadId) {
|
|
36513
|
-
if (this.retired) return null;
|
|
36514
|
-
await this.materializePending();
|
|
36515
|
-
const child = this.children.get(threadId);
|
|
36516
|
-
if (child) await this.ensureAnnounced(child);
|
|
36517
|
-
return child?.sessionId ?? null;
|
|
36518
|
-
}
|
|
36519
|
-
closingChildSessions(notification) {
|
|
36520
|
-
if (notification.method !== "turn/completed") return [];
|
|
36521
|
-
const child = this.children.get(notification.params.threadId);
|
|
36522
|
-
const turn = notification.params.turn;
|
|
36523
|
-
if (!child || turn.status === "inProgress" || child.endedTurns.has(turn.id) || child.turnId !== null && child.turnId !== turn.id) return [];
|
|
36524
|
-
return [{
|
|
36525
|
-
threadId: child.threadId,
|
|
36526
|
-
sessionId: child.sessionId,
|
|
36527
|
-
state: turn.status === "interrupted" ? "cancelled" : turn.status === "failed" ? "failed" : "completed"
|
|
36528
|
-
}];
|
|
36529
|
-
}
|
|
36530
|
-
async wait(_signal) {
|
|
36531
|
-
return "settled";
|
|
36532
|
-
}
|
|
36533
|
-
hasOutstanding() {
|
|
36534
|
-
return [...this.children.values()].some((child) => child.turnId !== null);
|
|
36535
|
-
}
|
|
36536
|
-
legacyActivityStarted(item) {
|
|
36537
|
-
this.legacyActivities.add(item.id);
|
|
36538
|
-
return SubagentActivityReporter.activity(item, "in_progress", "start");
|
|
36539
|
-
}
|
|
36540
|
-
legacyActivityCompleted(item) {
|
|
36541
|
-
return SubagentActivityReporter.activity(item, "completed", this.legacyActivities.delete(item.id) ? "update" : "start");
|
|
36542
|
-
}
|
|
36543
|
-
legacyCollaborationStarted(item) {
|
|
36544
|
-
return CollabAgentReporter.started(item);
|
|
36545
|
-
}
|
|
36546
|
-
legacyCollaborationCompleted(item) {
|
|
36547
|
-
return CollabAgentReporter.completed(item);
|
|
36548
|
-
}
|
|
36549
|
-
};
|
|
36550
|
-
function turnEndState(turn) {
|
|
36551
|
-
switch (turn.status) {
|
|
36552
|
-
case "inProgress":
|
|
36553
|
-
return void 0;
|
|
36554
|
-
case "completed":
|
|
36555
|
-
return toV2IdleState({ stopReason: "end_turn" });
|
|
36556
|
-
case "interrupted":
|
|
36557
|
-
return toV2IdleState({ stopReason: "cancelled" });
|
|
36558
|
-
case "failed":
|
|
36559
|
-
return toV2IdleState({ stopReason: "end_turn" }, {
|
|
36560
|
-
code: -32603,
|
|
36561
|
-
message: turn.error ? readableServiceErrorMessage(turn.error.message) : "Subagent work failed"
|
|
36562
|
-
});
|
|
36563
|
-
}
|
|
36564
|
-
}
|
|
36565
|
-
|
|
36566
|
-
// src/RateLimitsMap.ts
|
|
36567
|
-
function rateLimitId(snapshot, fallback = "codex") {
|
|
36568
|
-
return snapshot.limitId ?? fallback;
|
|
36569
|
-
}
|
|
36570
|
-
function createRateLimitsMap(response) {
|
|
36571
|
-
const result = /* @__PURE__ */ new Map();
|
|
36572
|
-
const snapshots = Object.entries(response.rateLimitsByLimitId ?? {}).filter((entry) => entry[1] !== void 0);
|
|
36573
|
-
if (snapshots.length === 0) {
|
|
36574
|
-
snapshots.push([rateLimitId(response.rateLimits), response.rateLimits]);
|
|
36575
|
-
}
|
|
36576
|
-
for (const [fallbackId, snapshot] of snapshots) {
|
|
36577
|
-
const limitId = rateLimitId(snapshot, fallbackId);
|
|
36578
|
-
result.set(limitId, {
|
|
36579
|
-
limitId,
|
|
36580
|
-
limitName: snapshot.limitName ?? limitId,
|
|
36581
|
-
snapshot
|
|
36582
|
-
});
|
|
36583
|
-
}
|
|
36584
|
-
return result;
|
|
36585
|
-
}
|
|
36586
|
-
function mergeRateLimitSnapshot(previous, update) {
|
|
36587
|
-
return {
|
|
36588
|
-
...update,
|
|
36589
|
-
limitId: update.limitId ?? "codex",
|
|
36590
|
-
credits: update.credits ?? previous.credits,
|
|
36591
|
-
individualLimit: update.individualLimit ?? previous.individualLimit,
|
|
36592
|
-
spendControlReached: update.spendControlReached ?? previous.spendControlReached,
|
|
36593
|
-
planType: update.planType ?? previous.planType
|
|
36594
|
-
};
|
|
36595
|
-
}
|
|
36596
|
-
|
|
36597
|
-
// src/AgentFileChangeReport.ts
|
|
36598
|
-
import fs2 from "node:fs";
|
|
36599
|
-
import path5 from "node:path";
|
|
36600
|
-
var AGENT_FILE_CHANGE_REPORT_VERSION = 1;
|
|
36601
|
-
var AGENT_FILE_CHANGE_REPORT_MAX_PATHS = 1024;
|
|
36602
|
-
var AGENT_FILE_CHANGE_REPORT_MAX_PATH_LENGTH = 4096;
|
|
36603
|
-
var AGENT_FILE_CHANGE_REPORT_MAX_TOTAL_BYTES = 256 * 1024;
|
|
36604
|
-
var AGENT_FILE_CHANGE_REPORT_MAX_DIFF_BYTES = 8 * 1024 * 1024;
|
|
36605
|
-
var TURN_DIFF_UNCERTAINTY = "Codex turn diffs may omit same-content renames and changes made outside apply_patch, including shell commands, version-control commands, generators, and child processes.";
|
|
36606
|
-
function captureAgentFileChangeWorkspace(cwd, additionalDirectories) {
|
|
36607
|
-
const lexicalCwd = parseWorkspaceRoot(cwd);
|
|
36608
|
-
return {
|
|
36609
|
-
cwd,
|
|
36610
|
-
additionalDirectories: [...additionalDirectories],
|
|
36611
|
-
diffRoot: lexicalCwd === null ? cwd : findDiffDisplayRoot(lexicalCwd).value
|
|
36612
|
-
};
|
|
36613
|
-
}
|
|
36614
|
-
function parseAgentFileChangeReportRequest(meta3) {
|
|
36615
|
-
const jetbrains = asRecord2(meta3?.[JETBRAINS_META_KEY]);
|
|
36616
|
-
const air = asRecord2(jetbrains?.[AIR_META_KEY]);
|
|
36617
|
-
const request = asRecord2(air?.[AIR_AGENT_FILE_CHANGE_REPORT_REQUEST_KEY]);
|
|
36618
|
-
if (request === null || !hasOnlyKeys(request, ["version", "requestId"]) || request["version"] !== AGENT_FILE_CHANGE_REPORT_VERSION) {
|
|
36619
|
-
return null;
|
|
36620
|
-
}
|
|
36621
|
-
const requestId = request["requestId"];
|
|
36622
|
-
if (typeof requestId !== "string" || !/^[A-Za-z0-9._:-]{1,128}$/.test(requestId)) {
|
|
36623
|
-
return null;
|
|
36624
|
-
}
|
|
36625
|
-
return { version: AGENT_FILE_CHANGE_REPORT_VERSION, requestId };
|
|
36626
|
-
}
|
|
36627
|
-
function createReportedAgentFileChangeReport(requestId, diff, workspace) {
|
|
36628
|
-
if (Buffer.byteLength(diff, "utf8") > AGENT_FILE_CHANGE_REPORT_MAX_DIFF_BYTES) {
|
|
36629
|
-
throw new AgentFileChangeReportError("invalidOutput", "The turn diff exceeds the parser input limit");
|
|
36630
|
-
}
|
|
36631
|
-
const parsedReport = parseTurnDiff(diff);
|
|
36632
|
-
const normalized = normalizeFileChangeReport(parsedReport, workspace);
|
|
36633
|
-
return fitReportedAgentFileChangeReport({
|
|
36634
|
-
version: AGENT_FILE_CHANGE_REPORT_VERSION,
|
|
36635
|
-
requestId,
|
|
36636
|
-
status: "reported",
|
|
36637
|
-
...normalized
|
|
36638
|
-
});
|
|
36639
|
-
}
|
|
36640
|
-
function createUnavailableAgentFileChangeReport(requestId, reason) {
|
|
36641
|
-
return {
|
|
36642
|
-
version: AGENT_FILE_CHANGE_REPORT_VERSION,
|
|
36643
|
-
requestId,
|
|
36644
|
-
status: "unavailable",
|
|
36645
|
-
reason
|
|
36646
|
-
};
|
|
36647
|
-
}
|
|
36648
|
-
var AgentFileChangeReportError = class extends Error {
|
|
36649
|
-
reason;
|
|
36650
|
-
constructor(reason, message) {
|
|
36651
|
-
super(message);
|
|
36652
|
-
this.name = "AgentFileChangeReportError";
|
|
36653
|
-
this.reason = reason;
|
|
36654
|
-
}
|
|
36655
|
-
};
|
|
36656
|
-
function parseTurnDiff(diff) {
|
|
36657
|
-
if (diff.trim() === "") {
|
|
36658
|
-
return { paths: [], complete: false, uncertainty: TURN_DIFF_UNCERTAINTY };
|
|
36659
|
-
}
|
|
36660
|
-
let patches;
|
|
36661
|
-
try {
|
|
36662
|
-
patches = parsePatch(diff);
|
|
36663
|
-
} catch (error62) {
|
|
36664
|
-
throw new AgentFileChangeReportError(
|
|
36665
|
-
"invalidOutput",
|
|
36666
|
-
`The turn diff is not valid unified diff: ${error62 instanceof Error ? error62.message : String(error62)}`
|
|
36667
|
-
);
|
|
36668
|
-
}
|
|
36669
|
-
if (patches.length === 0) {
|
|
36670
|
-
throw new AgentFileChangeReportError("invalidOutput", "The turn diff contains no parseable file patches");
|
|
36671
|
-
}
|
|
36672
|
-
const rawFileHeaders = extractRawFileHeaders(diff);
|
|
36673
|
-
const paths = [];
|
|
36674
|
-
for (const [index, patch] of patches.entries()) {
|
|
36675
|
-
const rawHeaders = rawFileHeaders[index];
|
|
36676
|
-
const oldPath = normalizeDiffPath(selectLosslessFileName(rawHeaders?.oldFileName, patch.oldFileName));
|
|
36677
|
-
const newPath = normalizeDiffPath(selectLosslessFileName(rawHeaders?.newFileName, patch.newFileName));
|
|
36678
|
-
if (oldPath === null && newPath === null) {
|
|
36679
|
-
throw new AgentFileChangeReportError("invalidOutput", "The turn diff contains a patch without a file path");
|
|
36680
|
-
}
|
|
36681
|
-
if (oldPath !== null) paths.push(oldPath);
|
|
36682
|
-
if (newPath !== null) paths.push(newPath);
|
|
36683
|
-
}
|
|
36684
|
-
return { paths, complete: false, uncertainty: TURN_DIFF_UNCERTAINTY };
|
|
36685
|
-
}
|
|
36686
|
-
function extractRawFileHeaders(diff) {
|
|
36687
|
-
return diff.split(/(?=^diff --git )/m).filter((section) => section.trim() !== "").map((section) => {
|
|
36688
|
-
const lines = section.split(/\r?\n/);
|
|
36689
|
-
for (let index = 0; index < lines.length; index += 1) {
|
|
36690
|
-
const line = lines[index];
|
|
36691
|
-
if (line?.startsWith("@@ ")) return null;
|
|
36692
|
-
const nextLine = lines[index + 1];
|
|
36693
|
-
if (line?.startsWith("--- ") && nextLine?.startsWith("+++ ")) {
|
|
36694
|
-
return {
|
|
36695
|
-
oldFileName: line.slice(4),
|
|
36696
|
-
newFileName: nextLine.slice(4)
|
|
36697
|
-
};
|
|
36698
|
-
}
|
|
36699
|
-
}
|
|
36700
|
-
return null;
|
|
36701
|
-
});
|
|
36702
|
-
}
|
|
36703
|
-
function selectLosslessFileName(rawFileName, parsedFileName) {
|
|
36704
|
-
return rawFileName === void 0 || rawFileName.startsWith('"') ? parsedFileName : rawFileName;
|
|
36705
|
-
}
|
|
36706
|
-
function normalizeDiffPath(value) {
|
|
36707
|
-
if (value === void 0 || value === "/dev/null") return null;
|
|
36708
|
-
return value.startsWith("a/") || value.startsWith("b/") ? value.slice(2) : value;
|
|
36709
|
-
}
|
|
36710
|
-
function fitReportedAgentFileChangeReport(report) {
|
|
36711
|
-
const paths = [...report.paths];
|
|
36712
|
-
let truncated = report.truncated;
|
|
36713
|
-
let fitted = report;
|
|
36714
|
-
while (Buffer.byteLength(JSON.stringify(fitted), "utf8") > AGENT_FILE_CHANGE_REPORT_MAX_TOTAL_BYTES) {
|
|
36715
|
-
if (paths.length === 0) {
|
|
36716
|
-
throw new AgentFileChangeReportError("invalidOutput", "The audit report exceeds the wire limit");
|
|
36717
|
-
}
|
|
36718
|
-
paths.pop();
|
|
36719
|
-
truncated = true;
|
|
36720
|
-
fitted = {
|
|
36721
|
-
...report,
|
|
36722
|
-
paths: [...paths],
|
|
36723
|
-
declaredComplete: false,
|
|
36724
|
-
truncated
|
|
36725
|
-
};
|
|
36861
|
+
/** Historical state bypasses the current foreground cache and grants no runtime ownership. */
|
|
36862
|
+
async replayTurnOutcome(threadId, turn) {
|
|
36863
|
+
const child = this.children.get(threadId);
|
|
36864
|
+
const state = turnEndState(turn);
|
|
36865
|
+
if (!child || state === void 0 || this.retired) return;
|
|
36866
|
+
await this.ensureAnnounced(child);
|
|
36867
|
+
if (this.retired) return;
|
|
36868
|
+
await this.session.updateSubagentState(child.sessionId, child.parentSessionId, state);
|
|
36726
36869
|
}
|
|
36727
|
-
|
|
36728
|
-
|
|
36729
|
-
function normalizeFileChangeReport(report, workspace) {
|
|
36730
|
-
const lexicalCwd = parseWorkspaceRoot(workspace.cwd);
|
|
36731
|
-
if (lexicalCwd === null) {
|
|
36732
|
-
throw new AgentFileChangeReportError("providerError", "The session working directory is not absolute");
|
|
36870
|
+
childSessionIds() {
|
|
36871
|
+
return [...this.children.values()].map((child) => child.sessionId);
|
|
36733
36872
|
}
|
|
36734
|
-
|
|
36735
|
-
|
|
36736
|
-
if (diffRoot === null || diffRoot.flavor !== cwd.flavor) {
|
|
36737
|
-
throw new AgentFileChangeReportError("providerError", "The captured turn-diff root is invalid");
|
|
36873
|
+
isNativeSubagentThread(threadId) {
|
|
36874
|
+
return this.children.has(threadId);
|
|
36738
36875
|
}
|
|
36739
|
-
|
|
36740
|
-
|
|
36741
|
-
return root === null || root.flavor !== cwd.flavor ? [] : [root];
|
|
36742
|
-
})];
|
|
36743
|
-
const paths = [];
|
|
36744
|
-
const seen = /* @__PURE__ */ new Set();
|
|
36745
|
-
let totalBytes = 0;
|
|
36746
|
-
let truncated = false;
|
|
36747
|
-
for (const reportedPath of report.paths) {
|
|
36748
|
-
if (reportedPath.length > AGENT_FILE_CHANGE_REPORT_MAX_PATH_LENGTH) {
|
|
36749
|
-
truncated = true;
|
|
36750
|
-
continue;
|
|
36751
|
-
}
|
|
36752
|
-
const normalized = normalizeReportedPath(reportedPath, diffRoot, roots);
|
|
36753
|
-
if (normalized === null || normalized.value.length > AGENT_FILE_CHANGE_REPORT_MAX_PATH_LENGTH) {
|
|
36754
|
-
truncated = true;
|
|
36755
|
-
continue;
|
|
36756
|
-
}
|
|
36757
|
-
const key = normalized.flavor === "windows" ? normalized.value.toLowerCase() : normalized.value;
|
|
36758
|
-
if (seen.has(key)) {
|
|
36759
|
-
continue;
|
|
36760
|
-
}
|
|
36761
|
-
const bytes = Buffer.byteLength(normalized.value, "utf8");
|
|
36762
|
-
if (paths.length >= AGENT_FILE_CHANGE_REPORT_MAX_PATHS || totalBytes + bytes > AGENT_FILE_CHANGE_REPORT_MAX_TOTAL_BYTES) {
|
|
36763
|
-
truncated = true;
|
|
36764
|
-
continue;
|
|
36765
|
-
}
|
|
36766
|
-
seen.add(key);
|
|
36767
|
-
paths.push(normalized.value);
|
|
36768
|
-
totalBytes += bytes;
|
|
36876
|
+
shouldIgnore() {
|
|
36877
|
+
return false;
|
|
36769
36878
|
}
|
|
36770
|
-
|
|
36771
|
-
|
|
36772
|
-
|
|
36773
|
-
truncated,
|
|
36774
|
-
...report.uncertainty ? { uncertainty: report.uncertainty } : {}
|
|
36775
|
-
};
|
|
36776
|
-
}
|
|
36777
|
-
function normalizeWorkspaceRoot(value) {
|
|
36778
|
-
const root = parseWorkspaceRoot(value);
|
|
36779
|
-
return root === null ? null : canonicalizeWorkspaceRoot(root);
|
|
36780
|
-
}
|
|
36781
|
-
function parseWorkspaceRoot(value) {
|
|
36782
|
-
const trimmed = value.trim();
|
|
36783
|
-
if (!isValidPathText(trimmed)) {
|
|
36784
|
-
return null;
|
|
36879
|
+
notificationSessionId(notification) {
|
|
36880
|
+
const threadId = notification.params.threadId;
|
|
36881
|
+
return typeof threadId === "string" ? this.children.get(threadId)?.sessionId ?? this.rootSessionId : this.rootSessionId;
|
|
36785
36882
|
}
|
|
36786
|
-
|
|
36787
|
-
return
|
|
36788
|
-
value: path5.win32.normalize(trimmed.replace(/\//g, "\\")),
|
|
36789
|
-
flavor: "windows"
|
|
36790
|
-
};
|
|
36883
|
+
takeBufferedNotifications() {
|
|
36884
|
+
return this.replayQueue.splice(0);
|
|
36791
36885
|
}
|
|
36792
|
-
|
|
36793
|
-
return
|
|
36794
|
-
|
|
36795
|
-
|
|
36796
|
-
|
|
36886
|
+
async waitForMaterializedSession(threadId) {
|
|
36887
|
+
if (this.retired) return null;
|
|
36888
|
+
await this.materializePending();
|
|
36889
|
+
const child = this.children.get(threadId);
|
|
36890
|
+
if (child) await this.ensureAnnounced(child);
|
|
36891
|
+
return child?.sessionId ?? null;
|
|
36797
36892
|
}
|
|
36798
|
-
|
|
36799
|
-
|
|
36800
|
-
|
|
36801
|
-
|
|
36802
|
-
return
|
|
36893
|
+
closingChildSessions(notification) {
|
|
36894
|
+
if (notification.method !== "turn/completed") return [];
|
|
36895
|
+
const child = this.children.get(notification.params.threadId);
|
|
36896
|
+
const turn = notification.params.turn;
|
|
36897
|
+
if (!child || turn.status === "inProgress" || child.endedTurns.has(turn.id) || child.turnId !== null && child.turnId !== turn.id) return [];
|
|
36898
|
+
return [{
|
|
36899
|
+
threadId: child.threadId,
|
|
36900
|
+
sessionId: child.sessionId,
|
|
36901
|
+
state: turn.status === "interrupted" ? "cancelled" : turn.status === "failed" ? "failed" : "completed"
|
|
36902
|
+
}];
|
|
36803
36903
|
}
|
|
36804
|
-
|
|
36805
|
-
|
|
36806
|
-
candidate = { value: path5.win32.normalize(value.replace(/\//g, "\\")), flavor: "windows" };
|
|
36807
|
-
} else if (path5.posix.isAbsolute(value)) {
|
|
36808
|
-
candidate = { value: path5.posix.normalize(value.replace(/\\/g, "/")), flavor: "posix" };
|
|
36809
|
-
} else if (relativeRoot.flavor === "windows") {
|
|
36810
|
-
candidate = {
|
|
36811
|
-
value: path5.win32.resolve(relativeRoot.value, value.replace(/\//g, "\\")),
|
|
36812
|
-
flavor: "windows"
|
|
36813
|
-
};
|
|
36814
|
-
} else {
|
|
36815
|
-
candidate = {
|
|
36816
|
-
value: path5.posix.resolve(relativeRoot.value, value.replace(/\\/g, "/")),
|
|
36817
|
-
flavor: "posix"
|
|
36818
|
-
};
|
|
36904
|
+
async wait(_signal) {
|
|
36905
|
+
return "settled";
|
|
36819
36906
|
}
|
|
36820
|
-
|
|
36821
|
-
|
|
36822
|
-
}
|
|
36823
|
-
function findDiffDisplayRoot(cwd) {
|
|
36824
|
-
if (!isNativePathFlavor(cwd.flavor)) return cwd;
|
|
36825
|
-
const pathImplementation = cwd.flavor === "windows" ? path5.win32 : path5.posix;
|
|
36826
|
-
let current = cwd.value;
|
|
36827
|
-
while (true) {
|
|
36828
|
-
if (fs2.existsSync(pathImplementation.join(current, ".git"))) {
|
|
36829
|
-
return canonicalizeWorkspaceRoot({ value: current, flavor: cwd.flavor });
|
|
36830
|
-
}
|
|
36831
|
-
const parent = pathImplementation.dirname(current);
|
|
36832
|
-
if (parent === current) return cwd;
|
|
36833
|
-
current = parent;
|
|
36907
|
+
hasOutstanding() {
|
|
36908
|
+
return [...this.children.values()].some((child) => child.turnId !== null);
|
|
36834
36909
|
}
|
|
36835
|
-
|
|
36836
|
-
|
|
36837
|
-
|
|
36838
|
-
return root;
|
|
36910
|
+
legacyActivityStarted(item) {
|
|
36911
|
+
this.legacyActivities.add(item.id);
|
|
36912
|
+
return SubagentActivityReporter.activity(item, "in_progress", "start");
|
|
36839
36913
|
}
|
|
36840
|
-
|
|
36841
|
-
|
|
36842
|
-
function canonicalizeReportedPath(candidate) {
|
|
36843
|
-
if (!isNativePathFlavor(candidate.flavor)) {
|
|
36844
|
-
return candidate;
|
|
36914
|
+
legacyActivityCompleted(item) {
|
|
36915
|
+
return SubagentActivityReporter.activity(item, "completed", this.legacyActivities.delete(item.id) ? "update" : "start");
|
|
36845
36916
|
}
|
|
36846
|
-
|
|
36847
|
-
|
|
36848
|
-
}
|
|
36849
|
-
function canonicalizeFromExistingAncestor(value) {
|
|
36850
|
-
const original = path5.resolve(value);
|
|
36851
|
-
let current = original;
|
|
36852
|
-
const missingSegments = [];
|
|
36853
|
-
while (true) {
|
|
36854
|
-
try {
|
|
36855
|
-
const canonical = fs2.realpathSync.native(current);
|
|
36856
|
-
return path5.resolve(canonical, ...missingSegments.reverse());
|
|
36857
|
-
} catch (error62) {
|
|
36858
|
-
if (!isMissingPathError(error62)) return original;
|
|
36859
|
-
}
|
|
36860
|
-
const parent = path5.dirname(current);
|
|
36861
|
-
if (parent === current) return original;
|
|
36862
|
-
missingSegments.push(path5.basename(current));
|
|
36863
|
-
current = parent;
|
|
36917
|
+
legacyCollaborationStarted(item) {
|
|
36918
|
+
return CollabAgentReporter.started(item);
|
|
36864
36919
|
}
|
|
36865
|
-
|
|
36866
|
-
|
|
36867
|
-
|
|
36868
|
-
|
|
36869
|
-
|
|
36870
|
-
|
|
36871
|
-
|
|
36872
|
-
|
|
36873
|
-
|
|
36874
|
-
|
|
36875
|
-
|
|
36920
|
+
legacyCollaborationCompleted(item) {
|
|
36921
|
+
return CollabAgentReporter.completed(item);
|
|
36922
|
+
}
|
|
36923
|
+
};
|
|
36924
|
+
function turnEndState(turn) {
|
|
36925
|
+
switch (turn.status) {
|
|
36926
|
+
case "inProgress":
|
|
36927
|
+
return void 0;
|
|
36928
|
+
case "completed":
|
|
36929
|
+
return toV2IdleState({ stopReason: "end_turn" });
|
|
36930
|
+
case "interrupted":
|
|
36931
|
+
return toV2IdleState({ stopReason: "cancelled" });
|
|
36932
|
+
case "failed":
|
|
36933
|
+
return toV2IdleState({ stopReason: "end_turn" }, {
|
|
36934
|
+
code: -32603,
|
|
36935
|
+
message: turn.error ? readableServiceErrorMessage(turn.error.message) : "Subagent work failed"
|
|
36936
|
+
});
|
|
36876
36937
|
}
|
|
36877
|
-
const pathImplementation = root.flavor === "windows" ? path5.win32 : path5.posix;
|
|
36878
|
-
const relative = pathImplementation.relative(root.value, candidate.value);
|
|
36879
|
-
return relative.length > 0 && !pathImplementation.isAbsolute(relative) && relative !== ".." && !relative.startsWith(`..${pathImplementation.sep}`);
|
|
36880
|
-
}
|
|
36881
|
-
function isWindowsAbsolutePath(value) {
|
|
36882
|
-
const portable = value.replace(/\\/g, "/");
|
|
36883
|
-
return /^[A-Za-z]:\//.test(portable) || /^\/\/[^/]+\/[^/]+(?:\/|$)/.test(portable);
|
|
36884
36938
|
}
|
|
36885
|
-
|
|
36886
|
-
|
|
36939
|
+
|
|
36940
|
+
// src/RateLimitsMap.ts
|
|
36941
|
+
function rateLimitId(snapshot, fallback = "codex") {
|
|
36942
|
+
return snapshot.limitId ?? fallback;
|
|
36887
36943
|
}
|
|
36888
|
-
function
|
|
36889
|
-
|
|
36944
|
+
function createRateLimitsMap(response) {
|
|
36945
|
+
const result = /* @__PURE__ */ new Map();
|
|
36946
|
+
const snapshots = Object.entries(response.rateLimitsByLimitId ?? {}).filter((entry) => entry[1] !== void 0);
|
|
36947
|
+
if (snapshots.length === 0) {
|
|
36948
|
+
snapshots.push([rateLimitId(response.rateLimits), response.rateLimits]);
|
|
36949
|
+
}
|
|
36950
|
+
for (const [fallbackId, snapshot] of snapshots) {
|
|
36951
|
+
const limitId = rateLimitId(snapshot, fallbackId);
|
|
36952
|
+
result.set(limitId, {
|
|
36953
|
+
limitId,
|
|
36954
|
+
limitName: snapshot.limitName ?? limitId,
|
|
36955
|
+
snapshot
|
|
36956
|
+
});
|
|
36957
|
+
}
|
|
36958
|
+
return result;
|
|
36890
36959
|
}
|
|
36891
|
-
function
|
|
36892
|
-
|
|
36893
|
-
|
|
36960
|
+
function mergeRateLimitSnapshot(previous, update) {
|
|
36961
|
+
return {
|
|
36962
|
+
...update,
|
|
36963
|
+
limitId: update.limitId ?? "codex",
|
|
36964
|
+
credits: update.credits ?? previous.credits,
|
|
36965
|
+
individualLimit: update.individualLimit ?? previous.individualLimit,
|
|
36966
|
+
spendControlReached: update.spendControlReached ?? previous.spendControlReached,
|
|
36967
|
+
planType: update.planType ?? previous.planType
|
|
36968
|
+
};
|
|
36894
36969
|
}
|
|
36895
36970
|
|
|
36896
36971
|
// src/SessionNotice.ts
|
|
@@ -38891,9 +38966,9 @@ function parsePersistOptions(meta3) {
|
|
|
38891
38966
|
function isMcpToolCallApproval(meta3) {
|
|
38892
38967
|
return isRecord2(meta3) && meta3["codex_approval_kind"] === "mcp_tool_call";
|
|
38893
38968
|
}
|
|
38894
|
-
function buildMcpPermissionOptions(isToolApproval, persistOptions,
|
|
38969
|
+
function buildMcpPermissionOptions(isToolApproval, persistOptions, capabilities) {
|
|
38895
38970
|
const permissionOption2 = (optionId, name, kind, description) => {
|
|
38896
|
-
const meta3 = optionPermissionMeta(
|
|
38971
|
+
const meta3 = optionPermissionMeta(capabilities, description);
|
|
38897
38972
|
return { optionId, name, kind, ...meta3 ? { _meta: meta3 } : {} };
|
|
38898
38973
|
};
|
|
38899
38974
|
const options = [permissionOption2(
|
|
@@ -38955,7 +39030,7 @@ function buildMcpPermissionRequest(sessionId, params, context, nextStandaloneToo
|
|
|
38955
39030
|
options: buildMcpPermissionOptions(
|
|
38956
39031
|
context.isToolApproval,
|
|
38957
39032
|
context.persistOptions,
|
|
38958
|
-
renderer.capabilities
|
|
39033
|
+
renderer.capabilities
|
|
38959
39034
|
)
|
|
38960
39035
|
},
|
|
38961
39036
|
correlatedCallId
|
|
@@ -39068,7 +39143,7 @@ function userInputResponseValue(content, fieldId) {
|
|
|
39068
39143
|
}
|
|
39069
39144
|
return value;
|
|
39070
39145
|
}
|
|
39071
|
-
function buildUserInputSchema(questions, clientCapabilities, answersRequired) {
|
|
39146
|
+
function buildUserInputSchema(questions, clientCapabilities, answersRequired, neutralCustomAnswer = false) {
|
|
39072
39147
|
const properties = {};
|
|
39073
39148
|
const required2 = [];
|
|
39074
39149
|
const questionIds = new Set(questions.map((question) => question.id));
|
|
@@ -39120,7 +39195,10 @@ function buildUserInputSchema(questions, clientCapabilities, answersRequired) {
|
|
|
39120
39195
|
properties[userInputNoteFieldId(question.id, questionIds)] = {
|
|
39121
39196
|
type: "string",
|
|
39122
39197
|
title: "Additional answer or note",
|
|
39123
|
-
_meta:
|
|
39198
|
+
_meta: {
|
|
39199
|
+
...airClient ? withAirMeta({ ...noteMeta, [LEGACY_AIR_CUSTOM_ANSWER_KEY]: true }, AIR_CUSTOM_ANSWER_KEY, true) : noteMeta,
|
|
39200
|
+
...neutralCustomAnswer ? { [NEUTRAL_QUESTION_CUSTOM_ANSWER_META_KEY]: { version: 1, questionId: question.id } } : {}
|
|
39201
|
+
}
|
|
39124
39202
|
};
|
|
39125
39203
|
}
|
|
39126
39204
|
}
|
|
@@ -39130,13 +39208,13 @@ function buildUserInputSchema(questions, clientCapabilities, answersRequired) {
|
|
|
39130
39208
|
...answersRequired ? { required: required2 } : {}
|
|
39131
39209
|
};
|
|
39132
39210
|
}
|
|
39133
|
-
function buildUserInputRequest(params, clientCapabilities) {
|
|
39211
|
+
function buildUserInputRequest(params, clientCapabilities, neutralCustomAnswer) {
|
|
39134
39212
|
return {
|
|
39135
39213
|
sessionId: params.threadId,
|
|
39136
39214
|
toolCallId: params.itemId,
|
|
39137
39215
|
mode: "form",
|
|
39138
39216
|
message: "Codex needs your input to continue.",
|
|
39139
|
-
requestedSchema: buildUserInputSchema(params.questions, clientCapabilities, true),
|
|
39217
|
+
requestedSchema: buildUserInputSchema(params.questions, clientCapabilities, true, neutralCustomAnswer),
|
|
39140
39218
|
_meta: {
|
|
39141
39219
|
codex: {
|
|
39142
39220
|
autoResolutionMs: params.autoResolutionMs
|
|
@@ -39299,7 +39377,7 @@ var CodexElicitationHandler = class {
|
|
|
39299
39377
|
return cancellationSignal ? { cancellationSignal } : void 0;
|
|
39300
39378
|
}
|
|
39301
39379
|
async requestUserInputElicitation(params) {
|
|
39302
|
-
const request = buildUserInputRequest(params, this.clientCapabilities);
|
|
39380
|
+
const request = buildUserInputRequest(params, this.clientCapabilities, this.renderer.capabilities.neutralQuestionCustomAnswer);
|
|
39303
39381
|
const signal = subagentInteractionSignal(params.threadId, this.cancellationSignal);
|
|
39304
39382
|
if (params.autoResolutionMs === null) {
|
|
39305
39383
|
return await withSubagentUserAction(params.threadId, () => this.connection.request(
|
|
@@ -40675,7 +40753,7 @@ var package_default = {
|
|
|
40675
40753
|
publishConfig: {
|
|
40676
40754
|
access: "public"
|
|
40677
40755
|
},
|
|
40678
|
-
version: "2.5.0-alas.
|
|
40756
|
+
version: "2.5.0-alas.7",
|
|
40679
40757
|
description: "",
|
|
40680
40758
|
main: "dist/index.js",
|
|
40681
40759
|
bin: {
|
|
@@ -40753,7 +40831,7 @@ var package_default = {
|
|
|
40753
40831
|
alasDownstream: {
|
|
40754
40832
|
upstreamVersion: "2.5.0",
|
|
40755
40833
|
upstreamCommit: "34e08970aa324a2be985f5080674d5aa91d7666f",
|
|
40756
|
-
sourceCommit: "
|
|
40834
|
+
sourceCommit: "4b88aaf47a9765b7b64a51712cca179fc141fa46"
|
|
40757
40835
|
}
|
|
40758
40836
|
};
|
|
40759
40837
|
|
|
@@ -49211,14 +49289,16 @@ var AsyncQuestionClient = class {
|
|
|
49211
49289
|
}
|
|
49212
49290
|
};
|
|
49213
49291
|
var AsyncQuestionElicitations = class {
|
|
49214
|
-
constructor(sessionId, clientCapabilities, client) {
|
|
49292
|
+
constructor(sessionId, clientCapabilities, client, neutralCustomAnswer = false) {
|
|
49215
49293
|
this.sessionId = sessionId;
|
|
49216
49294
|
this.clientCapabilities = clientCapabilities;
|
|
49217
49295
|
this.client = client;
|
|
49296
|
+
this.neutralCustomAnswer = neutralCustomAnswer;
|
|
49218
49297
|
}
|
|
49219
49298
|
sessionId;
|
|
49220
49299
|
clientCapabilities;
|
|
49221
49300
|
client;
|
|
49301
|
+
neutralCustomAnswer;
|
|
49222
49302
|
// The running turns that asked a question, each with the signal that cancels its questions.
|
|
49223
49303
|
turns = /* @__PURE__ */ new Map();
|
|
49224
49304
|
/** Asks the questions of a completed async message and cancels them when their turn ends; never waits. */
|
|
@@ -49263,7 +49343,7 @@ var AsyncQuestionElicitations = class {
|
|
|
49263
49343
|
mode: "form",
|
|
49264
49344
|
message: "Codex keeps working while you answer. An answer sent after it finishes is not delivered.",
|
|
49265
49345
|
// Questions are answered independently, as in Codex.
|
|
49266
|
-
requestedSchema: buildUserInputSchema(questions, this.clientCapabilities, false),
|
|
49346
|
+
requestedSchema: buildUserInputSchema(questions, this.clientCapabilities, false, this.neutralCustomAnswer),
|
|
49267
49347
|
_meta: { codex: { delivery: "async" } }
|
|
49268
49348
|
};
|
|
49269
49349
|
void this.client.createElicitation(request, turn.signal).then(
|
|
@@ -52176,9 +52256,6 @@ var DENY_ALL_ELICITATIONS = {
|
|
|
52176
52256
|
handleElicitation: async () => ({ action: "cancel", content: null, _meta: null }),
|
|
52177
52257
|
handleUserInput: async () => ({ answers: {} })
|
|
52178
52258
|
};
|
|
52179
|
-
function clientSupportsAgentFileChangeReports(capabilities) {
|
|
52180
|
-
return clientSupportsAirCapability(capabilities, AIR_AGENT_FILE_CHANGE_REPORT_KEY);
|
|
52181
|
-
}
|
|
52182
52259
|
function isAuthRequiredError(error62) {
|
|
52183
52260
|
return error62 instanceof RequestError && error62.code === RequestError.authRequired().code;
|
|
52184
52261
|
}
|
|
@@ -52625,6 +52702,19 @@ var CodexAcpServer = class {
|
|
|
52625
52702
|
...protocolVersion === 1 && this.capabilities.sessionFailureFormat === "neutral" ? {
|
|
52626
52703
|
[NEUTRAL_SESSION_FAILURE_META_KEY]: neutralSessionFailureCapability()
|
|
52627
52704
|
} : {},
|
|
52705
|
+
// The client-neutral agent file-change report, see `docs/air-extensions.md`. It is an ACP v1 extension,
|
|
52706
|
+
// so `ClientCapabilities.fromV2` never selects it.
|
|
52707
|
+
...protocolVersion === 1 && this.capabilities.agentFileChangeReportFormat === "neutral" ? {
|
|
52708
|
+
[NEUTRAL_AGENT_FILE_CHANGE_REPORT_META_KEY]: neutralAgentFileChangeReportCapability()
|
|
52709
|
+
} : {},
|
|
52710
|
+
// The client-neutral presentation contracts, see `docs/air-extensions.md`. `ClientCapabilities.fromV2`
|
|
52711
|
+
// never selects them.
|
|
52712
|
+
...this.capabilities.neutralPermissionPresentation ? {
|
|
52713
|
+
[NEUTRAL_PERMISSION_PRESENTATION_META_KEY]: neutralPresentationCapability()
|
|
52714
|
+
} : {},
|
|
52715
|
+
...this.capabilities.neutralQuestionCustomAnswer ? {
|
|
52716
|
+
[NEUTRAL_QUESTION_CUSTOM_ANSWER_META_KEY]: neutralPresentationCapability()
|
|
52717
|
+
} : {},
|
|
52628
52718
|
// The session index for a client that opted in without AIR, see `docs/air-extensions.md`.
|
|
52629
52719
|
...neutralSessionIndex ? {
|
|
52630
52720
|
[NEUTRAL_SESSION_INDEX_META_KEY]: neutralSessionIndex
|
|
@@ -55315,7 +55405,7 @@ You have been logged out. Please try again.`);
|
|
|
55315
55405
|
title
|
|
55316
55406
|
});
|
|
55317
55407
|
}
|
|
55318
|
-
async publishAgentFileChangeReport(sessionState, turnId, request, unavailableReason, turnDiff, workspace) {
|
|
55408
|
+
async publishAgentFileChangeReport(sessionState, format, turnId, request, unavailableReason, turnDiff, workspace) {
|
|
55319
55409
|
let report;
|
|
55320
55410
|
try {
|
|
55321
55411
|
report = turnId === null ? createUnavailableAgentFileChangeReport(request.requestId, unavailableReason) : createReportedAgentFileChangeReport(request.requestId, turnDiff, workspace);
|
|
@@ -55333,14 +55423,7 @@ You have been logged out. Please try again.`);
|
|
|
55333
55423
|
const session = new ACPSessionConnection(this.connection, sessionState.sessionId);
|
|
55334
55424
|
await session.update({
|
|
55335
55425
|
sessionUpdate: "session_info_update",
|
|
55336
|
-
_meta:
|
|
55337
|
-
[JETBRAINS_META_KEY]: {
|
|
55338
|
-
[AIR_META_KEY]: {
|
|
55339
|
-
[AIR_EXTENSION_VERSION_KEY]: AIR_EXTENSION_VERSION,
|
|
55340
|
-
[AIR_AGENT_FILE_CHANGE_REPORT_KEY]: report
|
|
55341
|
-
}
|
|
55342
|
-
}
|
|
55343
|
-
}
|
|
55426
|
+
_meta: agentFileChangeReportMeta(format, report)
|
|
55344
55427
|
});
|
|
55345
55428
|
} catch (error62) {
|
|
55346
55429
|
logger.error("Failed to publish agent file-change report", error62);
|
|
@@ -56013,7 +56096,8 @@ You have been logged out. Please try again.`);
|
|
|
56013
56096
|
const sessionState = this.getSessionState(params.sessionId);
|
|
56014
56097
|
const clearing = sessionState.promptSuggestions?.clear();
|
|
56015
56098
|
if (clearing) await clearing;
|
|
56016
|
-
const
|
|
56099
|
+
const agentFileChangeReportFormat = this.capabilities.agentFileChangeReportFormat;
|
|
56100
|
+
const agentFileChangeReportRequest = agentFileChangeReportRequestFor(agentFileChangeReportFormat, params._meta);
|
|
56017
56101
|
const agentFileChangeWorkspace = agentFileChangeReportRequest === null ? null : captureAgentFileChangeWorkspace(sessionState.cwd, sessionState.additionalDirectories);
|
|
56018
56102
|
let agentFileChangeReportTurnId = null;
|
|
56019
56103
|
let agentFileChangeReportUnavailableReason = "providerError";
|
|
@@ -56547,7 +56631,7 @@ You have been logged out. Please try again.`);
|
|
|
56547
56631
|
} catch (error62) {
|
|
56548
56632
|
logger.error("Failed to publish terminal compaction or subagent state during prompt cleanup", error62);
|
|
56549
56633
|
}
|
|
56550
|
-
if (agentFileChangeReportRequest !== null && agentFileChangeWorkspace !== null) {
|
|
56634
|
+
if (agentFileChangeReportFormat !== "none" && agentFileChangeReportRequest !== null && agentFileChangeWorkspace !== null) {
|
|
56551
56635
|
if (promptWasCancelled || activePrompt.signal.aborted || this.sessionIsClosing(params.sessionId)) {
|
|
56552
56636
|
agentFileChangeReportTurnId = null;
|
|
56553
56637
|
agentFileChangeReportUnavailableReason = "cancelled";
|
|
@@ -56557,6 +56641,7 @@ You have been logged out. Please try again.`);
|
|
|
56557
56641
|
}
|
|
56558
56642
|
await this.publishAgentFileChangeReport(
|
|
56559
56643
|
sessionState,
|
|
56644
|
+
agentFileChangeReportFormat,
|
|
56560
56645
|
agentFileChangeReportTurnId,
|
|
56561
56646
|
agentFileChangeReportRequest,
|
|
56562
56647
|
agentFileChangeReportUnavailableReason,
|
|
@@ -56616,7 +56701,7 @@ You have been logged out. Please try again.`);
|
|
|
56616
56701
|
this.connection,
|
|
56617
56702
|
this.clientCapabilities,
|
|
56618
56703
|
() => this.codexAcpClient
|
|
56619
|
-
));
|
|
56704
|
+
), this.capabilities.neutralQuestionCustomAnswer);
|
|
56620
56705
|
this.asyncQuestions.set(sessionId, questions);
|
|
56621
56706
|
}
|
|
56622
56707
|
return questions;
|