@openclaw/acpx 2026.7.2-beta.1 → 2026.7.2-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/index.js CHANGED
@@ -1,10 +1,11 @@
1
- import { t as createAcpxRuntimeService } from "./register.runtime-DBqbPx5P.js";
1
+ import { t as createAcpxRuntimeService } from "./register.runtime-BrVpU-xc.js";
2
2
  import "./config-schema-lrk5nlcV.js";
3
3
  import { tryDispatchAcpReplyHook } from "openclaw/plugin-sdk/acp-runtime-backend";
4
4
  import { finiteSecondsToTimerSafeMilliseconds } from "openclaw/plugin-sdk/number-runtime";
5
5
  import process$1 from "node:process";
6
- import { decodeNodePtyResumeParams, resolveExecutableFromPathEnv, runNodePtyCommand } from "openclaw/plugin-sdk/node-host";
6
+ import { decodeNodePtyResumeParams, resolveNodeHostExecutable, runNodePtyCommand } from "openclaw/plugin-sdk/node-host";
7
7
  import { isRecord } from "openclaw/plugin-sdk/string-coerce-runtime";
8
+ import { truncateUtf16Safe } from "openclaw/plugin-sdk/text-utility-runtime";
8
9
  import { createReadStream, readFileSync, statSync } from "node:fs";
9
10
  import fs$1 from "node:fs/promises";
10
11
  import path from "node:path";
@@ -389,7 +390,7 @@ async function readPiSessionById(threadId, env) {
389
390
  const LOCAL_HOST_ID$1 = "gateway";
390
391
  const DEFAULT_PAGE_LIMIT = 20;
391
392
  const MAX_PAGE_LIMIT$1 = 100;
392
- const MAX_SEARCH_LENGTH$1 = 500;
393
+ const MAX_SEARCH_LENGTH = 500;
393
394
  const MAX_CURSOR_LENGTH$1 = 128;
394
395
  const MAX_TRANSCRIPT_ITEM_BYTES = 512 * 1024;
395
396
  const MAX_TRANSCRIPT_PAGE_BYTES = 20 * 1024 * 1024;
@@ -483,7 +484,7 @@ function parseListParams(value) {
483
484
  "cursor"
484
485
  ].includes(key));
485
486
  if (unknown) throw new Error(`unknown Pi session list parameter: ${unknown}`);
486
- const searchTerm = optionalPiString(value.searchTerm, MAX_SEARCH_LENGTH$1);
487
+ const searchTerm = optionalPiString(value.searchTerm, MAX_SEARCH_LENGTH);
487
488
  if (value.searchTerm !== void 0 && !searchTerm) throw new Error("searchTerm is invalid");
488
489
  const cursor = optionalPiString(value.cursor, MAX_CURSOR_LENGTH$1);
489
490
  if (value.cursor !== void 0 && !cursor) throw new Error("cursor is invalid");
@@ -534,7 +535,7 @@ function isoTimestamp(message, entry) {
534
535
  function jsonText(value, maxLength = 2e4) {
535
536
  try {
536
537
  const text = JSON.stringify(value);
537
- return text.length > maxLength ? `${text.slice(0, maxLength)}…` : text;
538
+ return text.length > maxLength ? `${truncateUtf16Safe(text, maxLength)}…` : text;
538
539
  } catch {
539
540
  return;
540
541
  }
@@ -693,7 +694,6 @@ const LOCAL_HOST_ID = "gateway";
693
694
  const MAX_PAGE_LIMIT = 100;
694
695
  const MAX_HOSTS = 100;
695
696
  const MAX_CURSOR_LENGTH = 128;
696
- const MAX_SEARCH_LENGTH = 500;
697
697
  const NODE_TIMEOUT_MS = 2e4;
698
698
  const SESSION_ID_PATTERN = /^(?!-)[A-Za-z0-9._:-]{1,256}$/u;
699
699
  const TRANSCRIPT_ITEM_TYPES = /* @__PURE__ */ new Set([
@@ -762,15 +762,23 @@ function createPiSessionNodeHostCommands() {
762
762
  isAvailable: ({ config, env }) => storeAvailable({
763
763
  config,
764
764
  env
765
- }) && Boolean(resolveExecutableFromPathEnv("pi", env.PATH ?? "")),
765
+ }) && Boolean(resolveNodeHostExecutable("pi", {
766
+ env,
767
+ pathEnv: env.PATH ?? env.Path ?? "",
768
+ strategy: "direct"
769
+ })),
766
770
  handle: async (paramsJSON, io) => {
767
771
  if (!io) throw new Error("Pi terminal command requires duplex transport");
768
772
  const params = decodeNodePtyResumeParams(paramsJSON, validatePiThreadId);
769
773
  const record = await requireLocalPiSession(params.threadId);
770
- const file = resolveExecutableFromPathEnv("pi", process$1.env.PATH ?? "");
771
- if (!file) throw new Error("Pi CLI is unavailable");
774
+ const resolution = resolveNodeHostExecutable("pi", {
775
+ env: process$1.env,
776
+ pathEnv: process$1.env.PATH ?? process$1.env.Path ?? "",
777
+ strategy: "direct"
778
+ });
779
+ if (!resolution) throw new Error("Pi CLI is unavailable");
772
780
  return JSON.stringify(await runNodePtyCommand({
773
- file,
781
+ file: resolution.executable,
774
782
  args: ["--session", params.threadId],
775
783
  cwd: record.cwd,
776
784
  cols: params.cols,
@@ -828,7 +836,7 @@ async function listPiNodeHost(runtime, query, node) {
828
836
  command: PI_SESSIONS_LIST_COMMAND,
829
837
  params: {
830
838
  ...query.limitPerHost ? { limit: query.limitPerHost } : {},
831
- ...query.search?.trim() ? { searchTerm: query.search.trim().slice(0, MAX_SEARCH_LENGTH) } : {},
839
+ ...query.search ? { searchTerm: query.search } : {},
832
840
  ...query.cursors?.[hostId] ? { cursor: query.cursors[hostId] } : {}
833
841
  },
834
842
  timeoutMs: NODE_TIMEOUT_MS,
@@ -874,7 +882,6 @@ function parseNodeTranscriptPage(value, threadId) {
874
882
  }
875
883
  async function listPiHosts(runtime, query) {
876
884
  const requested = query.hostIds ? new Set(query.hostIds) : void 0;
877
- const searchTerm = query.search?.trim().slice(0, MAX_SEARCH_LENGTH) || void 0;
878
885
  const hosts = [];
879
886
  if ((!requested || requested.has(LOCAL_HOST_ID)) && piSessionStoreAvailable(process$1.env)) try {
880
887
  hosts.push({
@@ -884,9 +891,13 @@ async function listPiHosts(runtime, query) {
884
891
  connected: true,
885
892
  ...await listLocalPiSessionPage({
886
893
  limit: query.limitPerHost,
887
- ...searchTerm ? { searchTerm } : {},
894
+ ...query.search ? { searchTerm: query.search } : {},
888
895
  cursor: query.cursors?.[LOCAL_HOST_ID]
889
- }).then((page) => setTerminalCapability(page, resolveExecutableFromPathEnv("pi", process$1.env.PATH ?? "") !== void 0))
896
+ }).then((page) => setTerminalCapability(page, resolveNodeHostExecutable("pi", {
897
+ env: process$1.env,
898
+ pathEnv: process$1.env.PATH ?? "",
899
+ strategy: "fallback"
900
+ }) !== void 0))
890
901
  });
891
902
  } catch {
892
903
  hosts.push({
@@ -937,16 +948,21 @@ async function openPiTerminal(params) {
937
948
  const title = `pi --session ${params.threadId.slice(0, 12)}…`;
938
949
  if (params.hostId === LOCAL_HOST_ID) {
939
950
  const record = await requireLocalPiSession(params.threadId);
940
- const executable = resolveExecutableFromPathEnv("pi", process$1.env.PATH ?? "");
941
- if (!executable) throw new Error("Pi CLI is unavailable");
951
+ const resolution = resolveNodeHostExecutable("pi", {
952
+ env: process$1.env,
953
+ pathEnv: process$1.env.PATH ?? "",
954
+ strategy: "fallback"
955
+ });
956
+ if (!resolution) throw new Error("Pi CLI is unavailable");
942
957
  return {
943
958
  kind: "local",
944
959
  argv: [
945
- executable,
960
+ resolution.executable,
946
961
  "--session",
947
962
  params.threadId
948
963
  ],
949
964
  ...record.cwd ? { cwd: record.cwd } : {},
965
+ ...resolution.pathEnv ? { pathEnv: resolution.pathEnv } : {},
950
966
  title
951
967
  };
952
968
  }
@@ -7,6 +7,12 @@ import fs from "node:fs";
7
7
  import path from "node:path";
8
8
  import { runExec } from "openclaw/plugin-sdk/process-runtime";
9
9
  import { fileURLToPath } from "node:url";
10
+ //#region extensions/acpx/src/codex-adapter.ts
11
+ const CODEX_ACP_PACKAGE = "@agentclientprotocol/codex-acp";
12
+ const CODEX_ACP_BIN = "codex-acp";
13
+ const LEGACY_CODEX_ACP_PACKAGE = "@zed-industries/codex-acp";
14
+ const OPENCLAW_CODEX_CONFIG_ARG = "--openclaw-codex-config";
15
+ //#endregion
10
16
  //#region extensions/acpx/src/command-line.ts
11
17
  /**
12
18
  * Small shell-command helpers for ACPX-launched processes. Splitting supports
@@ -248,8 +254,10 @@ function resolveAcpxPluginConfig(params) {
248
254
  const requireFromHere = createRequire(import.meta.url);
249
255
  const GENERATED_WRAPPER_BASENAMES = /* @__PURE__ */ new Set(["codex-acp-wrapper.mjs", "claude-agent-acp-wrapper.mjs"]);
250
256
  const OPENCLAW_PLUGIN_DEPS_MARKER = "/plugin-runtime-deps/";
257
+ const ACPX_PROCESS_LIST_TIMEOUT_MS = 2e3;
251
258
  const OWNED_ACP_PACKAGE_NAMES = [
252
- "@zed-industries/codex-acp",
259
+ CODEX_ACP_PACKAGE,
260
+ LEGACY_CODEX_ACP_PACKAGE,
253
261
  "@zed-industries/codex-acp-darwin-arm64",
254
262
  "@zed-industries/codex-acp-darwin-x64",
255
263
  "@zed-industries/codex-acp-linux-arm64",
@@ -259,7 +267,20 @@ const OWNED_ACP_PACKAGE_NAMES = [
259
267
  "@agentclientprotocol/claude-agent-acp",
260
268
  "acpx"
261
269
  ];
262
- const ACP_PACKAGE_MARKERS = [...OWNED_ACP_PACKAGE_NAMES.map((packageName) => `/node_modules/${packageName}/`), "/acpx/dist/"];
270
+ const PLUGIN_DEPS_CODEX_PACKAGE_NAMES = [
271
+ "@openai/codex",
272
+ "@openai/codex-darwin-arm64",
273
+ "@openai/codex-darwin-x64",
274
+ "@openai/codex-linux-arm64",
275
+ "@openai/codex-linux-x64",
276
+ "@openai/codex-win32-arm64",
277
+ "@openai/codex-win32-x64"
278
+ ];
279
+ const ACP_PACKAGE_MARKERS = [
280
+ ...OWNED_ACP_PACKAGE_NAMES.map((packageName) => `/node_modules/${packageName}/`),
281
+ ...PLUGIN_DEPS_CODEX_PACKAGE_NAMES.map((packageName) => `/node_modules/${packageName}/`),
282
+ "/acpx/dist/"
283
+ ];
263
284
  function normalizePathLike(value) {
264
285
  return value.replaceAll("\\", "/");
265
286
  }
@@ -354,7 +375,8 @@ async function listPlatformProcesses() {
354
375
  if (process.platform === "win32") return [];
355
376
  const { stdout } = await runExec("ps", ["-axo", "pid=,ppid=,command="], {
356
377
  logOutput: false,
357
- maxBuffer: 8 * 1024 * 1024
378
+ maxBuffer: 8 * 1024 * 1024,
379
+ timeoutMs: ACPX_PROCESS_LIST_TIMEOUT_MS
358
380
  });
359
381
  return parseProcessList(stdout);
360
382
  }
@@ -488,4 +510,4 @@ async function reapStaleOpenClawOwnedAcpxOrphans(params) {
488
510
  };
489
511
  }
490
512
  //#endregion
491
- export { resolveAcpxPluginRoot as a, splitCommandParts as c, resolveAcpxPluginConfig as i, isOpenClawLeaseAwareAcpxProcessCommand as n, toAcpMcpServers as o, reapStaleOpenClawOwnedAcpxOrphans as r, quoteCommandPart as s, cleanupOpenClawOwnedAcpxProcessTree as t };
513
+ export { resolveAcpxPluginRoot as a, splitCommandParts as c, LEGACY_CODEX_ACP_PACKAGE as d, OPENCLAW_CODEX_CONFIG_ARG as f, resolveAcpxPluginConfig as i, CODEX_ACP_BIN as l, isOpenClawLeaseAwareAcpxProcessCommand as n, toAcpMcpServers as o, reapStaleOpenClawOwnedAcpxOrphans as r, quoteCommandPart as s, cleanupOpenClawOwnedAcpxProcessTree as t, CODEX_ACP_PACKAGE as u };
@@ -200,7 +200,7 @@ function createLazyAcpRuntimeProxy(resolveRuntime) {
200
200
  * immediately, then imports the heavier service only when a session needs it.
201
201
  */
202
202
  const ACPX_BACKEND_ID = "acpx";
203
- const loadServiceModule = createLazyRuntimeModule(() => import("./service-Dm8hpy-C.js"));
203
+ const loadServiceModule = createLazyRuntimeModule(() => import("./service-D6LQXIcJ.js"));
204
204
  async function startRealService(state) {
205
205
  if (state.realRuntime) return state.realRuntime;
206
206
  if (!state.ctx) throw new Error("ACPX runtime service is not started");
@@ -1,2 +1,2 @@
1
- import { t as createAcpxRuntimeService } from "./register.runtime-DBqbPx5P.js";
1
+ import { t as createAcpxRuntimeService } from "./register.runtime-BrVpU-xc.js";
2
2
  export { createAcpxRuntimeService };
@@ -1,19 +1,20 @@
1
1
  import { i as createAcpxProcessLeaseId, o as hashAcpxProcessCommand, u as withAcpxLeaseEnvironment } from "./process-lease-DiKkFj6F.js";
2
2
  import { AcpRuntimeError } from "./runtime-api.js";
3
- import { c as splitCommandParts, n as isOpenClawLeaseAwareAcpxProcessCommand, t as cleanupOpenClawOwnedAcpxProcessTree } from "./process-reaper-B29BzBk4.js";
3
+ import { c as splitCommandParts, f as OPENCLAW_CODEX_CONFIG_ARG, n as isOpenClawLeaseAwareAcpxProcessCommand, t as cleanupOpenClawOwnedAcpxProcessTree, u as CODEX_ACP_PACKAGE } from "./process-reaper-CoGRyMJ_.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";
6
7
  import fs from "node:fs/promises";
7
8
  import path, { resolve } from "node:path";
8
9
  import { AsyncLocalStorage } from "node:async_hooks";
9
10
  import { ACPX_BACKEND_ID, AcpxRuntime as AcpxRuntime$1, createAcpRuntime, createAgentRegistry, createFileSessionStore, decodeAcpxRuntimeHandleState, encodeAcpxRuntimeHandleState, isRequestedModelUnsupportedError } from "acpx/runtime";
10
11
  import { redactSensitiveText } from "openclaw/plugin-sdk/security-runtime";
11
- import { sliceUtf16Safe } from "openclaw/plugin-sdk/text-utility-runtime";
12
12
  //#region extensions/acpx/src/runtime.ts
13
13
  /**
14
14
  * OpenClaw ACPX runtime adapter. It wraps the upstream acpx runtime with
15
15
  * OpenClaw session metadata, lease tracking, model scoping, and cleanup policy.
16
16
  */
17
+ const ACPX_PLUGIN_TOOLS_MCP_SERVER_NAME = "openclaw-plugin-tools";
17
18
  const ACPX_OPENCLAW_TOOLS_MCP_SERVER_NAME = "openclaw-tools";
18
19
  const OPENCLAW_TOOLS_MCP_AGENT_SESSION_KEY_ENV = "OPENCLAW_TOOLS_MCP_AGENT_SESSION_KEY";
19
20
  function withOpenClawManagedTurnTimeout(input) {
@@ -165,12 +166,6 @@ const OPENCLAW_BRIDGE_SUBCOMMAND = "acp";
165
166
  const CODEX_ACP_AGENT_ID = "codex";
166
167
  const CODEX_ACP_OPENCLAW_PREFIX = "openai/";
167
168
  const CLAUDE_ACP_OPENCLAW_PREFIX = "anthropic/";
168
- const CODEX_ACP_REASONING_EFFORTS = /* @__PURE__ */ new Set([
169
- "low",
170
- "medium",
171
- "high",
172
- "xhigh"
173
- ]);
174
169
  const CODEX_ACP_THINKING_ALIASES = /* @__PURE__ */ new Map([
175
170
  ["off", void 0],
176
171
  ["minimal", "low"],
@@ -256,7 +251,7 @@ function isOpenClawBridgeCommand(command) {
256
251
  }
257
252
  function isCodexAcpCommand(command) {
258
253
  return isAcpCommand(command, {
259
- packageName: "@zed-industries/codex-acp",
254
+ packageName: CODEX_ACP_PACKAGE,
260
255
  executableName: "codex-acp"
261
256
  });
262
257
  }
@@ -285,27 +280,50 @@ function normalizeCodexAcpReasoningEffort(rawThinking) {
285
280
  if (!CODEX_ACP_THINKING_ALIASES.has(normalized)) failUnsupportedCodexAcpThinking(rawThinking ?? "");
286
281
  return CODEX_ACP_THINKING_ALIASES.get(normalized);
287
282
  }
288
- function normalizeCodexAcpModelOverride(rawModel, rawThinking) {
283
+ function isCodexAcpReasoningEffortAlias(value) {
284
+ const normalized = value?.trim().toLowerCase();
285
+ return Boolean(normalized && CODEX_ACP_THINKING_ALIASES.has(normalized));
286
+ }
287
+ function classifyCodexAcpModelRequest(rawModel, rawThinking) {
289
288
  const raw = rawModel?.trim();
290
289
  const thinkingReasoningEffort = normalizeCodexAcpReasoningEffort(rawThinking);
291
- if (!raw) return thinkingReasoningEffort ? { reasoningEffort: thinkingReasoningEffort } : void 0;
290
+ const thinkingOnlyOverride = thinkingReasoningEffort ? { reasoningEffort: thinkingReasoningEffort } : void 0;
291
+ if (!raw) return {
292
+ kind: "override",
293
+ override: thinkingOnlyOverride ?? {}
294
+ };
292
295
  let value = raw;
293
- if (value.toLowerCase().startsWith(CODEX_ACP_OPENCLAW_PREFIX)) value = value.slice(7);
294
- const parts = value.split("/");
295
- if (parts.length > 2) failUnsupportedCodexAcpModel(raw, `Codex ACP model "${raw}" is not supported. Use openai/<model> or <model>/<reasoning-effort>.`);
296
- const model = (parts[0] ?? "").trim();
297
- const modelReasoningEffort = normalizeCodexAcpReasoningEffort(parts[1]);
298
- if (!model) failUnsupportedCodexAcpModel(raw, `Codex ACP model "${raw}" is not supported. Use openai/<model> or <model>/<reasoning-effort>.`);
296
+ let hadOpenAiQualifier = false;
297
+ if (value.toLowerCase().startsWith(CODEX_ACP_OPENCLAW_PREFIX)) {
298
+ value = value.slice(7);
299
+ hadOpenAiQualifier = true;
300
+ }
301
+ let model = value.trim();
302
+ let modelReasoningEffort;
303
+ const slashIndex = value.lastIndexOf("/");
304
+ if (slashIndex >= 0 && isCodexAcpReasoningEffortAlias(value.slice(slashIndex + 1))) {
305
+ modelReasoningEffort = normalizeCodexAcpReasoningEffort(value.slice(slashIndex + 1));
306
+ model = value.slice(0, slashIndex).trim();
307
+ }
308
+ if (hadOpenAiQualifier && (!model || model.includes("/"))) failUnsupportedCodexAcpModel(raw, `Codex ACP model "${raw}" is not supported. Use openai/<model> or <model>/<reasoning-effort>.`);
309
+ if (!model || model.includes("/")) return thinkingOnlyOverride ? {
310
+ kind: "unsupported",
311
+ thinkingOverride: thinkingOnlyOverride
312
+ } : { kind: "unsupported" };
299
313
  const reasoningEffort = thinkingReasoningEffort ?? modelReasoningEffort;
300
- if (reasoningEffort && !CODEX_ACP_REASONING_EFFORTS.has(reasoningEffort)) failUnsupportedCodexAcpThinking(reasoningEffort);
301
314
  return {
302
- model,
303
- ...reasoningEffort ? { reasoningEffort } : {}
315
+ kind: "override",
316
+ override: {
317
+ model,
318
+ ...reasoningEffort ? { reasoningEffort } : {}
319
+ }
304
320
  };
305
321
  }
306
- function codexAcpSessionModelId(override) {
307
- if (!override.model) return "";
308
- return override.reasoningEffort ? `${override.model}/${override.reasoningEffort}` : override.model;
322
+ function withCodexSessionModel(input, override) {
323
+ const next = { ...input };
324
+ if (override?.model) next.model = override.model;
325
+ else delete next.model;
326
+ return next;
309
327
  }
310
328
  function normalizeClaudeAcpModelOverride(rawModel) {
311
329
  const raw = rawModel?.trim();
@@ -320,8 +338,9 @@ function withAcpxSessionOptions(input) {
320
338
  ...existingOptions,
321
339
  model
322
340
  } : existingOptions;
341
+ const { modelExplicit: _modelExplicit, ...rest } = input;
323
342
  return {
324
- ...input,
343
+ ...rest,
325
344
  ...sessionOptions ? { sessionOptions } : {}
326
345
  };
327
346
  }
@@ -344,10 +363,12 @@ function quoteShellArg(value) {
344
363
  return `'${value.replace(/'/g, "'\\''")}'`;
345
364
  }
346
365
  function appendCodexAcpConfigOverrides(command, override) {
347
- const configArgs = override.model ? [`model=${override.model}`] : [];
348
- if (override.reasoningEffort) configArgs.push(`model_reasoning_effort=${override.reasoningEffort}`);
349
- if (configArgs.length === 0) return command;
350
- return `${command} ${configArgs.map((arg) => `-c ${quoteShellArg(arg)}`).join(" ")}`;
366
+ const config = {
367
+ ...override.model ? { model: override.model } : {},
368
+ ...override.reasoningEffort ? { model_reasoning_effort: override.reasoningEffort } : {}
369
+ };
370
+ if (Object.keys(config).length === 0) return command;
371
+ return `${command} ${OPENCLAW_CODEX_CONFIG_ARG} ${quoteShellArg(JSON.stringify(config))}`;
351
372
  }
352
373
  function createModelScopedAgentRegistry(params) {
353
374
  return {
@@ -375,12 +396,14 @@ function shouldUseDistinctBridgeDelegate(options) {
375
396
  const { mcpServers } = options;
376
397
  return Array.isArray(mcpServers) && mcpServers.length > 0;
377
398
  }
378
- function withOpenClawToolsMcpSessionEnv(params) {
399
+ function withManagedToolsMcpSessionEnv(params) {
379
400
  const sessionKey = params.sessionKey.trim();
380
- if (!params.enabled || !sessionKey || !params.mcpServers?.length) return params.mcpServers;
401
+ if (!params.pluginToolsEnabled && !params.openclawToolsEnabled || !sessionKey || !params.mcpServers?.length) return params.mcpServers;
381
402
  let changed = false;
382
403
  const nextServers = params.mcpServers.map((server) => {
383
- if (server.name !== ACPX_OPENCLAW_TOOLS_MCP_SERVER_NAME || !("command" in server)) return server;
404
+ const isManagedPluginTools = params.pluginToolsEnabled && server.name === ACPX_PLUGIN_TOOLS_MCP_SERVER_NAME;
405
+ const isManagedOpenClawTools = params.openclawToolsEnabled && server.name === ACPX_OPENCLAW_TOOLS_MCP_SERVER_NAME;
406
+ if (!isManagedPluginTools && !isManagedOpenClawTools || !("command" in server)) return server;
384
407
  changed = true;
385
408
  const env = [...server.env.filter((entry) => entry.name !== OPENCLAW_TOOLS_MCP_AGENT_SESSION_KEY_ENV), {
386
409
  name: OPENCLAW_TOOLS_MCP_AGENT_SESSION_KEY_ENV,
@@ -397,14 +420,16 @@ function withOpenClawToolsMcpSessionEnv(params) {
397
420
  var AcpxRuntime = class {
398
421
  constructor(options, testOptions) {
399
422
  this.codexAcpModelOverrideScope = new AsyncLocalStorage();
400
- this.openclawToolsSessionDelegates = /* @__PURE__ */ new Map();
423
+ this.managedToolsSessionDelegates = /* @__PURE__ */ new Map();
401
424
  this.launchLeaseScope = new AsyncLocalStorage();
402
425
  const { openclawProcessCleanup, ...delegateTestOptions } = testOptions ?? {};
403
426
  this.processCleanupDeps = openclawProcessCleanup;
404
427
  this.wrapperRoot = options.openclawWrapperRoot;
405
428
  this.gatewayInstanceId = options.openclawGatewayInstanceId;
406
429
  this.processLeaseStore = options.openclawProcessLeaseStore;
430
+ this.pluginToolsMcpBridgeEnabled = options.pluginToolsMcpBridgeEnabled === true;
407
431
  this.openclawToolsMcpBridgeEnabled = options.openclawToolsMcpBridgeEnabled === true;
432
+ this.managedToolsMcpBridgeEnabled = this.pluginToolsMcpBridgeEnabled || this.openclawToolsMcpBridgeEnabled;
408
433
  this.cwd = options.cwd;
409
434
  this.sessionStore = createResetAwareSessionStore(options.sessionStore, {
410
435
  gatewayInstanceId: this.gatewayInstanceId,
@@ -433,35 +458,36 @@ var AcpxRuntime = class {
433
458
  agentName: normalizeAgentName(options.probeAgent) ?? "codex",
434
459
  agentRegistry: this.agentRegistry
435
460
  });
436
- const useBridgeSafeProbe = this.openclawToolsMcpBridgeEnabled || shouldUseBridgeSafeDelegateForCommand(probeCommand);
461
+ const useBridgeSafeProbe = this.managedToolsMcpBridgeEnabled || shouldUseBridgeSafeDelegateForCommand(probeCommand);
437
462
  this.probeDelegate = useBridgeSafeProbe ? this.bridgeSafeDelegate : this.delegate;
438
463
  }
439
464
  resolveDelegateForSession(params) {
440
465
  if (shouldUseBridgeSafeDelegateForCommand(params.command)) return this.bridgeSafeDelegate;
441
- return this.resolveOpenClawToolsDelegateForSession(params.sessionKey);
466
+ return this.resolveManagedToolsDelegateForSession(params.sessionKey);
442
467
  }
443
- resolveOpenClawToolsDelegateForSession(sessionKey) {
444
- if (!this.openclawToolsMcpBridgeEnabled) return this.delegate;
468
+ resolveManagedToolsDelegateForSession(sessionKey) {
469
+ if (!this.managedToolsMcpBridgeEnabled) return this.delegate;
445
470
  const normalizedSessionKey = sessionKey.trim();
446
471
  if (!normalizedSessionKey) return this.delegate;
447
- const cached = this.openclawToolsSessionDelegates.get(normalizedSessionKey);
472
+ const cached = this.managedToolsSessionDelegates.get(normalizedSessionKey);
448
473
  if (cached) return cached;
449
474
  const delegate = new AcpxRuntime$1({
450
475
  ...this.delegateOptions,
451
- mcpServers: withOpenClawToolsMcpSessionEnv({
452
- enabled: this.openclawToolsMcpBridgeEnabled,
476
+ mcpServers: withManagedToolsMcpSessionEnv({
477
+ pluginToolsEnabled: this.pluginToolsMcpBridgeEnabled,
478
+ openclawToolsEnabled: this.openclawToolsMcpBridgeEnabled,
453
479
  mcpServers: this.delegateOptions.mcpServers,
454
480
  sessionKey: normalizedSessionKey
455
481
  })
456
482
  }, this.delegateTestOptions);
457
- this.openclawToolsSessionDelegates.set(normalizedSessionKey, delegate);
483
+ this.managedToolsSessionDelegates.set(normalizedSessionKey, delegate);
458
484
  return delegate;
459
485
  }
460
- releaseOpenClawToolsDelegateForSession(sessionKey) {
461
- if (!this.openclawToolsMcpBridgeEnabled) return;
486
+ releaseManagedToolsDelegateForSession(sessionKey) {
487
+ if (!this.managedToolsMcpBridgeEnabled) return;
462
488
  const normalizedSessionKey = sessionKey.trim();
463
489
  if (!normalizedSessionKey) return;
464
- this.openclawToolsSessionDelegates.delete(normalizedSessionKey);
490
+ this.managedToolsSessionDelegates.delete(normalizedSessionKey);
465
491
  }
466
492
  async resolveDelegateForHandle(handle) {
467
493
  const record = await this.sessionStore.load(handle.acpxRecordId ?? handle.sessionKey);
@@ -613,9 +639,18 @@ var AcpxRuntime = class {
613
639
  command,
614
640
  sessionKey: input.sessionKey
615
641
  });
642
+ const isCodexAcp = normalizeAgentName(input.agent) === CODEX_ACP_AGENT_ID && isCodexAcpCommand(command);
616
643
  const claudeModelOverride = isClaudeAcpCommand(command) ? normalizeClaudeAcpModelOverride(input.model) : void 0;
617
- const codexModelOverride = normalizeAgentName(input.agent) === CODEX_ACP_AGENT_ID && isCodexAcpCommand(command) ? normalizeCodexAcpModelOverride(input.model, input.thinking) : void 0;
618
- const ensureInput = claudeModelOverride ? {
644
+ const codexClassification = isCodexAcp ? classifyCodexAcpModelRequest(input.model, input.thinking) : void 0;
645
+ if (codexClassification?.kind === "unsupported" && input.modelExplicit) failUnsupportedCodexAcpModel(input.model ?? "");
646
+ const classifiedCodexOverride = codexClassification?.kind === "override" ? codexClassification.override : codexClassification?.thinkingOverride;
647
+ const codexModelOverride = classifiedCodexOverride && Object.keys(classifiedCodexOverride).length > 0 ? classifiedCodexOverride : void 0;
648
+ const requestedModel = input.model?.trim();
649
+ const appliedModel = isCodexAcp && requestedModel ? codexModelOverride?.model ? {
650
+ kind: "applied",
651
+ model: requestedModel
652
+ } : { kind: "dropped" } : void 0;
653
+ const ensureInput = isCodexAcp ? withCodexSessionModel(input, codexModelOverride) : claudeModelOverride ? {
619
654
  ...input,
620
655
  model: claudeModelOverride
621
656
  } : input;
@@ -627,7 +662,7 @@ var AcpxRuntime = class {
627
662
  command: stableLaunchCommand,
628
663
  resumeSessionId: input.resumeSessionId
629
664
  });
630
- if (!codexModelOverride) return await this.runWithLaunchLease({
665
+ const handle = !codexModelOverride ? await this.runWithLaunchLease({
631
666
  sessionKey: ensureInput.sessionKey,
632
667
  command: stableLaunchCommand,
633
668
  enabled: shouldStartWithLease,
@@ -636,21 +671,20 @@ var AcpxRuntime = class {
636
671
  fallbackCode: "ACP_SESSION_INIT_FAILED",
637
672
  run: () => ensureDelegateSessionWithModelFallback(delegate, ensureInput)
638
673
  })
639
- });
640
- const normalizedInput = {
641
- ...ensureInput,
642
- ...codexAcpSessionModelId(codexModelOverride) ? { model: codexAcpSessionModelId(codexModelOverride) } : {}
643
- };
644
- return await this.runWithLaunchLease({
674
+ }) : await this.runWithLaunchLease({
645
675
  sessionKey: input.sessionKey,
646
676
  command: stableLaunchCommand,
647
677
  enabled: shouldStartWithLease,
648
678
  run: () => this.codexAcpModelOverrideScope.run(codexModelOverride, () => this.withCodexWrapperDiagnostics({
649
679
  command: stableLaunchCommand,
650
680
  fallbackCode: "ACP_SESSION_INIT_FAILED",
651
- run: () => delegate.ensureSession(withAcpxSessionOptions(normalizedInput))
681
+ run: () => delegate.ensureSession(withAcpxSessionOptions(ensureInput))
652
682
  }))
653
683
  });
684
+ return appliedModel ? {
685
+ ...handle,
686
+ appliedModel
687
+ } : handle;
654
688
  }
655
689
  async *runTurn(input) {
656
690
  const command = await this.resolveCommandForHandle(input.handle);
@@ -751,8 +785,8 @@ var AcpxRuntime = class {
751
785
  }
752
786
  };
753
787
  }
754
- getCapabilities() {
755
- return this.delegate.getCapabilities();
788
+ getCapabilities(input) {
789
+ return this.delegate.getCapabilities(input);
756
790
  }
757
791
  async getStatus(input) {
758
792
  return (await this.resolveDelegateForHandle(input.handle)).getStatus(input);
@@ -767,22 +801,32 @@ var AcpxRuntime = class {
767
801
  const isCodexAcp = isCodexAcpCommand(command);
768
802
  if (WIRE_TIMEOUT_CONFIG_KEYS.has(key) && (isCodexAcp || isClaudeAcpCommand(command))) return;
769
803
  if (isCodexAcp) {
770
- if (key === "model" || key === "thinking" || key === "thought_level" || key === "reasoning_effort") {
771
- const override = key === "model" ? normalizeCodexAcpModelOverride(input.value) : normalizeCodexAcpModelOverride(void 0, input.value);
772
- if (!override && key !== "model") return;
773
- if (override) {
774
- if (override.model) await delegate.setConfigOption({
775
- ...input,
776
- key: "model",
777
- value: override.model
778
- });
779
- if (override.reasoningEffort) await delegate.setConfigOption({
780
- ...input,
781
- key: "reasoning_effort",
782
- value: override.reasoningEffort
783
- });
784
- return;
785
- }
804
+ if (key === "model") {
805
+ const classification = classifyCodexAcpModelRequest(input.value);
806
+ if (classification.kind === "unsupported") failUnsupportedCodexAcpModel(input.value);
807
+ const { override } = classification;
808
+ if (override.model) await delegate.setConfigOption({
809
+ ...input,
810
+ key: "model",
811
+ value: override.model
812
+ });
813
+ if (override.reasoningEffort) await delegate.setConfigOption({
814
+ ...input,
815
+ key: "reasoning_effort",
816
+ value: override.reasoningEffort
817
+ });
818
+ return;
819
+ }
820
+ if (key === "thinking" || key === "thought_level" || key === "reasoning_effort") {
821
+ const classification = classifyCodexAcpModelRequest(void 0, input.value);
822
+ const reasoningEffort = classification.kind === "override" ? classification.override.reasoningEffort : void 0;
823
+ if (!reasoningEffort) return;
824
+ await delegate.setConfigOption({
825
+ ...input,
826
+ key: "reasoning_effort",
827
+ value: reasoningEffort
828
+ });
829
+ return;
786
830
  }
787
831
  }
788
832
  if (isClaudeAcpCommand(command) && key === "model") {
@@ -815,7 +859,7 @@ var AcpxRuntime = class {
815
859
  } finally {
816
860
  await this.cleanupProcessTreeForRecord(input.handle, record);
817
861
  }
818
- if (closeSucceeded) this.releaseOpenClawToolsDelegateForSession(input.handle.sessionKey);
862
+ if (closeSucceeded) this.releaseManagedToolsDelegateForSession(input.handle.sessionKey);
819
863
  if (closeSucceeded && input.discardPersistentState) this.sessionStore.markFresh(input.handle.sessionKey);
820
864
  }
821
865
  };
@@ -823,11 +867,10 @@ var AcpxRuntime = class {
823
867
  const testing = {
824
868
  appendCodexAcpConfigOverrides,
825
869
  assertSupportedRuntimeSessionMode,
826
- codexAcpSessionModelId,
870
+ classifyCodexAcpModelRequest,
827
871
  isClaudeAcpCommand,
828
872
  isCodexAcpCommand,
829
- normalizeClaudeAcpModelOverride,
830
- normalizeCodexAcpModelOverride
873
+ normalizeClaudeAcpModelOverride
831
874
  };
832
875
  //#endregion
833
876
  export { ACPX_BACKEND_ID, AcpxRuntime, testing as __testing, testing, createAcpRuntime, createAgentRegistry, createFileSessionStore, decodeAcpxRuntimeHandleState, encodeAcpxRuntimeHandleState };