acpx 0.13.0 → 0.13.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/README.md +64 -382
- package/dist/{cli-D52eGvxU.js → cli-_7Sei6dD.js} +4 -4
- package/dist/{cli-D52eGvxU.js.map → cli-_7Sei6dD.js.map} +1 -1
- package/dist/cli.d.ts +1 -1
- package/dist/cli.js +6 -6
- package/dist/cli.js.map +1 -1
- package/dist/{client-BeKvumq9.d.ts → client-CxNllqui.d.ts} +15 -3
- package/dist/client-CxNllqui.d.ts.map +1 -0
- package/dist/{flags---9OR06b.js → flags-Ds6FzmHG.js} +3 -3
- package/dist/{flags---9OR06b.js.map → flags-Ds6FzmHG.js.map} +1 -1
- package/dist/{flows-CYfjwbn2.js → flows-fzH0GKYF.js} +3 -3
- package/dist/{flows-CYfjwbn2.js.map → flows-fzH0GKYF.js.map} +1 -1
- package/dist/flows.d.ts +2 -2
- package/dist/flows.js +1 -1
- package/dist/{live-checkpoint-CBecfnSH.js → live-checkpoint-BSIrfgVo.js} +345 -186
- package/dist/live-checkpoint-BSIrfgVo.js.map +1 -0
- package/dist/{output-CzN8vLdE.js → output-BZQE0gI1.js} +50 -11
- package/dist/output-BZQE0gI1.js.map +1 -0
- package/dist/runtime.d.ts +104 -17
- package/dist/runtime.d.ts.map +1 -1
- package/dist/runtime.js +600 -149
- package/dist/runtime.js.map +1 -1
- package/dist/{session-options-CTdZvr68.d.ts → session-options-DwRDODlr.d.ts} +25 -3
- package/dist/session-options-DwRDODlr.d.ts.map +1 -0
- package/package.json +2 -2
- package/dist/client-BeKvumq9.d.ts.map +0 -1
- package/dist/live-checkpoint-CBecfnSH.js.map +0 -1
- package/dist/output-CzN8vLdE.js.map +0 -1
- package/dist/session-options-CTdZvr68.d.ts.map +0 -1
|
@@ -6,9 +6,8 @@ import os from "node:os";
|
|
|
6
6
|
import { randomUUID } from "node:crypto";
|
|
7
7
|
import { execFile, spawn } from "node:child_process";
|
|
8
8
|
import { Readable, Writable } from "node:stream";
|
|
9
|
-
import {
|
|
9
|
+
import { PROTOCOL_VERSION, client, methods } from "@agentclientprotocol/sdk";
|
|
10
10
|
import readline from "node:readline/promises";
|
|
11
|
-
import { promisify } from "node:util";
|
|
12
11
|
//#region src/errors.ts
|
|
13
12
|
var AcpxOperationalError = class extends Error {
|
|
14
13
|
outputCode;
|
|
@@ -1721,7 +1720,8 @@ function assertPersistedKeyPolicy(value) {
|
|
|
1721
1720
|
//#endregion
|
|
1722
1721
|
//#region src/session/persistence/atomic-write.ts
|
|
1723
1722
|
function createAtomicWriteTempPath(filePath, createUniqueId = randomUUID) {
|
|
1724
|
-
|
|
1723
|
+
const tempName = `.acpx-write.${process.pid}.${Date.now()}.${createUniqueId()}.tmp`;
|
|
1724
|
+
return path.join(path.dirname(filePath), tempName);
|
|
1725
1725
|
}
|
|
1726
1726
|
//#endregion
|
|
1727
1727
|
//#region src/session/persistence/index.ts
|
|
@@ -2633,9 +2633,41 @@ function getAcpxVersion() {
|
|
|
2633
2633
|
cachedVersion = resolveAcpxVersion();
|
|
2634
2634
|
return cachedVersion;
|
|
2635
2635
|
}
|
|
2636
|
-
|
|
2637
|
-
|
|
2638
|
-
|
|
2636
|
+
async function runTimedExecFile(command, args, options = {}) {
|
|
2637
|
+
const timeoutMs = Math.max(1, Math.round(options.timeoutMs ?? 8e3));
|
|
2638
|
+
return await new Promise((resolve, reject) => {
|
|
2639
|
+
let settled = false;
|
|
2640
|
+
let timer;
|
|
2641
|
+
const child = execFile(command, [...args], {
|
|
2642
|
+
encoding: "utf8",
|
|
2643
|
+
maxBuffer: options.maxBufferBytes ?? 33554432,
|
|
2644
|
+
killSignal: "SIGKILL",
|
|
2645
|
+
windowsHide: options.windowsHide
|
|
2646
|
+
}, (error, stdout) => {
|
|
2647
|
+
if (settled) return;
|
|
2648
|
+
settled = true;
|
|
2649
|
+
if (timer) clearTimeout(timer);
|
|
2650
|
+
if (error) {
|
|
2651
|
+
reject(error);
|
|
2652
|
+
return;
|
|
2653
|
+
}
|
|
2654
|
+
resolve(stdout);
|
|
2655
|
+
});
|
|
2656
|
+
timer = setTimeout(() => {
|
|
2657
|
+
if (settled) return;
|
|
2658
|
+
settled = true;
|
|
2659
|
+
const killed = child.kill("SIGKILL");
|
|
2660
|
+
child.stdout?.destroy();
|
|
2661
|
+
child.stderr?.destroy();
|
|
2662
|
+
child.unref();
|
|
2663
|
+
reject(Object.assign(/* @__PURE__ */ new Error(`${command} timed out after ${timeoutMs}ms`), {
|
|
2664
|
+
code: "ETIMEDOUT",
|
|
2665
|
+
killed,
|
|
2666
|
+
signal: "SIGKILL"
|
|
2667
|
+
}));
|
|
2668
|
+
}, timeoutMs);
|
|
2669
|
+
});
|
|
2670
|
+
}
|
|
2639
2671
|
function normalizeAgentCommandInput(value) {
|
|
2640
2672
|
if (typeof value === "string") return { agentCommand: value };
|
|
2641
2673
|
const parts = toCommandParts([...value]);
|
|
@@ -2832,8 +2864,7 @@ function isWindowsExecutableCommand(command) {
|
|
|
2832
2864
|
return WINDOWS_EXECUTABLE_EXTENSION_RE.test(normalized);
|
|
2833
2865
|
}
|
|
2834
2866
|
async function runWslpath(cwd) {
|
|
2835
|
-
|
|
2836
|
-
return stdout;
|
|
2867
|
+
return await runTimedExecFile("wslpath", ["-w", cwd]);
|
|
2837
2868
|
}
|
|
2838
2869
|
function basenameToken(value) {
|
|
2839
2870
|
return path.basename(value).toLowerCase().replace(/\.(cmd|exe|bat)$/u, "");
|
|
@@ -3376,6 +3407,7 @@ var TerminalManager = class {
|
|
|
3376
3407
|
usesDefaultConfirmExecute;
|
|
3377
3408
|
confirmExecute;
|
|
3378
3409
|
killGraceMs;
|
|
3410
|
+
processHelperTimeoutMs;
|
|
3379
3411
|
terminals = /* @__PURE__ */ new Map();
|
|
3380
3412
|
constructor(options) {
|
|
3381
3413
|
this.cwd = options.cwd;
|
|
@@ -3385,6 +3417,7 @@ var TerminalManager = class {
|
|
|
3385
3417
|
this.usesDefaultConfirmExecute = options.confirmExecute == null;
|
|
3386
3418
|
this.confirmExecute = options.confirmExecute ?? defaultConfirmExecute;
|
|
3387
3419
|
this.killGraceMs = Math.max(0, Math.round(options.killGraceMs ?? DEFAULT_KILL_GRACE_MS));
|
|
3420
|
+
this.processHelperTimeoutMs = Math.max(1, Math.round(options.processHelperTimeoutMs ?? 8e3));
|
|
3388
3421
|
}
|
|
3389
3422
|
updatePermissionPolicy(permissionMode, nonInteractivePermissions) {
|
|
3390
3423
|
this.permissionMode = permissionMode;
|
|
@@ -3411,6 +3444,7 @@ var TerminalManager = class {
|
|
|
3411
3444
|
process: proc,
|
|
3412
3445
|
killProcessGroup: spawnCommand.killProcessGroup,
|
|
3413
3446
|
descendantPids: /* @__PURE__ */ new Set(),
|
|
3447
|
+
processHelperTimeoutMs: this.processHelperTimeoutMs,
|
|
3414
3448
|
output: Buffer.alloc(0),
|
|
3415
3449
|
truncated: false,
|
|
3416
3450
|
outputByteLimit,
|
|
@@ -3636,7 +3670,7 @@ var TerminalManager = class {
|
|
|
3636
3670
|
}
|
|
3637
3671
|
async captureDescendantPids(terminal, pid) {
|
|
3638
3672
|
if (!this.isRunning(terminal)) await terminal.processGroupSnapshotPromise?.catch(() => {});
|
|
3639
|
-
for (const descendantPid of await listDescendantPids(pid)) terminal.descendantPids.add(descendantPid);
|
|
3673
|
+
for (const descendantPid of await listDescendantPids(pid, terminal.processHelperTimeoutMs)) terminal.descendantPids.add(descendantPid);
|
|
3640
3674
|
}
|
|
3641
3675
|
async waitForCleanupAfterSignal(terminal) {
|
|
3642
3676
|
return await Promise.race([this.waitForTerminalAndTrackedDescendants(terminal).then(() => true), waitMs(this.killGraceMs).then(() => false)]);
|
|
@@ -3689,10 +3723,10 @@ function commandPathExists(command, cwd) {
|
|
|
3689
3723
|
const resolvedPath = path.isAbsolute(command) ? command : path.resolve(cwd, command);
|
|
3690
3724
|
return fs.existsSync(resolvedPath);
|
|
3691
3725
|
}
|
|
3692
|
-
async function listDescendantPids(rootPid) {
|
|
3726
|
+
async function listDescendantPids(rootPid, timeoutMs) {
|
|
3693
3727
|
let output;
|
|
3694
3728
|
try {
|
|
3695
|
-
output = await runProcessListCommand();
|
|
3729
|
+
output = await runProcessListCommand(timeoutMs);
|
|
3696
3730
|
} catch {
|
|
3697
3731
|
return [];
|
|
3698
3732
|
}
|
|
@@ -3725,47 +3759,23 @@ function parseProcessListLine(line) {
|
|
|
3725
3759
|
parentPid
|
|
3726
3760
|
};
|
|
3727
3761
|
}
|
|
3728
|
-
async function runProcessListCommand() {
|
|
3729
|
-
if (process.platform === "win32") return await runWindowsProcessListCommand();
|
|
3730
|
-
return await
|
|
3731
|
-
const child = spawn("ps", ["-eo", "pid=,ppid="], { stdio: [
|
|
3732
|
-
"ignore",
|
|
3733
|
-
"pipe",
|
|
3734
|
-
"pipe"
|
|
3735
|
-
] });
|
|
3736
|
-
let stdout = "";
|
|
3737
|
-
let stderr = "";
|
|
3738
|
-
child.stdout.setEncoding("utf8");
|
|
3739
|
-
child.stderr.setEncoding("utf8");
|
|
3740
|
-
child.stdout.on("data", (chunk) => {
|
|
3741
|
-
stdout += chunk;
|
|
3742
|
-
});
|
|
3743
|
-
child.stderr.on("data", (chunk) => {
|
|
3744
|
-
stderr += chunk;
|
|
3745
|
-
});
|
|
3746
|
-
child.once("error", reject);
|
|
3747
|
-
child.once("close", (code, signal) => {
|
|
3748
|
-
if (code === 0) {
|
|
3749
|
-
resolve(stdout);
|
|
3750
|
-
return;
|
|
3751
|
-
}
|
|
3752
|
-
reject(/* @__PURE__ */ new Error(`ps exited with code ${code ?? "null"} signal ${signal ?? "null"}: ${stderr}`));
|
|
3753
|
-
});
|
|
3754
|
-
});
|
|
3762
|
+
async function runProcessListCommand(timeoutMs) {
|
|
3763
|
+
if (process.platform === "win32") return await runWindowsProcessListCommand(timeoutMs);
|
|
3764
|
+
return await runTimedExecFile("ps", ["-eo", "pid=,ppid="], { timeoutMs });
|
|
3755
3765
|
}
|
|
3756
3766
|
async function rememberProcessGroupPids(terminal) {
|
|
3757
3767
|
const processGroupId = terminal.process.pid;
|
|
3758
3768
|
if (!terminal.killProcessGroup || !processGroupId) return;
|
|
3759
3769
|
if (process.platform === "win32") {
|
|
3760
|
-
for (const pid of await listDescendantPids(processGroupId)) terminal.descendantPids.add(pid);
|
|
3770
|
+
for (const pid of await listDescendantPids(processGroupId, terminal.processHelperTimeoutMs)) terminal.descendantPids.add(pid);
|
|
3761
3771
|
return;
|
|
3762
3772
|
}
|
|
3763
|
-
for (const pid of await listProcessGroupPids(processGroupId)) if (pid !== processGroupId) terminal.descendantPids.add(pid);
|
|
3773
|
+
for (const pid of await listProcessGroupPids(processGroupId, terminal.processHelperTimeoutMs)) if (pid !== processGroupId) terminal.descendantPids.add(pid);
|
|
3764
3774
|
}
|
|
3765
|
-
async function listProcessGroupPids(processGroupId) {
|
|
3775
|
+
async function listProcessGroupPids(processGroupId, timeoutMs) {
|
|
3766
3776
|
let output;
|
|
3767
3777
|
try {
|
|
3768
|
-
output = await runProcessGroupListCommand();
|
|
3778
|
+
output = await runProcessGroupListCommand(timeoutMs);
|
|
3769
3779
|
} catch {
|
|
3770
3780
|
return [];
|
|
3771
3781
|
}
|
|
@@ -3779,66 +3789,18 @@ async function listProcessGroupPids(processGroupId) {
|
|
|
3779
3789
|
}
|
|
3780
3790
|
return pids;
|
|
3781
3791
|
}
|
|
3782
|
-
async function runProcessGroupListCommand() {
|
|
3783
|
-
return await
|
|
3784
|
-
|
|
3785
|
-
|
|
3786
|
-
|
|
3787
|
-
|
|
3788
|
-
|
|
3789
|
-
|
|
3790
|
-
|
|
3791
|
-
|
|
3792
|
-
|
|
3793
|
-
|
|
3794
|
-
stdout += chunk;
|
|
3795
|
-
});
|
|
3796
|
-
child.stderr.on("data", (chunk) => {
|
|
3797
|
-
stderr += chunk;
|
|
3798
|
-
});
|
|
3799
|
-
child.once("error", reject);
|
|
3800
|
-
child.once("close", (code, signal) => {
|
|
3801
|
-
if (code === 0) {
|
|
3802
|
-
resolve(stdout);
|
|
3803
|
-
return;
|
|
3804
|
-
}
|
|
3805
|
-
reject(/* @__PURE__ */ new Error(`ps exited with code ${code ?? "null"} signal ${signal ?? "null"}: ${stderr}`));
|
|
3806
|
-
});
|
|
3807
|
-
});
|
|
3808
|
-
}
|
|
3809
|
-
async function runWindowsProcessListCommand() {
|
|
3810
|
-
return await new Promise((resolve, reject) => {
|
|
3811
|
-
const child = spawn("powershell.exe", [
|
|
3812
|
-
"-NoProfile",
|
|
3813
|
-
"-NonInteractive",
|
|
3814
|
-
"-Command",
|
|
3815
|
-
["Get-CimInstance Win32_Process |", "ForEach-Object { \"$($_.ProcessId) $($_.ParentProcessId)\" }"].join(" ")
|
|
3816
|
-
], {
|
|
3817
|
-
stdio: [
|
|
3818
|
-
"ignore",
|
|
3819
|
-
"pipe",
|
|
3820
|
-
"pipe"
|
|
3821
|
-
],
|
|
3822
|
-
windowsHide: true
|
|
3823
|
-
});
|
|
3824
|
-
let stdout = "";
|
|
3825
|
-
let stderr = "";
|
|
3826
|
-
child.stdout.setEncoding("utf8");
|
|
3827
|
-
child.stderr.setEncoding("utf8");
|
|
3828
|
-
child.stdout.on("data", (chunk) => {
|
|
3829
|
-
stdout += chunk;
|
|
3830
|
-
});
|
|
3831
|
-
child.stderr.on("data", (chunk) => {
|
|
3832
|
-
stderr += chunk;
|
|
3833
|
-
});
|
|
3834
|
-
child.once("error", reject);
|
|
3835
|
-
child.once("close", (code, signal) => {
|
|
3836
|
-
if (code === 0) {
|
|
3837
|
-
resolve(stdout);
|
|
3838
|
-
return;
|
|
3839
|
-
}
|
|
3840
|
-
reject(/* @__PURE__ */ new Error(`powershell process list exited with code ${code ?? "null"} signal ${signal ?? "null"}: ${stderr}`));
|
|
3841
|
-
});
|
|
3792
|
+
async function runProcessGroupListCommand(timeoutMs) {
|
|
3793
|
+
return await runTimedExecFile("ps", ["-eo", "pid=,pgid="], { timeoutMs });
|
|
3794
|
+
}
|
|
3795
|
+
async function runWindowsProcessListCommand(timeoutMs) {
|
|
3796
|
+
return await runTimedExecFile("powershell.exe", [
|
|
3797
|
+
"-NoProfile",
|
|
3798
|
+
"-NonInteractive",
|
|
3799
|
+
"-Command",
|
|
3800
|
+
["Get-CimInstance Win32_Process |", "ForEach-Object { \"$($_.ProcessId) $($_.ParentProcessId)\" }"].join(" ")
|
|
3801
|
+
], {
|
|
3802
|
+
timeoutMs,
|
|
3803
|
+
windowsHide: true
|
|
3842
3804
|
});
|
|
3843
3805
|
}
|
|
3844
3806
|
async function killWindowsProcessTree(pid, signal) {
|
|
@@ -3898,6 +3860,14 @@ const STARTUP_STDERR_MAX_CHARS = 8192;
|
|
|
3898
3860
|
const DEVIN_COMPATIBILITY_CLIENT_CAPABILITIES_META = Object.freeze({ "cognition.ai/requestDiagnostics": true });
|
|
3899
3861
|
const DEVIN_COMPATIBILITY_CLIENT_NAME = "windsurf";
|
|
3900
3862
|
const DEFAULT_DEVIN_COMPATIBILITY_CLIENT_VERSION = "1.110.1";
|
|
3863
|
+
const ELICITATION_CANCEL_MESSAGES = {
|
|
3864
|
+
inactive: "elicitation owner is no longer active",
|
|
3865
|
+
unavailable: "elicitation handler is unavailable",
|
|
3866
|
+
unsupported: "elicitation mode is not supported",
|
|
3867
|
+
mismatchedSession: "elicitation session is not active",
|
|
3868
|
+
cancelled: "elicitation request was cancelled",
|
|
3869
|
+
requestScoped: "request-scoped elicitation has no owner"
|
|
3870
|
+
};
|
|
3901
3871
|
function resolveClientInfo(devinAcp) {
|
|
3902
3872
|
if (!devinAcp) return {
|
|
3903
3873
|
name: "acpx",
|
|
@@ -3908,13 +3878,88 @@ function resolveClientInfo(devinAcp) {
|
|
|
3908
3878
|
version: process.env.ACPX_DEVIN_WINDSURF_VERSION ?? DEFAULT_DEVIN_COMPATIBILITY_CLIENT_VERSION
|
|
3909
3879
|
};
|
|
3910
3880
|
}
|
|
3881
|
+
function normalizeElicitationModes(modes) {
|
|
3882
|
+
return [...new Set((modes ?? []).filter((mode) => mode === "form" || mode === "url"))];
|
|
3883
|
+
}
|
|
3884
|
+
function cancelledElicitationResponse(message) {
|
|
3885
|
+
return {
|
|
3886
|
+
action: "cancel",
|
|
3887
|
+
_meta: { message }
|
|
3888
|
+
};
|
|
3889
|
+
}
|
|
3890
|
+
function isKnownElicitationResponse(response) {
|
|
3891
|
+
if (!response || typeof response !== "object") return false;
|
|
3892
|
+
const action = response.action;
|
|
3893
|
+
return action === "accept" || action === "decline" || action === "cancel";
|
|
3894
|
+
}
|
|
3895
|
+
function elicitationSessionId(request) {
|
|
3896
|
+
const value = request.sessionId;
|
|
3897
|
+
return typeof value === "string" ? value : void 0;
|
|
3898
|
+
}
|
|
3899
|
+
function elicitationRequestScopeId(request) {
|
|
3900
|
+
const value = request.requestId;
|
|
3901
|
+
return value === null || typeof value === "string" || typeof value === "number" ? value : void 0;
|
|
3902
|
+
}
|
|
3903
|
+
function waitForAbort(signal) {
|
|
3904
|
+
if (signal.aborted) return Promise.resolve({ kind: "aborted" });
|
|
3905
|
+
return new Promise((resolve) => {
|
|
3906
|
+
signal.addEventListener("abort", () => resolve({ kind: "aborted" }), { once: true });
|
|
3907
|
+
});
|
|
3908
|
+
}
|
|
3909
|
+
function isExtensionNotification(message) {
|
|
3910
|
+
if (!("method" in message) || "id" in message || typeof message.method !== "string") return false;
|
|
3911
|
+
return message.method !== methods.client.session.update && message.method !== methods.client.elicitation.complete && message.method !== methods.protocol.cancelRequest;
|
|
3912
|
+
}
|
|
3913
|
+
function elicitationRequestId(message) {
|
|
3914
|
+
if (!("method" in message) || message.method !== methods.client.elicitation.create || !("id" in message)) return;
|
|
3915
|
+
return message.id;
|
|
3916
|
+
}
|
|
3917
|
+
function responseId(message) {
|
|
3918
|
+
if (!("id" in message) || "method" in message) return;
|
|
3919
|
+
return message.id;
|
|
3920
|
+
}
|
|
3921
|
+
function promptRequestOwner(message) {
|
|
3922
|
+
if (!("method" in message) || message.method !== methods.agent.session.prompt || !("id" in message)) return;
|
|
3923
|
+
const sessionId = message.params?.sessionId;
|
|
3924
|
+
return typeof sessionId === "string" ? {
|
|
3925
|
+
requestId: message.id,
|
|
3926
|
+
sessionId
|
|
3927
|
+
} : void 0;
|
|
3928
|
+
}
|
|
3929
|
+
function createAgentConnectionFacade(connection) {
|
|
3930
|
+
const agent = connection.agent;
|
|
3931
|
+
return {
|
|
3932
|
+
signal: connection.signal,
|
|
3933
|
+
close: (error) => connection.close(error),
|
|
3934
|
+
initialize: async (params) => await agent.request(methods.agent.initialize, params),
|
|
3935
|
+
authenticate: async (params) => {
|
|
3936
|
+
await agent.request(methods.agent.authenticate, params);
|
|
3937
|
+
},
|
|
3938
|
+
newSession: async (params) => await agent.request(methods.agent.session.new, params),
|
|
3939
|
+
loadSession: async (params) => await agent.request(methods.agent.session.load, params),
|
|
3940
|
+
resumeSession: async (params) => await agent.request(methods.agent.session.resume, params),
|
|
3941
|
+
prompt: async (params) => await agent.request(methods.agent.session.prompt, params),
|
|
3942
|
+
setSessionMode: async (params) => await agent.request(methods.agent.session.setMode, params),
|
|
3943
|
+
setSessionConfigOption: async (params) => await agent.request(methods.agent.session.setConfigOption, params),
|
|
3944
|
+
extMethod: async (method, params) => await agent.request(method, params),
|
|
3945
|
+
cancel: async (params) => await agent.notify(methods.agent.session.cancel, params),
|
|
3946
|
+
closeSession: async (params) => {
|
|
3947
|
+
await agent.request(methods.agent.session.close, params);
|
|
3948
|
+
},
|
|
3949
|
+
listSessions: async (params) => await agent.request(methods.agent.session.list, params)
|
|
3950
|
+
};
|
|
3951
|
+
}
|
|
3911
3952
|
function resolveClientCapabilities(params) {
|
|
3912
3953
|
const baseCapabilities = {
|
|
3913
3954
|
fs: {
|
|
3914
3955
|
readTextFile: params.fs,
|
|
3915
3956
|
writeTextFile: params.fs
|
|
3916
3957
|
},
|
|
3917
|
-
terminal: params.terminal
|
|
3958
|
+
terminal: params.terminal,
|
|
3959
|
+
...params.elicitationModes.length > 0 ? { elicitation: {
|
|
3960
|
+
...params.elicitationModes.includes("form") ? { form: {} } : {},
|
|
3961
|
+
...params.elicitationModes.includes("url") ? { url: {} } : {}
|
|
3962
|
+
} } : {}
|
|
3918
3963
|
};
|
|
3919
3964
|
if (!params.devinAcp) return baseCapabilities;
|
|
3920
3965
|
return {
|
|
@@ -3922,9 +3967,6 @@ function resolveClientCapabilities(params) {
|
|
|
3922
3967
|
_meta: DEVIN_COMPATIBILITY_CLIENT_CAPABILITIES_META
|
|
3923
3968
|
};
|
|
3924
3969
|
}
|
|
3925
|
-
function isDevinRequestDiagnosticsMethod(method) {
|
|
3926
|
-
return method === "_cognition.ai/request_diagnostics";
|
|
3927
|
-
}
|
|
3928
3970
|
function hasResponseField(response, field) {
|
|
3929
3971
|
return !!response && typeof response === "object" && field in response;
|
|
3930
3972
|
}
|
|
@@ -3945,6 +3987,15 @@ function toReconnectedSessionResult(response) {
|
|
|
3945
3987
|
legacyModelMetadataPresent: hasResponseField(response, "models")
|
|
3946
3988
|
};
|
|
3947
3989
|
}
|
|
3990
|
+
function snapshotPermissionPolicy(policy) {
|
|
3991
|
+
if (!policy) return;
|
|
3992
|
+
return {
|
|
3993
|
+
...policy.autoApprove ? { autoApprove: [...policy.autoApprove] } : {},
|
|
3994
|
+
...policy.autoDeny ? { autoDeny: [...policy.autoDeny] } : {},
|
|
3995
|
+
...policy.escalate ? { escalate: [...policy.escalate] } : {},
|
|
3996
|
+
...policy.defaultAction ? { defaultAction: policy.defaultAction } : {}
|
|
3997
|
+
};
|
|
3998
|
+
}
|
|
3948
3999
|
function childProcessIsRunning(agent) {
|
|
3949
4000
|
if (!agent) return false;
|
|
3950
4001
|
return agent.exitCode == null && agent.signalCode == null && !agent.killed;
|
|
@@ -4037,6 +4088,7 @@ var AcpClient = class {
|
|
|
4037
4088
|
suppressSessionUpdates = false;
|
|
4038
4089
|
suppressReplaySessionUpdateMessages = false;
|
|
4039
4090
|
activePrompt;
|
|
4091
|
+
pendingPromptOwners = [];
|
|
4040
4092
|
cancellingSessionIds = /* @__PURE__ */ new Set();
|
|
4041
4093
|
permissionAbortControllers = /* @__PURE__ */ new Map();
|
|
4042
4094
|
closing = false;
|
|
@@ -4051,7 +4103,9 @@ var AcpClient = class {
|
|
|
4051
4103
|
this.options = {
|
|
4052
4104
|
...options,
|
|
4053
4105
|
cwd: asAbsoluteCwd(options.cwd),
|
|
4054
|
-
authPolicy: options.authPolicy ?? "skip"
|
|
4106
|
+
authPolicy: options.authPolicy ?? "skip",
|
|
4107
|
+
permissionPolicy: snapshotPermissionPolicy(options.permissionPolicy),
|
|
4108
|
+
elicitationModes: normalizeElicitationModes(options.elicitationModes)
|
|
4055
4109
|
};
|
|
4056
4110
|
this.eventHandlers = {
|
|
4057
4111
|
onAcpMessage: this.options.onAcpMessage,
|
|
@@ -4118,7 +4172,7 @@ var AcpClient = class {
|
|
|
4118
4172
|
const shouldRefreshPermissionPolicy = options.permissionMode !== void 0 || options.nonInteractivePermissions !== void 0;
|
|
4119
4173
|
if (options.permissionMode) this.options.permissionMode = options.permissionMode;
|
|
4120
4174
|
if (options.nonInteractivePermissions !== void 0) this.options.nonInteractivePermissions = options.nonInteractivePermissions;
|
|
4121
|
-
if (Object.prototype.hasOwnProperty.call(options, "permissionPolicy")) this.options.permissionPolicy = options.permissionPolicy;
|
|
4175
|
+
if (Object.prototype.hasOwnProperty.call(options, "permissionPolicy")) this.options.permissionPolicy = snapshotPermissionPolicy(options.permissionPolicy);
|
|
4122
4176
|
this.updateClientCapabilityPreferences(options);
|
|
4123
4177
|
this.refreshRuntimePermissionPolicy(shouldRefreshPermissionPolicy);
|
|
4124
4178
|
if (options.suppressSdkConsoleErrors !== void 0) this.options.suppressSdkConsoleErrors = options.suppressSdkConsoleErrors;
|
|
@@ -4141,6 +4195,15 @@ var AcpClient = class {
|
|
|
4141
4195
|
if (sessionId == null) return true;
|
|
4142
4196
|
return this.activePrompt.sessionId === sessionId;
|
|
4143
4197
|
}
|
|
4198
|
+
hasUnresolvedPrompt() {
|
|
4199
|
+
return this.activePrompt !== void 0;
|
|
4200
|
+
}
|
|
4201
|
+
endPromptElicitation(sessionId) {
|
|
4202
|
+
const active = this.activePrompt;
|
|
4203
|
+
if (!active || active.sessionId !== sessionId) return;
|
|
4204
|
+
active.elicitationHandler = void 0;
|
|
4205
|
+
active.elicitationController.abort();
|
|
4206
|
+
}
|
|
4144
4207
|
async start() {
|
|
4145
4208
|
if (this.connection && this.agent && isChildProcessRunning(this.agent)) return;
|
|
4146
4209
|
if (this.connection || this.agent) await this.close();
|
|
@@ -4228,42 +4291,31 @@ var AcpClient = class {
|
|
|
4228
4291
|
return requireAgentStdio(spawnedChild);
|
|
4229
4292
|
}
|
|
4230
4293
|
createConnection(stream, launch) {
|
|
4231
|
-
|
|
4232
|
-
|
|
4233
|
-
|
|
4234
|
-
|
|
4235
|
-
|
|
4236
|
-
|
|
4237
|
-
|
|
4238
|
-
|
|
4239
|
-
|
|
4240
|
-
|
|
4241
|
-
|
|
4242
|
-
|
|
4243
|
-
|
|
4244
|
-
|
|
4245
|
-
|
|
4246
|
-
|
|
4247
|
-
|
|
4248
|
-
|
|
4249
|
-
|
|
4250
|
-
|
|
4251
|
-
|
|
4252
|
-
|
|
4253
|
-
|
|
4254
|
-
|
|
4255
|
-
|
|
4256
|
-
waitForTerminalExit: async (params) => {
|
|
4257
|
-
return this.handleWaitForTerminalExit(params);
|
|
4258
|
-
},
|
|
4259
|
-
killTerminal: async (params) => {
|
|
4260
|
-
return this.handleKillTerminal(params);
|
|
4261
|
-
},
|
|
4262
|
-
releaseTerminal: async (params) => {
|
|
4263
|
-
return this.handleReleaseTerminal(params);
|
|
4264
|
-
},
|
|
4265
|
-
extNotification: async () => {}
|
|
4266
|
-
}), stream);
|
|
4294
|
+
const app = client({ name: "acpx" }).onNotification(methods.client.session.update, async ({ params }) => {
|
|
4295
|
+
await this.handleSessionUpdate(params);
|
|
4296
|
+
}).onNotification(methods.client.elicitation.complete, async () => {}).onRequest(methods.client.session.requestPermission, async ({ params }) => {
|
|
4297
|
+
return await this.handlePermissionRequest(params);
|
|
4298
|
+
}).onRequest(methods.client.elicitation.create, async ({ params, requestId, signal }) => {
|
|
4299
|
+
return await this.handleElicitationRequest(params, requestId, signal);
|
|
4300
|
+
}).onRequest(methods.client.fs.readTextFile, async ({ params }) => {
|
|
4301
|
+
return await this.handleReadTextFile(params);
|
|
4302
|
+
}).onRequest(methods.client.fs.writeTextFile, async ({ params }) => {
|
|
4303
|
+
return await this.handleWriteTextFile(params);
|
|
4304
|
+
}).onRequest(methods.client.terminal.create, async ({ params }) => {
|
|
4305
|
+
return await this.handleCreateTerminal(params);
|
|
4306
|
+
}).onRequest(methods.client.terminal.output, async ({ params }) => {
|
|
4307
|
+
return await this.handleTerminalOutput(params);
|
|
4308
|
+
}).onRequest(methods.client.terminal.waitForExit, async ({ params }) => {
|
|
4309
|
+
return await this.handleWaitForTerminalExit(params);
|
|
4310
|
+
}).onRequest(methods.client.terminal.kill, async ({ params }) => {
|
|
4311
|
+
return await this.handleKillTerminal(params);
|
|
4312
|
+
}).onRequest(methods.client.terminal.release, async ({ params }) => {
|
|
4313
|
+
return await this.handleReleaseTerminal(params);
|
|
4314
|
+
});
|
|
4315
|
+
if (launch.devinAcp) app.onRequest("_cognition.ai/request_diagnostics", (params) => {
|
|
4316
|
+
return params && typeof params === "object" && !Array.isArray(params) ? params : {};
|
|
4317
|
+
}, async () => ({}));
|
|
4318
|
+
return createAgentConnectionFacade(app.connect(stream));
|
|
4267
4319
|
}
|
|
4268
4320
|
async initializeAgentConnection(params) {
|
|
4269
4321
|
try {
|
|
@@ -4274,6 +4326,7 @@ var AcpClient = class {
|
|
|
4274
4326
|
this.initResult = initResult;
|
|
4275
4327
|
this.log(`initialized protocol version ${initResult.protocolVersion}`);
|
|
4276
4328
|
} catch (error) {
|
|
4329
|
+
params.connection.close?.(error);
|
|
4277
4330
|
await this.handleInitializeFailure(params, error);
|
|
4278
4331
|
}
|
|
4279
4332
|
}
|
|
@@ -4283,7 +4336,8 @@ var AcpClient = class {
|
|
|
4283
4336
|
clientCapabilities: resolveClientCapabilities({
|
|
4284
4337
|
devinAcp: launch.devinAcp,
|
|
4285
4338
|
fs: this.options.fs !== false,
|
|
4286
|
-
terminal: this.options.terminal !== false
|
|
4339
|
+
terminal: this.options.terminal !== false,
|
|
4340
|
+
elicitationModes: this.options.elicitationModes ?? []
|
|
4287
4341
|
}),
|
|
4288
4342
|
clientInfo: resolveClientInfo(launch.devinAcp)
|
|
4289
4343
|
});
|
|
@@ -4306,9 +4360,24 @@ var AcpClient = class {
|
|
|
4306
4360
|
createTappedStream(base) {
|
|
4307
4361
|
const onAcpMessage = () => this.eventHandlers.onAcpMessage;
|
|
4308
4362
|
const onAcpOutputMessage = () => this.eventHandlers.onAcpOutputMessage;
|
|
4363
|
+
const elicitationRequestIds = /* @__PURE__ */ new Set();
|
|
4364
|
+
const bindPromptOwner = (owner) => {
|
|
4365
|
+
this.bindPromptOwner(owner);
|
|
4366
|
+
};
|
|
4309
4367
|
const shouldSuppressInboundReplaySessionUpdate = (message) => {
|
|
4310
4368
|
return this.suppressReplaySessionUpdateMessages && isSessionUpdateNotification(message);
|
|
4311
4369
|
};
|
|
4370
|
+
const observeInbound = (message) => {
|
|
4371
|
+
const requestId = elicitationRequestId(message);
|
|
4372
|
+
if (requestId !== void 0) {
|
|
4373
|
+
elicitationRequestIds.add(requestId);
|
|
4374
|
+
return;
|
|
4375
|
+
}
|
|
4376
|
+
if (!shouldSuppressInboundReplaySessionUpdate(message)) {
|
|
4377
|
+
onAcpOutputMessage()?.("inbound", message);
|
|
4378
|
+
onAcpMessage()?.("inbound", message);
|
|
4379
|
+
}
|
|
4380
|
+
};
|
|
4312
4381
|
return {
|
|
4313
4382
|
readable: new ReadableStream({ async start(controller) {
|
|
4314
4383
|
const reader = base.readable.getReader();
|
|
@@ -4317,10 +4386,8 @@ var AcpClient = class {
|
|
|
4317
4386
|
const { value, done } = await reader.read();
|
|
4318
4387
|
if (done) break;
|
|
4319
4388
|
if (!value) continue;
|
|
4320
|
-
|
|
4321
|
-
|
|
4322
|
-
onAcpMessage()?.("inbound", value);
|
|
4323
|
-
}
|
|
4389
|
+
observeInbound(value);
|
|
4390
|
+
if (isExtensionNotification(value)) continue;
|
|
4324
4391
|
controller.enqueue(value);
|
|
4325
4392
|
}
|
|
4326
4393
|
} finally {
|
|
@@ -4329,8 +4396,13 @@ var AcpClient = class {
|
|
|
4329
4396
|
}
|
|
4330
4397
|
} }),
|
|
4331
4398
|
writable: new WritableStream({ async write(message) {
|
|
4332
|
-
|
|
4333
|
-
|
|
4399
|
+
const promptOwner = promptRequestOwner(message);
|
|
4400
|
+
if (promptOwner) bindPromptOwner(promptOwner);
|
|
4401
|
+
const id = responseId(message);
|
|
4402
|
+
if (!(id !== void 0 && elicitationRequestIds.delete(id))) {
|
|
4403
|
+
onAcpOutputMessage()?.("outbound", message);
|
|
4404
|
+
onAcpMessage()?.("outbound", message);
|
|
4405
|
+
}
|
|
4334
4406
|
const writer = base.writable.getWriter();
|
|
4335
4407
|
try {
|
|
4336
4408
|
await writer.write(message);
|
|
@@ -4426,24 +4498,23 @@ var AcpClient = class {
|
|
|
4426
4498
|
this.suppressSessionUpdates = previous.suppressSessionUpdates;
|
|
4427
4499
|
this.suppressReplaySessionUpdateMessages = previous.suppressReplaySessionUpdateMessages;
|
|
4428
4500
|
}
|
|
4429
|
-
async prompt(sessionId, prompt) {
|
|
4501
|
+
async prompt(sessionId, prompt, onRequestStarted, onElicitation) {
|
|
4430
4502
|
const connection = this.getConnection();
|
|
4431
4503
|
const normalizedPrompt = this.normalizePromptForAgent(prompt);
|
|
4432
4504
|
const restoreConsoleError = this.options.suppressSdkConsoleErrors ? installSdkConsoleErrorSuppression() : void 0;
|
|
4505
|
+
const activePrompt = this.beginActivePrompt(sessionId, onElicitation);
|
|
4433
4506
|
let promptPromise;
|
|
4434
4507
|
try {
|
|
4435
4508
|
promptPromise = this.runConnectionRequest(() => connection.prompt({
|
|
4436
4509
|
sessionId,
|
|
4437
4510
|
prompt: normalizedPrompt
|
|
4438
|
-
}));
|
|
4511
|
+
}), onRequestStarted, () => !connection.signal?.aborted);
|
|
4439
4512
|
} catch (error) {
|
|
4513
|
+
this.clearActivePrompt(activePrompt);
|
|
4440
4514
|
restoreConsoleError?.();
|
|
4441
4515
|
throw error;
|
|
4442
4516
|
}
|
|
4443
|
-
|
|
4444
|
-
sessionId,
|
|
4445
|
-
promise: promptPromise
|
|
4446
|
-
};
|
|
4517
|
+
activePrompt.promise = promptPromise;
|
|
4447
4518
|
try {
|
|
4448
4519
|
return this.returnPromptResponseOrPermissionFailure(sessionId, await promptPromise);
|
|
4449
4520
|
} catch (error) {
|
|
@@ -4451,12 +4522,37 @@ var AcpClient = class {
|
|
|
4451
4522
|
throw error;
|
|
4452
4523
|
} finally {
|
|
4453
4524
|
restoreConsoleError?.();
|
|
4454
|
-
|
|
4525
|
+
this.clearActivePrompt(activePrompt);
|
|
4455
4526
|
this.cancellingSessionIds.delete(sessionId);
|
|
4456
4527
|
this.abortAndDropPermissionSignal(sessionId);
|
|
4457
4528
|
this.promptPermissionFailures.delete(sessionId);
|
|
4458
4529
|
}
|
|
4459
4530
|
}
|
|
4531
|
+
beginActivePrompt(sessionId, elicitationHandler) {
|
|
4532
|
+
const previous = this.activePrompt;
|
|
4533
|
+
this.cancellingSessionIds.delete(sessionId);
|
|
4534
|
+
const active = {
|
|
4535
|
+
sessionId,
|
|
4536
|
+
elicitationHandler,
|
|
4537
|
+
elicitationController: new AbortController()
|
|
4538
|
+
};
|
|
4539
|
+
this.activePrompt = active;
|
|
4540
|
+
this.pendingPromptOwners.push(active);
|
|
4541
|
+
previous?.elicitationController?.abort();
|
|
4542
|
+
return active;
|
|
4543
|
+
}
|
|
4544
|
+
bindPromptOwner(owner) {
|
|
4545
|
+
const active = this.pendingPromptOwners.find((candidate) => {
|
|
4546
|
+
return candidate.requestId === void 0 && candidate.sessionId === owner.sessionId;
|
|
4547
|
+
});
|
|
4548
|
+
if (active) active.requestId = owner.requestId;
|
|
4549
|
+
}
|
|
4550
|
+
clearActivePrompt(active) {
|
|
4551
|
+
if (this.activePrompt === active) this.activePrompt = void 0;
|
|
4552
|
+
const pendingIndex = this.pendingPromptOwners.indexOf(active);
|
|
4553
|
+
if (pendingIndex >= 0) this.pendingPromptOwners.splice(pendingIndex, 1);
|
|
4554
|
+
active.elicitationController.abort();
|
|
4555
|
+
}
|
|
4460
4556
|
normalizePromptForAgent(prompt) {
|
|
4461
4557
|
const normalizedPrompt = typeof prompt === "string" ? textPrompt(prompt) : prompt;
|
|
4462
4558
|
const unsupportedPromptContent = getUnsupportedPromptContentMessage(normalizedPrompt, this.initResult?.agentCapabilities);
|
|
@@ -4569,12 +4665,18 @@ var AcpClient = class {
|
|
|
4569
4665
|
}
|
|
4570
4666
|
async cancel(sessionId) {
|
|
4571
4667
|
const connection = this.getConnection();
|
|
4572
|
-
this.
|
|
4668
|
+
const active = this.activePrompt;
|
|
4669
|
+
if (active?.sessionId === sessionId) {
|
|
4670
|
+
this.cancellingSessionIds.add(sessionId);
|
|
4671
|
+
active.elicitationController?.abort();
|
|
4672
|
+
} else this.cancellingSessionIds.delete(sessionId);
|
|
4573
4673
|
this.abortAndDropPermissionSignal(sessionId);
|
|
4574
4674
|
await this.runConnectionRequest(() => connection.cancel({ sessionId }));
|
|
4575
4675
|
}
|
|
4576
4676
|
async closeSession(sessionId) {
|
|
4577
4677
|
const connection = this.getConnection();
|
|
4678
|
+
this.cancellingSessionIds.add(sessionId);
|
|
4679
|
+
if (this.activePrompt?.sessionId === sessionId) this.activePrompt.elicitationController?.abort();
|
|
4578
4680
|
await this.runConnectionRequest(() => connection.closeSession({ sessionId }));
|
|
4579
4681
|
if (this.loadedSessionId === sessionId) this.loadedSessionId = void 0;
|
|
4580
4682
|
this.modelConfigIds.delete(sessionId);
|
|
@@ -4600,21 +4702,25 @@ var AcpClient = class {
|
|
|
4600
4702
|
this.log(`failed to send session/cancel: ${message}`);
|
|
4601
4703
|
}
|
|
4602
4704
|
if (waitMs <= 0) return;
|
|
4705
|
+
const activePromise = active.promise;
|
|
4706
|
+
if (!activePromise) return;
|
|
4603
4707
|
let timer;
|
|
4604
4708
|
const timeoutPromise = new Promise((resolve) => {
|
|
4605
4709
|
timer = setTimeout(resolve, waitMs);
|
|
4606
4710
|
});
|
|
4607
4711
|
try {
|
|
4608
|
-
return await Promise.race([
|
|
4712
|
+
return await Promise.race([activePromise.then((response) => response, () => void 0), timeoutPromise]);
|
|
4609
4713
|
} finally {
|
|
4610
4714
|
if (timer) clearTimeout(timer);
|
|
4611
4715
|
}
|
|
4612
4716
|
}
|
|
4613
4717
|
async close() {
|
|
4614
4718
|
this.closing = true;
|
|
4719
|
+
this.abortActiveElicitation();
|
|
4615
4720
|
await this.terminalManager.shutdown();
|
|
4616
4721
|
const agent = this.agent;
|
|
4617
4722
|
if (agent) await this.terminateAgentProcess(agent);
|
|
4723
|
+
this.closeConnection();
|
|
4618
4724
|
if (this.pendingConnectionRequests.size > 0) this.rejectPendingConnectionRequests(this.lastAgentExit ? new AgentDisconnectedError(this.lastAgentExit.reason, this.lastAgentExit.exitCode, this.lastAgentExit.signal, { outputAlreadyEmitted: Boolean(this.activePrompt) }) : new AgentDisconnectedError("connection_close", null, null, { outputAlreadyEmitted: Boolean(this.activePrompt) }));
|
|
4619
4725
|
this.sessionUpdateChain = Promise.resolve();
|
|
4620
4726
|
this.observedSessionUpdates = 0;
|
|
@@ -4622,6 +4728,7 @@ var AcpClient = class {
|
|
|
4622
4728
|
this.suppressSessionUpdates = false;
|
|
4623
4729
|
this.suppressReplaySessionUpdateMessages = false;
|
|
4624
4730
|
this.activePrompt = void 0;
|
|
4731
|
+
this.pendingPromptOwners.length = 0;
|
|
4625
4732
|
this.cancellingSessionIds.clear();
|
|
4626
4733
|
for (const controller of this.permissionAbortControllers.values()) controller.abort();
|
|
4627
4734
|
this.permissionAbortControllers.clear();
|
|
@@ -4633,6 +4740,12 @@ var AcpClient = class {
|
|
|
4633
4740
|
this.connection = void 0;
|
|
4634
4741
|
this.agent = void 0;
|
|
4635
4742
|
}
|
|
4743
|
+
abortActiveElicitation() {
|
|
4744
|
+
this.activePrompt?.elicitationController?.abort();
|
|
4745
|
+
}
|
|
4746
|
+
closeConnection() {
|
|
4747
|
+
this.connection?.close?.();
|
|
4748
|
+
}
|
|
4636
4749
|
async terminateAgentProcess(child) {
|
|
4637
4750
|
const stdinCloseGraceMs = resolveAgentCloseAfterStdinEndMs(this.options.agentCommand);
|
|
4638
4751
|
this.endAgentStdin(child);
|
|
@@ -4791,12 +4904,12 @@ var AcpClient = class {
|
|
|
4791
4904
|
const { command, args } = resolveAgentCommandParts(this.options.agentCommand, this.options.agentArgv);
|
|
4792
4905
|
return command.replace(/\\/g, "/").split("/").pop()?.replace(/\.(cmd|exe|ps1)$/iu, "").toLowerCase() === "grok" && args[0] === "agent" && args[1] === "stdio";
|
|
4793
4906
|
}
|
|
4794
|
-
async authenticateIfRequired(connection,
|
|
4795
|
-
if (
|
|
4796
|
-
const selected = this.selectAuthMethod(
|
|
4907
|
+
async authenticateIfRequired(connection, authMethods) {
|
|
4908
|
+
if (authMethods.length === 0) return;
|
|
4909
|
+
const selected = this.selectAuthMethod(authMethods);
|
|
4797
4910
|
if (!selected) {
|
|
4798
|
-
if (this.options.authPolicy === "fail") throw new AuthPolicyError(`agent advertised auth methods [${
|
|
4799
|
-
this.log(`agent advertised auth methods [${
|
|
4911
|
+
if (this.options.authPolicy === "fail") throw new AuthPolicyError(`agent advertised auth methods [${authMethods.map((m) => m.id).join(", ")}] but no matching credentials found`);
|
|
4912
|
+
this.log(`agent advertised auth methods [${authMethods.map((m) => m.id).join(", ")}] but no matching credentials found — skipping (agent may handle auth internally)`);
|
|
4800
4913
|
return;
|
|
4801
4914
|
}
|
|
4802
4915
|
await connection.authenticate({ methodId: selected.methodId });
|
|
@@ -4813,6 +4926,50 @@ var AcpClient = class {
|
|
|
4813
4926
|
}
|
|
4814
4927
|
return response;
|
|
4815
4928
|
}
|
|
4929
|
+
async handleElicitationRequest(request, requestId, requestSignal) {
|
|
4930
|
+
const resolved = this.resolveElicitationOwner(request);
|
|
4931
|
+
if ("response" in resolved) return resolved.response;
|
|
4932
|
+
const { active, handler } = resolved.owner;
|
|
4933
|
+
const signal = AbortSignal.any([requestSignal, active.elicitationController.signal]);
|
|
4934
|
+
const handlerAttempt = Promise.resolve().then(async () => await handler(request, {
|
|
4935
|
+
requestId,
|
|
4936
|
+
signal
|
|
4937
|
+
})).then((response) => ({
|
|
4938
|
+
kind: "response",
|
|
4939
|
+
response
|
|
4940
|
+
}), (error) => ({
|
|
4941
|
+
kind: "error",
|
|
4942
|
+
error
|
|
4943
|
+
}));
|
|
4944
|
+
const outcome = await Promise.race([handlerAttempt, waitForAbort(signal)]);
|
|
4945
|
+
if (this.activePrompt !== active) return cancelledElicitationResponse(ELICITATION_CANCEL_MESSAGES.inactive);
|
|
4946
|
+
if (outcome.kind === "aborted" || signal.aborted) return cancelledElicitationResponse(ELICITATION_CANCEL_MESSAGES.cancelled);
|
|
4947
|
+
if (outcome.kind === "error" || !isKnownElicitationResponse(outcome.response)) return cancelledElicitationResponse(ELICITATION_CANCEL_MESSAGES.unavailable);
|
|
4948
|
+
return outcome.response;
|
|
4949
|
+
}
|
|
4950
|
+
resolveElicitationOwner(request) {
|
|
4951
|
+
if (!this.options.elicitationModes?.includes(request.mode)) return { response: cancelledElicitationResponse(ELICITATION_CANCEL_MESSAGES.unsupported) };
|
|
4952
|
+
const active = this.activePrompt;
|
|
4953
|
+
if (!active) return { response: cancelledElicitationResponse(ELICITATION_CANCEL_MESSAGES.inactive) };
|
|
4954
|
+
const scope = this.resolveElicitationScope(request, active);
|
|
4955
|
+
if ("response" in scope) return scope;
|
|
4956
|
+
if (this.isElicitationSessionCancelling(scope.sessionId)) return { response: cancelledElicitationResponse(ELICITATION_CANCEL_MESSAGES.cancelled) };
|
|
4957
|
+
if (!active.elicitationHandler) return { response: cancelledElicitationResponse(ELICITATION_CANCEL_MESSAGES.unavailable) };
|
|
4958
|
+
return { owner: {
|
|
4959
|
+
active,
|
|
4960
|
+
handler: active.elicitationHandler
|
|
4961
|
+
} };
|
|
4962
|
+
}
|
|
4963
|
+
resolveElicitationScope(request, active) {
|
|
4964
|
+
const sessionId = elicitationSessionId(request);
|
|
4965
|
+
if (sessionId) return sessionId === active.sessionId ? { sessionId } : { response: cancelledElicitationResponse(ELICITATION_CANCEL_MESSAGES.mismatchedSession) };
|
|
4966
|
+
const requestScopeId = elicitationRequestScopeId(request);
|
|
4967
|
+
if (requestScopeId === void 0 || requestScopeId !== active.requestId) return { response: cancelledElicitationResponse(ELICITATION_CANCEL_MESSAGES.requestScoped) };
|
|
4968
|
+
return { sessionId: active.sessionId };
|
|
4969
|
+
}
|
|
4970
|
+
isElicitationSessionCancelling(sessionId) {
|
|
4971
|
+
return this.closing || this.cancellingSessionIds.has(sessionId);
|
|
4972
|
+
}
|
|
4816
4973
|
async tryHandlePermissionRequestWithHost(params) {
|
|
4817
4974
|
if (!this.options.onPermissionRequest) return;
|
|
4818
4975
|
const signal = this.cancellationSignalForSession(params.sessionId);
|
|
@@ -4898,7 +5055,7 @@ var AcpClient = class {
|
|
|
4898
5055
|
if (error) this.promptPermissionFailures.delete(sessionId);
|
|
4899
5056
|
return error;
|
|
4900
5057
|
}
|
|
4901
|
-
async runConnectionRequest(run) {
|
|
5058
|
+
async runConnectionRequest(run, onRequestStarted, canStartRequest = () => true) {
|
|
4902
5059
|
return await new Promise((resolve, reject) => {
|
|
4903
5060
|
const pending = {
|
|
4904
5061
|
settled: false,
|
|
@@ -4911,7 +5068,20 @@ var AcpClient = class {
|
|
|
4911
5068
|
cb();
|
|
4912
5069
|
};
|
|
4913
5070
|
this.pendingConnectionRequests.add(pending);
|
|
4914
|
-
Promise.resolve().then(
|
|
5071
|
+
Promise.resolve().then(async () => {
|
|
5072
|
+
if (pending.settled) return { started: false };
|
|
5073
|
+
const requestCanStart = canStartRequest();
|
|
5074
|
+
const request = run();
|
|
5075
|
+
if (requestCanStart) try {
|
|
5076
|
+
Promise.resolve(onRequestStarted?.()).catch(() => {});
|
|
5077
|
+
} catch {}
|
|
5078
|
+
return {
|
|
5079
|
+
started: true,
|
|
5080
|
+
value: await request
|
|
5081
|
+
};
|
|
5082
|
+
}).then((outcome) => {
|
|
5083
|
+
if (outcome.started) finish(() => resolve(outcome.value));
|
|
5084
|
+
}, (error) => finish(() => reject(error)));
|
|
4915
5085
|
});
|
|
4916
5086
|
}
|
|
4917
5087
|
rejectPendingConnectionRequests(error) {
|
|
@@ -6178,35 +6348,24 @@ function createActiveSessionController(params) {
|
|
|
6178
6348
|
}
|
|
6179
6349
|
async function withConnectedSession(options) {
|
|
6180
6350
|
const record = await options.loadRecord(options.sessionRecordId);
|
|
6181
|
-
const
|
|
6351
|
+
const clientOptions = {
|
|
6182
6352
|
agentCommand: record.agentCommand,
|
|
6183
6353
|
agentArgv: record.agentArgv,
|
|
6184
6354
|
cwd: absolutePath(record.cwd),
|
|
6185
6355
|
mcpServers: options.mcpServers,
|
|
6186
6356
|
permissionMode: options.permissionMode ?? "approve-reads",
|
|
6187
6357
|
nonInteractivePermissions: options.nonInteractivePermissions,
|
|
6358
|
+
permissionPolicy: options.permissionPolicy,
|
|
6188
6359
|
onPermissionRequest: options.onPermissionRequest,
|
|
6189
6360
|
authCredentials: options.authCredentials,
|
|
6190
6361
|
authPolicy: options.authPolicy,
|
|
6191
6362
|
fs: options.fs,
|
|
6192
6363
|
terminal: options.terminal,
|
|
6364
|
+
elicitationModes: options.elicitationModes,
|
|
6193
6365
|
verbose: options.verbose,
|
|
6194
6366
|
sessionOptions: sessionOptionsFromRecord(record)
|
|
6195
|
-
}
|
|
6196
|
-
|
|
6197
|
-
agentArgv: record.agentArgv,
|
|
6198
|
-
cwd: absolutePath(record.cwd),
|
|
6199
|
-
mcpServers: options.mcpServers,
|
|
6200
|
-
permissionMode: options.permissionMode ?? "approve-reads",
|
|
6201
|
-
nonInteractivePermissions: options.nonInteractivePermissions,
|
|
6202
|
-
onPermissionRequest: options.onPermissionRequest,
|
|
6203
|
-
authCredentials: options.authCredentials,
|
|
6204
|
-
authPolicy: options.authPolicy,
|
|
6205
|
-
fs: options.fs,
|
|
6206
|
-
terminal: options.terminal,
|
|
6207
|
-
verbose: options.verbose,
|
|
6208
|
-
sessionOptions: sessionOptionsFromRecord(record)
|
|
6209
|
-
});
|
|
6367
|
+
};
|
|
6368
|
+
const client = options.createClient?.(clientOptions) ?? new AcpClient(clientOptions);
|
|
6210
6369
|
let activeSessionIdForControl = record.acpSessionId;
|
|
6211
6370
|
let notifiedClientAvailable = false;
|
|
6212
6371
|
const activeController = createActiveSessionController({
|
|
@@ -6278,7 +6437,7 @@ const SESSION_REPLY_IDLE_MS = 1e3;
|
|
|
6278
6437
|
const SESSION_REPLY_DRAIN_TIMEOUT_MS = 5e3;
|
|
6279
6438
|
async function runPromptTurn(params) {
|
|
6280
6439
|
try {
|
|
6281
|
-
const promptPromise = params.client.prompt(params.sessionId, params.prompt);
|
|
6440
|
+
const promptPromise = params.client.prompt(params.sessionId, params.prompt, params.onPromptRequestStarted, params.onElicitation);
|
|
6282
6441
|
await params.onPromptStarted?.();
|
|
6283
6442
|
const response = await withTimeout(promptPromise, params.timeoutMs);
|
|
6284
6443
|
await params.client.waitForSessionUpdatesIdle?.({
|
|
@@ -6357,6 +6516,6 @@ var LiveSessionCheckpoint = class {
|
|
|
6357
6516
|
}
|
|
6358
6517
|
};
|
|
6359
6518
|
//#endregion
|
|
6360
|
-
export {
|
|
6519
|
+
export { writeSessionRecord as $, PERMISSION_POLICY_ACTIONS as $t, REQUESTED_MODEL_UNSUPPORTED_ERROR_CODE as A, TimeoutError as At, getAcpxVersion as B, formatErrorMessage as Bt, mergeSessionOptions as C, PromptInputValidationError as Ct, applyLifecycleSnapshotToRecord as D, promptToDisplayText as Dt, applyConversation as E, parsePromptSource as Et, modelStateFromConfigOptions as F, normalizeAgentName$1 as Ft, findSession as G, toAcpErrorPayload as Gt, DEFAULT_HISTORY_LIMIT as H, normalizeOutputError as Ht, normalizeAgentCommandInput as I, resolveAgentArgv as It, listSessions as J, NON_INTERACTIVE_PERMISSION_POLICIES as Jt, findSessionByDirectoryWalk as K, AUTH_POLICIES as Kt, renderArgvIdentity as L, resolveAgentCommand as Lt, RequestedModelUnsupportedError as M, withTimeout as Mt, assertRequestedModelSupported as N, DEFAULT_AGENT_NAME as Nt, reconcileAgentSessionId as O, textPrompt as Ot, isRequestedModelUnsupportedError as P, listBuiltInAgents as Pt, resolveSessionRecord as Q, PERMISSION_MODES as Qt, runTimedExecFile as R, resolveCanonicalAgentName as Rt, advertisedModelState as S, parsePromptStopReason as St, sessionOptionsFromRecord as T, mergePromptSourceWithText as Tt, absolutePath as U, extractAcpError as Ut, permissionModeSatisfies as V, isRetryablePromptError as Vt, findGitRepositoryRoot as W, isAcpResourceNotFoundError as Wt, normalizeName as X, OUTPUT_ERROR_ORIGINS as Xt, listSessionsForAgent as Y, OUTPUT_ERROR_CODES as Yt, pruneSessions as Z, OUTPUT_FORMATS as Zt, createSessionConversation as _, sessionEventLockPath as _t, applyRequestedModelIfAdvertised as a, measurePerf as at, recordSessionUpdate as b, isAcpJsonRpcMessage as bt, setCurrentModelId as c, setPerfGauge as ct, setDesiredModelId as d, serializeSessionRecordForDisk as dt, SESSION_RECORD_SCHEMA as en, createAtomicWriteTempPath as et, syncAdvertisedModelState as f, normalizeRuntimeSessionId as ft, cloneSessionConversation as g, sessionEventActivePath as gt, cloneSessionAcpxState as h, sessionBaseDir$1 as ht, connectAndLoadSession as i, QueueProtocolError as in, incrementPerfCounter as it, REQUESTED_MODEL_UNSUPPORTED_REASONS as j, withInterrupt as jt, AcpClient as k, InterruptedError as kt, setDesiredConfigOption as l, startPerfTimer as lt, applyConfigOptionsToState as m, defaultSessionEventLog as mt, runPromptTurn as n, AgentSpawnError as nn, formatPerfMetric as nt, currentModelIdFromSetModelResponse as o, recordPerfDuration as ot, applyConfigOptionsToRecord as p, DEFAULT_EVENT_SEGMENT_MAX_BYTES as pt, isoNow$2 as q, EXIT_CODES as qt, withConnectedSession as r, QueueConnectionError as rn, getPerfMetricsSnapshot as rt, clearDesiredConfigOption as s, resetPerfMetrics as st, LiveSessionCheckpoint as t, AcpxOperationalError as tn, assertPersistedKeyPolicy as tt, setDesiredModeId as u, parseSessionRecord as ut, recordClientOperation as v, sessionEventSegmentPath as vt, persistSessionOptions as w, isPromptInput as wt, trimConversationForRuntime as x, parseJsonRpcErrorMessage as xt, recordPromptSubmission as y, extractSessionUpdateNotification as yt, splitCommandLine as z, exitCodeForOutputErrorCode as zt };
|
|
6361
6520
|
|
|
6362
|
-
//# sourceMappingURL=live-checkpoint-
|
|
6521
|
+
//# sourceMappingURL=live-checkpoint-BSIrfgVo.js.map
|