@openclaw/acpx 2026.7.2-beta.7 → 2026.7.33
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{process-lease-DSLDgiNl.js → .setup/process-lease-DiKkFj6F.mjs} +14 -65
- package/dist/{register.runtime-BbS2JTTv.js → .setup/register.runtime-DjVBj71-.mjs} +1 -1
- package/dist/{runtime-By_lR8uk.js → .setup/runtime-FxGnBh3l.mjs} +169 -408
- package/dist/{service-CBZSAymH.js → .setup/service-CE4bgxXH.mjs} +587 -226
- package/dist/doctor-contract-api.js +1 -1
- package/dist/index.js +2 -1364
- package/dist/register.runtime.js +1 -1
- package/dist/setup-api.js +1 -1
- package/openclaw.plugin.json +3 -13
- package/package.json +8 -25
- package/skills/acp-router/SKILL.md +1 -1
- package/dist/config-schema-lrk5nlcV.js +0 -39
- package/dist/process-reaper-DFwbcdPa.js +0 -469
|
@@ -1,20 +1,18 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { AcpRuntimeError } from "
|
|
3
|
-
import {
|
|
4
|
-
import { parseStrictPositiveInteger } from "openclaw/plugin-sdk/number-runtime";
|
|
5
|
-
import { normalizeStringEntries } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
6
|
-
import { sliceUtf16Safe } from "openclaw/plugin-sdk/text-utility-runtime";
|
|
1
|
+
import { i as createAcpxProcessLeaseId, o as hashAcpxProcessCommand, u as withAcpxLeaseEnvironment } from "./process-lease-DiKkFj6F.mjs";
|
|
2
|
+
import { AcpRuntimeError } from "../runtime-api.js";
|
|
3
|
+
import { i as splitCommandParts, n as cleanupOpenClawOwnedAcpxProcessTree, r as isOpenClawLeaseAwareAcpxProcessCommand } from "./service-CE4bgxXH.mjs";
|
|
7
4
|
import fs from "node:fs/promises";
|
|
8
5
|
import path, { resolve } from "node:path";
|
|
6
|
+
import { normalizeStringEntries } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
9
7
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
10
8
|
import { ACPX_BACKEND_ID, AcpxRuntime as AcpxRuntime$1, createAcpRuntime, createAgentRegistry, createFileSessionStore, decodeAcpxRuntimeHandleState, encodeAcpxRuntimeHandleState, isRequestedModelUnsupportedError } from "acpx/runtime";
|
|
9
|
+
import { parseStrictPositiveInteger } from "openclaw/plugin-sdk/number-runtime";
|
|
11
10
|
import { redactSensitiveText } from "openclaw/plugin-sdk/security-runtime";
|
|
12
11
|
//#region extensions/acpx/src/runtime.ts
|
|
13
12
|
/**
|
|
14
13
|
* OpenClaw ACPX runtime adapter. It wraps the upstream acpx runtime with
|
|
15
14
|
* OpenClaw session metadata, lease tracking, model scoping, and cleanup policy.
|
|
16
15
|
*/
|
|
17
|
-
const ACPX_PLUGIN_TOOLS_MCP_SERVER_NAME = "openclaw-plugin-tools";
|
|
18
16
|
const ACPX_OPENCLAW_TOOLS_MCP_SERVER_NAME = "openclaw-tools";
|
|
19
17
|
const OPENCLAW_TOOLS_MCP_AGENT_SESSION_KEY_ENV = "OPENCLAW_TOOLS_MCP_AGENT_SESSION_KEY";
|
|
20
18
|
function withOpenClawManagedTurnTimeout(input) {
|
|
@@ -50,7 +48,8 @@ function isGenericInternalAcpError(error) {
|
|
|
50
48
|
async function readCodexWrapperStderrTail(params) {
|
|
51
49
|
if (!params.wrapperRoot || !params.leaseId) return "";
|
|
52
50
|
try {
|
|
53
|
-
|
|
51
|
+
const text = await fs.readFile(path.join(params.wrapperRoot, codexWrapperStderrLogFileName(params.leaseId)), "utf8");
|
|
52
|
+
return compactDiagnosticText(redactSensitiveText(text.slice(-6e3)));
|
|
54
53
|
} catch {
|
|
55
54
|
return "";
|
|
56
55
|
}
|
|
@@ -128,42 +127,29 @@ function createResetAwareSessionStore(baseStore, params) {
|
|
|
128
127
|
let recordToSave = record;
|
|
129
128
|
const launch = params?.launchScope?.getStore();
|
|
130
129
|
const sessionName = readSessionRecordName(record);
|
|
130
|
+
const rootPid = readRecordAgentPid(record);
|
|
131
131
|
const agentCommand = readRecordAgentCommand(record);
|
|
132
|
-
const
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
rootPid,
|
|
154
|
-
...existing?.rootPid === rootPid && existing.processGroupId ? { processGroupId: existing.processGroupId } : {},
|
|
155
|
-
commandHash: hashAcpxProcessCommand(leasedCommand),
|
|
156
|
-
startedAt: existing?.rootPid === rootPid ? existing.startedAt : Date.now(),
|
|
157
|
-
state: "open"
|
|
158
|
-
});
|
|
159
|
-
recordToSave = withOpenClawLeaseSessionMetadata({
|
|
160
|
-
...lifecycleRecord,
|
|
161
|
-
agentCommand: leasedCommand
|
|
162
|
-
}, {
|
|
163
|
-
openclawLeaseId: leaseIdentity.leaseId,
|
|
164
|
-
openclawGatewayInstanceId: leaseIdentity.gatewayInstanceId
|
|
165
|
-
});
|
|
166
|
-
}
|
|
132
|
+
const stableAgentCommand = launch?.stableCommand ?? agentCommand;
|
|
133
|
+
if (launch && params?.leaseStore && sessionName === launch.sessionKey && rootPid && stableAgentCommand) {
|
|
134
|
+
const lease = {
|
|
135
|
+
leaseId: launch.leaseId,
|
|
136
|
+
gatewayInstanceId: launch.gatewayInstanceId,
|
|
137
|
+
sessionKey: launch.sessionKey,
|
|
138
|
+
wrapperRoot: launch.wrapperRoot,
|
|
139
|
+
wrapperPath: extractGeneratedWrapperPath(stableAgentCommand),
|
|
140
|
+
rootPid,
|
|
141
|
+
commandHash: hashAcpxProcessCommand(stableAgentCommand),
|
|
142
|
+
startedAt: Date.now(),
|
|
143
|
+
state: "open"
|
|
144
|
+
};
|
|
145
|
+
await params.leaseStore.save(lease);
|
|
146
|
+
recordToSave = withOpenClawLeaseSessionMetadata({
|
|
147
|
+
...record,
|
|
148
|
+
agentCommand: stableAgentCommand
|
|
149
|
+
}, {
|
|
150
|
+
openclawLeaseId: launch.leaseId,
|
|
151
|
+
openclawGatewayInstanceId: launch.gatewayInstanceId
|
|
152
|
+
});
|
|
167
153
|
}
|
|
168
154
|
await baseStore.save(recordToSave);
|
|
169
155
|
if (sessionName) freshSessionKeys.delete(sessionName);
|
|
@@ -179,6 +165,12 @@ const OPENCLAW_BRIDGE_SUBCOMMAND = "acp";
|
|
|
179
165
|
const CODEX_ACP_AGENT_ID = "codex";
|
|
180
166
|
const CODEX_ACP_OPENCLAW_PREFIX = "openai/";
|
|
181
167
|
const CLAUDE_ACP_OPENCLAW_PREFIX = "anthropic/";
|
|
168
|
+
const CODEX_ACP_REASONING_EFFORTS = /* @__PURE__ */ new Set([
|
|
169
|
+
"low",
|
|
170
|
+
"medium",
|
|
171
|
+
"high",
|
|
172
|
+
"xhigh"
|
|
173
|
+
]);
|
|
182
174
|
const CODEX_ACP_THINKING_ALIASES = /* @__PURE__ */ new Map([
|
|
183
175
|
["off", void 0],
|
|
184
176
|
["minimal", "low"],
|
|
@@ -222,14 +214,9 @@ function isEnvAssignment(value) {
|
|
|
222
214
|
return /^[A-Za-z_][A-Za-z0-9_]*=/.test(value);
|
|
223
215
|
}
|
|
224
216
|
function unwrapEnvCommand(parts) {
|
|
225
|
-
|
|
226
|
-
if (!command || basename(command) !== "env") return parts;
|
|
217
|
+
if (!parts.length || basename(parts[0]) !== "env") return parts;
|
|
227
218
|
let index = 1;
|
|
228
|
-
while (
|
|
229
|
-
const part = parts.at(index);
|
|
230
|
-
if (!part || !isEnvAssignment(part)) break;
|
|
231
|
-
index += 1;
|
|
232
|
-
}
|
|
219
|
+
while (index < parts.length && isEnvAssignment(parts[index])) index += 1;
|
|
233
220
|
return parts.slice(index);
|
|
234
221
|
}
|
|
235
222
|
function matchesExecutableName(value, executableName) {
|
|
@@ -264,7 +251,7 @@ function isOpenClawBridgeCommand(command) {
|
|
|
264
251
|
}
|
|
265
252
|
function isCodexAcpCommand(command) {
|
|
266
253
|
return isAcpCommand(command, {
|
|
267
|
-
packageName:
|
|
254
|
+
packageName: "@zed-industries/codex-acp",
|
|
268
255
|
executableName: "codex-acp"
|
|
269
256
|
});
|
|
270
257
|
}
|
|
@@ -293,50 +280,27 @@ function normalizeCodexAcpReasoningEffort(rawThinking) {
|
|
|
293
280
|
if (!CODEX_ACP_THINKING_ALIASES.has(normalized)) failUnsupportedCodexAcpThinking(rawThinking ?? "");
|
|
294
281
|
return CODEX_ACP_THINKING_ALIASES.get(normalized);
|
|
295
282
|
}
|
|
296
|
-
function
|
|
297
|
-
const normalized = value?.trim().toLowerCase();
|
|
298
|
-
return Boolean(normalized && CODEX_ACP_THINKING_ALIASES.has(normalized));
|
|
299
|
-
}
|
|
300
|
-
function classifyCodexAcpModelRequest(rawModel, rawThinking) {
|
|
283
|
+
function normalizeCodexAcpModelOverride(rawModel, rawThinking) {
|
|
301
284
|
const raw = rawModel?.trim();
|
|
302
285
|
const thinkingReasoningEffort = normalizeCodexAcpReasoningEffort(rawThinking);
|
|
303
|
-
|
|
304
|
-
if (!raw) return {
|
|
305
|
-
kind: "override",
|
|
306
|
-
override: thinkingOnlyOverride ?? {}
|
|
307
|
-
};
|
|
286
|
+
if (!raw) return thinkingReasoningEffort ? { reasoningEffort: thinkingReasoningEffort } : void 0;
|
|
308
287
|
let value = raw;
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
let modelReasoningEffort;
|
|
316
|
-
const slashIndex = value.lastIndexOf("/");
|
|
317
|
-
if (slashIndex >= 0 && isCodexAcpReasoningEffortAlias(value.slice(slashIndex + 1))) {
|
|
318
|
-
modelReasoningEffort = normalizeCodexAcpReasoningEffort(value.slice(slashIndex + 1));
|
|
319
|
-
model = value.slice(0, slashIndex).trim();
|
|
320
|
-
}
|
|
321
|
-
if (hadOpenAiQualifier && (!model || model.includes("/"))) failUnsupportedCodexAcpModel(raw, `Codex ACP model "${raw}" is not supported. Use openai/<model> or <model>/<reasoning-effort>.`);
|
|
322
|
-
if (!model || model.includes("/")) return thinkingOnlyOverride ? {
|
|
323
|
-
kind: "unsupported",
|
|
324
|
-
thinkingOverride: thinkingOnlyOverride
|
|
325
|
-
} : { kind: "unsupported" };
|
|
288
|
+
if (value.toLowerCase().startsWith(CODEX_ACP_OPENCLAW_PREFIX)) value = value.slice(7);
|
|
289
|
+
const parts = value.split("/");
|
|
290
|
+
if (parts.length > 2) failUnsupportedCodexAcpModel(raw, `Codex ACP model "${raw}" is not supported. Use openai/<model> or <model>/<reasoning-effort>.`);
|
|
291
|
+
const model = (parts[0] ?? "").trim();
|
|
292
|
+
const modelReasoningEffort = normalizeCodexAcpReasoningEffort(parts[1]);
|
|
293
|
+
if (!model) failUnsupportedCodexAcpModel(raw, `Codex ACP model "${raw}" is not supported. Use openai/<model> or <model>/<reasoning-effort>.`);
|
|
326
294
|
const reasoningEffort = thinkingReasoningEffort ?? modelReasoningEffort;
|
|
295
|
+
if (reasoningEffort && !CODEX_ACP_REASONING_EFFORTS.has(reasoningEffort)) failUnsupportedCodexAcpThinking(reasoningEffort);
|
|
327
296
|
return {
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
model,
|
|
331
|
-
...reasoningEffort ? { reasoningEffort } : {}
|
|
332
|
-
}
|
|
297
|
+
model,
|
|
298
|
+
...reasoningEffort ? { reasoningEffort } : {}
|
|
333
299
|
};
|
|
334
300
|
}
|
|
335
|
-
function
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
else delete next.model;
|
|
339
|
-
return next;
|
|
301
|
+
function codexAcpSessionModelId(override) {
|
|
302
|
+
if (!override.model) return "";
|
|
303
|
+
return override.reasoningEffort ? `${override.model}/${override.reasoningEffort}` : override.model;
|
|
340
304
|
}
|
|
341
305
|
function normalizeClaudeAcpModelOverride(rawModel) {
|
|
342
306
|
const raw = rawModel?.trim();
|
|
@@ -351,9 +315,8 @@ function withAcpxSessionOptions(input) {
|
|
|
351
315
|
...existingOptions,
|
|
352
316
|
model
|
|
353
317
|
} : existingOptions;
|
|
354
|
-
const { modelExplicit: _modelExplicit, ...rest } = input;
|
|
355
318
|
return {
|
|
356
|
-
...
|
|
319
|
+
...input,
|
|
357
320
|
...sessionOptions ? { sessionOptions } : {}
|
|
358
321
|
};
|
|
359
322
|
}
|
|
@@ -375,21 +338,16 @@ function quoteShellArg(value) {
|
|
|
375
338
|
if (/^[A-Za-z0-9_./:=@+-]+$/.test(value)) return value;
|
|
376
339
|
return `'${value.replace(/'/g, "'\\''")}'`;
|
|
377
340
|
}
|
|
378
|
-
function normalizeAgentCommand(command) {
|
|
379
|
-
return (Array.isArray(command) ? command.map((part) => quoteShellArg(part)).join(" ") : command).trim() || void 0;
|
|
380
|
-
}
|
|
381
341
|
function appendCodexAcpConfigOverrides(command, override) {
|
|
382
|
-
const
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
}
|
|
386
|
-
if (Object.keys(config).length === 0) return command;
|
|
387
|
-
return `${command} ${OPENCLAW_CODEX_CONFIG_ARG} ${quoteShellArg(JSON.stringify(config))}`;
|
|
342
|
+
const configArgs = override.model ? [`model=${override.model}`] : [];
|
|
343
|
+
if (override.reasoningEffort) configArgs.push(`model_reasoning_effort=${override.reasoningEffort}`);
|
|
344
|
+
if (configArgs.length === 0) return command;
|
|
345
|
+
return `${command} ${configArgs.map((arg) => `-c ${quoteShellArg(arg)}`).join(" ")}`;
|
|
388
346
|
}
|
|
389
347
|
function createModelScopedAgentRegistry(params) {
|
|
390
348
|
return {
|
|
391
349
|
resolve(agentName) {
|
|
392
|
-
const command =
|
|
350
|
+
const command = params.agentRegistry.resolve(agentName);
|
|
393
351
|
const override = params.scope.getStore();
|
|
394
352
|
if (!override || normalizeAgentName(agentName) !== CODEX_ACP_AGENT_ID || !isCodexAcpCommand(command)) return params.leaseCommand(command);
|
|
395
353
|
return params.leaseCommand(appendCodexAcpConfigOverrides(command, override));
|
|
@@ -402,7 +360,15 @@ function createModelScopedAgentRegistry(params) {
|
|
|
402
360
|
function resolveAgentCommand(params) {
|
|
403
361
|
const normalizedAgentName = normalizeAgentName(params.agentName);
|
|
404
362
|
if (!normalizedAgentName) return;
|
|
405
|
-
|
|
363
|
+
const resolvedCommand = params.agentRegistry.resolve(normalizedAgentName);
|
|
364
|
+
return typeof resolvedCommand === "string" ? resolvedCommand.trim() || void 0 : void 0;
|
|
365
|
+
}
|
|
366
|
+
function resolveProbeAgentName(options) {
|
|
367
|
+
const { probeAgent } = options;
|
|
368
|
+
return normalizeAgentName(typeof probeAgent === "string" ? probeAgent : void 0) ?? "codex";
|
|
369
|
+
}
|
|
370
|
+
function resolveAgentCommandForName(params) {
|
|
371
|
+
return resolveAgentCommand(params);
|
|
406
372
|
}
|
|
407
373
|
function shouldUseBridgeSafeDelegateForCommand(command) {
|
|
408
374
|
return isOpenClawBridgeCommand(command);
|
|
@@ -411,14 +377,12 @@ function shouldUseDistinctBridgeDelegate(options) {
|
|
|
411
377
|
const { mcpServers } = options;
|
|
412
378
|
return Array.isArray(mcpServers) && mcpServers.length > 0;
|
|
413
379
|
}
|
|
414
|
-
function
|
|
380
|
+
function withOpenClawToolsMcpSessionEnv(params) {
|
|
415
381
|
const sessionKey = params.sessionKey.trim();
|
|
416
|
-
if (!params.
|
|
382
|
+
if (!params.enabled || !sessionKey || !params.mcpServers?.length) return params.mcpServers;
|
|
417
383
|
let changed = false;
|
|
418
384
|
const nextServers = params.mcpServers.map((server) => {
|
|
419
|
-
|
|
420
|
-
const isManagedOpenClawTools = params.openclawToolsEnabled && server.name === ACPX_OPENCLAW_TOOLS_MCP_SERVER_NAME;
|
|
421
|
-
if (!isManagedPluginTools && !isManagedOpenClawTools || !("command" in server)) return server;
|
|
385
|
+
if (server.name !== ACPX_OPENCLAW_TOOLS_MCP_SERVER_NAME || !("command" in server)) return server;
|
|
422
386
|
changed = true;
|
|
423
387
|
const env = [...server.env.filter((entry) => entry.name !== OPENCLAW_TOOLS_MCP_AGENT_SESSION_KEY_ENV), {
|
|
424
388
|
name: OPENCLAW_TOOLS_MCP_AGENT_SESSION_KEY_ENV,
|
|
@@ -435,25 +399,19 @@ function withManagedToolsMcpSessionEnv(params) {
|
|
|
435
399
|
var AcpxRuntime = class {
|
|
436
400
|
constructor(options, testOptions) {
|
|
437
401
|
this.codexAcpModelOverrideScope = new AsyncLocalStorage();
|
|
438
|
-
this.
|
|
402
|
+
this.openclawToolsSessionDelegates = /* @__PURE__ */ new Map();
|
|
439
403
|
this.launchLeaseScope = new AsyncLocalStorage();
|
|
440
|
-
this.ensureSessionTails = /* @__PURE__ */ new Map();
|
|
441
|
-
this.processLeaseTransitionTails = /* @__PURE__ */ new Map();
|
|
442
|
-
this.processLeaseOperationCounts = /* @__PURE__ */ new Map();
|
|
443
404
|
const { openclawProcessCleanup, ...delegateTestOptions } = testOptions ?? {};
|
|
444
405
|
this.processCleanupDeps = openclawProcessCleanup;
|
|
445
406
|
this.wrapperRoot = options.openclawWrapperRoot;
|
|
446
407
|
this.gatewayInstanceId = options.openclawGatewayInstanceId;
|
|
447
408
|
this.processLeaseStore = options.openclawProcessLeaseStore;
|
|
448
|
-
this.pluginToolsMcpBridgeEnabled = options.pluginToolsMcpBridgeEnabled === true;
|
|
449
409
|
this.openclawToolsMcpBridgeEnabled = options.openclawToolsMcpBridgeEnabled === true;
|
|
450
|
-
this.managedToolsMcpBridgeEnabled = this.pluginToolsMcpBridgeEnabled || this.openclawToolsMcpBridgeEnabled;
|
|
451
410
|
this.cwd = options.cwd;
|
|
452
411
|
this.sessionStore = createResetAwareSessionStore(options.sessionStore, {
|
|
453
412
|
gatewayInstanceId: this.gatewayInstanceId,
|
|
454
413
|
leaseStore: this.processLeaseStore,
|
|
455
|
-
launchScope: this.launchLeaseScope
|
|
456
|
-
wrapperRoot: this.wrapperRoot
|
|
414
|
+
launchScope: this.launchLeaseScope
|
|
457
415
|
});
|
|
458
416
|
this.agentRegistry = options.agentRegistry;
|
|
459
417
|
this.scopedAgentRegistry = createModelScopedAgentRegistry({
|
|
@@ -473,40 +431,44 @@ var AcpxRuntime = class {
|
|
|
473
431
|
...sharedOptions,
|
|
474
432
|
mcpServers: []
|
|
475
433
|
}, this.delegateTestOptions) : this.delegate;
|
|
476
|
-
|
|
477
|
-
|
|
434
|
+
this.probeDelegate = this.openclawToolsMcpBridgeEnabled ? this.bridgeSafeDelegate : this.resolveDelegateForAgent(resolveProbeAgentName(options));
|
|
435
|
+
}
|
|
436
|
+
resolveDelegateForAgent(agentName) {
|
|
437
|
+
const command = resolveAgentCommandForName({
|
|
438
|
+
agentName,
|
|
478
439
|
agentRegistry: this.agentRegistry
|
|
479
440
|
});
|
|
480
|
-
|
|
481
|
-
|
|
441
|
+
return this.resolveDelegateForCommand(command);
|
|
442
|
+
}
|
|
443
|
+
resolveDelegateForCommand(command) {
|
|
444
|
+
return shouldUseBridgeSafeDelegateForCommand(command) ? this.bridgeSafeDelegate : this.delegate;
|
|
482
445
|
}
|
|
483
446
|
resolveDelegateForSession(params) {
|
|
484
447
|
if (shouldUseBridgeSafeDelegateForCommand(params.command)) return this.bridgeSafeDelegate;
|
|
485
|
-
return this.
|
|
448
|
+
return this.resolveOpenClawToolsDelegateForSession(params.sessionKey);
|
|
486
449
|
}
|
|
487
|
-
|
|
488
|
-
if (!this.
|
|
450
|
+
resolveOpenClawToolsDelegateForSession(sessionKey) {
|
|
451
|
+
if (!this.openclawToolsMcpBridgeEnabled) return this.delegate;
|
|
489
452
|
const normalizedSessionKey = sessionKey.trim();
|
|
490
453
|
if (!normalizedSessionKey) return this.delegate;
|
|
491
|
-
const cached = this.
|
|
454
|
+
const cached = this.openclawToolsSessionDelegates.get(normalizedSessionKey);
|
|
492
455
|
if (cached) return cached;
|
|
493
456
|
const delegate = new AcpxRuntime$1({
|
|
494
457
|
...this.delegateOptions,
|
|
495
|
-
mcpServers:
|
|
496
|
-
|
|
497
|
-
openclawToolsEnabled: this.openclawToolsMcpBridgeEnabled,
|
|
458
|
+
mcpServers: withOpenClawToolsMcpSessionEnv({
|
|
459
|
+
enabled: this.openclawToolsMcpBridgeEnabled,
|
|
498
460
|
mcpServers: this.delegateOptions.mcpServers,
|
|
499
461
|
sessionKey: normalizedSessionKey
|
|
500
462
|
})
|
|
501
463
|
}, this.delegateTestOptions);
|
|
502
|
-
this.
|
|
464
|
+
this.openclawToolsSessionDelegates.set(normalizedSessionKey, delegate);
|
|
503
465
|
return delegate;
|
|
504
466
|
}
|
|
505
|
-
|
|
506
|
-
if (!this.
|
|
467
|
+
releaseOpenClawToolsDelegateForSession(sessionKey) {
|
|
468
|
+
if (!this.openclawToolsMcpBridgeEnabled) return;
|
|
507
469
|
const normalizedSessionKey = sessionKey.trim();
|
|
508
470
|
if (!normalizedSessionKey) return;
|
|
509
|
-
this.
|
|
471
|
+
this.openclawToolsSessionDelegates.delete(normalizedSessionKey);
|
|
510
472
|
}
|
|
511
473
|
async resolveDelegateForHandle(handle) {
|
|
512
474
|
const record = await this.sessionStore.load(handle.acpxRecordId ?? handle.sessionKey);
|
|
@@ -518,7 +480,7 @@ var AcpxRuntime = class {
|
|
|
518
480
|
command: recordCommand,
|
|
519
481
|
sessionKey: handle.sessionKey
|
|
520
482
|
});
|
|
521
|
-
const command =
|
|
483
|
+
const command = resolveAgentCommandForName({
|
|
522
484
|
agentName: readAgentFromHandle(handle),
|
|
523
485
|
agentRegistry: this.agentRegistry
|
|
524
486
|
});
|
|
@@ -530,7 +492,7 @@ var AcpxRuntime = class {
|
|
|
530
492
|
async resolveCommandForHandle(handle) {
|
|
531
493
|
const recordCommand = readAgentCommandFromRecord(await this.sessionStore.load(handle.acpxRecordId ?? handle.sessionKey));
|
|
532
494
|
if (recordCommand) return recordCommand;
|
|
533
|
-
return
|
|
495
|
+
return resolveAgentCommandForName({
|
|
534
496
|
agentName: readAgentFromHandle(handle),
|
|
535
497
|
agentRegistry: this.agentRegistry
|
|
536
498
|
});
|
|
@@ -538,206 +500,47 @@ var AcpxRuntime = class {
|
|
|
538
500
|
commandWithLaunchLease(command) {
|
|
539
501
|
const launch = this.launchLeaseScope.getStore();
|
|
540
502
|
if (!launch) return command;
|
|
541
|
-
|
|
503
|
+
launch.stableCommand = command;
|
|
542
504
|
return withAcpxLeaseEnvironment({
|
|
543
505
|
command,
|
|
544
506
|
leaseId: launch.leaseId,
|
|
545
507
|
gatewayInstanceId: launch.gatewayInstanceId
|
|
546
508
|
});
|
|
547
509
|
}
|
|
548
|
-
async
|
|
549
|
-
if (params.mode !== "persistent" || !params.command) return;
|
|
510
|
+
async canReuseStablePersistentSession(params) {
|
|
511
|
+
if (params.mode !== "persistent" || !params.command) return false;
|
|
550
512
|
const existing = await this.sessionStore.load(params.sessionKey);
|
|
551
|
-
if (!existing || readRecordResetOnNextEnsure(existing)) return;
|
|
513
|
+
if (!existing || readRecordResetOnNextEnsure(existing)) return false;
|
|
552
514
|
const recordCwd = readRecordCwd(existing);
|
|
553
|
-
if (!recordCwd || resolve(recordCwd) !== resolve(params.cwd?.trim() || this.cwd)) return;
|
|
554
|
-
|
|
555
|
-
if (!recordCommand) return;
|
|
556
|
-
const leaseIdentity = readAcpxProcessLeaseIdentity(recordCommand);
|
|
557
|
-
if (leaseIdentity && leaseIdentity.gatewayInstanceId !== this.gatewayInstanceId) return;
|
|
558
|
-
if (recordCommand !== (leaseIdentity ? withAcpxLeaseEnvironment({
|
|
559
|
-
command: params.command,
|
|
560
|
-
leaseId: leaseIdentity.leaseId,
|
|
561
|
-
gatewayInstanceId: leaseIdentity.gatewayInstanceId
|
|
562
|
-
}) : params.command)) return;
|
|
515
|
+
if (!recordCwd || resolve(recordCwd) !== resolve(params.cwd?.trim() || this.cwd)) return false;
|
|
516
|
+
if (readRecordAgentCommand(existing) !== params.command) return false;
|
|
563
517
|
const existingSessionId = typeof existing === "object" && existing !== null ? existing.acpSessionId : void 0;
|
|
564
|
-
return !params.resumeSessionId || existingSessionId === params.resumeSessionId
|
|
518
|
+
return !params.resumeSessionId || existingSessionId === params.resumeSessionId;
|
|
565
519
|
}
|
|
566
520
|
async runWithLaunchLease(params) {
|
|
567
|
-
if (!params.command || !this.wrapperRoot || !this.gatewayInstanceId || !this.processLeaseStore || !isOpenClawLeaseAwareAcpxProcessCommand({
|
|
521
|
+
if (params.enabled === false || !params.command || !this.wrapperRoot || !this.gatewayInstanceId || !this.processLeaseStore || !isOpenClawLeaseAwareAcpxProcessCommand({
|
|
568
522
|
command: params.command,
|
|
569
523
|
wrapperRoot: this.wrapperRoot
|
|
570
524
|
})) return await params.run();
|
|
571
|
-
const processLeaseStore = this.processLeaseStore;
|
|
572
|
-
const reusableIdentity = readAcpxProcessLeaseIdentity(params.reusableCommand);
|
|
573
|
-
const canReuseLeaseIdentity = reusableIdentity?.gatewayInstanceId === this.gatewayInstanceId;
|
|
574
|
-
const leaseId = canReuseLeaseIdentity ? reusableIdentity.leaseId : createAcpxProcessLeaseId();
|
|
575
|
-
const leasedCommand = withAcpxLeaseEnvironment({
|
|
576
|
-
command: params.command,
|
|
577
|
-
leaseId,
|
|
578
|
-
gatewayInstanceId: this.gatewayInstanceId
|
|
579
|
-
});
|
|
580
525
|
const launch = {
|
|
581
|
-
leaseId,
|
|
526
|
+
leaseId: createAcpxProcessLeaseId(),
|
|
582
527
|
gatewayInstanceId: this.gatewayInstanceId,
|
|
583
528
|
sessionKey: params.sessionKey,
|
|
584
529
|
wrapperRoot: this.wrapperRoot,
|
|
585
|
-
stableCommand: params.command
|
|
586
|
-
resolvedCommand: params.reusableCommand ?? leasedCommand,
|
|
587
|
-
leasedCommand
|
|
530
|
+
stableCommand: params.command
|
|
588
531
|
};
|
|
589
|
-
await this.
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
rootPid: 0,
|
|
600
|
-
commandHash: hashAcpxProcessCommand(leasedCommand),
|
|
601
|
-
startedAt: Date.now(),
|
|
602
|
-
state: "open"
|
|
603
|
-
});
|
|
604
|
-
});
|
|
605
|
-
try {
|
|
606
|
-
const result = await this.launchLeaseScope.run(launch, params.run);
|
|
607
|
-
await this.finalizeProcessLeaseForSession(params.sessionKey, launch);
|
|
608
|
-
return result;
|
|
609
|
-
} catch (error) {
|
|
610
|
-
await this.retirePendingProcessLease(launch);
|
|
611
|
-
throw error;
|
|
612
|
-
}
|
|
613
|
-
}
|
|
614
|
-
async prepareProcessLeaseForOperation(handle) {
|
|
615
|
-
if (!this.processLeaseStore || !this.gatewayInstanceId || !this.wrapperRoot) return;
|
|
616
|
-
const processLeaseStore = this.processLeaseStore;
|
|
617
|
-
const wrapperRoot = this.wrapperRoot;
|
|
618
|
-
const record = await this.sessionStore.load(handle.acpxRecordId ?? handle.sessionKey);
|
|
619
|
-
const recordPid = readRecordAgentPid(record);
|
|
620
|
-
const command = readAgentCommandFromRecord(record);
|
|
621
|
-
const identity = readAcpxProcessLeaseIdentity(command);
|
|
622
|
-
if (!command || !isOpenClawLeaseAwareAcpxProcessCommand({
|
|
623
|
-
command,
|
|
624
|
-
wrapperRoot
|
|
625
|
-
})) return;
|
|
626
|
-
if (!identity) return;
|
|
627
|
-
if (identity.gatewayInstanceId !== this.gatewayInstanceId) throw new AcpRuntimeError("ACP_TURN_FAILED", `ACPX process lease ${identity.leaseId} belongs to another gateway`);
|
|
628
|
-
await this.retainProcessLeaseOperation(identity, async () => {
|
|
629
|
-
const existing = await processLeaseStore.load(identity.leaseId);
|
|
630
|
-
if (!existing) {
|
|
631
|
-
await processLeaseStore.save({
|
|
632
|
-
leaseId: identity.leaseId,
|
|
633
|
-
gatewayInstanceId: identity.gatewayInstanceId,
|
|
634
|
-
sessionKey: handle.sessionKey,
|
|
635
|
-
wrapperRoot,
|
|
636
|
-
wrapperPath: extractGeneratedWrapperPath(command),
|
|
637
|
-
rootPid: recordPid ?? 0,
|
|
638
|
-
commandHash: hashAcpxProcessCommand(command),
|
|
639
|
-
startedAt: Date.now(),
|
|
640
|
-
state: "open"
|
|
641
|
-
});
|
|
642
|
-
return;
|
|
643
|
-
}
|
|
644
|
-
if (existing.gatewayInstanceId !== identity.gatewayInstanceId || existing.sessionKey !== handle.sessionKey || existing.wrapperRoot !== wrapperRoot) throw new AcpRuntimeError("ACP_TURN_FAILED", `ACPX process lease ${identity.leaseId} belongs to another session`);
|
|
645
|
-
});
|
|
646
|
-
return identity;
|
|
647
|
-
}
|
|
648
|
-
async runSerializedProcessLeaseTransition(leaseId, run) {
|
|
649
|
-
const previous = this.processLeaseTransitionTails.get(leaseId) ?? Promise.resolve();
|
|
650
|
-
let release;
|
|
651
|
-
const current = new Promise((resolve) => {
|
|
652
|
-
release = resolve;
|
|
653
|
-
});
|
|
654
|
-
const tail = previous.then(() => current);
|
|
655
|
-
this.processLeaseTransitionTails.set(leaseId, tail);
|
|
656
|
-
await previous;
|
|
657
|
-
try {
|
|
658
|
-
return await run();
|
|
659
|
-
} finally {
|
|
660
|
-
release();
|
|
661
|
-
if (this.processLeaseTransitionTails.get(leaseId) === tail) this.processLeaseTransitionTails.delete(leaseId);
|
|
662
|
-
}
|
|
663
|
-
}
|
|
664
|
-
async retainProcessLeaseOperation(identity, prepare) {
|
|
665
|
-
await this.runSerializedProcessLeaseTransition(identity.leaseId, async () => {
|
|
666
|
-
await prepare();
|
|
667
|
-
this.processLeaseOperationCounts.set(identity.leaseId, (this.processLeaseOperationCounts.get(identity.leaseId) ?? 0) + 1);
|
|
668
|
-
});
|
|
669
|
-
}
|
|
670
|
-
async releaseProcessLeaseOperation(identity, finalize) {
|
|
671
|
-
if (!identity) return;
|
|
672
|
-
await this.runSerializedProcessLeaseTransition(identity.leaseId, async () => {
|
|
673
|
-
const count = this.processLeaseOperationCounts.get(identity.leaseId) ?? 0;
|
|
674
|
-
if (count > 1) {
|
|
675
|
-
this.processLeaseOperationCounts.set(identity.leaseId, count - 1);
|
|
676
|
-
return;
|
|
677
|
-
}
|
|
678
|
-
if (count === 0) return;
|
|
679
|
-
this.processLeaseOperationCounts.delete(identity.leaseId);
|
|
680
|
-
await finalize();
|
|
681
|
-
});
|
|
682
|
-
}
|
|
683
|
-
async finalizeProcessLeaseForOperation(handle, identity) {
|
|
684
|
-
await this.finalizeProcessLeaseForSession(handle.acpxRecordId ?? handle.sessionKey, identity);
|
|
685
|
-
}
|
|
686
|
-
async finalizeProcessLeaseForSession(sessionId, identity) {
|
|
687
|
-
if (!identity || !this.processLeaseStore) return;
|
|
688
|
-
const processLeaseStore = this.processLeaseStore;
|
|
689
|
-
await this.releaseProcessLeaseOperation(identity, async () => {
|
|
690
|
-
const lease = await processLeaseStore.load(identity.leaseId);
|
|
691
|
-
if (!lease || lease.gatewayInstanceId !== identity.gatewayInstanceId) return;
|
|
692
|
-
if (lease.rootPid <= 0) {
|
|
693
|
-
await processLeaseStore.markState(identity.leaseId, "lost");
|
|
694
|
-
return;
|
|
695
|
-
}
|
|
696
|
-
try {
|
|
697
|
-
const recordIdentity = readAcpxProcessLeaseIdentity(readAgentCommandFromRecord(await this.sessionStore.load(sessionId)));
|
|
698
|
-
if (recordIdentity?.leaseId !== identity.leaseId || recordIdentity.gatewayInstanceId !== identity.gatewayInstanceId) await processLeaseStore.markState(identity.leaseId, "lost");
|
|
699
|
-
} catch {}
|
|
700
|
-
});
|
|
701
|
-
}
|
|
702
|
-
async retirePendingProcessLease(identity) {
|
|
703
|
-
if (!identity || !this.processLeaseStore) return;
|
|
704
|
-
const processLeaseStore = this.processLeaseStore;
|
|
705
|
-
await this.releaseProcessLeaseOperation(identity, async () => {
|
|
706
|
-
const lease = await processLeaseStore.load(identity.leaseId);
|
|
707
|
-
if (lease?.gatewayInstanceId === identity.gatewayInstanceId && lease.rootPid <= 0) await processLeaseStore.markState(identity.leaseId, "lost");
|
|
708
|
-
});
|
|
709
|
-
}
|
|
710
|
-
async runWithProcessLeaseForHandle(handle, run) {
|
|
711
|
-
const identity = await this.prepareProcessLeaseForOperation(handle);
|
|
712
|
-
try {
|
|
713
|
-
return await run();
|
|
714
|
-
} finally {
|
|
715
|
-
await this.finalizeProcessLeaseForOperation(handle, identity);
|
|
716
|
-
}
|
|
717
|
-
}
|
|
718
|
-
async finalizeProcessLeaseAfter(handle, identityPromise, resultPromise) {
|
|
719
|
-
try {
|
|
720
|
-
return await resultPromise;
|
|
721
|
-
} finally {
|
|
722
|
-
await this.finalizeProcessLeaseForOperation(handle, await identityPromise);
|
|
723
|
-
}
|
|
724
|
-
}
|
|
725
|
-
async runSerializedSessionEnsure(sessionKey, run) {
|
|
726
|
-
const key = sessionKey.trim() || sessionKey;
|
|
727
|
-
const previous = this.ensureSessionTails.get(key) ?? Promise.resolve();
|
|
728
|
-
let release;
|
|
729
|
-
const current = new Promise((resolve) => {
|
|
730
|
-
release = resolve;
|
|
532
|
+
await this.processLeaseStore.save({
|
|
533
|
+
leaseId: launch.leaseId,
|
|
534
|
+
gatewayInstanceId: launch.gatewayInstanceId,
|
|
535
|
+
sessionKey: launch.sessionKey,
|
|
536
|
+
wrapperRoot: launch.wrapperRoot,
|
|
537
|
+
wrapperPath: extractGeneratedWrapperPath(params.command),
|
|
538
|
+
rootPid: 0,
|
|
539
|
+
commandHash: hashAcpxProcessCommand(params.command),
|
|
540
|
+
startedAt: Date.now(),
|
|
541
|
+
state: "open"
|
|
731
542
|
});
|
|
732
|
-
|
|
733
|
-
this.ensureSessionTails.set(key, tail);
|
|
734
|
-
await previous;
|
|
735
|
-
try {
|
|
736
|
-
return await run();
|
|
737
|
-
} finally {
|
|
738
|
-
release();
|
|
739
|
-
if (this.ensureSessionTails.get(key) === tail) this.ensureSessionTails.delete(key);
|
|
740
|
-
}
|
|
543
|
+
return await this.launchLeaseScope.run(launch, params.run);
|
|
741
544
|
}
|
|
742
545
|
async withCodexWrapperDiagnostics(params) {
|
|
743
546
|
try {
|
|
@@ -780,10 +583,10 @@ var AcpxRuntime = class {
|
|
|
780
583
|
wrapperRoot: lease.wrapperRoot,
|
|
781
584
|
deps: this.processCleanupDeps
|
|
782
585
|
});
|
|
783
|
-
await this.processLeaseStore?.markState(lease.leaseId, result.
|
|
586
|
+
await this.processLeaseStore?.markState(lease.leaseId, result.terminatedPids.length > 0 || result.skippedReason === "missing-root" ? "closed" : "lost");
|
|
784
587
|
return;
|
|
785
588
|
}
|
|
786
|
-
const rootCommand = readAgentCommandFromRecord(record) ??
|
|
589
|
+
const rootCommand = readAgentCommandFromRecord(record) ?? resolveAgentCommandForName({
|
|
787
590
|
agentName: readAgentFromHandle(handle),
|
|
788
591
|
agentRegistry: this.agentRegistry
|
|
789
592
|
});
|
|
@@ -808,11 +611,8 @@ var AcpxRuntime = class {
|
|
|
808
611
|
return this.probeDelegate.doctor();
|
|
809
612
|
}
|
|
810
613
|
async ensureSession(input) {
|
|
811
|
-
return await this.runSerializedSessionEnsure(input.sessionKey, () => this.ensureSessionUnlocked(input));
|
|
812
|
-
}
|
|
813
|
-
async ensureSessionUnlocked(input) {
|
|
814
614
|
assertSupportedRuntimeSessionMode(input.mode);
|
|
815
|
-
const command =
|
|
615
|
+
const command = resolveAgentCommandForName({
|
|
816
616
|
agentName: input.agent,
|
|
817
617
|
agentRegistry: this.agentRegistry
|
|
818
618
|
});
|
|
@@ -820,59 +620,49 @@ var AcpxRuntime = class {
|
|
|
820
620
|
command,
|
|
821
621
|
sessionKey: input.sessionKey
|
|
822
622
|
});
|
|
823
|
-
const isCodexAcp = normalizeAgentName(input.agent) === CODEX_ACP_AGENT_ID && isCodexAcpCommand(command);
|
|
824
623
|
const claudeModelOverride = isClaudeAcpCommand(command) ? normalizeClaudeAcpModelOverride(input.model) : void 0;
|
|
825
|
-
const
|
|
826
|
-
|
|
827
|
-
const classifiedCodexOverride = codexClassification?.kind === "override" ? codexClassification.override : codexClassification?.thinkingOverride;
|
|
828
|
-
const codexModelOverride = classifiedCodexOverride && Object.keys(classifiedCodexOverride).length > 0 ? classifiedCodexOverride : void 0;
|
|
829
|
-
const requestedModel = input.model?.trim();
|
|
830
|
-
const appliedModel = isCodexAcp && requestedModel ? codexModelOverride?.model ? {
|
|
831
|
-
kind: "applied",
|
|
832
|
-
model: requestedModel
|
|
833
|
-
} : { kind: "dropped" } : void 0;
|
|
834
|
-
const ensureInput = isCodexAcp ? withCodexSessionModel(input, codexModelOverride) : claudeModelOverride ? {
|
|
624
|
+
const codexModelOverride = normalizeAgentName(input.agent) === CODEX_ACP_AGENT_ID && isCodexAcpCommand(command) ? normalizeCodexAcpModelOverride(input.model, input.thinking) : void 0;
|
|
625
|
+
const ensureInput = claudeModelOverride ? {
|
|
835
626
|
...input,
|
|
836
627
|
model: claudeModelOverride
|
|
837
628
|
} : input;
|
|
838
629
|
const stableLaunchCommand = codexModelOverride && command ? appendCodexAcpConfigOverrides(command, codexModelOverride) : command;
|
|
839
|
-
const
|
|
630
|
+
const shouldStartWithLease = !await this.canReuseStablePersistentSession({
|
|
840
631
|
sessionKey: input.sessionKey,
|
|
841
632
|
mode: input.mode,
|
|
842
633
|
cwd: input.cwd,
|
|
843
634
|
command: stableLaunchCommand,
|
|
844
635
|
resumeSessionId: input.resumeSessionId
|
|
845
636
|
});
|
|
846
|
-
|
|
637
|
+
if (!codexModelOverride) return await this.runWithLaunchLease({
|
|
847
638
|
sessionKey: ensureInput.sessionKey,
|
|
848
639
|
command: stableLaunchCommand,
|
|
849
|
-
|
|
640
|
+
enabled: shouldStartWithLease,
|
|
850
641
|
run: () => this.withCodexWrapperDiagnostics({
|
|
851
642
|
command: stableLaunchCommand,
|
|
852
643
|
fallbackCode: "ACP_SESSION_INIT_FAILED",
|
|
853
644
|
run: () => ensureDelegateSessionWithModelFallback(delegate, ensureInput)
|
|
854
645
|
})
|
|
855
|
-
})
|
|
646
|
+
});
|
|
647
|
+
const normalizedInput = {
|
|
648
|
+
...ensureInput,
|
|
649
|
+
...codexAcpSessionModelId(codexModelOverride) ? { model: codexAcpSessionModelId(codexModelOverride) } : {}
|
|
650
|
+
};
|
|
651
|
+
return await this.runWithLaunchLease({
|
|
856
652
|
sessionKey: input.sessionKey,
|
|
857
653
|
command: stableLaunchCommand,
|
|
858
|
-
|
|
654
|
+
enabled: shouldStartWithLease,
|
|
859
655
|
run: () => this.codexAcpModelOverrideScope.run(codexModelOverride, () => this.withCodexWrapperDiagnostics({
|
|
860
656
|
command: stableLaunchCommand,
|
|
861
657
|
fallbackCode: "ACP_SESSION_INIT_FAILED",
|
|
862
|
-
run: () => delegate.ensureSession(withAcpxSessionOptions(
|
|
658
|
+
run: () => delegate.ensureSession(withAcpxSessionOptions(normalizedInput))
|
|
863
659
|
}))
|
|
864
660
|
});
|
|
865
|
-
return appliedModel ? {
|
|
866
|
-
...handle,
|
|
867
|
-
appliedModel
|
|
868
|
-
} : handle;
|
|
869
661
|
}
|
|
870
662
|
async *runTurn(input) {
|
|
871
|
-
const
|
|
872
|
-
|
|
663
|
+
const command = await this.resolveCommandForHandle(input.handle);
|
|
664
|
+
const delegate = await this.resolveDelegateForHandle(input.handle);
|
|
873
665
|
try {
|
|
874
|
-
command = await this.resolveCommandForHandle(input.handle);
|
|
875
|
-
const delegate = await this.resolveDelegateForHandle(input.handle);
|
|
876
666
|
for await (const event of delegate.runTurn(withOpenClawManagedTurnTimeout(input))) {
|
|
877
667
|
if (event.type !== "error" || !isCodexAcpCommand(command) || !isGenericInternalAcpErrorMessage(event.message)) {
|
|
878
668
|
yield event;
|
|
@@ -894,18 +684,11 @@ var AcpxRuntime = class {
|
|
|
894
684
|
const stderrTail = await this.readCodexTurnFailureStderr({ handle: input.handle });
|
|
895
685
|
if (!stderrTail) throw error;
|
|
896
686
|
throw new AcpRuntimeError("ACP_TURN_FAILED", `Internal error: ${stderrTail}`, { cause: error });
|
|
897
|
-
} finally {
|
|
898
|
-
await this.finalizeProcessLeaseForOperation(input.handle, turnLease);
|
|
899
687
|
}
|
|
900
688
|
}
|
|
901
689
|
startTurn(input) {
|
|
902
690
|
const readCodexTurnFailureStderr = () => this.readCodexTurnFailureStderr({ handle: input.handle });
|
|
903
|
-
const
|
|
904
|
-
const turnPromise = Promise.all([
|
|
905
|
-
turnLeasePromise,
|
|
906
|
-
this.resolveCommandForHandle(input.handle),
|
|
907
|
-
this.resolveDelegateForHandle(input.handle)
|
|
908
|
-
]).then(async ([, command, delegate]) => {
|
|
691
|
+
const turnPromise = Promise.all([this.resolveCommandForHandle(input.handle), this.resolveDelegateForHandle(input.handle)]).then(async ([command, delegate]) => {
|
|
909
692
|
try {
|
|
910
693
|
return {
|
|
911
694
|
command,
|
|
@@ -946,7 +729,7 @@ var AcpxRuntime = class {
|
|
|
946
729
|
throw new AcpRuntimeError("ACP_TURN_FAILED", `Internal error: ${stderrTail}`, { cause: error });
|
|
947
730
|
}
|
|
948
731
|
} },
|
|
949
|
-
result:
|
|
732
|
+
result: turnPromise.then(async ({ command, turn }) => {
|
|
950
733
|
try {
|
|
951
734
|
const result = await turn.result;
|
|
952
735
|
if (result.status !== "failed" || !isCodexAcpCommand(command) || !isGenericInternalAcpErrorMessage(result.error.message)) return result;
|
|
@@ -966,7 +749,7 @@ var AcpxRuntime = class {
|
|
|
966
749
|
if (!stderrTail) throw error;
|
|
967
750
|
throw new AcpRuntimeError("ACP_TURN_FAILED", `Internal error: ${stderrTail}`, { cause: error });
|
|
968
751
|
}
|
|
969
|
-
})
|
|
752
|
+
}),
|
|
970
753
|
cancel(inputArgs) {
|
|
971
754
|
return turnPromise.then(({ turn }) => turn.cancel(inputArgs));
|
|
972
755
|
},
|
|
@@ -975,52 +758,38 @@ var AcpxRuntime = class {
|
|
|
975
758
|
}
|
|
976
759
|
};
|
|
977
760
|
}
|
|
978
|
-
getCapabilities(
|
|
979
|
-
return this.delegate.getCapabilities(
|
|
761
|
+
getCapabilities() {
|
|
762
|
+
return this.delegate.getCapabilities();
|
|
980
763
|
}
|
|
981
764
|
async getStatus(input) {
|
|
982
765
|
return (await this.resolveDelegateForHandle(input.handle)).getStatus(input);
|
|
983
766
|
}
|
|
984
767
|
async setMode(input) {
|
|
985
|
-
|
|
986
|
-
await this.runWithProcessLeaseForHandle(input.handle, () => delegate.setMode(input));
|
|
768
|
+
await (await this.resolveDelegateForHandle(input.handle)).setMode(input);
|
|
987
769
|
}
|
|
988
770
|
async setConfigOption(input) {
|
|
989
|
-
await this.runWithProcessLeaseForHandle(input.handle, () => this.setConfigOptionUnlocked(input));
|
|
990
|
-
}
|
|
991
|
-
async setConfigOptionUnlocked(input) {
|
|
992
771
|
const delegate = await this.resolveDelegateForHandle(input.handle);
|
|
993
772
|
const command = await this.resolveCommandForHandle(input.handle);
|
|
994
773
|
const key = input.key.trim().toLowerCase();
|
|
995
774
|
const isCodexAcp = isCodexAcpCommand(command);
|
|
996
775
|
if (WIRE_TIMEOUT_CONFIG_KEYS.has(key) && (isCodexAcp || isClaudeAcpCommand(command))) return;
|
|
997
776
|
if (isCodexAcp) {
|
|
998
|
-
if (key === "model") {
|
|
999
|
-
const
|
|
1000
|
-
if (
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
if (key === "thinking" || key === "thought_level" || key === "reasoning_effort") {
|
|
1015
|
-
const classification = classifyCodexAcpModelRequest(void 0, input.value);
|
|
1016
|
-
const reasoningEffort = classification.kind === "override" ? classification.override.reasoningEffort : void 0;
|
|
1017
|
-
if (!reasoningEffort) return;
|
|
1018
|
-
await delegate.setConfigOption({
|
|
1019
|
-
...input,
|
|
1020
|
-
key: "reasoning_effort",
|
|
1021
|
-
value: reasoningEffort
|
|
1022
|
-
});
|
|
1023
|
-
return;
|
|
777
|
+
if (key === "model" || key === "thinking" || key === "thought_level" || key === "reasoning_effort") {
|
|
778
|
+
const override = key === "model" ? normalizeCodexAcpModelOverride(input.value) : normalizeCodexAcpModelOverride(void 0, input.value);
|
|
779
|
+
if (!override && key !== "model") return;
|
|
780
|
+
if (override) {
|
|
781
|
+
if (override.model) await delegate.setConfigOption({
|
|
782
|
+
...input,
|
|
783
|
+
key: "model",
|
|
784
|
+
value: override.model
|
|
785
|
+
});
|
|
786
|
+
if (override.reasoningEffort) await delegate.setConfigOption({
|
|
787
|
+
...input,
|
|
788
|
+
key: "reasoning_effort",
|
|
789
|
+
value: override.reasoningEffort
|
|
790
|
+
});
|
|
791
|
+
return;
|
|
792
|
+
}
|
|
1024
793
|
}
|
|
1025
794
|
}
|
|
1026
795
|
if (isClaudeAcpCommand(command) && key === "model") {
|
|
@@ -1040,40 +809,32 @@ var AcpxRuntime = class {
|
|
|
1040
809
|
this.sessionStore.markFresh(input.sessionKey);
|
|
1041
810
|
}
|
|
1042
811
|
async close(input) {
|
|
1043
|
-
const
|
|
1044
|
-
let
|
|
812
|
+
const record = await this.sessionStore.load(input.handle.acpxRecordId ?? input.handle.sessionKey);
|
|
813
|
+
let closeSucceeded;
|
|
814
|
+
const delegate = this.resolveDelegateForLoadedRecord(input.handle, record);
|
|
1045
815
|
try {
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
reason: input.reason,
|
|
1053
|
-
discardPersistentState: input.discardPersistentState
|
|
1054
|
-
});
|
|
1055
|
-
closeSucceeded = true;
|
|
1056
|
-
} finally {
|
|
1057
|
-
await this.cleanupProcessTreeForRecord(input.handle, record);
|
|
1058
|
-
cleanupSucceeded = true;
|
|
1059
|
-
}
|
|
1060
|
-
if (closeSucceeded) this.releaseManagedToolsDelegateForSession(input.handle.sessionKey);
|
|
1061
|
-
if (closeSucceeded && input.discardPersistentState) this.sessionStore.markFresh(input.handle.sessionKey);
|
|
816
|
+
await delegate.close({
|
|
817
|
+
handle: input.handle,
|
|
818
|
+
reason: input.reason,
|
|
819
|
+
discardPersistentState: input.discardPersistentState
|
|
820
|
+
});
|
|
821
|
+
closeSucceeded = true;
|
|
1062
822
|
} finally {
|
|
1063
|
-
|
|
1064
|
-
else await this.retirePendingProcessLease(closeLease);
|
|
823
|
+
await this.cleanupProcessTreeForRecord(input.handle, record);
|
|
1065
824
|
}
|
|
825
|
+
if (closeSucceeded) this.releaseOpenClawToolsDelegateForSession(input.handle.sessionKey);
|
|
826
|
+
if (closeSucceeded && input.discardPersistentState) this.sessionStore.markFresh(input.handle.sessionKey);
|
|
1066
827
|
}
|
|
1067
828
|
};
|
|
1068
829
|
/** Test-only hooks for ACPX runtime behavior that is otherwise private. */
|
|
1069
830
|
const testing = {
|
|
1070
831
|
appendCodexAcpConfigOverrides,
|
|
1071
832
|
assertSupportedRuntimeSessionMode,
|
|
1072
|
-
|
|
833
|
+
codexAcpSessionModelId,
|
|
1073
834
|
isClaudeAcpCommand,
|
|
1074
835
|
isCodexAcpCommand,
|
|
1075
|
-
|
|
1076
|
-
|
|
836
|
+
normalizeClaudeAcpModelOverride,
|
|
837
|
+
normalizeCodexAcpModelOverride
|
|
1077
838
|
};
|
|
1078
839
|
//#endregion
|
|
1079
840
|
export { ACPX_BACKEND_ID, AcpxRuntime, testing as __testing, testing, createAcpRuntime, createAgentRegistry, createFileSessionStore, decodeAcpxRuntimeHandleState, encodeAcpxRuntimeHandleState };
|