acpx 0.13.0 → 0.13.2
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-DJT3MRRI.js} +6 -5
- package/dist/{cli-D52eGvxU.js.map → cli-DJT3MRRI.js.map} +1 -1
- package/dist/cli.d.ts +1 -1
- package/dist/cli.js +20 -13
- 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-CM2rAdBo.js} +3 -3
- package/dist/{flags---9OR06b.js.map → flags-CM2rAdBo.js.map} +1 -1
- package/dist/{flows-CYfjwbn2.js → flows-BiRKgCnW.js} +4 -4
- package/dist/{flows-CYfjwbn2.js.map → flows-BiRKgCnW.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-Gw2oGjhe.js} +445 -252
- package/dist/live-checkpoint-Gw2oGjhe.js.map +1 -0
- package/dist/{output-CzN8vLdE.js → output-DiPPprGk.js} +40 -84
- package/dist/output-DiPPprGk.js.map +1 -0
- package/dist/runtime.d.ts +107 -23
- package/dist/runtime.d.ts.map +1 -1
- package/dist/runtime.js +600 -202
- 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 +15 -15
- package/skills/acpx/SKILL.md +5 -1
- 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;
|
|
@@ -983,7 +982,7 @@ function parseJsonRpcErrorMessage(message) {
|
|
|
983
982
|
}
|
|
984
983
|
//#endregion
|
|
985
984
|
//#region src/session/event-log.ts
|
|
986
|
-
const DEFAULT_EVENT_SEGMENT_MAX_BYTES =
|
|
985
|
+
const DEFAULT_EVENT_SEGMENT_MAX_BYTES = 67108864;
|
|
987
986
|
function sessionBaseDir$1() {
|
|
988
987
|
return path.join(os.homedir(), ".acpx", "sessions");
|
|
989
988
|
}
|
|
@@ -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
|
|
@@ -2068,7 +2068,7 @@ function toWritePreview(content) {
|
|
|
2068
2068
|
const visibleLines = lines.slice(0, WRITE_PREVIEW_MAX_LINES);
|
|
2069
2069
|
let preview = visibleLines.join("\n");
|
|
2070
2070
|
if (lines.length > visibleLines.length) preview += `\n... (${lines.length - visibleLines.length} more lines)`;
|
|
2071
|
-
if (preview.length > WRITE_PREVIEW_MAX_CHARS) preview = `${preview.slice(0,
|
|
2071
|
+
if (preview.length > WRITE_PREVIEW_MAX_CHARS) preview = `${preview.slice(0, 1197)}...`;
|
|
2072
2072
|
return preview;
|
|
2073
2073
|
}
|
|
2074
2074
|
async function defaultConfirmWrite(filePath, preview) {
|
|
@@ -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, "");
|
|
@@ -3307,7 +3338,7 @@ function maybeWrapSessionControlError(method, error, context) {
|
|
|
3307
3338
|
}
|
|
3308
3339
|
//#endregion
|
|
3309
3340
|
//#region src/acp/terminal-manager.ts
|
|
3310
|
-
const DEFAULT_TERMINAL_OUTPUT_LIMIT_BYTES =
|
|
3341
|
+
const DEFAULT_TERMINAL_OUTPUT_LIMIT_BYTES = 65536;
|
|
3311
3342
|
const DEFAULT_KILL_GRACE_MS = 1500;
|
|
3312
3343
|
function nowIso() {
|
|
3313
3344
|
return (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -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) {
|
|
@@ -5712,18 +5882,6 @@ function trimRuntimeToolResult(result) {
|
|
|
5712
5882
|
if (typeof result.output === "string") result.output = trimRuntimeText(result.output, MAX_RUNTIME_TOOL_IO_CHARS);
|
|
5713
5883
|
}
|
|
5714
5884
|
//#endregion
|
|
5715
|
-
//#region src/session/config-options.ts
|
|
5716
|
-
function applyConfigOptionsToState(state, configOptions) {
|
|
5717
|
-
const acpxState = cloneSessionAcpxState(state) ?? {};
|
|
5718
|
-
applyConfigOptionsModelState(acpxState, configOptions);
|
|
5719
|
-
return acpxState;
|
|
5720
|
-
}
|
|
5721
|
-
function applyConfigOptionsToRecord(record, result) {
|
|
5722
|
-
const configOptions = result?.configOptions;
|
|
5723
|
-
if (!configOptions) return;
|
|
5724
|
-
record.acpx = applyConfigOptionsToState(record.acpx, configOptions);
|
|
5725
|
-
}
|
|
5726
|
-
//#endregion
|
|
5727
5885
|
//#region src/session/mode-preference.ts
|
|
5728
5886
|
function ensureAcpxState(state) {
|
|
5729
5887
|
return state ?? {};
|
|
@@ -5756,17 +5914,6 @@ function setDesiredModeId(record, modeId) {
|
|
|
5756
5914
|
else delete acpx.desired_mode_id;
|
|
5757
5915
|
record.acpx = acpx;
|
|
5758
5916
|
}
|
|
5759
|
-
function setDesiredConfigOption(record, configId, value) {
|
|
5760
|
-
const normalizedConfigId = normalizeModeId(configId);
|
|
5761
|
-
if (!normalizedConfigId || normalizedConfigId === "mode" || normalizedConfigId === "model") return;
|
|
5762
|
-
const acpx = ensureAcpxState(record.acpx);
|
|
5763
|
-
const desired = { ...acpx.desired_config_options };
|
|
5764
|
-
if (typeof value === "string") desired[normalizedConfigId] = value;
|
|
5765
|
-
else delete desired[normalizedConfigId];
|
|
5766
|
-
if (Object.keys(desired).length > 0) acpx.desired_config_options = desired;
|
|
5767
|
-
else delete acpx.desired_config_options;
|
|
5768
|
-
record.acpx = acpx;
|
|
5769
|
-
}
|
|
5770
5917
|
function clearDesiredConfigOption(state, configId) {
|
|
5771
5918
|
const normalizedConfigId = normalizeModeId(configId);
|
|
5772
5919
|
if (!normalizedConfigId || !state.desired_config_options) return;
|
|
@@ -5778,20 +5925,6 @@ function clearDesiredConfigOption(state, configId) {
|
|
|
5778
5925
|
function getDesiredModelId(state) {
|
|
5779
5926
|
return normalizeModelId(state?.session_options?.model);
|
|
5780
5927
|
}
|
|
5781
|
-
function hasStoredSessionOptions(options) {
|
|
5782
|
-
return typeof options.model === "string" || Array.isArray(options.allowed_tools) || typeof options.max_turns === "number" || options.system_prompt !== void 0 || options.env !== void 0;
|
|
5783
|
-
}
|
|
5784
|
-
function setDesiredModelId(record, modelId, modelConfigId) {
|
|
5785
|
-
const acpx = ensureAcpxState(record.acpx);
|
|
5786
|
-
const normalized = normalizeModelId(modelId);
|
|
5787
|
-
const sessionOptions = { ...acpx.session_options };
|
|
5788
|
-
if (normalized) sessionOptions.model = normalized;
|
|
5789
|
-
else delete sessionOptions.model;
|
|
5790
|
-
if (hasStoredSessionOptions(sessionOptions)) acpx.session_options = sessionOptions;
|
|
5791
|
-
else delete acpx.session_options;
|
|
5792
|
-
clearDesiredConfigOption(acpx, modelConfigId ?? modelStateFromConfigOptions(acpx.config_options)?.configId);
|
|
5793
|
-
record.acpx = acpx;
|
|
5794
|
-
}
|
|
5795
5928
|
function setCurrentModelId(record, modelId) {
|
|
5796
5929
|
const acpx = ensureAcpxState(record.acpx);
|
|
5797
5930
|
const normalized = normalizeModelId(modelId);
|
|
@@ -5828,6 +5961,50 @@ async function applyRequestedModelIfAdvertised(params) {
|
|
|
5828
5961
|
};
|
|
5829
5962
|
}
|
|
5830
5963
|
//#endregion
|
|
5964
|
+
//#region src/session/config-options.ts
|
|
5965
|
+
function applyConfigOptionsToState(state, configOptions) {
|
|
5966
|
+
const acpxState = cloneSessionAcpxState(state) ?? {};
|
|
5967
|
+
applyConfigOptionsModelState(acpxState, configOptions);
|
|
5968
|
+
return acpxState;
|
|
5969
|
+
}
|
|
5970
|
+
function applyConfigOptionsToRecord(record, result) {
|
|
5971
|
+
const configOptions = result?.configOptions;
|
|
5972
|
+
if (!configOptions) return;
|
|
5973
|
+
record.acpx = applyConfigOptionsToState(record.acpx, configOptions);
|
|
5974
|
+
}
|
|
5975
|
+
function applyAcceptedConfigOptions(state, response) {
|
|
5976
|
+
const next = cloneSessionAcpxState(state) ?? {};
|
|
5977
|
+
if (!response) return next;
|
|
5978
|
+
applyConfigOptionsModelState(next, response.configOptions);
|
|
5979
|
+
if (!next.desired_config_options) return next;
|
|
5980
|
+
const desired = {};
|
|
5981
|
+
for (const option of response.configOptions) if (typeof option.currentValue === "string" && Object.hasOwn(next.desired_config_options, option.id)) desired[option.id] = option.currentValue;
|
|
5982
|
+
if (Object.keys(desired).length > 0) next.desired_config_options = desired;
|
|
5983
|
+
else delete next.desired_config_options;
|
|
5984
|
+
return next;
|
|
5985
|
+
}
|
|
5986
|
+
function applyModelSelection(state, modelId, response) {
|
|
5987
|
+
const modelConfigId = advertisedModelState(state)?.configId;
|
|
5988
|
+
const next = applyAcceptedConfigOptions(state, response);
|
|
5989
|
+
next.session_options = {
|
|
5990
|
+
...next.session_options,
|
|
5991
|
+
model: modelId
|
|
5992
|
+
};
|
|
5993
|
+
next.current_model_id = currentModelIdFromSetModelResponse(response, modelId);
|
|
5994
|
+
clearDesiredConfigOption(next, modelConfigId ?? advertisedModelState(next)?.configId);
|
|
5995
|
+
return next;
|
|
5996
|
+
}
|
|
5997
|
+
function applyConfigOptionSelection(state, configId, value, response, modelConfigId = advertisedModelState(state)?.configId) {
|
|
5998
|
+
if (configId === modelConfigId || configId === modelStateFromConfigOptions(response.configOptions)?.configId) return applyModelSelection(state, value, response);
|
|
5999
|
+
const next = cloneSessionAcpxState(state) ?? {};
|
|
6000
|
+
if (configId === "mode") next.desired_mode_id = value;
|
|
6001
|
+
else next.desired_config_options = {
|
|
6002
|
+
...next.desired_config_options,
|
|
6003
|
+
[configId]: value
|
|
6004
|
+
};
|
|
6005
|
+
return applyAcceptedConfigOptions(next, response);
|
|
6006
|
+
}
|
|
6007
|
+
//#endregion
|
|
5831
6008
|
//#region src/runtime/engine/reconnect.ts
|
|
5832
6009
|
function isProcessAlive(pid) {
|
|
5833
6010
|
if (!pid || !Number.isInteger(pid) || pid <= 0 || pid === process.pid) return false;
|
|
@@ -5872,8 +6049,11 @@ async function replayDesiredMode(params) {
|
|
|
5872
6049
|
});
|
|
5873
6050
|
}
|
|
5874
6051
|
}
|
|
6052
|
+
function canReplayModel(desiredModelId, models, createdFreshSession) {
|
|
6053
|
+
return Boolean(desiredModelId) && (createdFreshSession || models !== void 0);
|
|
6054
|
+
}
|
|
5875
6055
|
async function replayDesiredModel(params) {
|
|
5876
|
-
if (!params.desiredModelId) return { replayed: false };
|
|
6056
|
+
if (!canReplayModel(params.desiredModelId, params.models, params.createdFreshSession)) return { replayed: false };
|
|
5877
6057
|
try {
|
|
5878
6058
|
emitModelSupportWarning(assertRequestedModelSupported({
|
|
5879
6059
|
requestedModel: params.desiredModelId,
|
|
@@ -5881,21 +6061,21 @@ async function replayDesiredModel(params) {
|
|
|
5881
6061
|
agentCommand: params.record.agentCommand,
|
|
5882
6062
|
context: "replay"
|
|
5883
6063
|
}), params.suppressWarnings);
|
|
5884
|
-
if (!params.models
|
|
6064
|
+
if (!params.models) return { replayed: false };
|
|
5885
6065
|
const response = await withTimeout(params.client.setSessionModel(params.sessionId, params.desiredModelId, params.models), params.timeoutMs);
|
|
5886
|
-
|
|
6066
|
+
params.record.acpx = applyModelSelection(params.record.acpx, params.desiredModelId, response);
|
|
5887
6067
|
const models = response ? modelStateFromConfigOptions(response.configOptions) : {
|
|
5888
6068
|
...params.models,
|
|
5889
6069
|
currentModelId: params.desiredModelId
|
|
5890
6070
|
};
|
|
5891
|
-
if (params.verbose) process.stderr.write(`[acpx] replayed desired model ${params.desiredModelId} on
|
|
6071
|
+
if (params.verbose) process.stderr.write(`[acpx] replayed desired model ${params.desiredModelId} on ACP session ${params.sessionId} (previous ${params.previousSessionId})\n`);
|
|
5892
6072
|
return {
|
|
5893
6073
|
replayed: true,
|
|
5894
6074
|
models,
|
|
5895
|
-
|
|
6075
|
+
configOptions: response?.configOptions
|
|
5896
6076
|
};
|
|
5897
6077
|
} catch (error) {
|
|
5898
|
-
throw new SessionModelReplayError(`Failed to replay saved session model ${params.desiredModelId} on
|
|
6078
|
+
throw new SessionModelReplayError(`Failed to replay saved session model ${params.desiredModelId} on ACP session ${params.sessionId}: ${formatErrorMessage(error)}`, {
|
|
5899
6079
|
cause: error instanceof Error ? error : void 0,
|
|
5900
6080
|
retryable: true
|
|
5901
6081
|
});
|
|
@@ -5906,19 +6086,25 @@ function emitModelSupportWarning(warning, suppressWarnings) {
|
|
|
5906
6086
|
}
|
|
5907
6087
|
async function replayDesiredConfigOptions(params) {
|
|
5908
6088
|
let result = { replayed: false };
|
|
5909
|
-
|
|
5910
|
-
|
|
5911
|
-
|
|
5912
|
-
|
|
5913
|
-
|
|
5914
|
-
|
|
5915
|
-
|
|
5916
|
-
|
|
5917
|
-
|
|
5918
|
-
|
|
5919
|
-
|
|
5920
|
-
|
|
5921
|
-
|
|
6089
|
+
let acceptedConfigOptions = params.acceptedConfigOptions;
|
|
6090
|
+
const replacingKey = resolveReplacingConfigOptionId(params.replacingConfigOption, params.record);
|
|
6091
|
+
for (const [configId, value] of Object.entries(params.desiredConfigOptions)) {
|
|
6092
|
+
if (configId === replacingKey || acceptedConfigOptions && !acceptsSavedConfigValue(acceptedConfigOptions.find((option) => option.id === configId), value)) continue;
|
|
6093
|
+
try {
|
|
6094
|
+
const response = await withTimeout(params.client.setSessionConfigOption(params.sessionId, configId, value), params.timeoutMs);
|
|
6095
|
+
params.record.acpx = applyConfigOptionSelection(params.record.acpx, configId, value, response);
|
|
6096
|
+
acceptedConfigOptions = response.configOptions;
|
|
6097
|
+
result = {
|
|
6098
|
+
replayed: true,
|
|
6099
|
+
models: modelStateFromConfigOptions(response.configOptions)
|
|
6100
|
+
};
|
|
6101
|
+
if (params.verbose) process.stderr.write(`[acpx] replayed desired config option ${configId} on ACP session ${params.sessionId} (previous ${params.previousSessionId})\n`);
|
|
6102
|
+
} catch (error) {
|
|
6103
|
+
throw new SessionConfigOptionReplayError(`Failed to replay saved session config option ${configId} on ACP session ${params.sessionId}: ${formatErrorMessage(error)}`, {
|
|
6104
|
+
cause: error instanceof Error ? error : void 0,
|
|
6105
|
+
retryable: true
|
|
6106
|
+
});
|
|
6107
|
+
}
|
|
5922
6108
|
}
|
|
5923
6109
|
return result;
|
|
5924
6110
|
}
|
|
@@ -5965,10 +6151,12 @@ async function connectAndLoadSession(options) {
|
|
|
5965
6151
|
createdFreshSession = loadState.createdFreshSession;
|
|
5966
6152
|
pendingAgentSessionId = loadState.pendingAgentSessionId;
|
|
5967
6153
|
sessionModels = loadState.sessionModels;
|
|
5968
|
-
const preferenceReplay = await
|
|
6154
|
+
const preferenceReplay = await replaySessionPreferences({
|
|
5969
6155
|
client,
|
|
5970
6156
|
record,
|
|
5971
6157
|
createdFreshSession,
|
|
6158
|
+
reusingLoadedSession,
|
|
6159
|
+
replacingConfigOption: options.replacingConfigOption,
|
|
5972
6160
|
sessionId,
|
|
5973
6161
|
pendingAgentSessionId,
|
|
5974
6162
|
originalSessionId,
|
|
@@ -5999,7 +6187,7 @@ function preserveLegacyModels(models) {
|
|
|
5999
6187
|
return models && !models.configId ? models : void 0;
|
|
6000
6188
|
}
|
|
6001
6189
|
function resolveConfigOptionsPresenceAfterReplay(replay, initiallyPresent) {
|
|
6002
|
-
return initiallyPresent || replay.configReplay.replayed || replay.modelReplay.
|
|
6190
|
+
return initiallyPresent || replay.configReplay.replayed || replay.modelReplay.configOptions !== void 0;
|
|
6003
6191
|
}
|
|
6004
6192
|
function applyReconnectedModelState(record, sessionModels, configOptionsPresent, legacyModelMetadataPresent, createdFreshSession) {
|
|
6005
6193
|
clearOmittedFreshSessionConfigOptions(record, createdFreshSession, configOptionsPresent);
|
|
@@ -6022,18 +6210,30 @@ function logReconnectAttempt(record, storedProcessAlive, shouldReconnect, verbos
|
|
|
6022
6210
|
}
|
|
6023
6211
|
if (shouldReconnect) process.stderr.write(`[acpx] saved session pid ${record.pid} is dead; respawning agent and attempting session reconnect\n`);
|
|
6024
6212
|
}
|
|
6025
|
-
|
|
6026
|
-
|
|
6213
|
+
function replacesModel(replacingConfigOption, models, originalAcpx) {
|
|
6214
|
+
const key = replacingConfigOption?.key;
|
|
6215
|
+
return key !== void 0 && (key === "model" || key === models?.configId || key === advertisedModelState(originalAcpx)?.configId);
|
|
6216
|
+
}
|
|
6217
|
+
function acceptsSavedConfigValue(option, value) {
|
|
6218
|
+
if (!option || option.type !== "select") return false;
|
|
6219
|
+
return option.currentValue === value || option.options.some((entry) => "options" in entry ? entry.options.some((choice) => choice.value === value) : entry.value === value);
|
|
6220
|
+
}
|
|
6221
|
+
function resolveReplacingConfigOptionId(replacement, record) {
|
|
6222
|
+
return replacement?.resolve?.(record) ?? replacement?.key;
|
|
6223
|
+
}
|
|
6224
|
+
async function replaySessionPreferences(params) {
|
|
6225
|
+
if (params.reusingLoadedSession) return {
|
|
6027
6226
|
modelReplay: { replayed: false },
|
|
6028
6227
|
configReplay: { replayed: false }
|
|
6029
6228
|
};
|
|
6030
6229
|
let modelReplay = { replayed: false };
|
|
6031
6230
|
let configReplay = { replayed: false };
|
|
6231
|
+
const replacingModel = replacesModel(params.replacingConfigOption, params.sessionModels, params.originalAcpx);
|
|
6032
6232
|
try {
|
|
6033
6233
|
await replayDesiredMode({
|
|
6034
6234
|
client: params.client,
|
|
6035
6235
|
sessionId: params.sessionId,
|
|
6036
|
-
desiredModeId: params.desiredModeId,
|
|
6236
|
+
desiredModeId: params.createdFreshSession ? params.desiredModeId : void 0,
|
|
6037
6237
|
previousSessionId: params.originalSessionId,
|
|
6038
6238
|
timeoutMs: params.timeoutMs,
|
|
6039
6239
|
verbose: params.verbose
|
|
@@ -6041,10 +6241,11 @@ async function replayFreshSessionPreferences(params) {
|
|
|
6041
6241
|
modelReplay = await replayDesiredModel({
|
|
6042
6242
|
client: params.client,
|
|
6043
6243
|
sessionId: params.sessionId,
|
|
6044
|
-
desiredModelId: params.desiredModelId,
|
|
6244
|
+
desiredModelId: replacingModel ? void 0 : params.desiredModelId,
|
|
6045
6245
|
previousSessionId: params.originalSessionId,
|
|
6046
6246
|
record: params.record,
|
|
6047
6247
|
models: params.sessionModels,
|
|
6248
|
+
createdFreshSession: params.createdFreshSession,
|
|
6048
6249
|
timeoutMs: params.timeoutMs,
|
|
6049
6250
|
verbose: params.verbose,
|
|
6050
6251
|
suppressWarnings: params.suppressWarnings
|
|
@@ -6053,7 +6254,9 @@ async function replayFreshSessionPreferences(params) {
|
|
|
6053
6254
|
client: params.client,
|
|
6054
6255
|
record: params.record,
|
|
6055
6256
|
sessionId: params.sessionId,
|
|
6056
|
-
desiredConfigOptions: params.desiredConfigOptions,
|
|
6257
|
+
desiredConfigOptions: replacingModel ? {} : params.desiredConfigOptions,
|
|
6258
|
+
acceptedConfigOptions: modelReplay.configOptions,
|
|
6259
|
+
replacingConfigOption: replacingModel ? void 0 : params.replacingConfigOption,
|
|
6057
6260
|
previousSessionId: params.originalSessionId,
|
|
6058
6261
|
timeoutMs: params.timeoutMs,
|
|
6059
6262
|
verbose: params.verbose
|
|
@@ -6178,35 +6381,24 @@ function createActiveSessionController(params) {
|
|
|
6178
6381
|
}
|
|
6179
6382
|
async function withConnectedSession(options) {
|
|
6180
6383
|
const record = await options.loadRecord(options.sessionRecordId);
|
|
6181
|
-
const
|
|
6182
|
-
agentCommand: record.agentCommand,
|
|
6183
|
-
agentArgv: record.agentArgv,
|
|
6184
|
-
cwd: absolutePath(record.cwd),
|
|
6185
|
-
mcpServers: options.mcpServers,
|
|
6186
|
-
permissionMode: options.permissionMode ?? "approve-reads",
|
|
6187
|
-
nonInteractivePermissions: options.nonInteractivePermissions,
|
|
6188
|
-
onPermissionRequest: options.onPermissionRequest,
|
|
6189
|
-
authCredentials: options.authCredentials,
|
|
6190
|
-
authPolicy: options.authPolicy,
|
|
6191
|
-
fs: options.fs,
|
|
6192
|
-
terminal: options.terminal,
|
|
6193
|
-
verbose: options.verbose,
|
|
6194
|
-
sessionOptions: sessionOptionsFromRecord(record)
|
|
6195
|
-
}) ?? new AcpClient({
|
|
6384
|
+
const clientOptions = {
|
|
6196
6385
|
agentCommand: record.agentCommand,
|
|
6197
6386
|
agentArgv: record.agentArgv,
|
|
6198
6387
|
cwd: absolutePath(record.cwd),
|
|
6199
6388
|
mcpServers: options.mcpServers,
|
|
6200
6389
|
permissionMode: options.permissionMode ?? "approve-reads",
|
|
6201
6390
|
nonInteractivePermissions: options.nonInteractivePermissions,
|
|
6391
|
+
permissionPolicy: options.permissionPolicy,
|
|
6202
6392
|
onPermissionRequest: options.onPermissionRequest,
|
|
6203
6393
|
authCredentials: options.authCredentials,
|
|
6204
6394
|
authPolicy: options.authPolicy,
|
|
6205
6395
|
fs: options.fs,
|
|
6206
6396
|
terminal: options.terminal,
|
|
6397
|
+
elicitationModes: options.elicitationModes,
|
|
6207
6398
|
verbose: options.verbose,
|
|
6208
6399
|
sessionOptions: sessionOptionsFromRecord(record)
|
|
6209
|
-
}
|
|
6400
|
+
};
|
|
6401
|
+
const client = options.createClient?.(clientOptions) ?? new AcpClient(clientOptions);
|
|
6210
6402
|
let activeSessionIdForControl = record.acpSessionId;
|
|
6211
6403
|
let notifiedClientAvailable = false;
|
|
6212
6404
|
const activeController = createActiveSessionController({
|
|
@@ -6220,6 +6412,7 @@ async function withConnectedSession(options) {
|
|
|
6220
6412
|
client,
|
|
6221
6413
|
record,
|
|
6222
6414
|
resumePolicy: options.resumePolicy,
|
|
6415
|
+
replacingConfigOption: options.replacingConfigOption,
|
|
6223
6416
|
timeoutMs: options.timeoutMs,
|
|
6224
6417
|
verbose: options.verbose,
|
|
6225
6418
|
activeController,
|
|
@@ -6278,7 +6471,7 @@ const SESSION_REPLY_IDLE_MS = 1e3;
|
|
|
6278
6471
|
const SESSION_REPLY_DRAIN_TIMEOUT_MS = 5e3;
|
|
6279
6472
|
async function runPromptTurn(params) {
|
|
6280
6473
|
try {
|
|
6281
|
-
const promptPromise = params.client.prompt(params.sessionId, params.prompt);
|
|
6474
|
+
const promptPromise = params.client.prompt(params.sessionId, params.prompt, params.onPromptRequestStarted, params.onElicitation);
|
|
6282
6475
|
await params.onPromptStarted?.();
|
|
6283
6476
|
const response = await withTimeout(promptPromise, params.timeoutMs);
|
|
6284
6477
|
await params.client.waitForSessionUpdatesIdle?.({
|
|
@@ -6357,6 +6550,6 @@ var LiveSessionCheckpoint = class {
|
|
|
6357
6550
|
}
|
|
6358
6551
|
};
|
|
6359
6552
|
//#endregion
|
|
6360
|
-
export {
|
|
6553
|
+
export { formatPerfMetric as $, AgentSpawnError as $t, RequestedModelUnsupportedError as A, DEFAULT_AGENT_NAME as At, absolutePath as B, extractAcpError as Bt, sessionOptionsFromRecord as C, parsePromptSource as Ct, AcpClient as D, TimeoutError as Dt, reconcileAgentSessionId as E, InterruptedError as Et, runTimedExecFile as F, resolveCanonicalAgentName as Ft, listSessions as G, NON_INTERACTIVE_PERMISSION_POLICIES as Gt, findSession as H, toAcpErrorPayload as Ht, splitCommandLine as I, exitCodeForOutputErrorCode as It, pruneSessions as J, OUTPUT_FORMATS as Jt, listSessionsForAgent as K, OUTPUT_ERROR_CODES as Kt, getAcpxVersion as L, formatErrorMessage as Lt, modelStateFromConfigOptions as M, normalizeAgentName$1 as Mt, normalizeAgentCommandInput as N, resolveAgentArgv as Nt, REQUESTED_MODEL_UNSUPPORTED_ERROR_CODE as O, withInterrupt as Ot, renderArgvIdentity as P, resolveAgentCommand as Pt, assertPersistedKeyPolicy as Q, AcpxOperationalError as Qt, permissionModeSatisfies as R, isRetryablePromptError as Rt, persistSessionOptions as S, mergePromptSourceWithText as St, applyLifecycleSnapshotToRecord as T, textPrompt as Tt, findSessionByDirectoryWalk as U, AUTH_POLICIES as Ut, findGitRepositoryRoot as V, isAcpResourceNotFoundError as Vt, isoNow$2 as W, EXIT_CODES as Wt, writeSessionRecord as X, PERMISSION_POLICY_ACTIONS as Xt, resolveSessionRecord as Y, PERMISSION_MODES as Yt, createAtomicWriteTempPath as Z, SESSION_RECORD_SCHEMA as Zt, recordPromptSubmission as _, isAcpJsonRpcMessage as _t, applyConfigOptionSelection as a, setPerfGauge as at, advertisedModelState as b, PromptInputValidationError as bt, applyRequestedModelIfAdvertised as c, serializeSessionRecordForDisk as ct, setDesiredModeId as d, defaultSessionEventLog as dt, QueueConnectionError as en, getPerfMetricsSnapshot as et, syncAdvertisedModelState as f, sessionBaseDir$1 as ft, recordClientOperation as g, extractSessionUpdateNotification as gt, createSessionConversation as h, sessionEventSegmentPath as ht, connectAndLoadSession as i, resetPerfMetrics as it, isRequestedModelUnsupportedError as j, listBuiltInAgents as jt, REQUESTED_MODEL_UNSUPPORTED_REASONS as k, withTimeout as kt, currentModelIdFromSetModelResponse as l, normalizeRuntimeSessionId as lt, cloneSessionConversation as m, sessionEventLockPath as mt, runPromptTurn as n, measurePerf as nt, applyConfigOptionsToRecord as o, startPerfTimer as ot, cloneSessionAcpxState as p, sessionEventActivePath as pt, normalizeName as q, OUTPUT_ERROR_ORIGINS as qt, withConnectedSession as r, recordPerfDuration as rt, applyModelSelection as s, parseSessionRecord as st, LiveSessionCheckpoint as t, QueueProtocolError as tn, incrementPerfCounter as tt, setCurrentModelId as u, DEFAULT_EVENT_SEGMENT_MAX_BYTES as ut, recordSessionUpdate as v, parseJsonRpcErrorMessage as vt, applyConversation as w, promptToDisplayText as wt, mergeSessionOptions as x, isPromptInput as xt, trimConversationForRuntime as y, parsePromptStopReason as yt, DEFAULT_HISTORY_LIMIT as z, normalizeOutputError as zt };
|
|
6361
6554
|
|
|
6362
|
-
//# sourceMappingURL=live-checkpoint-
|
|
6555
|
+
//# sourceMappingURL=live-checkpoint-Gw2oGjhe.js.map
|