@openclaw/acpx 2026.10.5 → 2026.10.7

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/README.md CHANGED
@@ -25,6 +25,10 @@ to regenerate wrappers written by an older plugin version.
25
25
  - MCP bridge helpers for OpenClaw tools and plugin tools.
26
26
  - Static runtime assets used by the ACP process bridge.
27
27
 
28
+ If the Gateway restarts before a one-shot session receives its first prompt, ACPX
29
+ reuses the initialized conversation when the agent supports loading or resuming
30
+ sessions. Completed one-shot runs still start a fresh conversation.
31
+
28
32
  ## Native agents in the model picker
29
33
 
30
34
  Install GitHub Copilot CLI, Kilo Code, OpenCode, Pi ACP, or Qwen Code and complete its login on the Gateway host,
@@ -53,7 +53,7 @@ function createLazyAcpRuntimeProxy(resolveRuntime) {
53
53
  * immediately, then imports the heavier service only when a session needs it.
54
54
  */
55
55
  const ACPX_BACKEND_ID = "acpx";
56
- const loadServiceModule = createLazyRuntimeModule(() => import("./service-De_oVTL3.mjs"));
56
+ const loadServiceModule = createLazyRuntimeModule(() => import("./service-42j3ASsm.mjs"));
57
57
  function unregisterOwnedRuntime(runtime) {
58
58
  if (runtime && getAcpRuntimeBackend(ACPX_BACKEND_ID)?.runtime === runtime) unregisterAcpRuntimeBackend(ACPX_BACKEND_ID);
59
59
  }
@@ -6,7 +6,7 @@ import { createRequire } from "node:module";
6
6
  import { AcpxRuntime, createAgentRegistry, createFileSessionStore, decodeAcpxRuntimeHandleState, isRequestedModelUnsupportedError } from "acpx/runtime";
7
7
  import { finiteSecondsToTimerSafeMilliseconds, parseStrictPositiveInteger } from "openclaw/plugin-sdk/number-runtime";
8
8
  import fs from "node:fs";
9
- import path, { resolve } from "node:path";
9
+ import path from "node:path";
10
10
  import { asOptionalObjectRecord, isRecord, normalizeLowercaseStringOrEmpty, normalizeOptionalLowercaseString, normalizeOptionalString, normalizeStringEntries } from "openclaw/plugin-sdk/string-coerce-runtime";
11
11
  import os, { availableParallelism } from "node:os";
12
12
  import { randomUUID } from "node:crypto";
@@ -1892,9 +1892,9 @@ var AcpxRuntime$1 = class {
1892
1892
  },
1893
1893
  list: () => this.agentRegistry.list()
1894
1894
  };
1895
- const createDelegate = (probeAgent = options.probeAgent) => new AcpxRuntime({
1895
+ const createBase = (overrides = {}) => new AcpxRuntime({
1896
1896
  ...options,
1897
- probeAgent,
1897
+ ...overrides,
1898
1898
  sessionStore: this.sessionStore,
1899
1899
  agentRegistry: this.scopedAgentRegistry,
1900
1900
  sessionPermissions: (context) => {
@@ -1933,11 +1933,14 @@ var AcpxRuntime$1 = class {
1933
1933
  onExit: options.processLifecycle?.onExit
1934
1934
  }
1935
1935
  }, testOptions);
1936
- this.delegate = createDelegate();
1937
- this.generationRegistry = new AcpxGenerationRegistry(this.sessionStore, this.delegate, createDelegate);
1936
+ this.delegate = createBase();
1937
+ this.generationRegistry = new AcpxGenerationRegistry(this.sessionStore, this.delegate, createBase);
1938
1938
  this.probe = new AcpxRuntimeProbe({
1939
1939
  getAgent: () => normalizeOptionalLowercaseString(options.getProbeAgent?.() ?? options.probeAgent) ?? "codex",
1940
- createRuntime: createDelegate,
1940
+ createRuntime: (probeAgent) => createBase({
1941
+ probeAgent,
1942
+ cwd: this.wrapperRoot ?? this.cwd
1943
+ }),
1941
1944
  assertRunning: () => this.generationRegistry.assertRunning(),
1942
1945
  runWithLease: (agent, run) => this.runWithLaunchLease({
1943
1946
  agent,
@@ -2008,23 +2011,32 @@ var AcpxRuntime$1 = class {
2008
2011
  resolveDelegateForOperationSnapshot(handle, snapshot) {
2009
2012
  return this.generationRegistry.resolveDelegate(snapshot.generation, snapshot.generation.nativeTools ?? resolveBridgeSession(handle)?.native === true);
2010
2013
  }
2011
- async readReusablePersistentSessionCommand(params) {
2012
- if (params.mode !== "persistent" || !params.command) return;
2013
- const existing = await this.sessionStore.load(params.sessionKey);
2014
- if (!existing || readRecordResetOnNextEnsure(existing)) return;
2015
- const recordCwd = readRecordCwd(existing);
2016
- if (!recordCwd || resolve(recordCwd) !== resolve(params.cwd?.trim() || this.cwd)) return;
2017
- const recordCommand = readRecordAgentCommand(existing);
2018
- if (!recordCommand) return;
2019
- const leaseIdentity = readAcpxProcessLeaseIdentity(recordCommand);
2020
- if (leaseIdentity && leaseIdentity.gatewayInstanceId !== this.gatewayInstanceId) return;
2021
- const stableRecordCommand = leaseIdentity ? withAcpxLeaseArgs({
2022
- command: params.command,
2023
- leaseId: leaseIdentity.leaseId,
2024
- gatewayInstanceId: leaseIdentity.gatewayInstanceId
2025
- }) : params.command;
2026
- if (!isDeepStrictEqual(splitCommandParts(recordCommand), splitCommandParts(stableRecordCommand))) return;
2027
- return !params.resumeSessionId || existing.acpSessionId === params.resumeSessionId ? recordCommand : void 0;
2014
+ async readReusableSession(input, command) {
2015
+ const { persistedHandle, sessionKey, resumeSessionId } = input;
2016
+ const oneShot = input.mode === "oneshot";
2017
+ const decoded = persistedHandle && decodeAcpxRuntimeHandleState(persistedHandle.runtimeSessionName);
2018
+ if (!command || oneShot && (resumeSessionId || persistedHandle?.backend !== "acpx" || !persistedHandle.acpxRecordId || decoded?.mode !== "oneshot" || decoded.name !== sessionKey || decoded.acpxRecordId !== persistedHandle.acpxRecordId || decoded.agent !== normalizeOptionalLowercaseString(input.agent))) return;
2019
+ const recordId = oneShot ? persistedHandle?.acpxRecordId : sessionKey;
2020
+ if (!recordId) return;
2021
+ const record = await this.sessionStore.load(recordId);
2022
+ if (!record || readRecordResetOnNextEnsure(record)) return;
2023
+ if (oneShot && (record.acpxRecordId !== recordId || readSessionRecordName(record) !== 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;
2024
+ const recordCwd = readRecordCwd(record);
2025
+ const recordCommand = readRecordAgentCommand(record);
2026
+ if (!recordCwd || !recordCommand || path.resolve(recordCwd) !== path.resolve(input.cwd?.trim() || this.cwd) || !oneShot && resumeSessionId && record.acpSessionId !== resumeSessionId) return;
2027
+ const lease = readAcpxProcessLeaseIdentity(recordCommand);
2028
+ const ownLease = !lease || lease.gatewayInstanceId === this.gatewayInstanceId;
2029
+ if (!oneShot && !ownLease) return;
2030
+ const expectedCommand = lease ? withAcpxLeaseArgs({
2031
+ command,
2032
+ leaseId: lease.leaseId,
2033
+ gatewayInstanceId: lease.gatewayInstanceId
2034
+ }) : command;
2035
+ if (!isDeepStrictEqual(splitCommandParts(recordCommand), splitCommandParts(expectedCommand))) return;
2036
+ return {
2037
+ reusableCommand: ownLease ? recordCommand : void 0,
2038
+ resumeSessionId: oneShot ? record.acpSessionId : void 0
2039
+ };
2028
2040
  }
2029
2041
  async runWithLaunchLease(params) {
2030
2042
  if (!params.command || !this.wrapperRoot || !this.gatewayInstanceId || !this.processLeaseStore || !isOpenClawLeaseAwareAcpxProcessCommand({
@@ -2183,26 +2195,28 @@ var AcpxRuntime$1 = class {
2183
2195
  model: claudeModelOverride
2184
2196
  } : effectiveInput;
2185
2197
  const stableLaunchCommand = codexModelOverride && command ? appendCodexAcpConfigOverrides(command, codexModelOverride) : command;
2186
- const reusableCommand = await this.readReusablePersistentSessionCommand({
2187
- sessionKey: input.sessionKey,
2188
- mode: input.mode,
2189
- cwd: input.cwd,
2190
- command: stableLaunchCommand,
2191
- resumeSessionId: input.resumeSessionId
2192
- });
2198
+ const restoration = await this.readReusableSession(input, stableLaunchCommand);
2199
+ this.generationRegistry.assertCurrentGeneration(generation);
2200
+ const restoredInput = restoration?.resumeSessionId ? {
2201
+ ...ensureInput,
2202
+ resumeSessionId: restoration.resumeSessionId
2203
+ } : ensureInput;
2193
2204
  return {
2194
2205
  ...await this.runWithLaunchLease({
2195
- agent: ensureInput.agent,
2206
+ agent: restoredInput.agent,
2196
2207
  sessionKey: ensureInput.sessionKey,
2197
2208
  command: stableLaunchCommand,
2198
- reusableCommand,
2209
+ reusableCommand: restoration?.reusableCommand,
2199
2210
  run: () => this.withCodexWrapperDiagnostics({
2200
2211
  command: stableLaunchCommand,
2201
2212
  fallbackCode: "ACP_SESSION_INIT_FAILED",
2202
- run: () => codexModelOverride ? delegate.ensureSession(withAcpxSessionOptions(ensureInput)) : ensureSessionWithModelRef((request) => {
2213
+ run: () => {
2203
2214
  this.generationRegistry.assertCurrentGeneration(generation);
2204
- return delegate.ensureSession(request);
2205
- }, ensureInput)
2215
+ return codexModelOverride ? delegate.ensureSession(withAcpxSessionOptions(restoredInput)) : ensureSessionWithModelRef((request) => {
2216
+ this.generationRegistry.assertCurrentGeneration(generation);
2217
+ return delegate.ensureSession(request);
2218
+ }, restoredInput);
2219
+ }
2206
2220
  })
2207
2221
  }),
2208
2222
  ...logicalTarget,
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { t as createAcpxRuntimeService } from "./.setup/register.runtime-DfAHoa8o.mjs";
1
+ import { t as createAcpxRuntimeService } from "./.setup/register.runtime-Cm9fd3R2.mjs";
2
2
  import { g as AcpxNativeAgentsSchema, h as ACPX_NATIVE_AGENT_IDS, t as resolveAcpxPluginConfig } from "./.setup/config-D0ATuiVJ.mjs";
3
3
  import { a as PI_SESSIONS_CAPABILITY, c as PI_SESSION_READ_COMMAND, l as PI_TERMINAL_RESUME_COMMAND, o as PI_SESSIONS_LIST_COMMAND, r as piSessionStoreAvailable, s as PI_SESSION_ID_PATTERN } from "./.setup/pi-session-paths-CIvyk6KB.mjs";
4
4
  import { createAgentRegistry } from "acpx/agent-registry";
@@ -1 +1 @@
1
- export { t as createAcpxRuntimeService } from "./.setup/register.runtime-DfAHoa8o.mjs";
1
+ export { t as createAcpxRuntimeService } from "./.setup/register.runtime-Cm9fd3R2.mjs";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openclaw/acpx",
3
- "version": "2026.10.5",
3
+ "version": "2026.10.7",
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.85.1",
12
12
  "@agentclientprotocol/codex-acp": "2.1.1",
13
- "@openclaw/fs-safe": "0.25.0",
13
+ "@openclaw/fs-safe": "0.26.0",
14
14
  "acpx": "0.19.4",
15
15
  "smol-toml": "1.9.0",
16
16
  "zod": "4.6.5"
@@ -45,10 +45,10 @@
45
45
  ]
46
46
  },
47
47
  "compat": {
48
- "pluginApi": ">=2026.10.5"
48
+ "pluginApi": ">=2026.10.7"
49
49
  },
50
50
  "build": {
51
- "openclawVersion": "2026.10.5"
51
+ "openclawVersion": "2026.10.7"
52
52
  },
53
53
  "release": {
54
54
  "publishToClawHub": true,
@@ -68,7 +68,7 @@
68
68
  "skills/**"
69
69
  ],
70
70
  "peerDependencies": {
71
- "openclaw": ">=2026.10.5"
71
+ "openclaw": ">=2026.10.7"
72
72
  },
73
73
  "peerDependenciesMeta": {
74
74
  "openclaw": {