@openclaw/acpx 2026.7.2-beta.7 → 2026.8.1-beta.3
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/{config-schema-lrk5nlcV.js → config-schema-DN_uAi4R.js} +0 -2
- package/dist/doctor-contract-api.js +36 -4
- package/dist/index.js +47 -1318
- package/dist/pi-session-catalog-runtime-BIu-8uRZ.js +887 -0
- package/dist/pi-session-paths-EMbd4Hkz.js +84 -0
- package/dist/{process-lease-DSLDgiNl.js → process-lease-Cwvj7WGe.js} +5 -2
- package/dist/{process-reaper-DFwbcdPa.js → process-reaper-DduWm_7N.js} +66 -24
- package/dist/register.runtime-Dj29TKFy.js +180 -0
- package/dist/register.runtime.js +1 -1
- package/dist/{runtime-By_lR8uk.js → runtime-BmOxa15I.js} +89 -67
- package/dist/{service-CBZSAymH.js → service-PRlUtXMf.js} +39 -45
- package/openclaw.plugin.json +5 -17
- package/package.json +5 -5
- package/dist/register.runtime-BbS2JTTv.js +0 -263
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { d as withAcpxLeaseEnvironment, i as createAcpxProcessLeaseId, o as hashAcpxProcessCommand, t as ACPX_PROBE_LEASE_SESSION_KEY, u as readAcpxProcessLeaseIdentity, v as splitCommandParts } from "./process-lease-Cwvj7WGe.js";
|
|
2
2
|
import { AcpRuntimeError } from "./runtime-api.js";
|
|
3
|
-
import {
|
|
3
|
+
import { d as OPENCLAW_CODEX_CONFIG_ARG, l as CODEX_ACP_PACKAGE, n as cleanupOpenClawOwnedAcpxProcessTree, r as isOpenClawLeaseAwareAcpxProcessCommand, t as cleanupOpenClawOwnedAcpxPendingLease } from "./process-reaper-DduWm_7N.js";
|
|
4
4
|
import { parseStrictPositiveInteger } from "openclaw/plugin-sdk/number-runtime";
|
|
5
5
|
import { normalizeStringEntries } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
6
|
-
import { sliceUtf16Safe } from "openclaw/plugin-sdk/text-utility-runtime";
|
|
7
|
-
import fs from "node:fs/promises";
|
|
8
6
|
import path, { resolve } from "node:path";
|
|
7
|
+
import fs from "node:fs/promises";
|
|
8
|
+
import { sliceUtf16Safe } from "openclaw/plugin-sdk/text-utility-runtime";
|
|
9
9
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
10
10
|
import { ACPX_BACKEND_ID, AcpxRuntime as AcpxRuntime$1, createAcpRuntime, createAgentRegistry, createFileSessionStore, decodeAcpxRuntimeHandleState, encodeAcpxRuntimeHandleState, isRequestedModelUnsupportedError } from "acpx/runtime";
|
|
11
11
|
import { redactSensitiveText } from "openclaw/plugin-sdk/security-runtime";
|
|
@@ -440,6 +440,7 @@ var AcpxRuntime = class {
|
|
|
440
440
|
this.ensureSessionTails = /* @__PURE__ */ new Map();
|
|
441
441
|
this.processLeaseTransitionTails = /* @__PURE__ */ new Map();
|
|
442
442
|
this.processLeaseOperationCounts = /* @__PURE__ */ new Map();
|
|
443
|
+
this.uncertainProcessLeaseIds = /* @__PURE__ */ new Set();
|
|
443
444
|
const { openclawProcessCleanup, ...delegateTestOptions } = testOptions ?? {};
|
|
444
445
|
this.processCleanupDeps = openclawProcessCleanup;
|
|
445
446
|
this.wrapperRoot = options.openclawWrapperRoot;
|
|
@@ -477,6 +478,7 @@ var AcpxRuntime = class {
|
|
|
477
478
|
agentName: normalizeAgentName(options.probeAgent) ?? "codex",
|
|
478
479
|
agentRegistry: this.agentRegistry
|
|
479
480
|
});
|
|
481
|
+
this.probeCommand = probeCommand;
|
|
480
482
|
const useBridgeSafeProbe = this.managedToolsMcpBridgeEnabled || shouldUseBridgeSafeDelegateForCommand(probeCommand);
|
|
481
483
|
this.probeDelegate = useBridgeSafeProbe ? this.bridgeSafeDelegate : this.delegate;
|
|
482
484
|
}
|
|
@@ -508,33 +510,22 @@ var AcpxRuntime = class {
|
|
|
508
510
|
if (!normalizedSessionKey) return;
|
|
509
511
|
this.managedToolsSessionDelegates.delete(normalizedSessionKey);
|
|
510
512
|
}
|
|
511
|
-
async
|
|
513
|
+
async loadOperationSnapshotForHandle(handle) {
|
|
512
514
|
const record = await this.sessionStore.load(handle.acpxRecordId ?? handle.sessionKey);
|
|
513
|
-
return
|
|
515
|
+
return {
|
|
516
|
+
record,
|
|
517
|
+
command: readAgentCommandFromRecord(record) ?? resolveAgentCommand({
|
|
518
|
+
agentName: readAgentFromHandle(handle),
|
|
519
|
+
agentRegistry: this.agentRegistry
|
|
520
|
+
})
|
|
521
|
+
};
|
|
514
522
|
}
|
|
515
|
-
|
|
516
|
-
const recordCommand = readAgentCommandFromRecord(record);
|
|
517
|
-
if (recordCommand) return this.resolveDelegateForSession({
|
|
518
|
-
command: recordCommand,
|
|
519
|
-
sessionKey: handle.sessionKey
|
|
520
|
-
});
|
|
521
|
-
const command = resolveAgentCommand({
|
|
522
|
-
agentName: readAgentFromHandle(handle),
|
|
523
|
-
agentRegistry: this.agentRegistry
|
|
524
|
-
});
|
|
523
|
+
resolveDelegateForOperationSnapshot(handle, snapshot) {
|
|
525
524
|
return this.resolveDelegateForSession({
|
|
526
|
-
command,
|
|
525
|
+
command: snapshot.command,
|
|
527
526
|
sessionKey: handle.sessionKey
|
|
528
527
|
});
|
|
529
528
|
}
|
|
530
|
-
async resolveCommandForHandle(handle) {
|
|
531
|
-
const recordCommand = readAgentCommandFromRecord(await this.sessionStore.load(handle.acpxRecordId ?? handle.sessionKey));
|
|
532
|
-
if (recordCommand) return recordCommand;
|
|
533
|
-
return resolveAgentCommand({
|
|
534
|
-
agentName: readAgentFromHandle(handle),
|
|
535
|
-
agentRegistry: this.agentRegistry
|
|
536
|
-
});
|
|
537
|
-
}
|
|
538
529
|
commandWithLaunchLease(command) {
|
|
539
530
|
const launch = this.launchLeaseScope.getStore();
|
|
540
531
|
if (!launch) return command;
|
|
@@ -571,7 +562,7 @@ var AcpxRuntime = class {
|
|
|
571
562
|
const processLeaseStore = this.processLeaseStore;
|
|
572
563
|
const reusableIdentity = readAcpxProcessLeaseIdentity(params.reusableCommand);
|
|
573
564
|
const canReuseLeaseIdentity = reusableIdentity?.gatewayInstanceId === this.gatewayInstanceId;
|
|
574
|
-
const leaseId = canReuseLeaseIdentity ? reusableIdentity.leaseId : createAcpxProcessLeaseId();
|
|
565
|
+
const leaseId = canReuseLeaseIdentity ? reusableIdentity.leaseId : params.finalizeCompletedProbe ? `probe-${hashAcpxProcessCommand(`${this.gatewayInstanceId}\0${extractGeneratedWrapperPath(params.command)}`)}` : createAcpxProcessLeaseId();
|
|
575
566
|
const leasedCommand = withAcpxLeaseEnvironment({
|
|
576
567
|
command: params.command,
|
|
577
568
|
leaseId,
|
|
@@ -604,18 +595,18 @@ var AcpxRuntime = class {
|
|
|
604
595
|
});
|
|
605
596
|
try {
|
|
606
597
|
const result = await this.launchLeaseScope.run(launch, params.run);
|
|
607
|
-
await this.
|
|
598
|
+
if (params.finalizeCompletedProbe) await this.finalizeCompletedProbeLease(launch);
|
|
599
|
+
else await this.finalizeProcessLeaseForSession(params.sessionKey, launch);
|
|
608
600
|
return result;
|
|
609
601
|
} catch (error) {
|
|
610
|
-
await this.
|
|
602
|
+
await this.releaseProcessLeaseAfterUncertainFailure(launch);
|
|
611
603
|
throw error;
|
|
612
604
|
}
|
|
613
605
|
}
|
|
614
|
-
async prepareProcessLeaseForOperation(handle) {
|
|
606
|
+
async prepareProcessLeaseForOperation(handle, record) {
|
|
615
607
|
if (!this.processLeaseStore || !this.gatewayInstanceId || !this.wrapperRoot) return;
|
|
616
608
|
const processLeaseStore = this.processLeaseStore;
|
|
617
609
|
const wrapperRoot = this.wrapperRoot;
|
|
618
|
-
const record = await this.sessionStore.load(handle.acpxRecordId ?? handle.sessionKey);
|
|
619
610
|
const recordPid = readRecordAgentPid(record);
|
|
620
611
|
const command = readAgentCommandFromRecord(record);
|
|
621
612
|
const identity = readAcpxProcessLeaseIdentity(command);
|
|
@@ -690,25 +681,44 @@ var AcpxRuntime = class {
|
|
|
690
681
|
const lease = await processLeaseStore.load(identity.leaseId);
|
|
691
682
|
if (!lease || lease.gatewayInstanceId !== identity.gatewayInstanceId) return;
|
|
692
683
|
if (lease.rootPid <= 0) {
|
|
684
|
+
if (this.uncertainProcessLeaseIds.has(identity.leaseId)) return;
|
|
693
685
|
await processLeaseStore.markState(identity.leaseId, "lost");
|
|
694
686
|
return;
|
|
695
687
|
}
|
|
688
|
+
this.uncertainProcessLeaseIds.delete(identity.leaseId);
|
|
696
689
|
try {
|
|
697
690
|
const recordIdentity = readAcpxProcessLeaseIdentity(readAgentCommandFromRecord(await this.sessionStore.load(sessionId)));
|
|
698
691
|
if (recordIdentity?.leaseId !== identity.leaseId || recordIdentity.gatewayInstanceId !== identity.gatewayInstanceId) await processLeaseStore.markState(identity.leaseId, "lost");
|
|
699
692
|
} catch {}
|
|
700
693
|
});
|
|
701
694
|
}
|
|
702
|
-
async
|
|
695
|
+
async finalizeCompletedProbeLease(identity) {
|
|
696
|
+
if (!this.processLeaseStore) return;
|
|
697
|
+
const processLeaseStore = this.processLeaseStore;
|
|
698
|
+
await this.releaseProcessLeaseOperation(identity, async () => {
|
|
699
|
+
const lease = await processLeaseStore.load(identity.leaseId);
|
|
700
|
+
if (!lease || lease.gatewayInstanceId !== identity.gatewayInstanceId) return;
|
|
701
|
+
if (lease.rootPid > 0) return;
|
|
702
|
+
await cleanupOpenClawOwnedAcpxPendingLease({
|
|
703
|
+
leaseId: lease.leaseId,
|
|
704
|
+
gatewayInstanceId: lease.gatewayInstanceId,
|
|
705
|
+
wrapperRoot: lease.wrapperRoot,
|
|
706
|
+
wrapperPath: lease.wrapperPath,
|
|
707
|
+
deps: this.processCleanupDeps
|
|
708
|
+
});
|
|
709
|
+
});
|
|
710
|
+
}
|
|
711
|
+
async releaseProcessLeaseAfterUncertainFailure(identity) {
|
|
703
712
|
if (!identity || !this.processLeaseStore) return;
|
|
713
|
+
this.uncertainProcessLeaseIds.add(identity.leaseId);
|
|
704
714
|
const processLeaseStore = this.processLeaseStore;
|
|
705
715
|
await this.releaseProcessLeaseOperation(identity, async () => {
|
|
706
716
|
const lease = await processLeaseStore.load(identity.leaseId);
|
|
707
|
-
if (lease
|
|
717
|
+
if (!lease || lease.gatewayInstanceId !== identity.gatewayInstanceId || lease.rootPid > 0) this.uncertainProcessLeaseIds.delete(identity.leaseId);
|
|
708
718
|
});
|
|
709
719
|
}
|
|
710
|
-
async runWithProcessLeaseForHandle(handle, run) {
|
|
711
|
-
const identity = await this.prepareProcessLeaseForOperation(handle);
|
|
720
|
+
async runWithProcessLeaseForHandle(handle, record, run) {
|
|
721
|
+
const identity = await this.prepareProcessLeaseForOperation(handle, record);
|
|
712
722
|
try {
|
|
713
723
|
return await run();
|
|
714
724
|
} finally {
|
|
@@ -780,7 +790,7 @@ var AcpxRuntime = class {
|
|
|
780
790
|
wrapperRoot: lease.wrapperRoot,
|
|
781
791
|
deps: this.processCleanupDeps
|
|
782
792
|
});
|
|
783
|
-
await this.processLeaseStore?.markState(lease.leaseId, result.skippedReason === "process-list-unavailable" ? "open" : result.terminatedPids.length > 0 || result.skippedReason === "missing-root" ? "closed" : "lost");
|
|
793
|
+
await this.processLeaseStore?.markState(lease.leaseId, result.skippedReason === "process-list-unavailable" || result.skippedReason === "unsupported-platform" ? "open" : result.terminatedPids.length > 0 || result.skippedReason === "missing-root" ? "closed" : "lost");
|
|
784
794
|
return;
|
|
785
795
|
}
|
|
786
796
|
const rootCommand = readAgentCommandFromRecord(record) ?? resolveAgentCommand({
|
|
@@ -801,11 +811,21 @@ var AcpxRuntime = class {
|
|
|
801
811
|
isHealthy() {
|
|
802
812
|
return this.probeDelegate.isHealthy();
|
|
803
813
|
}
|
|
804
|
-
probeAvailability() {
|
|
805
|
-
|
|
814
|
+
async probeAvailability() {
|
|
815
|
+
await this.runWithLaunchLease({
|
|
816
|
+
sessionKey: ACPX_PROBE_LEASE_SESSION_KEY,
|
|
817
|
+
command: this.probeCommand,
|
|
818
|
+
finalizeCompletedProbe: true,
|
|
819
|
+
run: () => this.probeDelegate.probeAvailability()
|
|
820
|
+
});
|
|
806
821
|
}
|
|
807
|
-
doctor() {
|
|
808
|
-
return this.
|
|
822
|
+
async doctor() {
|
|
823
|
+
return await this.runWithLaunchLease({
|
|
824
|
+
sessionKey: ACPX_PROBE_LEASE_SESSION_KEY,
|
|
825
|
+
command: this.probeCommand,
|
|
826
|
+
finalizeCompletedProbe: true,
|
|
827
|
+
run: () => this.probeDelegate.doctor()
|
|
828
|
+
});
|
|
809
829
|
}
|
|
810
830
|
async ensureSession(input) {
|
|
811
831
|
return await this.runSerializedSessionEnsure(input.sessionKey, () => this.ensureSessionUnlocked(input));
|
|
@@ -868,11 +888,12 @@ var AcpxRuntime = class {
|
|
|
868
888
|
} : handle;
|
|
869
889
|
}
|
|
870
890
|
async *runTurn(input) {
|
|
871
|
-
const
|
|
891
|
+
const record = await this.sessionStore.load(input.handle.acpxRecordId ?? input.handle.sessionKey);
|
|
892
|
+
const turnLease = await this.prepareProcessLeaseForOperation(input.handle, record);
|
|
872
893
|
let command;
|
|
873
894
|
try {
|
|
874
|
-
command = await this.
|
|
875
|
-
const delegate = await this.
|
|
895
|
+
command = (await this.loadOperationSnapshotForHandle(input.handle)).command;
|
|
896
|
+
const delegate = this.resolveDelegateForOperationSnapshot(input.handle, await this.loadOperationSnapshotForHandle(input.handle));
|
|
876
897
|
for await (const event of delegate.runTurn(withOpenClawManagedTurnTimeout(input))) {
|
|
877
898
|
if (event.type !== "error" || !isCodexAcpCommand(command) || !isGenericInternalAcpErrorMessage(event.message)) {
|
|
878
899
|
yield event;
|
|
@@ -900,12 +921,11 @@ var AcpxRuntime = class {
|
|
|
900
921
|
}
|
|
901
922
|
startTurn(input) {
|
|
902
923
|
const readCodexTurnFailureStderr = () => this.readCodexTurnFailureStderr({ handle: input.handle });
|
|
903
|
-
const
|
|
904
|
-
const
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
this.
|
|
908
|
-
]).then(async ([, command, delegate]) => {
|
|
924
|
+
const snapshotPromise = this.loadOperationSnapshotForHandle(input.handle);
|
|
925
|
+
const turnLeasePromise = snapshotPromise.then(({ record }) => this.prepareProcessLeaseForOperation(input.handle, record));
|
|
926
|
+
const turnPromise = Promise.all([snapshotPromise, turnLeasePromise]).then(async ([snapshot]) => {
|
|
927
|
+
const { command } = snapshot;
|
|
928
|
+
const delegate = this.resolveDelegateForOperationSnapshot(input.handle, snapshot);
|
|
909
929
|
try {
|
|
910
930
|
return {
|
|
911
931
|
command,
|
|
@@ -920,6 +940,9 @@ var AcpxRuntime = class {
|
|
|
920
940
|
});
|
|
921
941
|
return {
|
|
922
942
|
requestId: input.requestId,
|
|
943
|
+
get promptStarted() {
|
|
944
|
+
return turnPromise.then(({ turn }) => turn.promptStarted);
|
|
945
|
+
},
|
|
923
946
|
events: { async *[Symbol.asyncIterator]() {
|
|
924
947
|
const { command, turn } = await turnPromise;
|
|
925
948
|
try {
|
|
@@ -979,18 +1002,20 @@ var AcpxRuntime = class {
|
|
|
979
1002
|
return this.delegate.getCapabilities(input);
|
|
980
1003
|
}
|
|
981
1004
|
async getStatus(input) {
|
|
982
|
-
|
|
1005
|
+
const snapshot = await this.loadOperationSnapshotForHandle(input.handle);
|
|
1006
|
+
return this.resolveDelegateForOperationSnapshot(input.handle, snapshot).getStatus(input);
|
|
983
1007
|
}
|
|
984
1008
|
async setMode(input) {
|
|
985
|
-
const
|
|
986
|
-
await this.runWithProcessLeaseForHandle(input.handle, () =>
|
|
1009
|
+
const snapshot = await this.loadOperationSnapshotForHandle(input.handle);
|
|
1010
|
+
await this.runWithProcessLeaseForHandle(input.handle, snapshot.record, () => this.resolveDelegateForOperationSnapshot(input.handle, snapshot).setMode(input));
|
|
987
1011
|
}
|
|
988
1012
|
async setConfigOption(input) {
|
|
989
|
-
await this.
|
|
1013
|
+
const snapshot = await this.loadOperationSnapshotForHandle(input.handle);
|
|
1014
|
+
await this.runWithProcessLeaseForHandle(input.handle, snapshot.record, () => this.setConfigOptionUnlocked(input, snapshot));
|
|
990
1015
|
}
|
|
991
|
-
async setConfigOptionUnlocked(input) {
|
|
992
|
-
const
|
|
993
|
-
const
|
|
1016
|
+
async setConfigOptionUnlocked(input, snapshot) {
|
|
1017
|
+
const { command } = snapshot;
|
|
1018
|
+
const delegate = this.resolveDelegateForOperationSnapshot(input.handle, snapshot);
|
|
994
1019
|
const key = input.key.trim().toLowerCase();
|
|
995
1020
|
const isCodexAcp = isCodexAcpCommand(command);
|
|
996
1021
|
if (WIRE_TIMEOUT_CONFIG_KEYS.has(key) && (isCodexAcp || isClaudeAcpCommand(command))) return;
|
|
@@ -1033,19 +1058,19 @@ var AcpxRuntime = class {
|
|
|
1033
1058
|
await delegate.setConfigOption(input);
|
|
1034
1059
|
}
|
|
1035
1060
|
async cancel(input) {
|
|
1036
|
-
const
|
|
1037
|
-
await this.
|
|
1061
|
+
const snapshot = await this.loadOperationSnapshotForHandle(input.handle);
|
|
1062
|
+
await this.resolveDelegateForOperationSnapshot(input.handle, snapshot).cancel(input);
|
|
1038
1063
|
}
|
|
1039
1064
|
async prepareFreshSession(input) {
|
|
1040
1065
|
this.sessionStore.markFresh(input.sessionKey);
|
|
1041
1066
|
}
|
|
1042
1067
|
async close(input) {
|
|
1043
|
-
const
|
|
1068
|
+
const snapshot = await this.loadOperationSnapshotForHandle(input.handle);
|
|
1069
|
+
const closeLease = await this.prepareProcessLeaseForOperation(input.handle, snapshot.record);
|
|
1044
1070
|
let cleanupSucceeded = false;
|
|
1045
1071
|
try {
|
|
1046
|
-
const
|
|
1072
|
+
const delegate = this.resolveDelegateForOperationSnapshot(input.handle, snapshot);
|
|
1047
1073
|
let closeSucceeded;
|
|
1048
|
-
const delegate = this.resolveDelegateForLoadedRecord(input.handle, record);
|
|
1049
1074
|
try {
|
|
1050
1075
|
await delegate.close({
|
|
1051
1076
|
handle: input.handle,
|
|
@@ -1054,26 +1079,23 @@ var AcpxRuntime = class {
|
|
|
1054
1079
|
});
|
|
1055
1080
|
closeSucceeded = true;
|
|
1056
1081
|
} finally {
|
|
1057
|
-
await this.cleanupProcessTreeForRecord(input.handle, record);
|
|
1082
|
+
await this.cleanupProcessTreeForRecord(input.handle, snapshot.record);
|
|
1058
1083
|
cleanupSucceeded = true;
|
|
1059
1084
|
}
|
|
1060
1085
|
if (closeSucceeded) this.releaseManagedToolsDelegateForSession(input.handle.sessionKey);
|
|
1061
1086
|
if (closeSucceeded && input.discardPersistentState) this.sessionStore.markFresh(input.handle.sessionKey);
|
|
1062
1087
|
} finally {
|
|
1063
1088
|
if (cleanupSucceeded) await this.finalizeProcessLeaseForOperation(input.handle, closeLease);
|
|
1064
|
-
else await this.
|
|
1089
|
+
else await this.releaseProcessLeaseAfterUncertainFailure(closeLease);
|
|
1065
1090
|
}
|
|
1066
1091
|
}
|
|
1067
1092
|
};
|
|
1068
1093
|
/** Test-only hooks for ACPX runtime behavior that is otherwise private. */
|
|
1069
1094
|
const testing = {
|
|
1070
1095
|
appendCodexAcpConfigOverrides,
|
|
1071
|
-
assertSupportedRuntimeSessionMode,
|
|
1072
|
-
classifyCodexAcpModelRequest,
|
|
1073
1096
|
isClaudeAcpCommand,
|
|
1074
1097
|
isCodexAcpCommand,
|
|
1075
|
-
normalizeAgentCommand
|
|
1076
|
-
normalizeClaudeAcpModelOverride
|
|
1098
|
+
normalizeAgentCommand
|
|
1077
1099
|
};
|
|
1078
1100
|
//#endregion
|
|
1079
|
-
export { ACPX_BACKEND_ID, AcpxRuntime,
|
|
1101
|
+
export { ACPX_BACKEND_ID, AcpxRuntime, createAcpRuntime, createAgentRegistry, createFileSessionStore, decodeAcpxRuntimeHandleState, encodeAcpxRuntimeHandleState, testing };
|
|
@@ -1,16 +1,15 @@
|
|
|
1
|
-
import { n as createLazyAcpRuntimeProxy } from "./register.runtime-
|
|
2
|
-
import "./config-schema-
|
|
3
|
-
import { _ as
|
|
4
|
-
import {
|
|
5
|
-
import { a as resolveAcpxPluginRoot, c as CODEX_ACP_PACKAGE, i as resolveAcpxPluginConfig, l as LEGACY_CODEX_ACP_PACKAGE, o as toAcpMcpServers, r as reapStaleOpenClawOwnedAcpxOrphans, s as CODEX_ACP_BIN, t as cleanupOpenClawOwnedAcpxProcessTree, u as OPENCLAW_CODEX_CONFIG_ARG } from "./process-reaper-DFwbcdPa.js";
|
|
1
|
+
import { n as createLazyAcpRuntimeProxy } from "./register.runtime-Dj29TKFy.js";
|
|
2
|
+
import "./config-schema-DN_uAi4R.js";
|
|
3
|
+
import { _ as quoteCommandPart, a as createAcpxProcessLeaseStore, f as ACPX_GATEWAY_INSTANCE_KEY, g as normalizeAcpxGatewayInstanceRecord, l as openAcpxProcessLeaseStateStore, n as OPENCLAW_ACPX_LEASE_ID_ARG, p as ACPX_GATEWAY_INSTANCE_NAMESPACE, r as OPENCLAW_GATEWAY_INSTANCE_ID_ARG, v as splitCommandParts } from "./process-lease-Cwvj7WGe.js";
|
|
4
|
+
import { a as resolveAcpxPluginConfig, c as CODEX_ACP_BIN, d as OPENCLAW_CODEX_CONFIG_ARG, i as reapStaleOpenClawOwnedAcpxOrphans, l as CODEX_ACP_PACKAGE, n as cleanupOpenClawOwnedAcpxProcessTree, o as resolveAcpxPluginRoot, s as toAcpMcpServers, t as cleanupOpenClawOwnedAcpxPendingLease, u as LEGACY_CODEX_ACP_PACKAGE } from "./process-reaper-DduWm_7N.js";
|
|
6
5
|
import { createRequire } from "node:module";
|
|
7
6
|
import { finiteSecondsToTimerSafeMilliseconds } from "openclaw/plugin-sdk/number-runtime";
|
|
8
7
|
import { createLazyRuntimeModule } from "openclaw/plugin-sdk/lazy-runtime";
|
|
9
|
-
import { normalizeLowercaseStringOrEmpty } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
8
|
+
import { isRecord, normalizeLowercaseStringOrEmpty } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
10
9
|
import fs from "node:fs";
|
|
11
|
-
import fs$1 from "node:fs/promises";
|
|
12
|
-
import path from "node:path";
|
|
13
10
|
import os from "node:os";
|
|
11
|
+
import path from "node:path";
|
|
12
|
+
import fs$1 from "node:fs/promises";
|
|
14
13
|
import { randomUUID } from "node:crypto";
|
|
15
14
|
import { inspect } from "node:util";
|
|
16
15
|
import { formatErrorMessage } from "openclaw/plugin-sdk/error-runtime";
|
|
@@ -893,14 +892,11 @@ function extractConfiguredAdapterArgs(params) {
|
|
|
893
892
|
if (isAcpBinName(parts[0] ?? "", params.binName)) return parts.slice(1);
|
|
894
893
|
if (basename(parts[0] ?? "") === "node" && isAcpBinName(parts[1] ?? "", params.binName)) return parts.slice(2);
|
|
895
894
|
}
|
|
896
|
-
function isConfigRecord(value) {
|
|
897
|
-
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
898
|
-
}
|
|
899
895
|
function mergeConfigRecords(base, override) {
|
|
900
896
|
const merged = { ...base };
|
|
901
897
|
for (const [key, value] of Object.entries(override)) {
|
|
902
898
|
const existing = merged[key];
|
|
903
|
-
const nextValue =
|
|
899
|
+
const nextValue = isRecord(existing) && isRecord(value) ? mergeConfigRecords(existing, value) : value;
|
|
904
900
|
Object.defineProperty(merged, key, {
|
|
905
901
|
value: nextValue,
|
|
906
902
|
configurable: true,
|
|
@@ -976,7 +972,7 @@ function buildCodexAcpWrapperCommand(wrapperPath, configuredCommand) {
|
|
|
976
972
|
}
|
|
977
973
|
async function persistMigratedCodexMcpConfig(params) {
|
|
978
974
|
const mcpServers = params.migratedConfig?.mcp_servers;
|
|
979
|
-
if (!
|
|
975
|
+
if (!isRecord(mcpServers)) return;
|
|
980
976
|
const configPath = path.join(params.codexHome, "config.toml");
|
|
981
977
|
const merged = mergeConfigRecords(parse(await fs$1.readFile(configPath, "utf8")), { mcp_servers: mcpServers });
|
|
982
978
|
await fs$1.writeFile(configPath, stringify(merged), "utf8");
|
|
@@ -1025,8 +1021,7 @@ async function prepareAcpxCodexAuthConfig(params) {
|
|
|
1025
1021
|
*/
|
|
1026
1022
|
const ENABLE_STARTUP_PROBE_ENV = "OPENCLAW_ACPX_RUNTIME_STARTUP_PROBE";
|
|
1027
1023
|
const SKIP_RUNTIME_PROBE_ENV = "OPENCLAW_SKIP_ACPX_RUNTIME_PROBE";
|
|
1028
|
-
const
|
|
1029
|
-
const loadRuntimeModule = createLazyRuntimeModule(() => import("./runtime-By_lR8uk.js"));
|
|
1024
|
+
const loadRuntimeModule = createLazyRuntimeModule(() => import("./runtime-BmOxa15I.js"));
|
|
1030
1025
|
/** Convert ACPX timeout seconds into timer-safe milliseconds. */
|
|
1031
1026
|
function resolveAcpxTimerTimeoutMs(timeoutSeconds) {
|
|
1032
1027
|
if (timeoutSeconds === void 0) return;
|
|
@@ -1051,6 +1046,7 @@ function createLazyDefaultRuntime(params) {
|
|
|
1051
1046
|
openclawToolsMcpBridgeEnabled: params.pluginConfig.openClawToolsMcpBridge,
|
|
1052
1047
|
permissionMode: params.pluginConfig.permissionMode,
|
|
1053
1048
|
nonInteractivePermissions: params.pluginConfig.nonInteractivePermissions,
|
|
1049
|
+
elicitationModes: ["form", "url"],
|
|
1054
1050
|
timeoutMs: resolveAcpxTimerTimeoutMs(params.pluginConfig.timeoutSeconds)
|
|
1055
1051
|
});
|
|
1056
1052
|
return runtime;
|
|
@@ -1067,13 +1063,6 @@ function createLazyDefaultRuntime(params) {
|
|
|
1067
1063
|
}
|
|
1068
1064
|
};
|
|
1069
1065
|
}
|
|
1070
|
-
function warnOnIgnoredLegacyCompatibilityConfig(params) {
|
|
1071
|
-
const ignoredFields = [];
|
|
1072
|
-
if (params.pluginConfig.legacyCompatibilityConfig.queueOwnerTtlSeconds != null) ignoredFields.push("queueOwnerTtlSeconds");
|
|
1073
|
-
if (params.pluginConfig.legacyCompatibilityConfig.strictWindowsCmdWrapper === false) ignoredFields.push("strictWindowsCmdWrapper=false");
|
|
1074
|
-
if (ignoredFields.length === 0) return;
|
|
1075
|
-
params.logger?.warn(`embedded acpx runtime ignores legacy compatibility config: ${ignoredFields.join(", ")}`);
|
|
1076
|
-
}
|
|
1077
1066
|
function formatDoctorDetail(detail) {
|
|
1078
1067
|
if (!detail) return null;
|
|
1079
1068
|
if (typeof detail === "string") return detail.trim() || null;
|
|
@@ -1152,21 +1141,22 @@ async function reapOpenAcpxProcessLeases(params) {
|
|
|
1152
1141
|
const leases = await params.leaseStore.listOpen(params.gatewayInstanceId);
|
|
1153
1142
|
const inspectedPids = [];
|
|
1154
1143
|
const terminatedPids = [];
|
|
1155
|
-
const
|
|
1144
|
+
const legacyWrapperRoots = /* @__PURE__ */ new Set();
|
|
1156
1145
|
for (const lease of leases) {
|
|
1157
1146
|
if (lease.rootPid <= 0) {
|
|
1147
|
+
legacyWrapperRoots.add(lease.wrapperRoot);
|
|
1158
1148
|
await params.leaseStore.markState(lease.leaseId, "closing");
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
await params.leaseStore.markState(lease.leaseId, result.terminatedPids.length > 0 ? "closed" : "lost");
|
|
1149
|
+
const result = await cleanupOpenClawOwnedAcpxPendingLease({
|
|
1150
|
+
leaseId: lease.leaseId,
|
|
1151
|
+
gatewayInstanceId: lease.gatewayInstanceId,
|
|
1152
|
+
wrapperRoot: lease.wrapperRoot,
|
|
1153
|
+
wrapperPath: lease.wrapperPath,
|
|
1154
|
+
deps: params.deps
|
|
1155
|
+
});
|
|
1156
|
+
inspectedPids.push(...result.inspectedPids);
|
|
1157
|
+
terminatedPids.push(...result.terminatedPids);
|
|
1158
|
+
const retryableEvidenceFailure = result.skippedReason === "ambiguous-root" || result.skippedReason === "process-list-unavailable" || result.skippedReason === "unsupported-platform" || result.skippedReason === "unverified-root" || lease.sessionKey === "openclaw:acpx:probe" && result.skippedReason === "missing-root";
|
|
1159
|
+
await params.leaseStore.markState(lease.leaseId, retryableEvidenceFailure ? "open" : result.terminatedPids.length > 0 ? "closed" : "lost");
|
|
1170
1160
|
continue;
|
|
1171
1161
|
}
|
|
1172
1162
|
await params.leaseStore.markState(lease.leaseId, "closing");
|
|
@@ -1179,7 +1169,15 @@ async function reapOpenAcpxProcessLeases(params) {
|
|
|
1179
1169
|
});
|
|
1180
1170
|
inspectedPids.push(...result.inspectedPids);
|
|
1181
1171
|
terminatedPids.push(...result.terminatedPids);
|
|
1182
|
-
await params.leaseStore.markState(lease.leaseId, result.skippedReason === "process-list-unavailable" ? "open" : result.terminatedPids.length > 0 ? "closed" : "lost");
|
|
1172
|
+
await params.leaseStore.markState(lease.leaseId, result.skippedReason === "process-list-unavailable" || result.skippedReason === "unsupported-platform" ? "open" : result.terminatedPids.length > 0 ? "closed" : "lost");
|
|
1173
|
+
}
|
|
1174
|
+
for (const wrapperRoot of legacyWrapperRoots) {
|
|
1175
|
+
const legacyResult = await reapStaleOpenClawOwnedAcpxOrphans({
|
|
1176
|
+
wrapperRoot,
|
|
1177
|
+
deps: params.deps
|
|
1178
|
+
});
|
|
1179
|
+
inspectedPids.push(...legacyResult.inspectedPids);
|
|
1180
|
+
terminatedPids.push(...legacyResult.terminatedPids);
|
|
1183
1181
|
}
|
|
1184
1182
|
return {
|
|
1185
1183
|
inspectedPids,
|
|
@@ -1187,7 +1185,7 @@ async function reapOpenAcpxProcessLeases(params) {
|
|
|
1187
1185
|
};
|
|
1188
1186
|
}
|
|
1189
1187
|
/** Create the ACPX plugin service that owns runtime registration and cleanup. */
|
|
1190
|
-
function createAcpxRuntimeService(params
|
|
1188
|
+
function createAcpxRuntimeService(params) {
|
|
1191
1189
|
let runtime = null;
|
|
1192
1190
|
let lifecycleRevision = 0;
|
|
1193
1191
|
return {
|
|
@@ -1225,10 +1223,6 @@ function createAcpxRuntimeService(params = {}) {
|
|
|
1225
1223
|
deps: params.processCleanupDeps
|
|
1226
1224
|
}));
|
|
1227
1225
|
if (startupReap.terminatedPids.length > 0) ctx.logger.info(`reaped ${startupReap.terminatedPids.length} stale OpenClaw-owned ACPX process${startupReap.terminatedPids.length === 1 ? "" : "es"}`);
|
|
1228
|
-
warnOnIgnoredLegacyCompatibilityConfig({
|
|
1229
|
-
pluginConfig,
|
|
1230
|
-
logger: ctx.logger
|
|
1231
|
-
});
|
|
1232
1226
|
const startedRuntime = await measureAcpxStartup(ctx, "runtime.create", () => params.runtimeFactory ? params.runtimeFactory({
|
|
1233
1227
|
pluginConfig,
|
|
1234
1228
|
gatewayInstanceId,
|
|
@@ -1246,11 +1240,11 @@ function createAcpxRuntimeService(params = {}) {
|
|
|
1246
1240
|
const shouldProbeRuntime = shouldProbeRuntimeAtStartup();
|
|
1247
1241
|
detailAcpxStartup(ctx, "probe-policy", [["startupProbeEnabledCount", shouldProbeRuntime ? 1 : 0], ["probeAgent", pluginConfig.probeAgent ?? "default"]]);
|
|
1248
1242
|
await measureAcpxStartup(ctx, "backend.register", () => {
|
|
1249
|
-
|
|
1250
|
-
id: ACPX_BACKEND_ID,
|
|
1243
|
+
const backend = {
|
|
1251
1244
|
runtime: startedRuntime,
|
|
1252
1245
|
...shouldProbeRuntime ? { healthy: () => runtime?.isHealthy() ?? false } : {}
|
|
1253
|
-
}
|
|
1246
|
+
};
|
|
1247
|
+
params.backendLifecycle.publish(backend);
|
|
1254
1248
|
ctx.logger.info(`embedded acpx runtime backend registered (cwd: ${pluginConfig.cwd})`);
|
|
1255
1249
|
});
|
|
1256
1250
|
if (!shouldProbeRuntime) return;
|
|
@@ -1267,7 +1261,7 @@ function createAcpxRuntimeService(params = {}) {
|
|
|
1267
1261
|
ctx.logger.info("embedded acpx runtime backend ready");
|
|
1268
1262
|
return;
|
|
1269
1263
|
}
|
|
1270
|
-
const doctorReport = await measureAcpxStartup(ctx, "probe.doctor", () => startedRuntime.doctor
|
|
1264
|
+
const doctorReport = await measureAcpxStartup(ctx, "probe.doctor", () => startedRuntime.doctor());
|
|
1271
1265
|
if (currentRevision !== lifecycleRevision) return;
|
|
1272
1266
|
detailAcpxStartup(ctx, "probe.result", [["healthyCount", 0]]);
|
|
1273
1267
|
ctx.logger.warn(`embedded acpx runtime backend probe failed: ${doctorReport ? formatDoctorFailureMessage(doctorReport) : "backend remained unhealthy after probe"}`);
|
|
@@ -1279,7 +1273,7 @@ function createAcpxRuntimeService(params = {}) {
|
|
|
1279
1273
|
},
|
|
1280
1274
|
async stop(_ctx) {
|
|
1281
1275
|
lifecycleRevision += 1;
|
|
1282
|
-
|
|
1276
|
+
if (runtime) params.backendLifecycle.retract(runtime);
|
|
1283
1277
|
runtime = null;
|
|
1284
1278
|
}
|
|
1285
1279
|
};
|
package/openclaw.plugin.json
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"id": "acpx",
|
|
3
|
+
"doctorContract": {
|
|
4
|
+
"configRepair": true,
|
|
5
|
+
"stateMigrations": true
|
|
6
|
+
},
|
|
3
7
|
"activation": {
|
|
4
8
|
"onStartup": true
|
|
5
9
|
},
|
|
@@ -37,18 +41,11 @@
|
|
|
37
41
|
"openClawToolsMcpBridge": {
|
|
38
42
|
"type": "boolean"
|
|
39
43
|
},
|
|
40
|
-
"strictWindowsCmdWrapper": {
|
|
41
|
-
"type": "boolean"
|
|
42
|
-
},
|
|
43
44
|
"timeoutSeconds": {
|
|
44
45
|
"type": "number",
|
|
45
46
|
"minimum": 0.001,
|
|
46
47
|
"default": 120
|
|
47
48
|
},
|
|
48
|
-
"queueOwnerTtlSeconds": {
|
|
49
|
-
"type": "number",
|
|
50
|
-
"minimum": 0
|
|
51
|
-
},
|
|
52
49
|
"piSessionCatalog": {
|
|
53
50
|
"type": "object",
|
|
54
51
|
"additionalProperties": false,
|
|
@@ -87,6 +84,7 @@
|
|
|
87
84
|
"type": "object",
|
|
88
85
|
"additionalProperties": {
|
|
89
86
|
"type": "object",
|
|
87
|
+
"additionalProperties": false,
|
|
90
88
|
"properties": {
|
|
91
89
|
"command": {
|
|
92
90
|
"type": "string",
|
|
@@ -129,21 +127,11 @@
|
|
|
129
127
|
"help": "Default off. When enabled, inject the built-in OpenClaw core-tools MCP server into embedded ACP sessions so ACP agents can call selected built-in tools such as cron.",
|
|
130
128
|
"advanced": true
|
|
131
129
|
},
|
|
132
|
-
"strictWindowsCmdWrapper": {
|
|
133
|
-
"label": "Strict Windows cmd Wrapper",
|
|
134
|
-
"help": "Legacy compatibility field. The current embedded acpx/runtime package uses its own Windows command resolution behavior. Setting this to false is accepted for compatibility and logged as ignored.",
|
|
135
|
-
"advanced": true
|
|
136
|
-
},
|
|
137
130
|
"timeoutSeconds": {
|
|
138
131
|
"label": "Runtime Operation Timeout Seconds",
|
|
139
132
|
"help": "Timeout for embedded ACP runtime startup and control operations. ACP turns use OpenClaw agent/run timeouts.",
|
|
140
133
|
"advanced": true
|
|
141
134
|
},
|
|
142
|
-
"queueOwnerTtlSeconds": {
|
|
143
|
-
"label": "Queue Owner TTL Seconds",
|
|
144
|
-
"help": "Reserved compatibility field for the older embedded ACPX queue-owner path. Accepted for compatibility and logged as ignored.",
|
|
145
|
-
"advanced": true
|
|
146
|
-
},
|
|
147
135
|
"piSessionCatalog.enabled": {
|
|
148
136
|
"label": "Pi Session Catalog",
|
|
149
137
|
"help": "Auto-detect Pi sessions on the Gateway and paired nodes, then show them in the sessions sidebar."
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openclaw/acpx",
|
|
3
|
-
"version": "2026.
|
|
3
|
+
"version": "2026.8.1-beta.3",
|
|
4
4
|
"description": "OpenClaw ACP runtime backend with plugin-owned session and transport management.",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
"dependencies": {
|
|
11
11
|
"@agentclientprotocol/claude-agent-acp": "0.62.0",
|
|
12
12
|
"@agentclientprotocol/codex-acp": "1.1.7",
|
|
13
|
-
"acpx": "0.13.
|
|
13
|
+
"acpx": "0.13.1",
|
|
14
14
|
"smol-toml": "1.7.1",
|
|
15
15
|
"zod": "4.4.3"
|
|
16
16
|
},
|
|
@@ -43,10 +43,10 @@
|
|
|
43
43
|
]
|
|
44
44
|
},
|
|
45
45
|
"compat": {
|
|
46
|
-
"pluginApi": ">=2026.
|
|
46
|
+
"pluginApi": ">=2026.8.1-beta.3"
|
|
47
47
|
},
|
|
48
48
|
"build": {
|
|
49
|
-
"openclawVersion": "2026.
|
|
49
|
+
"openclawVersion": "2026.8.1-beta.3",
|
|
50
50
|
"staticAssets": [
|
|
51
51
|
{
|
|
52
52
|
"source": "./src/runtime-internals/mcp-proxy.mjs",
|
|
@@ -74,7 +74,7 @@
|
|
|
74
74
|
"skills/**"
|
|
75
75
|
],
|
|
76
76
|
"peerDependencies": {
|
|
77
|
-
"openclaw": ">=2026.
|
|
77
|
+
"openclaw": ">=2026.8.1-beta.3"
|
|
78
78
|
},
|
|
79
79
|
"peerDependenciesMeta": {
|
|
80
80
|
"openclaw": {
|