@openclaw/acpx 2026.10.10 → 2026.11.5-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/.setup/{config-CE-ej7LM.mjs → config-Cplh34lQ.mjs} +15 -23
- package/dist/.setup/{harness-attempt-Bgcm-zBR.mjs → harness-attempt-Co9oLpPg.mjs} +5 -4
- package/dist/.setup/{pi-session-catalog-runtime-Cdf46b05.mjs → pi-session-catalog-runtime-DgzkbadO.mjs} +35 -57
- package/dist/.setup/{pi-session-paths-Co5515li.mjs → pi-session-paths-pUr6hnVA.mjs} +2 -2
- package/dist/.setup/{service-Dr8U5n0S.mjs → service-DmgP1gPb.mjs} +135 -373
- package/dist/.setup/{session-owner-migration-WmiXoSmh.mjs → session-owner-migration-CQA7L68K.mjs} +13 -10
- package/dist/.setup/{session-resource-Cv-RAA6y.mjs → session-resource-D_tXKvcv.mjs} +2 -2
- package/dist/.source-module-urls/9369b1b274d2ba70ea21d859abb3415ad8d63d0a1022a301763b953a5798469e.json +1 -0
- package/dist/doctor-contract-api.js +17 -11
- package/dist/index.js +206 -21
- package/openclaw.plugin.json +28 -1
- package/package.json +9 -9
- package/dist/.setup/register.runtime-CSJY10FS.mjs +0 -195
- package/dist/.source-module-urls/78a9d561eb54d4bf1ca0db6e6d12bb5688647241f2c0b289c611a0effb44d715.json +0 -1
- package/dist/register.runtime.js +0 -1
|
@@ -1,12 +1,13 @@
|
|
|
1
|
-
import { a as isClaudeAcpCommand, c as renderAgentCommand, d as CODEX_ACP_BIN, f as CODEX_ACP_PACKAGE, i as toAcpMcpServers, l as resolveAgentCommand, m as OPENCLAW_CODEX_CONFIG_ARG, n as resolveAcpxPluginRoot, o as isCodexAcpCommand, p as LEGACY_CODEX_ACP_PACKAGE, r as resolveOpenClawRoot, s as isOpenClawBridgeCommand, t as resolveAcpxPluginConfig, u as splitCommandParts } from "./config-
|
|
1
|
+
import { a as isClaudeAcpCommand, c as renderAgentCommand, d as CODEX_ACP_BIN, f as CODEX_ACP_PACKAGE, i as toAcpMcpServers, l as resolveAgentCommand, m as OPENCLAW_CODEX_CONFIG_ARG, n as resolveAcpxPluginRoot, o as isCodexAcpCommand, p as LEGACY_CODEX_ACP_PACKAGE, r as resolveOpenClawRoot, s as isOpenClawBridgeCommand, t as resolveAcpxPluginConfig, u as splitCommandParts } from "./config-Cplh34lQ.mjs";
|
|
2
2
|
import { AcpRuntimeError } from "../runtime-api.js";
|
|
3
|
-
import { t as resolveAcpxSessionResource } from "./session-resource-
|
|
4
|
-
import { a as hashAcpxProcessCommand, adoptAcpxStateDirectory, c as withAcpxLeaseArgs, d as normalizeAcpxGatewayInstanceRecord, i as createAcpxProcessLeaseStore, l as ACPX_GATEWAY_INSTANCE_KEY, n as OPENCLAW_ACPX_LEASE_ID_ARG, o as openAcpxProcessLeaseStateStore, r as OPENCLAW_GATEWAY_INSTANCE_ID_ARG, s as readAcpxProcessLeaseIdentity, t as ACPX_PROBE_LEASE_SESSION_KEY, u as ACPX_GATEWAY_INSTANCE_NAMESPACE } from "./session-owner-migration-
|
|
3
|
+
import { t as resolveAcpxSessionResource } from "./session-resource-D_tXKvcv.mjs";
|
|
4
|
+
import { a as hashAcpxProcessCommand, adoptAcpxStateDirectory, c as withAcpxLeaseArgs, d as normalizeAcpxGatewayInstanceRecord, i as createAcpxProcessLeaseStore, l as ACPX_GATEWAY_INSTANCE_KEY, n as OPENCLAW_ACPX_LEASE_ID_ARG, o as openAcpxProcessLeaseStateStore, r as OPENCLAW_GATEWAY_INSTANCE_ID_ARG, s as readAcpxProcessLeaseIdentity, t as ACPX_PROBE_LEASE_SESSION_KEY, u as ACPX_GATEWAY_INSTANCE_NAMESPACE } from "./session-owner-migration-CQA7L68K.mjs";
|
|
5
5
|
import { createRequire } from "node:module";
|
|
6
|
-
import { finiteSecondsToTimerSafeMilliseconds
|
|
6
|
+
import { finiteSecondsToTimerSafeMilliseconds } from "openclaw/plugin-sdk/number-runtime";
|
|
7
7
|
import fs from "node:fs";
|
|
8
8
|
import path from "node:path";
|
|
9
|
-
import {
|
|
9
|
+
import { isPidAlive, runExec } from "openclaw/plugin-sdk/process-runtime";
|
|
10
|
+
import { isRecord, normalizeLowercaseStringOrEmpty, normalizeOptionalLowercaseString, normalizeStringEntries } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
10
11
|
import os, { availableParallelism } from "node:os";
|
|
11
12
|
import { randomUUID } from "node:crypto";
|
|
12
13
|
import { formatErrorMessage } from "openclaw/plugin-sdk/error-runtime";
|
|
@@ -17,7 +18,6 @@ import { raceWithTimeout } from "openclaw/plugin-sdk/time-runtime";
|
|
|
17
18
|
import { tryReadJson } from "@openclaw/fs-safe/json";
|
|
18
19
|
import { parse, stringify } from "smol-toml";
|
|
19
20
|
import { setTimeout } from "node:timers/promises";
|
|
20
|
-
import { isPidAlive, runExec } from "openclaw/plugin-sdk/process-runtime";
|
|
21
21
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
22
22
|
import { isDeepStrictEqual } from "node:util";
|
|
23
23
|
import { redactSensitiveText } from "openclaw/plugin-sdk/security-runtime";
|
|
@@ -441,9 +441,7 @@ const parentWatcher =
|
|
|
441
441
|
return;
|
|
442
442
|
}
|
|
443
443
|
orphanCleanupStarted = true;
|
|
444
|
-
|
|
445
|
-
clearInterval(parentWatcher);
|
|
446
|
-
}
|
|
444
|
+
clearInterval(parentWatcher);
|
|
447
445
|
killChildTree("SIGTERM");
|
|
448
446
|
// Keep the wrapper alive long enough for stubborn adapters to receive
|
|
449
447
|
// a forced fallback signal after SIGTERM.
|
|
@@ -479,9 +477,7 @@ child.on("exit", (code, signal) => {
|
|
|
479
477
|
|
|
480
478
|
child.on("close", () => {
|
|
481
479
|
finishStderrLog();
|
|
482
|
-
|
|
483
|
-
clearInterval(parentWatcher);
|
|
484
|
-
}
|
|
480
|
+
clearInterval(parentWatcher);
|
|
485
481
|
childClosed = true;
|
|
486
482
|
finishWrapper();
|
|
487
483
|
});
|
|
@@ -490,121 +486,6 @@ main();
|
|
|
490
486
|
`;
|
|
491
487
|
}
|
|
492
488
|
// extensions/acpx/src/codex-trust-config.ts
|
|
493
|
-
function stripTomlComment(line) {
|
|
494
|
-
let quote = null;
|
|
495
|
-
let escaping = false;
|
|
496
|
-
for (let index = 0; index < line.length; index += 1) {
|
|
497
|
-
const ch = line[index];
|
|
498
|
-
if (escaping) {
|
|
499
|
-
escaping = false;
|
|
500
|
-
continue;
|
|
501
|
-
}
|
|
502
|
-
if (quote === "\"" && ch === "\\") {
|
|
503
|
-
escaping = true;
|
|
504
|
-
continue;
|
|
505
|
-
}
|
|
506
|
-
if (quote) {
|
|
507
|
-
if (ch === quote) quote = null;
|
|
508
|
-
continue;
|
|
509
|
-
}
|
|
510
|
-
if (ch === "'" || ch === "\"") {
|
|
511
|
-
quote = ch;
|
|
512
|
-
continue;
|
|
513
|
-
}
|
|
514
|
-
if (ch === "#") return line.slice(0, index);
|
|
515
|
-
}
|
|
516
|
-
return line;
|
|
517
|
-
}
|
|
518
|
-
function parseTomlString(value) {
|
|
519
|
-
const trimmed = value.trim();
|
|
520
|
-
if (trimmed.startsWith("\"") && trimmed.endsWith("\"")) try {
|
|
521
|
-
return JSON.parse(trimmed);
|
|
522
|
-
} catch {
|
|
523
|
-
return;
|
|
524
|
-
}
|
|
525
|
-
if (trimmed.startsWith("'") && trimmed.endsWith("'")) return trimmed.slice(1, -1);
|
|
526
|
-
}
|
|
527
|
-
function parseTomlDottedKey(value) {
|
|
528
|
-
const parts = [];
|
|
529
|
-
let current = "";
|
|
530
|
-
let quote = null;
|
|
531
|
-
let escaping = false;
|
|
532
|
-
for (const ch of value.trim()) {
|
|
533
|
-
if (escaping) {
|
|
534
|
-
current += ch;
|
|
535
|
-
escaping = false;
|
|
536
|
-
continue;
|
|
537
|
-
}
|
|
538
|
-
if (quote === "\"" && ch === "\\") {
|
|
539
|
-
current += ch;
|
|
540
|
-
escaping = true;
|
|
541
|
-
continue;
|
|
542
|
-
}
|
|
543
|
-
if (quote) {
|
|
544
|
-
current += ch;
|
|
545
|
-
if (ch === quote) quote = null;
|
|
546
|
-
continue;
|
|
547
|
-
}
|
|
548
|
-
if (ch === "'" || ch === "\"") {
|
|
549
|
-
quote = ch;
|
|
550
|
-
current += ch;
|
|
551
|
-
continue;
|
|
552
|
-
}
|
|
553
|
-
if (ch === ".") {
|
|
554
|
-
parts.push(current.trim());
|
|
555
|
-
current = "";
|
|
556
|
-
continue;
|
|
557
|
-
}
|
|
558
|
-
current += ch;
|
|
559
|
-
}
|
|
560
|
-
if (current.trim()) parts.push(current.trim());
|
|
561
|
-
return parts.map((part) => parseTomlString(part) ?? part);
|
|
562
|
-
}
|
|
563
|
-
function parseProjectHeader(line) {
|
|
564
|
-
const parts = parseTableHeader(line);
|
|
565
|
-
return parts?.length === 2 && parts[0] === "projects" ? parts[1] : void 0;
|
|
566
|
-
}
|
|
567
|
-
function parseTrustedInlineProjectEntries(value) {
|
|
568
|
-
const trusted = [];
|
|
569
|
-
for (const match of value.matchAll(/(?<key>"(?:\\.|[^"\\])*"|'[^']*'|[A-Za-z0-9_\-/.~:]+)\s*=\s*\{(?<body>[^{}]*(?:\{[^{}]*\}[^{}]*)*)\}/g)) {
|
|
570
|
-
const key = match.groups?.key;
|
|
571
|
-
const body = match.groups?.body;
|
|
572
|
-
if (!key || !body || !/\btrust_level\s*=\s*["']trusted["']/.test(body)) continue;
|
|
573
|
-
const projectPath = parseTomlString(key) ?? key.trim();
|
|
574
|
-
if (projectPath) trusted.push(projectPath);
|
|
575
|
-
}
|
|
576
|
-
return trusted;
|
|
577
|
-
}
|
|
578
|
-
function extractTrustedCodexProjectPaths(configToml) {
|
|
579
|
-
const trusted = /* @__PURE__ */ new Set();
|
|
580
|
-
let currentProjectPath;
|
|
581
|
-
let inProjectsTable = false;
|
|
582
|
-
for (const rawLine of configToml.split(/\r?\n/)) {
|
|
583
|
-
const line = stripTomlComment(rawLine).trim();
|
|
584
|
-
if (!line) continue;
|
|
585
|
-
if (line.startsWith("[")) {
|
|
586
|
-
currentProjectPath = parseProjectHeader(line);
|
|
587
|
-
inProjectsTable = line === "[projects]";
|
|
588
|
-
continue;
|
|
589
|
-
}
|
|
590
|
-
if (currentProjectPath && /^trust_level\s*=\s*["']trusted["']\s*$/.test(line)) {
|
|
591
|
-
trusted.add(currentProjectPath);
|
|
592
|
-
continue;
|
|
593
|
-
}
|
|
594
|
-
const assignment = /^(?<key>"(?:\\.|[^"\\])*"|'[^']*'|[A-Za-z0-9_\-/.~:]+)\s*=\s*(?<value>.+)$/.exec(line);
|
|
595
|
-
const rawKey = assignment?.groups?.key;
|
|
596
|
-
const rawValue = assignment?.groups?.value;
|
|
597
|
-
if (!rawKey || rawValue === void 0) continue;
|
|
598
|
-
const key = parseTomlString(rawKey) ?? rawKey;
|
|
599
|
-
const value = rawValue.trim();
|
|
600
|
-
if (inProjectsTable && /^\{.*\}$/.test(value)) {
|
|
601
|
-
if (/\btrust_level\s*=\s*["']trusted["']/.test(value) && key) trusted.add(key);
|
|
602
|
-
continue;
|
|
603
|
-
}
|
|
604
|
-
if (key === "projects" || inProjectsTable) for (const projectPath of parseTrustedInlineProjectEntries(value)) trusted.add(projectPath);
|
|
605
|
-
}
|
|
606
|
-
return Array.from(trusted);
|
|
607
|
-
}
|
|
608
489
|
const INHERITED_TOP_LEVEL_CODEX_CONFIG_KEYS = /* @__PURE__ */ new Set([
|
|
609
490
|
"model",
|
|
610
491
|
"model_provider",
|
|
@@ -622,61 +503,30 @@ const INHERITED_MODEL_PROVIDER_CONFIG_KEYS = /* @__PURE__ */ new Set([
|
|
|
622
503
|
"stream_max_retries",
|
|
623
504
|
"stream_idle_timeout_ms"
|
|
624
505
|
]);
|
|
625
|
-
function parseTableHeader(line) {
|
|
626
|
-
const trimmed = line.trim();
|
|
627
|
-
if (!trimmed.startsWith("[") || !trimmed.endsWith("]") || trimmed.startsWith("[[")) return;
|
|
628
|
-
return parseTomlDottedKey(trimmed.slice(1, -1));
|
|
629
|
-
}
|
|
630
|
-
function isInheritedModelProviderTable(parts) {
|
|
631
|
-
return parts?.[0] === "model_providers" && parts.length === 2;
|
|
632
|
-
}
|
|
633
|
-
function parseTopLevelAssignmentKey(line) {
|
|
634
|
-
return /^(?<key>[A-Za-z0-9_-]+)\s*=\s*(?<value>.+)$/.exec(line)?.groups?.key;
|
|
635
|
-
}
|
|
636
|
-
function extractInheritedCodexRuntimeConfig(configToml) {
|
|
637
|
-
const inheritedLines = [];
|
|
638
|
-
let inAnyTable = false;
|
|
639
|
-
let inInheritedTable = false;
|
|
640
|
-
let pendingInheritedTableHeader = "";
|
|
641
|
-
function flushInheritedTableHeader() {
|
|
642
|
-
if (!pendingInheritedTableHeader) return;
|
|
643
|
-
if (inheritedLines.length > 0 && inheritedLines[inheritedLines.length - 1] !== "") inheritedLines.push("");
|
|
644
|
-
inheritedLines.push(pendingInheritedTableHeader);
|
|
645
|
-
pendingInheritedTableHeader = "";
|
|
646
|
-
}
|
|
647
|
-
for (const rawLine of configToml.split(/\r?\n/)) {
|
|
648
|
-
const trimmedLine = rawLine.trim();
|
|
649
|
-
const semanticLine = stripTomlComment(rawLine).trim();
|
|
650
|
-
if (trimmedLine.startsWith("[")) {
|
|
651
|
-
const tableParts = parseTableHeader(trimmedLine);
|
|
652
|
-
inAnyTable = true;
|
|
653
|
-
inInheritedTable = isInheritedModelProviderTable(tableParts);
|
|
654
|
-
if (inInheritedTable) pendingInheritedTableHeader = rawLine.trimEnd();
|
|
655
|
-
else pendingInheritedTableHeader = "";
|
|
656
|
-
continue;
|
|
657
|
-
}
|
|
658
|
-
if (inInheritedTable) {
|
|
659
|
-
if (!semanticLine) continue;
|
|
660
|
-
const key = parseTopLevelAssignmentKey(semanticLine);
|
|
661
|
-
if (!key || !INHERITED_MODEL_PROVIDER_CONFIG_KEYS.has(key)) continue;
|
|
662
|
-
flushInheritedTableHeader();
|
|
663
|
-
inheritedLines.push(rawLine.trimEnd());
|
|
664
|
-
continue;
|
|
665
|
-
}
|
|
666
|
-
if (inAnyTable) continue;
|
|
667
|
-
const key = parseTopLevelAssignmentKey(semanticLine);
|
|
668
|
-
if (!key) continue;
|
|
669
|
-
if (!INHERITED_TOP_LEVEL_CODEX_CONFIG_KEYS.has(key)) continue;
|
|
670
|
-
inheritedLines.push(rawLine.trimEnd());
|
|
671
|
-
}
|
|
672
|
-
return inheritedLines.join("\n");
|
|
673
|
-
}
|
|
674
506
|
function renderIsolatedCodexConfig(params) {
|
|
675
|
-
|
|
507
|
+
let source = {};
|
|
508
|
+
if (params.sourceConfigToml) try {
|
|
509
|
+
source = parse(params.sourceConfigToml, { integersAsBigInt: true });
|
|
510
|
+
} catch {
|
|
511
|
+
throw new Error("Codex config.toml must be valid TOML before starting an ACP session.");
|
|
512
|
+
}
|
|
513
|
+
const providers = /* @__PURE__ */ new Map();
|
|
514
|
+
if (isRecord(source.model_providers)) for (const [name, provider] of Object.entries(source.model_providers)) {
|
|
515
|
+
if (!isRecord(provider)) continue;
|
|
516
|
+
const config = Object.fromEntries(Object.entries(provider).filter(([key]) => INHERITED_MODEL_PROVIDER_CONFIG_KEYS.has(key)));
|
|
517
|
+
if (Object.keys(config).length) providers.set(name, config);
|
|
518
|
+
}
|
|
519
|
+
const inherited = {
|
|
520
|
+
...Object.fromEntries(Object.entries(source).filter(([key]) => INHERITED_TOP_LEVEL_CODEX_CONFIG_KEYS.has(key))),
|
|
521
|
+
...providers.size ? { model_providers: Object.fromEntries(providers) } : {},
|
|
522
|
+
...params.mcpServers ? { mcp_servers: params.mcpServers } : {}
|
|
523
|
+
};
|
|
524
|
+
const trustedProjects = isRecord(source.projects) ? Object.entries(source.projects).filter(([, project]) => isRecord(project) && project.trust_level === "trusted").map(([projectPath]) => projectPath) : [];
|
|
525
|
+
const projectPaths = Array.from(new Set([...params.projectPaths, ...trustedProjects].map((projectPath) => projectPath.trim()).filter(Boolean).map((projectPath) => path.resolve(projectPath)))).toSorted((left, right) => left.localeCompare(right));
|
|
676
526
|
return [
|
|
677
527
|
"# Generated by OpenClaw for Codex ACP sessions.",
|
|
678
|
-
|
|
679
|
-
...
|
|
528
|
+
stringify(inherited, { numbersAsFloat: true }).trimEnd(),
|
|
529
|
+
...projectPaths.flatMap((projectPath) => [
|
|
680
530
|
"",
|
|
681
531
|
`[projects.${JSON.stringify(projectPath)}]`,
|
|
682
532
|
"trust_level = \"trusted\""
|
|
@@ -844,17 +694,15 @@ async function readSourceCodexConfig(codexHome) {
|
|
|
844
694
|
}
|
|
845
695
|
async function prepareIsolatedCodexHome(params) {
|
|
846
696
|
const sourceConfig = await readSourceCodexConfig(process.env.CODEX_HOME || path.join(os.homedir(), ".codex"));
|
|
847
|
-
const trustedProjectPaths = [...sourceConfig ? extractTrustedCodexProjectPaths(sourceConfig) : [], params.workspaceDir];
|
|
848
697
|
const codexHome = path.join(params.baseDir, "codex-home");
|
|
849
698
|
await fs$1.mkdir(codexHome, { recursive: true });
|
|
850
699
|
await fs$1.writeFile(path.join(codexHome, "config.toml"), renderIsolatedCodexConfig({
|
|
851
700
|
sourceConfigToml: sourceConfig,
|
|
852
|
-
projectPaths:
|
|
701
|
+
projectPaths: [params.workspaceDir],
|
|
702
|
+
mcpServers: isRecord(params.migratedConfig?.mcp_servers) ? params.migratedConfig.mcp_servers : void 0
|
|
853
703
|
}), "utf8");
|
|
854
|
-
return codexHome;
|
|
855
704
|
}
|
|
856
705
|
async function writeAdapterWrapper(baseDir, fileName, script) {
|
|
857
|
-
await fs$1.mkdir(baseDir, { recursive: true });
|
|
858
706
|
const wrapperPath = path.join(baseDir, fileName);
|
|
859
707
|
await fs$1.writeFile(wrapperPath, script, { encoding: "utf8" });
|
|
860
708
|
try {
|
|
@@ -966,13 +814,6 @@ function resolveCodexAdapterLaunch(configuredCommand) {
|
|
|
966
814
|
if (!maintainedAdapterArgs) return;
|
|
967
815
|
return { args: maintainedAdapterArgs };
|
|
968
816
|
}
|
|
969
|
-
async function persistMigratedCodexMcpConfig(params) {
|
|
970
|
-
const mcpServers = params.migratedConfig?.mcp_servers;
|
|
971
|
-
if (!isRecord(mcpServers)) return;
|
|
972
|
-
const configPath = path.join(params.codexHome, "config.toml");
|
|
973
|
-
const merged = mergeConfigRecords(parse(await fs$1.readFile(configPath, "utf8")), { mcp_servers: mcpServers });
|
|
974
|
-
await fs$1.writeFile(configPath, stringify(merged), "utf8");
|
|
975
|
-
}
|
|
976
817
|
function buildClaudeAcpWrapperCommand(wrapperPath, configuredCommand) {
|
|
977
818
|
const configuredAdapterArgs = extractConfiguredAdapterArgs({
|
|
978
819
|
configuredCommand,
|
|
@@ -988,17 +829,15 @@ async function prepareAcpxCodexAuthConfig(params) {
|
|
|
988
829
|
const configuredCodexCommand = params.pluginConfig.agents.codex;
|
|
989
830
|
const configuredClaudeCommand = params.pluginConfig.agents.claude;
|
|
990
831
|
const codexLaunch = resolveCodexAdapterLaunch(configuredCodexCommand);
|
|
991
|
-
await
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
workspaceDir: params.pluginConfig.cwd
|
|
995
|
-
}),
|
|
832
|
+
await prepareIsolatedCodexHome({
|
|
833
|
+
baseDir: codexBaseDir,
|
|
834
|
+
workspaceDir: params.pluginConfig.cwd,
|
|
996
835
|
migratedConfig: codexLaunch?.migratedConfig
|
|
997
836
|
});
|
|
998
|
-
const
|
|
999
|
-
const
|
|
1000
|
-
const wrapperPath = await writeAdapterWrapper(codexBaseDir, "codex-acp-wrapper.mjs", buildCodexAcpWrapperScript(
|
|
1001
|
-
const claudeWrapperPath = await writeAdapterWrapper(codexBaseDir, "claude-agent-acp-wrapper.mjs", buildClaudeAcpWrapperScript(
|
|
837
|
+
const codexBinPath = await resolveInstalledAcpPackageBinPath(CODEX_ACP_PACKAGE, CODEX_ACP_BIN);
|
|
838
|
+
const claudeBinPath = await resolveInstalledAcpPackageBinPath(CLAUDE_ACP_PACKAGE, CLAUDE_ACP_BIN);
|
|
839
|
+
const wrapperPath = await writeAdapterWrapper(codexBaseDir, "codex-acp-wrapper.mjs", buildCodexAcpWrapperScript(codexBinPath));
|
|
840
|
+
const claudeWrapperPath = await writeAdapterWrapper(codexBaseDir, "claude-agent-acp-wrapper.mjs", buildClaudeAcpWrapperScript(claudeBinPath));
|
|
1002
841
|
return {
|
|
1003
842
|
...params.pluginConfig,
|
|
1004
843
|
agents: {
|
|
@@ -1124,12 +963,16 @@ function parseProcessList(stdout) {
|
|
|
1124
963
|
}
|
|
1125
964
|
async function listPlatformProcesses() {
|
|
1126
965
|
if (process.platform === "win32") return [];
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
966
|
+
try {
|
|
967
|
+
const { stdout } = await runExec("ps", ["-axo", "pid=,ppid=,command="], {
|
|
968
|
+
logOutput: false,
|
|
969
|
+
maxBuffer: 8388608,
|
|
970
|
+
timeoutMs: ACPX_PROCESS_LIST_TIMEOUT_MS
|
|
971
|
+
});
|
|
972
|
+
return parseProcessList(stdout);
|
|
973
|
+
} catch {
|
|
974
|
+
return;
|
|
975
|
+
}
|
|
1133
976
|
}
|
|
1134
977
|
function collectProcessTree(processes, rootPid) {
|
|
1135
978
|
const childrenByParent = /* @__PURE__ */ new Map();
|
|
@@ -1138,7 +981,7 @@ function collectProcessTree(processes, rootPid) {
|
|
|
1138
981
|
children.push(processInfo);
|
|
1139
982
|
childrenByParent.set(processInfo.ppid, children);
|
|
1140
983
|
}
|
|
1141
|
-
const root =
|
|
984
|
+
const root = processes.find((processInfo) => processInfo.pid === rootPid);
|
|
1142
985
|
const collected = [];
|
|
1143
986
|
if (root) collected.push(root);
|
|
1144
987
|
const queue = [...childrenByParent.get(rootPid) ?? []];
|
|
@@ -1176,28 +1019,20 @@ async function terminatePids(pids, assertCurrent) {
|
|
|
1176
1019
|
async function cleanupOpenClawOwnedAcpxProcessTree(params) {
|
|
1177
1020
|
const rootPid = params.rootPid;
|
|
1178
1021
|
if (!rootPid || rootPid <= 0 || rootPid === process.pid) return {
|
|
1179
|
-
inspectedPids: [],
|
|
1180
1022
|
terminatedPids: [],
|
|
1181
1023
|
skippedReason: "missing-root"
|
|
1182
1024
|
};
|
|
1183
1025
|
if (process.platform === "win32") return {
|
|
1184
|
-
inspectedPids: [],
|
|
1185
1026
|
terminatedPids: [],
|
|
1186
1027
|
skippedReason: "unsupported-platform"
|
|
1187
1028
|
};
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
inspectedPids: [],
|
|
1194
|
-
terminatedPids: [],
|
|
1195
|
-
skippedReason: "process-list-unavailable"
|
|
1196
|
-
};
|
|
1197
|
-
}
|
|
1029
|
+
const processes = await listPlatformProcesses();
|
|
1030
|
+
if (!processes) return {
|
|
1031
|
+
terminatedPids: [],
|
|
1032
|
+
skippedReason: "process-list-unavailable"
|
|
1033
|
+
};
|
|
1198
1034
|
const listedTree = collectProcessTree(processes, rootPid);
|
|
1199
1035
|
if (listedTree.length === 0) return {
|
|
1200
|
-
inspectedPids: [],
|
|
1201
1036
|
terminatedPids: [],
|
|
1202
1037
|
skippedReason: "unverified-root"
|
|
1203
1038
|
};
|
|
@@ -1212,85 +1047,56 @@ async function cleanupOpenClawOwnedAcpxProcessTree(params) {
|
|
|
1212
1047
|
expectedLeaseId: params.expectedLeaseId,
|
|
1213
1048
|
expectedGatewayInstanceId: params.expectedGatewayInstanceId
|
|
1214
1049
|
})) return {
|
|
1215
|
-
inspectedPids: listedTree.map((processInfo) => processInfo.pid),
|
|
1216
1050
|
terminatedPids: [],
|
|
1217
1051
|
skippedReason: "not-openclaw-owned"
|
|
1218
1052
|
};
|
|
1219
|
-
|
|
1220
|
-
return {
|
|
1221
|
-
inspectedPids: uniquePids(listedTree),
|
|
1222
|
-
terminatedPids: await terminatePids(pids, params.assertCurrent)
|
|
1223
|
-
};
|
|
1053
|
+
return { terminatedPids: await terminatePids(uniquePids(listedTree.toReversed()), params.assertCurrent) };
|
|
1224
1054
|
}
|
|
1225
1055
|
/** Recover a pending lease by matching its exact live wrapper identity. */
|
|
1226
1056
|
async function cleanupOpenClawOwnedAcpxPendingLease(params) {
|
|
1227
1057
|
if (process.platform === "win32") return {
|
|
1228
|
-
inspectedPids: [],
|
|
1229
1058
|
terminatedPids: [],
|
|
1230
1059
|
skippedReason: "unsupported-platform"
|
|
1231
1060
|
};
|
|
1232
1061
|
if (!params.wrapperPath || !wrapperPathBelongsToRoot(params.wrapperPath, params.wrapperRoot)) return {
|
|
1233
|
-
inspectedPids: [],
|
|
1234
1062
|
terminatedPids: [],
|
|
1235
1063
|
skippedReason: "unverified-root"
|
|
1236
1064
|
};
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
inspectedPids: [],
|
|
1243
|
-
terminatedPids: [],
|
|
1244
|
-
skippedReason: "process-list-unavailable"
|
|
1245
|
-
};
|
|
1246
|
-
}
|
|
1065
|
+
const processes = await listPlatformProcesses();
|
|
1066
|
+
if (!processes) return {
|
|
1067
|
+
terminatedPids: [],
|
|
1068
|
+
skippedReason: "process-list-unavailable"
|
|
1069
|
+
};
|
|
1247
1070
|
const matchingRoots = processes.filter((processInfo) => commandContainsExactWrapperPath(processInfo.command, params.wrapperPath) && liveCommandMatchesLeaseIdentity({
|
|
1248
1071
|
command: processInfo.command,
|
|
1249
1072
|
expectedLeaseId: params.leaseId,
|
|
1250
1073
|
expectedGatewayInstanceId: params.gatewayInstanceId
|
|
1251
1074
|
}));
|
|
1252
1075
|
if (matchingRoots.length === 0) return {
|
|
1253
|
-
inspectedPids: [],
|
|
1254
1076
|
terminatedPids: [],
|
|
1255
1077
|
skippedReason: "missing-root"
|
|
1256
1078
|
};
|
|
1257
1079
|
if (matchingRoots.length > 1) return {
|
|
1258
|
-
inspectedPids: uniquePids(matchingRoots),
|
|
1259
1080
|
terminatedPids: [],
|
|
1260
1081
|
skippedReason: "ambiguous-root"
|
|
1261
1082
|
};
|
|
1262
|
-
|
|
1263
|
-
const pids = uniquePids(listedTree.toReversed());
|
|
1264
|
-
return {
|
|
1265
|
-
inspectedPids: uniquePids(listedTree),
|
|
1266
|
-
terminatedPids: await terminatePids(pids, params.assertCurrent)
|
|
1267
|
-
};
|
|
1083
|
+
return { terminatedPids: await terminatePids(uniquePids(collectProcessTree(processes, matchingRoots[0].pid).toReversed()), params.assertCurrent) };
|
|
1268
1084
|
}
|
|
1269
1085
|
/** Reap orphaned OpenClaw-owned ACPX wrapper trees during runtime startup. */
|
|
1270
1086
|
async function reapStaleOpenClawOwnedAcpxOrphans(params) {
|
|
1271
1087
|
if (process.platform === "win32") return {
|
|
1272
|
-
inspectedPids: [],
|
|
1273
1088
|
terminatedPids: [],
|
|
1274
1089
|
skippedReason: "unsupported-platform"
|
|
1275
1090
|
};
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
terminatedPids: [],
|
|
1283
|
-
skippedReason: "process-list-unavailable"
|
|
1284
|
-
};
|
|
1285
|
-
}
|
|
1286
|
-
const orphanTrees = processes.filter((processInfo) => processInfo.ppid === 1 && !readAcpxProcessLeaseIdentity(processInfo.command) && isOpenClawOwnedAcpxProcessCommand({
|
|
1091
|
+
const processes = await listPlatformProcesses();
|
|
1092
|
+
if (!processes) return {
|
|
1093
|
+
terminatedPids: [],
|
|
1094
|
+
skippedReason: "process-list-unavailable"
|
|
1095
|
+
};
|
|
1096
|
+
return { terminatedPids: await terminatePids(uniquePids(processes.filter((processInfo) => processInfo.ppid === 1 && !readAcpxProcessLeaseIdentity(processInfo.command) && isOpenClawOwnedAcpxProcessCommand({
|
|
1287
1097
|
command: processInfo.command,
|
|
1288
1098
|
wrapperRoot: params.wrapperRoot
|
|
1289
|
-
})).map((orphan) => collectProcessTree(processes, orphan.pid));
|
|
1290
|
-
return {
|
|
1291
|
-
inspectedPids: uniquePids(orphanTrees.flat()),
|
|
1292
|
-
terminatedPids: await terminatePids(uniquePids(orphanTrees.flatMap((tree) => tree.toReversed())), params.assertCurrent)
|
|
1293
|
-
};
|
|
1099
|
+
})).map((orphan) => collectProcessTree(processes, orphan.pid)).flatMap((tree) => tree.toReversed())), params.assertCurrent) };
|
|
1294
1100
|
}
|
|
1295
1101
|
// extensions/acpx/src/model-ref.ts
|
|
1296
1102
|
function withAcpxSessionOptions(input) {
|
|
@@ -1504,30 +1310,9 @@ function captureGenerationRecord(generation, record) {
|
|
|
1504
1310
|
}
|
|
1505
1311
|
const acpxGenerationKey = Symbol("openclaw.acpxGeneration");
|
|
1506
1312
|
const acpxOperationScope = new AsyncLocalStorage();
|
|
1507
|
-
function readSessionRecordName(record) {
|
|
1508
|
-
return normalizeOptionalString(asOptionalObjectRecord(record)?.name) ?? "";
|
|
1509
|
-
}
|
|
1510
1313
|
function readRecordAgentCommand(record) {
|
|
1511
1314
|
return record?.agentArgv ?? record?.agentCommand;
|
|
1512
1315
|
}
|
|
1513
|
-
function readRecordCwd(record) {
|
|
1514
|
-
return normalizeOptionalString(asOptionalObjectRecord(record)?.cwd);
|
|
1515
|
-
}
|
|
1516
|
-
function readRecordResetOnNextEnsure(record) {
|
|
1517
|
-
return asOptionalObjectRecord(asOptionalObjectRecord(record)?.acpx)?.reset_on_next_ensure === true;
|
|
1518
|
-
}
|
|
1519
|
-
function readRecordAgentPid(record) {
|
|
1520
|
-
const { pid, processId } = asOptionalObjectRecord(record) ?? {};
|
|
1521
|
-
const rawPid = pid ?? processId;
|
|
1522
|
-
const numericPid = typeof rawPid === "number" ? rawPid : typeof rawPid === "string" ? parseStrictPositiveInteger(rawPid) : void 0;
|
|
1523
|
-
return numericPid && Number.isInteger(numericPid) && numericPid > 0 ? numericPid : void 0;
|
|
1524
|
-
}
|
|
1525
|
-
function readOpenClawLeaseIdFromRecord(record) {
|
|
1526
|
-
return normalizeOptionalString(asOptionalObjectRecord(record)?.openclawLeaseId);
|
|
1527
|
-
}
|
|
1528
|
-
function readOpenClawGatewayInstanceIdFromRecord(record) {
|
|
1529
|
-
return normalizeOptionalString(asOptionalObjectRecord(record)?.openclawGatewayInstanceId);
|
|
1530
|
-
}
|
|
1531
1316
|
function extractGeneratedWrapperPath(command) {
|
|
1532
1317
|
return splitCommandParts(command ?? "").find((part) => (part.split(/[\\/]/).pop() ?? "") === "codex-acp-wrapper.mjs" || (part.split(/[\\/]/).pop() ?? "") === "claude-agent-acp-wrapper.mjs") ?? "";
|
|
1533
1318
|
}
|
|
@@ -1556,11 +1341,11 @@ function createResetAwareSessionStore(baseStore, params) {
|
|
|
1556
1341
|
const record = await baseStore.load(sessionId);
|
|
1557
1342
|
if (scope && record) captureGenerationRecord(scope.generation, record);
|
|
1558
1343
|
if (!record || !params?.leaseStore || !params.gatewayInstanceId) return record;
|
|
1559
|
-
const sessionName =
|
|
1344
|
+
const sessionName = record.name || normalized;
|
|
1560
1345
|
const lease = selectCurrentSessionLease({
|
|
1561
1346
|
leases: await params.leaseStore.listOpen(params.gatewayInstanceId),
|
|
1562
1347
|
sessionKeys: [sessionName, normalized],
|
|
1563
|
-
rootPid:
|
|
1348
|
+
rootPid: record.pid
|
|
1564
1349
|
});
|
|
1565
1350
|
if (!lease) return record;
|
|
1566
1351
|
const leasedRecord = withOpenClawLeaseSessionMetadata(record, lease);
|
|
@@ -1582,7 +1367,7 @@ function createResetAwareSessionStore(baseStore, params) {
|
|
|
1582
1367
|
}
|
|
1583
1368
|
let recordToSave = record;
|
|
1584
1369
|
const launch = params?.launchScope?.getStore();
|
|
1585
|
-
const sessionName =
|
|
1370
|
+
const sessionName = record.name;
|
|
1586
1371
|
const agentCommand = readRecordAgentCommand(record);
|
|
1587
1372
|
const leasedCommand = launch?.leasedCommand ?? agentCommand;
|
|
1588
1373
|
const leaseIdentity = launch ?? readAcpxProcessLeaseIdentity(leasedCommand);
|
|
@@ -1635,12 +1420,12 @@ function createResetAwareSessionStore(baseStore, params) {
|
|
|
1635
1420
|
/** Capture OpenClaw wrapper cleanup ownership before a backend close can yield. */
|
|
1636
1421
|
async function prepareAcpxProcessCleanup(params) {
|
|
1637
1422
|
const { leaseStore, gatewayInstanceId, wrapperRoot } = params;
|
|
1638
|
-
const rootPid =
|
|
1423
|
+
const rootPid = params.record?.pid;
|
|
1639
1424
|
const rootCommand = params.command ? renderAgentCommand(params.command) : void 0;
|
|
1640
1425
|
const identity = readAcpxProcessLeaseIdentity(params.command);
|
|
1641
|
-
const leaseId =
|
|
1642
|
-
const expectedGatewayInstanceId =
|
|
1643
|
-
const sessionKeys = [params.sessionKey,
|
|
1426
|
+
const leaseId = params.record?.openclawLeaseId ?? identity?.leaseId;
|
|
1427
|
+
const expectedGatewayInstanceId = params.record?.openclawGatewayInstanceId ?? identity?.gatewayInstanceId;
|
|
1428
|
+
const sessionKeys = [params.sessionKey, params.record?.name ?? ""];
|
|
1644
1429
|
const openLeases = rootPid && gatewayInstanceId && leaseStore ? await leaseStore.listOpen(gatewayInstanceId) : [];
|
|
1645
1430
|
const selectedLease = rootPid ? selectCurrentSessionLease({
|
|
1646
1431
|
leases: openLeases,
|
|
@@ -1648,8 +1433,7 @@ async function prepareAcpxProcessCleanup(params) {
|
|
|
1648
1433
|
rootPid
|
|
1649
1434
|
}) : void 0;
|
|
1650
1435
|
const loadedLease = leaseId ? await leaseStore?.load(leaseId) : void 0;
|
|
1651
|
-
const
|
|
1652
|
-
const lease = ownedLease ? { ...ownedLease } : void 0;
|
|
1436
|
+
const lease = selectedLease ?? (loadedLease && loadedLease.gatewayInstanceId === gatewayInstanceId && (!rootPid || loadedLease.rootPid === rootPid) && sessionKeys.includes(loadedLease.sessionKey) ? loadedLease : void 0);
|
|
1653
1437
|
return async () => {
|
|
1654
1438
|
if (lease && lease.gatewayInstanceId === gatewayInstanceId) {
|
|
1655
1439
|
await leaseStore?.markState(lease.leaseId, "closing");
|
|
@@ -1847,35 +1631,9 @@ function appendCodexAcpConfigOverrides(command, override) {
|
|
|
1847
1631
|
JSON.stringify(config)
|
|
1848
1632
|
];
|
|
1849
1633
|
}
|
|
1850
|
-
function withManagedToolsMcpSessionEnv(params) {
|
|
1851
|
-
const sessionKey = params.sessionKey.trim();
|
|
1852
|
-
if (!params.pluginToolsEnabled && !params.openclawToolsEnabled || !sessionKey || !params.mcpServers?.length) return params.mcpServers;
|
|
1853
|
-
let changed = false;
|
|
1854
|
-
const nextServers = params.mcpServers.map((server) => {
|
|
1855
|
-
const isManagedPluginTools = params.pluginToolsEnabled && server.name === ACPX_PLUGIN_TOOLS_MCP_SERVER_NAME;
|
|
1856
|
-
const isManagedOpenClawTools = params.openclawToolsEnabled && server.name === ACPX_OPENCLAW_TOOLS_MCP_SERVER_NAME;
|
|
1857
|
-
if (!isManagedPluginTools && !isManagedOpenClawTools || !("command" in server)) return server;
|
|
1858
|
-
changed = true;
|
|
1859
|
-
const env = [...server.env.filter((entry) => entry.name !== OPENCLAW_TOOLS_MCP_AGENT_SESSION_KEY_ENV), {
|
|
1860
|
-
name: OPENCLAW_TOOLS_MCP_AGENT_SESSION_KEY_ENV,
|
|
1861
|
-
value: sessionKey
|
|
1862
|
-
}];
|
|
1863
|
-
return {
|
|
1864
|
-
...server,
|
|
1865
|
-
env,
|
|
1866
|
-
args: params.agentId ? [
|
|
1867
|
-
...server.args,
|
|
1868
|
-
"--openclaw-agent-id",
|
|
1869
|
-
params.agentId
|
|
1870
|
-
] : server.args
|
|
1871
|
-
};
|
|
1872
|
-
});
|
|
1873
|
-
return changed ? nextServers : params.mcpServers;
|
|
1874
|
-
}
|
|
1875
1634
|
function resolveBridgeSession(handle) {
|
|
1876
1635
|
return handle.bridgeSession === void 0 ? handle : handle.bridgeSession;
|
|
1877
1636
|
}
|
|
1878
|
-
/** OpenClaw-managed ACP runtime implementation backed by the upstream acpx runtime. */
|
|
1879
1637
|
var AcpxRuntime$1 = class {
|
|
1880
1638
|
constructor(options, testOptions) {
|
|
1881
1639
|
this.ownerAwareSessions = 1;
|
|
@@ -1925,12 +1683,29 @@ var AcpxRuntime$1 = class {
|
|
|
1925
1683
|
if (target === null) return [];
|
|
1926
1684
|
if (!this.managedToolsMcpBridgeEnabled) return servers;
|
|
1927
1685
|
if (!target) throw new AcpRuntimeError("ACP_SESSION_INIT_FAILED", "ACP tool bridge has no session owner");
|
|
1928
|
-
|
|
1929
|
-
|
|
1930
|
-
|
|
1931
|
-
|
|
1932
|
-
|
|
1686
|
+
const sessionKey = target.sessionKey.trim();
|
|
1687
|
+
if (!this.pluginToolsMcpBridgeEnabled && !this.openclawToolsMcpBridgeEnabled || !sessionKey || !servers?.length) return servers;
|
|
1688
|
+
let changed = false;
|
|
1689
|
+
const nextServers = servers.map((server) => {
|
|
1690
|
+
const isManagedPluginTools = this.pluginToolsMcpBridgeEnabled && server.name === ACPX_PLUGIN_TOOLS_MCP_SERVER_NAME;
|
|
1691
|
+
const isManagedOpenClawTools = this.openclawToolsMcpBridgeEnabled && server.name === ACPX_OPENCLAW_TOOLS_MCP_SERVER_NAME;
|
|
1692
|
+
if (!isManagedPluginTools && !isManagedOpenClawTools || !("command" in server)) return server;
|
|
1693
|
+
changed = true;
|
|
1694
|
+
const env = [...server.env.filter((entry) => entry.name !== OPENCLAW_TOOLS_MCP_AGENT_SESSION_KEY_ENV), {
|
|
1695
|
+
name: OPENCLAW_TOOLS_MCP_AGENT_SESSION_KEY_ENV,
|
|
1696
|
+
value: sessionKey
|
|
1697
|
+
}];
|
|
1698
|
+
return {
|
|
1699
|
+
...server,
|
|
1700
|
+
env,
|
|
1701
|
+
args: target.agentId ? [
|
|
1702
|
+
...server.args,
|
|
1703
|
+
"--openclaw-agent-id",
|
|
1704
|
+
target.agentId
|
|
1705
|
+
] : server.args
|
|
1706
|
+
};
|
|
1933
1707
|
});
|
|
1708
|
+
return changed ? nextServers : servers;
|
|
1934
1709
|
},
|
|
1935
1710
|
processLifecycle: {
|
|
1936
1711
|
onBeforeSpawn: async (launch) => {
|
|
@@ -2023,9 +1798,9 @@ var AcpxRuntime$1 = class {
|
|
|
2023
1798
|
const recordId = oneShot ? persistedHandle?.acpxRecordId : sessionKey;
|
|
2024
1799
|
if (!recordId) return;
|
|
2025
1800
|
const record = await this.sessionStore.load(recordId);
|
|
2026
|
-
if (!record ||
|
|
2027
|
-
if (oneShot && (record.acpxRecordId !== recordId ||
|
|
2028
|
-
const recordCwd =
|
|
1801
|
+
if (!record || record.acpx?.reset_on_next_ensure === true) return;
|
|
1802
|
+
if (oneShot && (record.acpxRecordId !== recordId || record.name !== sessionKey || record.acpSessionId !== (persistedHandle?.backendSessionId ?? decoded?.backendSessionId) || !record.agentCapabilities?.loadSession && !record.agentCapabilities?.sessionCapabilities?.resume || record.lastPromptAt !== void 0 || record.messages.some((message) => typeof message !== "string" && "User" in message))) return;
|
|
1803
|
+
const recordCwd = record.cwd?.trim();
|
|
2029
1804
|
const recordCommand = readRecordAgentCommand(record);
|
|
2030
1805
|
if (!recordCwd || !recordCommand || path.resolve(recordCwd) !== path.resolve(input.cwd?.trim() || this.cwd) || !oneShot && resumeSessionId && record.acpSessionId !== resumeSessionId) return;
|
|
2031
1806
|
const lease = readAcpxProcessLeaseIdentity(recordCommand);
|
|
@@ -2116,7 +1891,7 @@ var AcpxRuntime$1 = class {
|
|
|
2116
1891
|
const record = await this.sessionStore.load(params.handle.acpxRecordId ?? resolveAcpxSessionResource(params.handle));
|
|
2117
1892
|
return readCodexWrapperStderrTail({
|
|
2118
1893
|
wrapperRoot: this.wrapperRoot,
|
|
2119
|
-
leaseId:
|
|
1894
|
+
leaseId: record?.openclawLeaseId
|
|
2120
1895
|
});
|
|
2121
1896
|
}
|
|
2122
1897
|
async findSession(input) {
|
|
@@ -2456,36 +2231,6 @@ function resolveAgentProcessEnv() {
|
|
|
2456
2231
|
if (process.env.TOKIO_WORKER_THREADS?.trim()) return;
|
|
2457
2232
|
return { TOKIO_WORKER_THREADS: String(Math.min(availableParallelism(), MAX_ACPX_TOKIO_WORKER_THREADS)) };
|
|
2458
2233
|
}
|
|
2459
|
-
async function createDefaultRuntime(params) {
|
|
2460
|
-
const names = await fs$1.readdir(path.join(params.pluginConfig.stateDir, "sessions")).catch((error) => {
|
|
2461
|
-
if (error instanceof Error && "code" in error && error.code === "ENOENT") return [];
|
|
2462
|
-
throw error;
|
|
2463
|
-
});
|
|
2464
|
-
const legacyBareSessionKeys = /* @__PURE__ */ new Set();
|
|
2465
|
-
for (const name of names) {
|
|
2466
|
-
if (!name.endsWith(".json")) continue;
|
|
2467
|
-
const recordId = decodeURIComponent(name.slice(0, -5));
|
|
2468
|
-
if (!recordId.startsWith("agent:") && !recordId.startsWith(".openclaw-owner-") && !recordId.includes(":oneshot:")) legacyBareSessionKeys.add(recordId.toLowerCase());
|
|
2469
|
-
}
|
|
2470
|
-
return new AcpxRuntime$1({
|
|
2471
|
-
cwd: params.pluginConfig.cwd,
|
|
2472
|
-
agentProcessEnv: resolveAgentProcessEnv(),
|
|
2473
|
-
openclawLegacyBareSessionKeys: legacyBareSessionKeys,
|
|
2474
|
-
openclawGatewayInstanceId: params.gatewayInstanceId,
|
|
2475
|
-
openclawProcessLeaseStore: params.processLeaseStore,
|
|
2476
|
-
openclawWrapperRoot: params.wrapperRoot,
|
|
2477
|
-
sessionStore: createFileSessionStore({ stateDir: params.pluginConfig.stateDir }),
|
|
2478
|
-
agentRegistry: createAgentRegistry({ overrides: params.pluginConfig.agents }),
|
|
2479
|
-
getProbeAgent: params.getProbeAgent,
|
|
2480
|
-
mcpServers: toAcpMcpServers(params.pluginConfig.mcpServers),
|
|
2481
|
-
pluginToolsMcpBridgeEnabled: params.pluginConfig.pluginToolsMcpBridge,
|
|
2482
|
-
openclawToolsMcpBridgeEnabled: params.pluginConfig.openClawToolsMcpBridge,
|
|
2483
|
-
permissionMode: params.pluginConfig.permissionMode,
|
|
2484
|
-
nonInteractivePermissions: params.pluginConfig.nonInteractivePermissions,
|
|
2485
|
-
elicitationModes: ["form", "url"],
|
|
2486
|
-
timeoutMs: resolveAcpxTimerTimeoutMs(params.pluginConfig.timeoutSeconds)
|
|
2487
|
-
});
|
|
2488
|
-
}
|
|
2489
2234
|
function formatDoctorFailureMessage(report) {
|
|
2490
2235
|
const detailText = report.details?.map((detail) => detail.trim()).filter(Boolean).join("; ");
|
|
2491
2236
|
return detailText ? `${report.message} (${detailText})` : report.message;
|
|
@@ -2513,7 +2258,6 @@ async function resolveGatewayInstanceId(openKeyedStore) {
|
|
|
2513
2258
|
async function reapOpenAcpxProcessLeases(params) {
|
|
2514
2259
|
const { assertCurrent } = params;
|
|
2515
2260
|
const leases = await params.leaseStore.listOpen(params.gatewayInstanceId);
|
|
2516
|
-
const inspectedPids = [];
|
|
2517
2261
|
const terminatedPids = [];
|
|
2518
2262
|
const legacyWrapperRoots = /* @__PURE__ */ new Set();
|
|
2519
2263
|
for (const lease of leases) {
|
|
@@ -2533,7 +2277,6 @@ async function reapOpenAcpxProcessLeases(params) {
|
|
|
2533
2277
|
wrapperRoot: lease.wrapperRoot,
|
|
2534
2278
|
assertCurrent
|
|
2535
2279
|
});
|
|
2536
|
-
inspectedPids.push(...result.inspectedPids);
|
|
2537
2280
|
terminatedPids.push(...result.terminatedPids);
|
|
2538
2281
|
const retryableEvidenceFailure = result.skippedReason === "process-list-unavailable" || result.skippedReason === "unsupported-platform" || pending && (result.skippedReason === "ambiguous-root" || result.skippedReason === "unverified-root" || lease.sessionKey === "openclaw:acpx:probe" && result.skippedReason === "missing-root");
|
|
2539
2282
|
await params.leaseStore.markState(lease.leaseId, retryableEvidenceFailure ? "open" : result.terminatedPids.length > 0 ? "closed" : "lost");
|
|
@@ -2543,13 +2286,9 @@ async function reapOpenAcpxProcessLeases(params) {
|
|
|
2543
2286
|
wrapperRoot,
|
|
2544
2287
|
assertCurrent
|
|
2545
2288
|
});
|
|
2546
|
-
inspectedPids.push(...legacyResult.inspectedPids);
|
|
2547
2289
|
terminatedPids.push(...legacyResult.terminatedPids);
|
|
2548
2290
|
}
|
|
2549
|
-
return {
|
|
2550
|
-
inspectedPids,
|
|
2551
|
-
terminatedPids
|
|
2552
|
-
};
|
|
2291
|
+
return { terminatedPids };
|
|
2553
2292
|
}
|
|
2554
2293
|
function createAcpxRuntimeService(params) {
|
|
2555
2294
|
let runtime = null;
|
|
@@ -2580,7 +2319,6 @@ function createAcpxRuntimeService(params) {
|
|
|
2580
2319
|
return;
|
|
2581
2320
|
}
|
|
2582
2321
|
const openKeyedStore = params.openKeyedStore;
|
|
2583
|
-
if (!openKeyedStore) throw new Error("ACPX runtime service requires plugin keyed state");
|
|
2584
2322
|
const basePluginConfig = await measureAcpxStartup(ctx, "config.resolve", () => resolveAcpxPluginConfig({
|
|
2585
2323
|
rawConfig: params.pluginConfig,
|
|
2586
2324
|
workspaceDir: ctx.workspaceDir,
|
|
@@ -2615,14 +2353,38 @@ function createAcpxRuntimeService(params) {
|
|
|
2615
2353
|
if (params.startupPurpose !== "inspection") await promote(ctx);
|
|
2616
2354
|
const getAllowedAgents = params.getAllowedAgents ?? (() => ctx.config.acp?.allowedAgents);
|
|
2617
2355
|
const getProbeAgent = () => pluginConfig.probeAgent ?? getAllowedAgents()?.map(normalizeLowercaseStringOrEmpty).find(Boolean);
|
|
2618
|
-
const startedRuntime = await measureAcpxStartup(ctx, "runtime.create", () =>
|
|
2619
|
-
pluginConfig,
|
|
2620
|
-
|
|
2621
|
-
|
|
2622
|
-
|
|
2623
|
-
|
|
2624
|
-
|
|
2625
|
-
|
|
2356
|
+
const startedRuntime = await measureAcpxStartup(ctx, "runtime.create", async () => {
|
|
2357
|
+
const names = await fs$1.readdir(path.join(pluginConfig.stateDir, "sessions")).catch((error) => {
|
|
2358
|
+
if (error instanceof Error && "code" in error && error.code === "ENOENT") return [];
|
|
2359
|
+
throw error;
|
|
2360
|
+
});
|
|
2361
|
+
const legacyBareSessionKeys = /* @__PURE__ */ new Set();
|
|
2362
|
+
for (const name of names) {
|
|
2363
|
+
if (!name.endsWith(".json")) continue;
|
|
2364
|
+
const recordId = decodeURIComponent(name.slice(0, -5));
|
|
2365
|
+
if (!recordId.startsWith("agent:") && !recordId.startsWith(".openclaw-owner-") && !recordId.includes(":oneshot:")) legacyBareSessionKeys.add(recordId.toLowerCase());
|
|
2366
|
+
}
|
|
2367
|
+
return new AcpxRuntime$1({
|
|
2368
|
+
cwd: pluginConfig.cwd,
|
|
2369
|
+
agentProcessEnv: resolveAgentProcessEnv(),
|
|
2370
|
+
agentProcessEnvAllow: pluginConfig.agentProcessEnvAllow,
|
|
2371
|
+
agentProcessEnvBlock: pluginConfig.agentProcessEnvBlock,
|
|
2372
|
+
openclawLegacyBareSessionKeys: legacyBareSessionKeys,
|
|
2373
|
+
openclawGatewayInstanceId: gatewayInstanceId,
|
|
2374
|
+
openclawProcessLeaseStore: processLeaseStore,
|
|
2375
|
+
openclawWrapperRoot: wrapperRoot,
|
|
2376
|
+
sessionStore: createFileSessionStore({ stateDir: pluginConfig.stateDir }),
|
|
2377
|
+
agentRegistry: createAgentRegistry({ overrides: pluginConfig.agents }),
|
|
2378
|
+
getProbeAgent,
|
|
2379
|
+
mcpServers: toAcpMcpServers(pluginConfig.mcpServers),
|
|
2380
|
+
pluginToolsMcpBridgeEnabled: pluginConfig.pluginToolsMcpBridge,
|
|
2381
|
+
openclawToolsMcpBridgeEnabled: pluginConfig.openClawToolsMcpBridge,
|
|
2382
|
+
permissionMode: pluginConfig.permissionMode,
|
|
2383
|
+
nonInteractivePermissions: pluginConfig.nonInteractivePermissions,
|
|
2384
|
+
elicitationModes: ["form", "url"],
|
|
2385
|
+
timeoutMs: resolveAcpxTimerTimeoutMs(pluginConfig.timeoutSeconds)
|
|
2386
|
+
});
|
|
2387
|
+
});
|
|
2626
2388
|
runtime = startedRuntime;
|
|
2627
2389
|
const shouldProbeRuntime = params.probeAtStartup !== false && shouldProbeRuntimeAtStartup();
|
|
2628
2390
|
ctx.startupTrace?.detail?.("probe-policy", [["startupProbeEnabledCount", shouldProbeRuntime ? 1 : 0], ["probeAgent", getProbeAgent() ?? "default"]]);
|