paperclip/patches/acpx@0.12.0.patch

181 lines
8.0 KiB
Diff

diff --git a/dist/live-checkpoint-ClPCSdrW.js b/dist/live-checkpoint-ClPCSdrW.js
index 243c9d13bcba520923b63adfddad75cf2d94362d..643315c1e9b529768695c863eae7a29e9f5a3dac 100644
--- a/dist/live-checkpoint-ClPCSdrW.js
+++ b/dist/live-checkpoint-ClPCSdrW.js
@@ -1532,7 +1532,7 @@ const ZED_TAG_KEYS = /* @__PURE__ */ new Set([
"RedactedThinking",
"ToolUse"
]);
-const MAP_OBJECT_PATHS = /* @__PURE__ */ new Set(["request_token_usage", "messages.Agent.tool_results"]);
+const MAP_OBJECT_PATHS = /* @__PURE__ */ new Set(["request_token_usage", "messages.Agent.tool_results", "acpx.session_options.env"]);
const OPAQUE_VALUE_PATHS = /* @__PURE__ */ new Set([
"agent_capabilities",
"messages.Agent.content.ToolUse.input",
@@ -2557,7 +2557,7 @@ function readCommandLineChar(state) {
escaping: false,
hasPart: true
};
- if (state.ch === "\\" && state.quote !== "'") return {
+ if (process.platform !== "win32" && state.ch === "\\" && state.quote !== "'") return {
current: state.current,
quote: state.quote,
escaping: true,
@@ -2912,8 +2912,8 @@ function promotePrefixedAuthEnvironment(env) {
}
return protectedKeys;
}
-function buildAgentEnvironment(authCredentials, sessionEnv) {
- const env = { ...process.env };
+function buildAgentEnvironment(authCredentials, sessionEnv, inheritProcessEnv = true) {
+ const env = inheritProcessEnv ? { ...process.env } : {};
const protectedAuthEnvKeys = promotePrefixedAuthEnvironment(env);
if (authCredentials) for (const [methodId, credential] of Object.entries(authCredentials)) {
addAuthCredentialEnvKeys(protectedAuthEnvKeys, methodId, credential);
@@ -2955,10 +2955,10 @@ function resolveConfiguredAuthCredential(methodId, authCredentials) {
const configCredentials = authCredentials ?? {};
return configCredentials[methodId] ?? configCredentials[toEnvToken(methodId)];
}
-function buildAgentSpawnOptions(cwd, authCredentials, sessionEnv) {
+function buildAgentSpawnOptions(cwd, authCredentials, sessionEnv, inheritProcessEnv) {
return {
cwd,
- env: buildAgentEnvironment(authCredentials, sessionEnv),
+ env: buildAgentEnvironment(authCredentials, sessionEnv, inheritProcessEnv),
stdio: [
"pipe",
"pipe",
@@ -3724,10 +3724,13 @@ function resolveClientCapabilities(params) {
},
terminal: params.terminal
};
- if (!params.devinAcp) return baseCapabilities;
+ const typedSessionFailureMeta = {
+ jetbrains: { air: { version: 1, capabilities: ["sessionFailure"] } }
+ };
+ if (!params.devinAcp) return { ...baseCapabilities, _meta: typedSessionFailureMeta };
return {
...baseCapabilities,
- _meta: DEVIN_COMPATIBILITY_CLIENT_CAPABILITIES_META
+ _meta: { ...typedSessionFailureMeta, ...DEVIN_COMPATIBILITY_CLIENT_CAPABILITIES_META }
};
}
function isDevinRequestDiagnosticsMethod(method) {
@@ -3957,9 +3960,26 @@ var AcpClient = class {
this.lastAgentExit = void 0;
this.lastKnownPid = child.pid ?? void 0;
this.attachAgentLifecycleObservers(child);
+ if (this.options.onAgentSpawn) {
+ try {
+ if (typeof child.pid !== "number" || child.pid <= 0) {
+ throw new Error("ACPX agent spawn did not expose a valid process id.");
+ }
+ await this.options.onAgentSpawn({ pid: child.pid, startedAt: this.agentStartedAt });
+ } catch (error) {
+ try {
+ child.kill("SIGKILL");
+ } catch {}
+ throw error;
+ }
+ }
const startupStderr = [];
child.stderr.on("data", (chunk) => {
this.captureStartupStderr(startupStderr, chunk);
+ if (this.options.onAgentStderr) {
+ this.options.onAgentStderr(chunk.toString());
+ return;
+ }
if (!this.options.verbose) return;
process.stderr.write(chunk);
});
@@ -3994,7 +4014,7 @@ var AcpClient = class {
geminiAcp: isGeminiAcpCommand(spawnCommand, args),
copilotAcp: isCopilotAcpCommand(spawnCommand, args),
claudeAcp: isClaudeAcpCommand(spawnCommand, args),
- spawnOptions: buildAgentSpawnOptions(this.options.cwd, this.options.authCredentials, this.options.sessionOptions?.env)
+ spawnOptions: buildAgentSpawnOptions(this.options.spawnCwd ?? this.options.cwd, this.options.authCredentials, this.options.sessionOptions?.env, this.options.inheritProcessEnv)
};
}
logAgentLaunch(plan) {
@@ -6070,6 +6090,27 @@ async function withConnectedSession(options) {
//#region src/runtime/engine/prompt-turn.ts
const SESSION_REPLY_IDLE_MS = 1e3;
const SESSION_REPLY_DRAIN_TIMEOUT_MS = 5e3;
+const TYPED_SESSION_FAILURE_CATEGORIES = /* @__PURE__ */ new Set([
+ "connection",
+ "access",
+ "limit",
+ "service",
+ "request",
+ "unknown"
+]);
+function typedTerminalSessionFailureCategory(response) {
+ if (response === null || typeof response !== "object" || Array.isArray(response)) return null;
+ const meta = response._meta;
+ if (meta === null || typeof meta !== "object" || Array.isArray(meta)) return null;
+ const jetbrains = meta.jetbrains;
+ if (jetbrains === null || typeof jetbrains !== "object" || Array.isArray(jetbrains)) return null;
+ const air = jetbrains.air;
+ if (air === null || typeof air !== "object" || Array.isArray(air)) return null;
+ if (!Number.isInteger(air.version) || air.version < 1) return null;
+ const failure = air.sessionFailure;
+ if (failure === null || typeof failure !== "object" || Array.isArray(failure) || failure.severity !== "error") return null;
+ return typeof failure.category === "string" && TYPED_SESSION_FAILURE_CATEGORIES.has(failure.category) ? failure.category : "unknown";
+}
async function runPromptTurn(params) {
try {
const promptPromise = params.client.prompt(params.sessionId, params.prompt);
@@ -6079,6 +6120,9 @@ async function runPromptTurn(params) {
idleMs: SESSION_REPLY_IDLE_MS,
timeoutMs: SESSION_REPLY_DRAIN_TIMEOUT_MS
}).catch(() => {});
+ const terminalFailureCategory = typedTerminalSessionFailureCategory(response);
+ if (terminalFailureCategory !== null)
+ throw new Error(`ACP agent reported a terminal ${terminalFailureCategory} failure.`);
recordPromptResponseUsage(params.conversation, response.usage, params.promptMessageId);
return {
stopReason: response.stopReason,
diff --git a/dist/runtime.d.ts b/dist/runtime.d.ts
index ccdbe5b032521518022223733049b8b38793473b..a04948e2b1ab8e169778e0d839ab5bf680573266 100644
--- a/dist/runtime.d.ts
+++ b/dist/runtime.d.ts
@@ -266,6 +266,10 @@ type AcpRuntimeOptions = {
timeoutMs?: number;
probeAgent?: string;
verbose?: boolean;
+ onAgentStderr?: (chunk: string) => void;
+ onAgentSpawn?: (meta: { pid: number; startedAt: string }) => Promise<void>;
+ spawnCwd?: string;
+ inheritProcessEnv?: boolean;
onPermissionRequest?: (req: AcpPermissionRequest, ctx: {
signal: AbortSignal;
}) => Promise<AcpPermissionDecision | undefined>;
diff --git a/dist/runtime.js b/dist/runtime.js
index 6c9cc999e50a11c399c68b3a0f1b7af4bc2317c0..7ec28ecf778623c6e63a2149a599172c184c49bd 100644
--- a/dist/runtime.js
+++ b/dist/runtime.js
@@ -744,7 +744,8 @@ var AcpRuntimeManager = class {
this.deps = deps;
}
createClient(options) {
- return this.deps.clientFactory?.(options) ?? new AcpClient(options);
+ const clientOptions = { ...options, onAgentStderr: this.options.onAgentStderr, onAgentSpawn: this.options.onAgentSpawn, spawnCwd: this.options.spawnCwd, inheritProcessEnv: this.options.inheritProcessEnv };
+ return this.deps.clientFactory?.(clientOptions) ?? new AcpClient(clientOptions);
}
async readPendingPersistentClient(record, options) {
const pendingClient = this.pendingPersistentClients.get(record.acpxRecordId);
diff --git a/dist/session-options-jkYbBxGE.d.ts b/dist/session-options-jkYbBxGE.d.ts
index 9d37f377fb6a0828e0d2bc5a48754f3aa71509a4..22dda59e0b7616a20ad45218913e5d8f884bae49 100644
--- a/dist/session-options-jkYbBxGE.d.ts
+++ b/dist/session-options-jkYbBxGE.d.ts
@@ -84,6 +84,10 @@ type AcpClientOptions = {
terminal?: boolean;
suppressSdkConsoleErrors?: boolean;
verbose?: boolean;
+ onAgentStderr?: (chunk: string) => void;
+ onAgentSpawn?: (meta: { pid: number; startedAt: string }) => Promise<void>;
+ spawnCwd?: string;
+ inheritProcessEnv?: boolean;
sessionOptions?: {
model?: string;
allowedTools?: string[];