@openclaw/acpx 2026.9.4 → 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,12 @@ 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
+ },
31
+ async shutdown() {
32
+ await (await resolveRuntime()).shutdown();
33
+ },
28
34
  async ensureSession(input) {
29
35
  return await (await resolveRuntime()).ensureSession(input);
30
36
  },
@@ -43,6 +49,9 @@ function createLazyAcpRuntimeProxy(resolveRuntime) {
43
49
  async setMode(input) {
44
50
  await (await resolveRuntime()).setMode(input);
45
51
  },
52
+ async setModel(input) {
53
+ await (await resolveRuntime()).setModel(input);
54
+ },
46
55
  async setConfigOption(input) {
47
56
  return await (await resolveRuntime()).setConfigOption(input);
48
57
  },
@@ -67,13 +76,12 @@ function createLazyAcpRuntimeProxy(resolveRuntime) {
67
76
  * immediately, then imports the heavier service only when a session needs it.
68
77
  */
69
78
  const ACPX_BACKEND_ID = "acpx";
70
- const loadServiceModule = createLazyRuntimeModule(() => import("./service-BAf6nuci.js").then((n) => n.t));
79
+ const loadServiceModule = createLazyRuntimeModule(() => import("./service-DMae5pPH.mjs"));
71
80
  function unregisterOwnedRuntime(runtime) {
72
81
  if (runtime && getAcpRuntimeBackend(ACPX_BACKEND_ID)?.runtime === runtime) unregisterAcpRuntimeBackend(ACPX_BACKEND_ID);
73
82
  }
74
- async function startRealService(state, lifecycleRevision, deferredRuntime) {
83
+ async function startRealService(state, lifecycleRevision, deferredRuntime, purpose = "gateway", probeAtStartup = purpose === "gateway") {
75
84
  if (state.lifecycleRevision !== lifecycleRevision || !state.ctx) throw new Error("ACPX runtime service is not started");
76
- if (state.realRuntime) return state.realRuntime;
77
85
  if (state.startPromise) return await state.startPromise;
78
86
  const ctx = state.ctx;
79
87
  state.startPromise = (async () => {
@@ -81,28 +89,30 @@ async function startRealService(state, lifecycleRevision, deferredRuntime) {
81
89
  const { createAcpxRuntimeService: createAcpxRuntimeServiceLocal } = await loadServiceModule();
82
90
  const service = createAcpxRuntimeServiceLocal({
83
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
+ },
84
97
  backendLifecycle: {
85
98
  publish(backend) {
86
99
  if (state.lifecycleRevision !== lifecycleRevision || state.ctx !== ctx) throw new Error("ACPX runtime service stopped during activation");
87
- if (getAcpRuntimeBackend(ACPX_BACKEND_ID)?.runtime !== deferredRuntime) throw new Error("ACPX runtime service lost registry ownership during activation");
88
- 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({
89
102
  id: ACPX_BACKEND_ID,
90
- ...backend
103
+ ...backend,
104
+ runtime: deferredRuntime
91
105
  });
92
106
  publishedRuntime = backend.runtime;
93
- state.ownedRuntime = backend.runtime;
94
107
  },
95
- retract(runtime) {
96
- unregisterOwnedRuntime(runtime);
97
- }
108
+ retract() {}
98
109
  }
99
110
  });
100
111
  state.realService = service;
101
112
  await service.start(ctx);
102
113
  if (state.lifecycleRevision !== lifecycleRevision || state.ctx !== ctx) throw new Error("ACPX runtime service stopped during activation");
103
114
  if (!publishedRuntime) throw new Error("ACPX runtime service did not register an ACP backend");
104
- if (getAcpRuntimeBackend(ACPX_BACKEND_ID)?.runtime !== publishedRuntime) throw new Error("ACPX runtime service lost registry ownership during activation");
105
- state.realRuntime = publishedRuntime;
115
+ if (state.published && getAcpRuntimeBackend(ACPX_BACKEND_ID)?.runtime !== deferredRuntime) throw new Error("ACPX runtime service lost registry ownership during activation");
106
116
  return publishedRuntime;
107
117
  })();
108
118
  try {
@@ -123,22 +133,51 @@ function createDeferredRuntime(state, lifecycleRevision) {
123
133
  function createAcpxRuntimeService(params = {}) {
124
134
  const state = {
125
135
  ctx: null,
136
+ published: false,
126
137
  lifecycleRevision: 0,
127
138
  ownedRuntime: null,
128
139
  params,
129
- realRuntime: null,
130
140
  realService: null,
131
141
  startPromise: null,
132
142
  stopPromise: null
133
143
  };
134
144
  return {
135
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
+ },
136
156
  async start(ctx) {
137
157
  if (process.env.OPENCLAW_SKIP_ACPX_RUNTIME === "1") {
138
158
  ctx.logger.info("skipping embedded acpx runtime backend (OPENCLAW_SKIP_ACPX_RUNTIME=1)");
139
159
  return;
140
160
  }
141
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;
142
181
  state.lifecycleRevision += 1;
143
182
  const lifecycleRevision = state.lifecycleRevision;
144
183
  state.ctx = ctx;
@@ -154,6 +193,7 @@ function createAcpxRuntimeService(params = {}) {
154
193
  if (state.stopPromise) return await state.stopPromise;
155
194
  state.lifecycleRevision += 1;
156
195
  state.ctx = null;
196
+ state.published = false;
157
197
  const ownedRuntime = state.ownedRuntime;
158
198
  unregisterOwnedRuntime(ownedRuntime);
159
199
  const startPromise = state.startPromise;
@@ -164,7 +204,6 @@ function createAcpxRuntimeService(params = {}) {
164
204
  } finally {
165
205
  unregisterOwnedRuntime(ownedRuntime);
166
206
  state.ownedRuntime = null;
167
- state.realRuntime = null;
168
207
  state.realService = null;
169
208
  state.startPromise = null;
170
209
  }
@@ -178,4 +217,4 @@ function createAcpxRuntimeService(params = {}) {
178
217
  };
179
218
  }
180
219
  //#endregion
181
- export { createLazyAcpRuntimeProxy as n, createAcpxRuntimeService as t };
220
+ export { createAcpxRuntimeService as t };