@openclaw/acpx 2026.9.5 → 2026.9.6

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,65 +1,5 @@
1
+ import { a as renderAgentCommand, s as splitCommandParts } from "./command-line-CPBLOiZM.mjs";
1
2
  import { createHash } from "node:crypto";
2
- //#region extensions/acpx/src/command-line.ts
3
- /** Match ACPX's persisted argv identity; scalar records keep their original bytes. */
4
- function renderAgentCommand(command) {
5
- return typeof command === "string" ? command : command.map((part) => /^[A-Za-z0-9_@%+=:,./^~-]+$/.test(part) ? part : JSON.stringify(part)).join(" ");
6
- }
7
- /** Split a command string into argv-like parts using simple quote/backslash rules. */
8
- function splitCommandParts(value) {
9
- if (Array.isArray(value)) return value;
10
- const windows = process.platform === "win32";
11
- const parts = [];
12
- let current = "";
13
- let quote = null;
14
- let escaping = false;
15
- let hasPart = false;
16
- for (const ch of value) {
17
- if (escaping) {
18
- current += ch;
19
- escaping = false;
20
- hasPart = true;
21
- continue;
22
- }
23
- if (ch === "\\" && quote !== "'" && !windows) {
24
- escaping = true;
25
- hasPart = true;
26
- continue;
27
- }
28
- if (windows && ch === "\"" && quote !== "'") {
29
- const backslashes = current.match(/\\+$/)?.[0].length ?? 0;
30
- current = current.slice(0, current.length - backslashes) + "\\".repeat(Math.floor(backslashes / 2));
31
- if (backslashes % 2 === 1) {
32
- current += "\"";
33
- continue;
34
- }
35
- }
36
- if (quote) {
37
- if (ch === quote) quote = null;
38
- else current += ch;
39
- continue;
40
- }
41
- if (ch === "'" || ch === "\"") {
42
- quote = ch;
43
- hasPart = true;
44
- continue;
45
- }
46
- if (/\s/.test(ch)) {
47
- if (hasPart) {
48
- parts.push(current);
49
- current = "";
50
- hasPart = false;
51
- }
52
- continue;
53
- }
54
- current += ch;
55
- hasPart = true;
56
- }
57
- if (escaping) current += "\\";
58
- if (quote) throw new Error("Invalid agent command: unterminated quote");
59
- if (hasPart) parts.push(current);
60
- return parts;
61
- }
62
- //#endregion
63
3
  //#region extensions/acpx/src/state.ts
64
4
  const ACPX_PROCESS_LEASE_NAMESPACE = "process-leases";
65
5
  const ACPX_PROCESS_LEASE_MAX_ENTRIES = 4096;
@@ -195,4 +135,4 @@ function withAcpxLeaseArgs(params) {
195
135
  ];
196
136
  }
197
137
  //#endregion
198
- export { splitCommandParts as _, hashAcpxProcessCommand as a, openAcpxProcessLeaseStateStore as c, ACPX_GATEWAY_INSTANCE_KEY as d, ACPX_GATEWAY_INSTANCE_NAMESPACE as f, renderAgentCommand as g, normalizeAcpxGatewayInstanceRecord as h, createAcpxProcessLeaseStore as i, readAcpxProcessLeaseIdentity as l, ACPX_LEGACY_PROCESS_LEASE_FILE as m, OPENCLAW_ACPX_LEASE_ID_ARG as n, normalizeAcpxProcessLease as o, ACPX_LEGACY_GATEWAY_INSTANCE_FILE as p, OPENCLAW_GATEWAY_INSTANCE_ID_ARG as r, normalizeAcpxProcessLeaseFile as s, ACPX_PROBE_LEASE_SESSION_KEY as t, withAcpxLeaseArgs as u };
138
+ export { hashAcpxProcessCommand as a, openAcpxProcessLeaseStateStore as c, ACPX_GATEWAY_INSTANCE_KEY as d, ACPX_GATEWAY_INSTANCE_NAMESPACE as f, normalizeAcpxGatewayInstanceRecord as h, createAcpxProcessLeaseStore as i, readAcpxProcessLeaseIdentity as l, ACPX_LEGACY_PROCESS_LEASE_FILE as m, OPENCLAW_ACPX_LEASE_ID_ARG as n, normalizeAcpxProcessLease as o, ACPX_LEGACY_GATEWAY_INSTANCE_FILE as p, OPENCLAW_GATEWAY_INSTANCE_ID_ARG as r, normalizeAcpxProcessLeaseFile as s, ACPX_PROBE_LEASE_SESSION_KEY as t, withAcpxLeaseArgs as u };
@@ -25,6 +25,9 @@ function lazyStartRuntimeTurn(resolveRuntime, input) {
25
25
  function createLazyAcpRuntimeProxy(resolveRuntime) {
26
26
  return {
27
27
  ownerAwareSessions: 1,
28
+ async findSession(input) {
29
+ return await (await resolveRuntime()).findSession(input);
30
+ },
28
31
  async shutdown() {
29
32
  await (await resolveRuntime()).shutdown();
30
33
  },
@@ -46,6 +49,9 @@ function createLazyAcpRuntimeProxy(resolveRuntime) {
46
49
  async setMode(input) {
47
50
  await (await resolveRuntime()).setMode(input);
48
51
  },
52
+ async setModel(input) {
53
+ await (await resolveRuntime()).setModel(input);
54
+ },
49
55
  async setConfigOption(input) {
50
56
  return await (await resolveRuntime()).setConfigOption(input);
51
57
  },
@@ -70,13 +76,12 @@ function createLazyAcpRuntimeProxy(resolveRuntime) {
70
76
  * immediately, then imports the heavier service only when a session needs it.
71
77
  */
72
78
  const ACPX_BACKEND_ID = "acpx";
73
- const loadServiceModule = createLazyRuntimeModule(() => import("./service-DZYyo6-7.mjs").then((n) => n.t));
79
+ const loadServiceModule = createLazyRuntimeModule(() => import("./service-DMae5pPH.mjs"));
74
80
  function unregisterOwnedRuntime(runtime) {
75
81
  if (runtime && getAcpRuntimeBackend(ACPX_BACKEND_ID)?.runtime === runtime) unregisterAcpRuntimeBackend(ACPX_BACKEND_ID);
76
82
  }
77
- async function startRealService(state, lifecycleRevision, deferredRuntime) {
83
+ async function startRealService(state, lifecycleRevision, deferredRuntime, purpose = "gateway", probeAtStartup = purpose === "gateway") {
78
84
  if (state.lifecycleRevision !== lifecycleRevision || !state.ctx) throw new Error("ACPX runtime service is not started");
79
- if (state.realRuntime) return state.realRuntime;
80
85
  if (state.startPromise) return await state.startPromise;
81
86
  const ctx = state.ctx;
82
87
  state.startPromise = (async () => {
@@ -84,28 +89,30 @@ async function startRealService(state, lifecycleRevision, deferredRuntime) {
84
89
  const { createAcpxRuntimeService: createAcpxRuntimeServiceLocal } = await loadServiceModule();
85
90
  const service = createAcpxRuntimeServiceLocal({
86
91
  ...state.params,
92
+ probeAtStartup,
93
+ startupPurpose: purpose,
94
+ assertCurrent: () => {
95
+ if (state.lifecycleRevision !== lifecycleRevision || state.ctx !== ctx || state.published && getAcpRuntimeBackend(ACPX_BACKEND_ID)?.runtime !== state.ownedRuntime) throw new Error("ACPX runtime service lost recovery ownership");
96
+ },
87
97
  backendLifecycle: {
88
98
  publish(backend) {
89
99
  if (state.lifecycleRevision !== lifecycleRevision || state.ctx !== ctx) throw new Error("ACPX runtime service stopped during activation");
90
- if (getAcpRuntimeBackend(ACPX_BACKEND_ID)?.runtime !== deferredRuntime) throw new Error("ACPX runtime service lost registry ownership during activation");
91
- registerAcpRuntimeBackend({
100
+ if (state.published && getAcpRuntimeBackend(ACPX_BACKEND_ID)?.runtime !== deferredRuntime) throw new Error("ACPX runtime service lost registry ownership during activation");
101
+ if (state.published) registerAcpRuntimeBackend({
92
102
  id: ACPX_BACKEND_ID,
93
- ...backend
103
+ ...backend,
104
+ runtime: deferredRuntime
94
105
  });
95
106
  publishedRuntime = backend.runtime;
96
- state.ownedRuntime = backend.runtime;
97
107
  },
98
- retract(runtime) {
99
- unregisterOwnedRuntime(runtime);
100
- }
108
+ retract() {}
101
109
  }
102
110
  });
103
111
  state.realService = service;
104
112
  await service.start(ctx);
105
113
  if (state.lifecycleRevision !== lifecycleRevision || state.ctx !== ctx) throw new Error("ACPX runtime service stopped during activation");
106
114
  if (!publishedRuntime) throw new Error("ACPX runtime service did not register an ACP backend");
107
- if (getAcpRuntimeBackend(ACPX_BACKEND_ID)?.runtime !== publishedRuntime) throw new Error("ACPX runtime service lost registry ownership during activation");
108
- state.realRuntime = publishedRuntime;
115
+ if (state.published && getAcpRuntimeBackend(ACPX_BACKEND_ID)?.runtime !== deferredRuntime) throw new Error("ACPX runtime service lost registry ownership during activation");
109
116
  return publishedRuntime;
110
117
  })();
111
118
  try {
@@ -126,22 +133,51 @@ function createDeferredRuntime(state, lifecycleRevision) {
126
133
  function createAcpxRuntimeService(params = {}) {
127
134
  const state = {
128
135
  ctx: null,
136
+ published: false,
129
137
  lifecycleRevision: 0,
130
138
  ownedRuntime: null,
131
139
  params,
132
- realRuntime: null,
133
140
  realService: null,
134
141
  startPromise: null,
135
142
  stopPromise: null
136
143
  };
137
144
  return {
138
145
  id: "acpx-runtime",
146
+ async getRuntime(ctx) {
147
+ if (state.stopPromise) await state.stopPromise;
148
+ if (!state.ctx) {
149
+ state.ctx = ctx;
150
+ state.lifecycleRevision += 1;
151
+ state.ownedRuntime = createDeferredRuntime(state, state.lifecycleRevision);
152
+ }
153
+ if (!state.ownedRuntime) throw new Error("ACPX runtime service lost its runtime owner");
154
+ return await startRealService(state, state.lifecycleRevision, state.ownedRuntime, state.published ? "gateway" : "inspection", false);
155
+ },
139
156
  async start(ctx) {
140
157
  if (process.env.OPENCLAW_SKIP_ACPX_RUNTIME === "1") {
141
158
  ctx.logger.info("skipping embedded acpx runtime backend (OPENCLAW_SKIP_ACPX_RUNTIME=1)");
142
159
  return;
143
160
  }
144
161
  if (state.stopPromise) await state.stopPromise;
162
+ if (state.ctx && state.ownedRuntime) {
163
+ const revision = state.lifecycleRevision;
164
+ const previous = getAcpRuntimeBackend(ACPX_BACKEND_ID)?.runtime;
165
+ const assertCurrent = () => {
166
+ const current = getAcpRuntimeBackend(ACPX_BACKEND_ID)?.runtime;
167
+ if (state.lifecycleRevision !== revision || !state.ctx || current !== previous && current !== state.ownedRuntime) throw new Error("ACPX runtime service lost promotion ownership");
168
+ };
169
+ await state.startPromise;
170
+ assertCurrent();
171
+ await state.realService?.promote(ctx, assertCurrent);
172
+ assertCurrent();
173
+ state.published = true;
174
+ registerAcpRuntimeBackend({
175
+ id: ACPX_BACKEND_ID,
176
+ runtime: state.ownedRuntime
177
+ });
178
+ return;
179
+ }
180
+ state.published = true;
145
181
  state.lifecycleRevision += 1;
146
182
  const lifecycleRevision = state.lifecycleRevision;
147
183
  state.ctx = ctx;
@@ -157,6 +193,7 @@ function createAcpxRuntimeService(params = {}) {
157
193
  if (state.stopPromise) return await state.stopPromise;
158
194
  state.lifecycleRevision += 1;
159
195
  state.ctx = null;
196
+ state.published = false;
160
197
  const ownedRuntime = state.ownedRuntime;
161
198
  unregisterOwnedRuntime(ownedRuntime);
162
199
  const startPromise = state.startPromise;
@@ -167,7 +204,6 @@ function createAcpxRuntimeService(params = {}) {
167
204
  } finally {
168
205
  unregisterOwnedRuntime(ownedRuntime);
169
206
  state.ownedRuntime = null;
170
- state.realRuntime = null;
171
207
  state.realService = null;
172
208
  state.startPromise = null;
173
209
  }
@@ -181,4 +217,4 @@ function createAcpxRuntimeService(params = {}) {
181
217
  };
182
218
  }
183
219
  //#endregion
184
- export { createLazyAcpRuntimeProxy as n, createAcpxRuntimeService as t };
220
+ export { createAcpxRuntimeService as t };