@openclaw/acpx 2026.5.16-beta.3 → 2026.5.16-beta.5

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.
@@ -1,16 +1,11 @@
1
- import { getAcpRuntimeBackend, registerAcpRuntimeBackend, unregisterAcpRuntimeBackend } from "openclaw/plugin-sdk/acp-runtime-backend";
1
+ import { getAcpRuntimeBackend, unregisterAcpRuntimeBackend } from "openclaw/plugin-sdk/acp-runtime-backend";
2
2
  //#region extensions/acpx/register.runtime.ts
3
3
  const ACPX_BACKEND_ID = "acpx";
4
- const ENABLE_STARTUP_PROBE_ENV = "OPENCLAW_ACPX_RUNTIME_STARTUP_PROBE";
5
- const SKIP_RUNTIME_PROBE_ENV = "OPENCLAW_SKIP_ACPX_RUNTIME_PROBE";
6
4
  let serviceModulePromise = null;
7
5
  function loadServiceModule() {
8
- serviceModulePromise ??= import("./service-D_VrHPXx.js");
6
+ serviceModulePromise ??= import("./service-DsH8by3_.js");
9
7
  return serviceModulePromise;
10
8
  }
11
- function shouldRunStartupProbe(env = process.env) {
12
- return env[ENABLE_STARTUP_PROBE_ENV] !== "0" && env[SKIP_RUNTIME_PROBE_ENV] !== "1";
13
- }
14
9
  async function startRealService(state) {
15
10
  if (state.realRuntime) return state.realRuntime;
16
11
  if (!state.ctx) throw new Error("ACPX runtime service is not started");
@@ -26,49 +21,6 @@ async function startRealService(state) {
26
21
  })();
27
22
  return await state.startPromise;
28
23
  }
29
- function createDeferredRuntime(state) {
30
- return {
31
- async ensureSession(input) {
32
- return await (await startRealService(state)).ensureSession(input);
33
- },
34
- async *runTurn(input) {
35
- yield* (await startRealService(state)).runTurn(input);
36
- },
37
- async getCapabilities(input) {
38
- return await (await startRealService(state)).getCapabilities?.(input) ?? { controls: [] };
39
- },
40
- async getStatus(input) {
41
- return await (await startRealService(state)).getStatus?.(input) ?? {};
42
- },
43
- async setMode(input) {
44
- await (await startRealService(state)).setMode?.(input);
45
- },
46
- async setConfigOption(input) {
47
- await (await startRealService(state)).setConfigOption?.(input);
48
- },
49
- async doctor() {
50
- return await (await startRealService(state)).doctor?.() ?? {
51
- ok: true,
52
- message: "ok"
53
- };
54
- },
55
- async prepareFreshSession(input) {
56
- await (await startRealService(state)).prepareFreshSession?.(input);
57
- },
58
- async cancel(input) {
59
- await (await startRealService(state)).cancel(input);
60
- },
61
- async close(input) {
62
- await (await startRealService(state)).close(input);
63
- },
64
- async probeAvailability() {
65
- await (await startRealService(state)).probeAvailability();
66
- },
67
- isHealthy() {
68
- return state.realRuntime?.isHealthy() ?? false;
69
- }
70
- };
71
- }
72
24
  function createAcpxRuntimeService(params = {}) {
73
25
  const state = {
74
26
  ctx: null,
@@ -85,15 +37,7 @@ function createAcpxRuntimeService(params = {}) {
85
37
  return;
86
38
  }
87
39
  state.ctx = ctx;
88
- if (shouldRunStartupProbe()) {
89
- await startRealService(state);
90
- return;
91
- }
92
- registerAcpRuntimeBackend({
93
- id: ACPX_BACKEND_ID,
94
- runtime: createDeferredRuntime(state)
95
- });
96
- ctx.logger.info("embedded acpx runtime backend registered lazily");
40
+ await startRealService(state);
97
41
  },
98
42
  async stop(ctx) {
99
43
  if (state.realService) await state.realService.stop?.(ctx);
@@ -6,6 +6,12 @@ import path, { resolve } from "node:path";
6
6
  import { ACPX_BACKEND_ID, AcpxRuntime as AcpxRuntime$1, createAcpRuntime, createAgentRegistry, createFileSessionStore, decodeAcpxRuntimeHandleState, encodeAcpxRuntimeHandleState } from "acpx/runtime";
7
7
  import { redactSensitiveText } from "openclaw/plugin-sdk/security-runtime";
8
8
  //#region extensions/acpx/src/runtime.ts
9
+ function withOpenClawManagedTurnTimeout(input) {
10
+ return {
11
+ ...input,
12
+ timeoutMs: 0
13
+ };
14
+ }
9
15
  const CODEX_WRAPPER_STDERR_LOG_PREFIX = "codex-acp-wrapper.stderr";
10
16
  const CODEX_WRAPPER_ERROR_TAIL_MAX_CHARS = 6e3;
11
17
  function safeDiagnosticFilePart(value) {
@@ -569,7 +575,7 @@ var AcpxRuntime = class {
569
575
  const command = await this.resolveCommandForHandle(input.handle);
570
576
  const delegate = await this.resolveDelegateForHandle(input.handle);
571
577
  try {
572
- for await (const event of delegate.runTurn(input)) {
578
+ for await (const event of delegate.runTurn(withOpenClawManagedTurnTimeout(input))) {
573
579
  if (event.type !== "error" || !isCodexAcpCommand(command) || !isGenericInternalAcpErrorMessage(event.message)) {
574
580
  yield event;
575
581
  continue;
@@ -592,6 +598,78 @@ var AcpxRuntime = class {
592
598
  throw new AcpRuntimeError("ACP_TURN_FAILED", `Internal error: ${stderrTail}`, { cause: error });
593
599
  }
594
600
  }
601
+ startTurn(input) {
602
+ const readCodexTurnFailureStderr = () => this.readCodexTurnFailureStderr({ handle: input.handle });
603
+ const turnPromise = Promise.all([this.resolveCommandForHandle(input.handle), this.resolveDelegateForHandle(input.handle)]).then(async ([command, delegate]) => {
604
+ try {
605
+ return {
606
+ command,
607
+ turn: delegate.startTurn(withOpenClawManagedTurnTimeout(input))
608
+ };
609
+ } catch (error) {
610
+ if (!isCodexAcpCommand(command) || !isGenericInternalAcpError(error)) throw error;
611
+ const stderrTail = await readCodexTurnFailureStderr();
612
+ if (!stderrTail) throw error;
613
+ throw new AcpRuntimeError("ACP_TURN_FAILED", `Internal error: ${stderrTail}`, { cause: error });
614
+ }
615
+ });
616
+ return {
617
+ requestId: input.requestId,
618
+ events: { async *[Symbol.asyncIterator]() {
619
+ const { command, turn } = await turnPromise;
620
+ try {
621
+ for await (const event of turn.events) {
622
+ if (event.type !== "error" || !isCodexAcpCommand(command) || !isGenericInternalAcpErrorMessage(event.message)) {
623
+ yield event;
624
+ continue;
625
+ }
626
+ const stderrTail = await readCodexTurnFailureStderr();
627
+ if (!stderrTail) {
628
+ yield event;
629
+ continue;
630
+ }
631
+ yield {
632
+ ...event,
633
+ code: "ACP_TURN_FAILED",
634
+ message: `Internal error: ${stderrTail}`
635
+ };
636
+ }
637
+ } catch (error) {
638
+ if (!isCodexAcpCommand(command) || !isGenericInternalAcpError(error)) throw error;
639
+ const stderrTail = await readCodexTurnFailureStderr();
640
+ if (!stderrTail) throw error;
641
+ throw new AcpRuntimeError("ACP_TURN_FAILED", `Internal error: ${stderrTail}`, { cause: error });
642
+ }
643
+ } },
644
+ result: turnPromise.then(async ({ command, turn }) => {
645
+ try {
646
+ const result = await turn.result;
647
+ if (result.status !== "failed" || !isCodexAcpCommand(command) || !isGenericInternalAcpErrorMessage(result.error.message)) return result;
648
+ const stderrTail = await this.readCodexTurnFailureStderr({ handle: input.handle });
649
+ if (!stderrTail) return result;
650
+ return {
651
+ status: "failed",
652
+ error: {
653
+ ...result.error,
654
+ code: "ACP_TURN_FAILED",
655
+ message: `Internal error: ${stderrTail}`
656
+ }
657
+ };
658
+ } catch (error) {
659
+ if (!isCodexAcpCommand(command) || !isGenericInternalAcpError(error)) throw error;
660
+ const stderrTail = await this.readCodexTurnFailureStderr({ handle: input.handle });
661
+ if (!stderrTail) throw error;
662
+ throw new AcpRuntimeError("ACP_TURN_FAILED", `Internal error: ${stderrTail}`, { cause: error });
663
+ }
664
+ }),
665
+ cancel(inputArgs) {
666
+ return turnPromise.then(({ turn }) => turn.cancel(inputArgs));
667
+ },
668
+ closeStream(inputArgs) {
669
+ return turnPromise.then(({ turn }) => turn.closeStream(inputArgs));
670
+ }
671
+ };
672
+ }
595
673
  getCapabilities() {
596
674
  return this.delegate.getCapabilities();
597
675
  }
@@ -1053,9 +1053,137 @@ const SKIP_RUNTIME_PROBE_ENV = "OPENCLAW_SKIP_ACPX_RUNTIME_PROBE";
1053
1053
  const ACPX_BACKEND_ID = "acpx";
1054
1054
  let runtimeModulePromise = null;
1055
1055
  function loadRuntimeModule() {
1056
- runtimeModulePromise ??= import("./runtime-WxNI8VkM.js");
1056
+ runtimeModulePromise ??= import("./runtime-DuZ9TePK.js");
1057
1057
  return runtimeModulePromise;
1058
1058
  }
1059
+ function createDeferredResult() {
1060
+ let resolve;
1061
+ let reject;
1062
+ return {
1063
+ promise: new Promise((resolvePromise, rejectPromise) => {
1064
+ resolve = resolvePromise;
1065
+ reject = rejectPromise;
1066
+ }),
1067
+ resolve,
1068
+ reject
1069
+ };
1070
+ }
1071
+ var LegacyRunTurnEventQueue = class {
1072
+ constructor() {
1073
+ this.items = [];
1074
+ this.waits = [];
1075
+ this.closed = false;
1076
+ }
1077
+ push(item) {
1078
+ if (this.closed) return;
1079
+ const waiter = this.waits.shift();
1080
+ if (waiter) {
1081
+ waiter.resolve(item);
1082
+ return;
1083
+ }
1084
+ this.items.push(item);
1085
+ }
1086
+ clear() {
1087
+ this.items.length = 0;
1088
+ }
1089
+ close() {
1090
+ if (this.closed) return;
1091
+ this.closed = true;
1092
+ for (const waiter of this.waits.splice(0)) waiter.resolve(null);
1093
+ }
1094
+ fail(error) {
1095
+ if (this.closed) return;
1096
+ this.error = error;
1097
+ this.closed = true;
1098
+ for (const waiter of this.waits.splice(0)) waiter.reject(error);
1099
+ }
1100
+ async next() {
1101
+ const item = this.items.shift();
1102
+ if (item) return item;
1103
+ if (this.error) throw this.error;
1104
+ if (this.closed) return null;
1105
+ return await new Promise((resolve, reject) => {
1106
+ this.waits.push({
1107
+ resolve,
1108
+ reject
1109
+ });
1110
+ });
1111
+ }
1112
+ async *iterate() {
1113
+ for (;;) {
1114
+ const item = await this.next();
1115
+ if (!item) return;
1116
+ yield item;
1117
+ }
1118
+ }
1119
+ };
1120
+ function legacyRunTurnAsStartTurn(runtime, input) {
1121
+ const result = createDeferredResult();
1122
+ result.promise.catch(() => {});
1123
+ const queue = new LegacyRunTurnEventQueue();
1124
+ let resultSettled = false;
1125
+ const settleResult = (next) => {
1126
+ if (resultSettled) return;
1127
+ resultSettled = true;
1128
+ result.resolve(next);
1129
+ };
1130
+ (async () => {
1131
+ try {
1132
+ for await (const event of runtime.runTurn(input)) {
1133
+ if (event.type === "done") {
1134
+ settleResult({
1135
+ status: "completed",
1136
+ ...event.stopReason ? { stopReason: event.stopReason } : {}
1137
+ });
1138
+ continue;
1139
+ }
1140
+ if (event.type === "error") {
1141
+ settleResult({
1142
+ status: "failed",
1143
+ error: {
1144
+ message: event.message,
1145
+ ...event.code ? { code: event.code } : {},
1146
+ ...event.detailCode ? { detailCode: event.detailCode } : {},
1147
+ ...event.retryable === void 0 ? {} : { retryable: event.retryable }
1148
+ }
1149
+ });
1150
+ continue;
1151
+ }
1152
+ queue.push(event);
1153
+ }
1154
+ settleResult({
1155
+ status: "failed",
1156
+ error: {
1157
+ code: "ACP_TURN_FAILED",
1158
+ message: "ACP turn ended without a terminal done event."
1159
+ }
1160
+ });
1161
+ } catch (error) {
1162
+ result.reject(error);
1163
+ queue.fail(error);
1164
+ return;
1165
+ }
1166
+ queue.close();
1167
+ })();
1168
+ return {
1169
+ requestId: input.requestId,
1170
+ events: queue.iterate(),
1171
+ result: result.promise,
1172
+ async cancel(inputArgs) {
1173
+ await runtime.cancel({
1174
+ handle: input.handle,
1175
+ reason: inputArgs?.reason
1176
+ });
1177
+ },
1178
+ async closeStream() {
1179
+ queue.clear();
1180
+ queue.close();
1181
+ }
1182
+ };
1183
+ }
1184
+ function startRuntimeTurn(runtime, input) {
1185
+ return runtime.startTurn?.(input) ?? legacyRunTurnAsStartTurn(runtime, input);
1186
+ }
1059
1187
  function createLazyDefaultRuntime(params) {
1060
1188
  let runtime = null;
1061
1189
  let runtimePromise = null;
@@ -1083,6 +1211,22 @@ function createLazyDefaultRuntime(params) {
1083
1211
  async ensureSession(input) {
1084
1212
  return await (await resolveRuntime()).ensureSession(input);
1085
1213
  },
1214
+ startTurn(input) {
1215
+ const turnPromise = resolveRuntime().then((resolved) => startRuntimeTurn(resolved, input));
1216
+ return {
1217
+ requestId: input.requestId,
1218
+ events: { async *[Symbol.asyncIterator]() {
1219
+ yield* (await turnPromise).events;
1220
+ } },
1221
+ result: turnPromise.then((turn) => turn.result),
1222
+ cancel(inputArgs) {
1223
+ return turnPromise.then((turn) => turn.cancel(inputArgs));
1224
+ },
1225
+ closeStream(inputArgs) {
1226
+ return turnPromise.then((turn) => turn.closeStream(inputArgs));
1227
+ }
1228
+ };
1229
+ },
1086
1230
  async *runTurn(input) {
1087
1231
  yield* (await resolveRuntime()).runTurn(input);
1088
1232
  },
@@ -129,8 +129,8 @@
129
129
  "advanced": true
130
130
  },
131
131
  "timeoutSeconds": {
132
- "label": "Prompt Timeout Seconds",
133
- "help": "Timeout for each embedded runtime turn. Defaults to 120 seconds so slower Gemini CLI ACP startups have room to initialize.",
132
+ "label": "Runtime Operation Timeout Seconds",
133
+ "help": "Timeout for embedded ACP runtime startup and control operations. ACP turns use OpenClaw agent/run timeouts.",
134
134
  "advanced": true
135
135
  },
136
136
  "queueOwnerTtlSeconds": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openclaw/acpx",
3
- "version": "2026.5.16-beta.3",
3
+ "version": "2026.5.16-beta.5",
4
4
  "description": "OpenClaw ACP runtime backend",
5
5
  "repository": {
6
6
  "type": "git",
@@ -26,10 +26,10 @@
26
26
  "minHostVersion": ">=2026.4.25"
27
27
  },
28
28
  "compat": {
29
- "pluginApi": ">=2026.5.16-beta.3"
29
+ "pluginApi": ">=2026.5.16-beta.5"
30
30
  },
31
31
  "build": {
32
- "openclawVersion": "2026.5.16-beta.3",
32
+ "openclawVersion": "2026.5.16-beta.5",
33
33
  "staticAssets": [
34
34
  {
35
35
  "source": "./src/runtime-internals/mcp-proxy.mjs",
@@ -59,7 +59,7 @@
59
59
  "skills/**"
60
60
  ],
61
61
  "peerDependencies": {
62
- "openclaw": ">=2026.5.16-beta.3"
62
+ "openclaw": ">=2026.5.16-beta.5"
63
63
  },
64
64
  "peerDependenciesMeta": {
65
65
  "openclaw": {