From 74ab62c6a297e2f92607c7f165a82598516f7fbb Mon Sep 17 00:00:00 2001 From: stain lu <109842185+stainlu@users.noreply.github.com> Date: Tue, 5 May 2026 02:13:53 +0800 Subject: [PATCH] fix: pass claude cli thinking effort (#77410) Summary: - Adds a plugin-owned CLI backend argument rewrite hook and wires Anthropic `claude-cli` to translate non-off `/think` levels into Claude Code `--effort`, with docs, changelog, API baseline, and tests. - Reproducibility: yes. Current main has a high-confidence source reproduction: choose `claude-cli`, set a non ... builds argv from backend args that contain no `--effort` even though `thinkLevel` exists on the run params. Automerge notes: - No ClawSweeper repair was needed after automerge opt-in. Validation: - ClawSweeper review passed for head be17754009e5651ec9df6472f46fbffdfe3346e7. - Required merge gates passed before the squash merge. Prepared head SHA: be17754009e5651ec9df6472f46fbffdfe3346e7 Review: https://github.com/openclaw/openclaw/pull/77410#issuecomment-4372812685 Co-authored-by: stainlu --- CHANGELOG.md | 1 + .../.generated/plugin-sdk-api-baseline.sha256 | 4 +- docs/gateway/cli-backends.md | 6 ++ docs/plugins/sdk-overview.md | 3 + docs/tools/thinking.md | 1 + extensions/anthropic/cli-backend.ts | 2 + extensions/anthropic/cli-shared.test.ts | 63 +++++++++++++++++++ extensions/anthropic/cli-shared.ts | 58 +++++++++++++++++ src/agents/cli-backends.test.ts | 26 ++++++++ src/agents/cli-backends.ts | 6 ++ src/agents/cli-runner.spawn.test.ts | 33 ++++++++++ src/agents/cli-runner/execute.ts | 20 ++++-- src/plugin-sdk/cli-backend.ts | 3 + src/plugins/cli-backend.types.ts | 33 ++++++++++ src/plugins/types.ts | 6 ++ 15 files changed, 259 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c34c89e193f..8a149cb9fb5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -50,6 +50,7 @@ Docs: https://docs.openclaw.ai - Gate zalouser startup name matching [AI]. (#77411) Thanks @pgondhi987. - fix(device-pair): require pairing scope for pair command [AI]. (#76377) Thanks @pgondhi987. - fix(qqbot): keep private commands off framework surface [AI]. (#77212) Thanks @pgondhi987. +- Claude CLI: honor non-off `/think` levels by passing Claude Code's session-scoped `--effort` flag through the CLI backend seam, so chat bridges no longer show an inert thinking control. Fixes #77303. Thanks @Petr1t. - Memory/wiki: preserve representation from both corpora in `corpus=all` searches while backfilling unused result capacity, so memory hits are not starved by numerically higher wiki integer scores. Fixes #77337. Thanks @hclsys. - Telegram: clean up tool-only draft previews after assistant message boundaries so transient `Surfacing...` tool-status bubbles do not linger when no matching final preview arrives. Thanks @BunsDev. - Cron: surface failed isolated-run diagnostics in `cron show`, status, and run history when requested tools are unavailable, so blocked cron runs report the actual tool-policy failure instead of a misleading green result. Fixes #75763. Thanks @RyanSandoval. diff --git a/docs/.generated/plugin-sdk-api-baseline.sha256 b/docs/.generated/plugin-sdk-api-baseline.sha256 index 95673ce3b0b..8d14cca3537 100644 --- a/docs/.generated/plugin-sdk-api-baseline.sha256 +++ b/docs/.generated/plugin-sdk-api-baseline.sha256 @@ -1,2 +1,2 @@ -f8495c07213012748f099b12ddb02847ffd4eaa1b46f2ae9dfa574fa0ef3299a plugin-sdk-api-baseline.json -815ac868dda35d0af88b9c522233d6065c3eeb70775e19c111162b80390733fa plugin-sdk-api-baseline.jsonl +a7116e6c0cae4c7b9ee7cd6dc48f2978812f4b5be647f3e36eee91ec9a81d85e plugin-sdk-api-baseline.json +2b6c9883d701379761724e21946d417399c1247e6a244d6b00c4a982c8ef5968 plugin-sdk-api-baseline.jsonl diff --git a/docs/gateway/cli-backends.md b/docs/gateway/cli-backends.md index 48eb1181a58..6cb5cb47b07 100644 --- a/docs/gateway/cli-backends.md +++ b/docs/gateway/cli-backends.md @@ -178,6 +178,12 @@ that agent. To force a different Claude mode, set explicit raw backend args such as `--permission-mode default` or `--permission-mode acceptEdits` under `agents.defaults.cliBackends.claude-cli.args` and matching `resumeArgs`. +The bundled Anthropic `claude-cli` backend also maps OpenClaw `/think` levels +to Claude Code's native `--effort` flag for non-off levels. `minimal` and +`low` map to `low`, `adaptive` and `medium` map to `medium`, and `high`, +`xhigh`, and `max` map directly. Other CLI backends need their owning plugin to +declare an equivalent argv mapper before `/think` can affect the spawned CLI. + Before OpenClaw can use the bundled `claude-cli` backend, Claude Code itself must already be logged in on the same host: diff --git a/docs/plugins/sdk-overview.md b/docs/plugins/sdk-overview.md index fa5474ac7fd..b3a253d1b3c 100644 --- a/docs/plugins/sdk-overview.md +++ b/docs/plugins/sdk-overview.md @@ -257,6 +257,9 @@ AI CLI backend such as `codex-cli`. plugin default before running the CLI. - Use `normalizeConfig` when a backend needs compatibility rewrites after merge (for example normalizing old flag shapes). +- Use `resolveExecutionArgs` for request-scoped argv rewrites that belong to + the CLI dialect, such as mapping OpenClaw thinking levels to a native effort + flag. ### Exclusive slots diff --git a/docs/tools/thinking.md b/docs/tools/thinking.md index 1b546bc2b09..659cd27ce43 100644 --- a/docs/tools/thinking.md +++ b/docs/tools/thinking.md @@ -54,6 +54,7 @@ title: "Thinking levels" ## Application by agent - **Embedded Pi**: the resolved level is passed to the in-process Pi agent runtime. +- **Claude CLI backend**: non-off levels are passed to Claude Code as `--effort` when using `claude-cli`; see [CLI backends](/gateway/cli-backends). ## Fast mode (/fast) diff --git a/extensions/anthropic/cli-backend.ts b/extensions/anthropic/cli-backend.ts index ae7bf5c39b5..6141ac99df2 100644 --- a/extensions/anthropic/cli-backend.ts +++ b/extensions/anthropic/cli-backend.ts @@ -10,6 +10,7 @@ import { CLAUDE_CLI_MODEL_ALIASES, CLAUDE_CLI_SESSION_ID_FIELDS, normalizeClaudeBackendConfig, + resolveClaudeCliExecutionArgs, } from "./cli-shared.js"; export function buildAnthropicCliBackend(): CliBackendPlugin { @@ -76,5 +77,6 @@ export function buildAnthropicCliBackend(): CliBackendPlugin { serialize: true, }, normalizeConfig: normalizeClaudeBackendConfig, + resolveExecutionArgs: resolveClaudeCliExecutionArgs, }; } diff --git a/extensions/anthropic/cli-shared.test.ts b/extensions/anthropic/cli-shared.test.ts index 4c4c577682d..27d5f2589bd 100644 --- a/extensions/anthropic/cli-shared.test.ts +++ b/extensions/anthropic/cli-shared.test.ts @@ -6,6 +6,7 @@ import { normalizeClaudePermissionArgs, normalizeClaudeSettingSourcesArgs, resolveClaudePermissionMode, + resolveClaudeCliExecutionArgs, } from "./cli-shared.js"; describe("normalizeClaudePermissionArgs", () => { @@ -75,6 +76,67 @@ describe("normalizeClaudeSettingSourcesArgs", () => { }); }); +describe("resolveClaudeCliExecutionArgs", () => { + it("omits effort args when thinking is off", () => { + expect( + resolveClaudeCliExecutionArgs({ + workspaceDir: "/tmp", + provider: "claude-cli", + modelId: "claude-sonnet-4-6", + thinkingLevel: "off", + useResume: false, + baseArgs: ["-p", "--output-format", "stream-json"], + }), + ).toEqual(["-p", "--output-format", "stream-json"]); + }); + + it("maps OpenClaw thinking levels to Claude effort args", () => { + expect( + resolveClaudeCliExecutionArgs({ + workspaceDir: "/tmp", + provider: "claude-cli", + modelId: "claude-opus-4-7", + thinkingLevel: "minimal", + useResume: false, + baseArgs: ["-p"], + }), + ).toEqual(["-p", "--effort", "low"]); + expect( + resolveClaudeCliExecutionArgs({ + workspaceDir: "/tmp", + provider: "claude-cli", + modelId: "claude-opus-4-7", + thinkingLevel: "adaptive", + useResume: false, + baseArgs: ["-p"], + }), + ).toEqual(["-p", "--effort", "medium"]); + expect( + resolveClaudeCliExecutionArgs({ + workspaceDir: "/tmp", + provider: "claude-cli", + modelId: "claude-opus-4-7", + thinkingLevel: "xhigh", + useResume: true, + baseArgs: ["-p", "--resume", "{sessionId}"], + }), + ).toEqual(["-p", "--resume", "{sessionId}", "--effort", "xhigh"]); + }); + + it("replaces static effort args when a session thinking level is active", () => { + expect( + resolveClaudeCliExecutionArgs({ + workspaceDir: "/tmp", + provider: "claude-cli", + modelId: "claude-opus-4-7", + thinkingLevel: "max", + useResume: false, + baseArgs: ["-p", "--effort", "low", "--effort=high"], + }), + ).toEqual(["-p", "--effort", "max"]); + }); +}); + describe("normalizeClaudeBackendConfig", () => { it("normalizes both args and resumeArgs for custom overrides", () => { const normalized = normalizeClaudeBackendConfig({ @@ -196,6 +258,7 @@ describe("normalizeClaudeBackendConfig", () => { expect(normalized?.resumeArgs).toContain("--permission-mode"); expect(normalized?.resumeArgs).toContain("bypassPermissions"); expect(normalized?.liveSession).toBe("claude-stdio"); + expect(backend.resolveExecutionArgs).toBe(resolveClaudeCliExecutionArgs); }); it("leaves claude cli subscription-managed, restricts setting sources, and clears inherited env overrides", () => { diff --git a/extensions/anthropic/cli-shared.ts b/extensions/anthropic/cli-shared.ts index f73c2ccb142..e981e207eb9 100644 --- a/extensions/anthropic/cli-shared.ts +++ b/extensions/anthropic/cli-shared.ts @@ -1,6 +1,7 @@ import type { CliBackendConfig, CliBackendNormalizeConfigContext, + CliBackendResolveExecutionArgsContext, } from "openclaw/plugin-sdk/cli-backend"; import { normalizeOptionalLowercaseString } from "openclaw/plugin-sdk/text-runtime"; import { CLAUDE_CLI_BACKEND_ID } from "./cli-constants.js"; @@ -60,9 +61,12 @@ export const CLAUDE_CLI_CLEAR_ENV = [ const CLAUDE_LEGACY_SKIP_PERMISSIONS_ARG = "--dangerously-skip-permissions"; const CLAUDE_PERMISSION_MODE_ARG = "--permission-mode"; const CLAUDE_SETTING_SOURCES_ARG = "--setting-sources"; +const CLAUDE_EFFORT_ARG = "--effort"; const CLAUDE_SAFE_SETTING_SOURCES = "user"; const CLAUDE_BYPASS_PERMISSION_MODE = "bypassPermissions"; +type ClaudeCliEffort = "low" | "medium" | "high" | "xhigh" | "max"; + export function isClaudeCliProvider(providerId: string): boolean { return normalizeOptionalLowercaseString(providerId) === CLAUDE_CLI_BACKEND_ID; } @@ -168,6 +172,60 @@ export function normalizeClaudeSettingSourcesArgs(args?: string[]): string[] | u return normalized; } +export function mapClaudeCliThinkingLevelToEffort( + thinkingLevel?: string | null, +): ClaudeCliEffort | undefined { + switch (normalizeOptionalLowercaseString(thinkingLevel)) { + case "minimal": + case "low": + return "low"; + case "adaptive": + case "medium": + return "medium"; + case "high": + return "high"; + case "xhigh": + return "xhigh"; + case "max": + return "max"; + default: + return undefined; + } +} + +function stripClaudeEffortArgs(args: readonly string[]): string[] { + const normalized: string[] = []; + for (let i = 0; i < args.length; i += 1) { + const arg = args[i] ?? ""; + if (arg === CLAUDE_EFFORT_ARG) { + const maybeValue = args[i + 1]; + if ( + typeof maybeValue === "string" && + maybeValue.trim().length > 0 && + !maybeValue.startsWith("-") + ) { + i += 1; + } + continue; + } + if (arg.startsWith(`${CLAUDE_EFFORT_ARG}=`)) { + continue; + } + normalized.push(arg); + } + return normalized; +} + +export function resolveClaudeCliExecutionArgs( + context: CliBackendResolveExecutionArgsContext, +): string[] { + const effort = mapClaudeCliThinkingLevelToEffort(context.thinkingLevel); + if (!effort) { + return [...context.baseArgs]; + } + return [...stripClaudeEffortArgs(context.baseArgs), CLAUDE_EFFORT_ARG, effort]; +} + export function normalizeClaudeBackendConfig( config: CliBackendConfig, context?: CliBackendNormalizeConfigContext, diff --git a/src/agents/cli-backends.test.ts b/src/agents/cli-backends.test.ts index ae385fd130f..56914ee1cc9 100644 --- a/src/agents/cli-backends.test.ts +++ b/src/agents/cli-backends.test.ts @@ -4,6 +4,7 @@ import type { CliBackendConfig } from "../config/types.js"; import type { CliBackendAuthEpochMode, CliBackendNormalizeConfigContext, + CliBackendResolveExecutionArgs, CliBundleMcpMode, } from "../plugins/types.js"; import { @@ -31,6 +32,7 @@ function createBackendEntry(params: { defaultAuthProfileId?: string; authEpochMode?: CliBackendAuthEpochMode; prepareExecution?: () => Promise; + resolveExecutionArgs?: CliBackendResolveExecutionArgs; normalizeConfig?: ( config: CliBackendConfig, context?: CliBackendNormalizeConfigContext, @@ -47,6 +49,7 @@ function createBackendEntry(params: { ...(params.defaultAuthProfileId ? { defaultAuthProfileId: params.defaultAuthProfileId } : {}), ...(params.authEpochMode ? { authEpochMode: params.authEpochMode } : {}), ...(params.prepareExecution ? { prepareExecution: params.prepareExecution } : {}), + ...(params.resolveExecutionArgs ? { resolveExecutionArgs: params.resolveExecutionArgs } : {}), ...(params.normalizeConfig ? { normalizeConfig: params.normalizeConfig } : {}), liveTest: { defaultModelRef: @@ -968,6 +971,29 @@ describe("resolveCliBackendConfig google-gemini-cli defaults", () => { expect(resolved?.config.systemPromptWhen).toBe("first"); expect(resolved?.config.imagePathScope).toBe("workspace"); }); + + it("preserves backend-owned per-run arg resolvers", () => { + const resolveExecutionArgs: CliBackendResolveExecutionArgs = ({ baseArgs }) => [ + ...baseArgs, + "--effort", + "high", + ]; + runtimeBackendEntries = [ + createRuntimeBackendEntry({ + pluginId: "anthropic", + id: "claude-cli", + config: { + command: "claude", + args: ["-p"], + }, + resolveExecutionArgs, + }), + ]; + + const resolved = resolveCliBackendConfig("claude-cli"); + + expect(resolved?.resolveExecutionArgs).toBe(resolveExecutionArgs); + }); }); describe("resolveCliBackendConfig alias precedence", () => { diff --git a/src/agents/cli-backends.ts b/src/agents/cli-backends.ts index b86d259e833..ae9718893ee 100644 --- a/src/agents/cli-backends.ts +++ b/src/agents/cli-backends.ts @@ -38,6 +38,7 @@ export type ResolvedCliBackend = { defaultAuthProfileId?: string; authEpochMode?: CliBackendAuthEpochMode; prepareExecution?: CliBackendPlugin["prepareExecution"]; + resolveExecutionArgs?: CliBackendPlugin["resolveExecutionArgs"]; nativeToolMode?: CliBackendNativeToolMode; }; @@ -62,6 +63,7 @@ type FallbackCliBackendPolicy = { defaultAuthProfileId?: string; authEpochMode?: CliBackendAuthEpochMode; prepareExecution?: CliBackendPlugin["prepareExecution"]; + resolveExecutionArgs?: CliBackendPlugin["resolveExecutionArgs"]; nativeToolMode?: CliBackendNativeToolMode; }; @@ -99,6 +101,7 @@ function resolveSetupCliBackendPolicy(provider: string): FallbackCliBackendPolic defaultAuthProfileId: entry.backend.defaultAuthProfileId, authEpochMode: entry.backend.authEpochMode, prepareExecution: entry.backend.prepareExecution, + resolveExecutionArgs: entry.backend.resolveExecutionArgs, nativeToolMode: entry.backend.nativeToolMode, }; } @@ -237,6 +240,7 @@ export function resolveCliBackendConfig( defaultAuthProfileId: registered.defaultAuthProfileId, authEpochMode: registered.authEpochMode, prepareExecution: registered.prepareExecution, + resolveExecutionArgs: registered.resolveExecutionArgs, nativeToolMode: registered.nativeToolMode, }; } @@ -266,6 +270,7 @@ export function resolveCliBackendConfig( defaultAuthProfileId: fallbackPolicy.defaultAuthProfileId, authEpochMode: fallbackPolicy.authEpochMode, prepareExecution: fallbackPolicy.prepareExecution, + resolveExecutionArgs: fallbackPolicy.resolveExecutionArgs, nativeToolMode: fallbackPolicy.nativeToolMode, }; } @@ -292,6 +297,7 @@ export function resolveCliBackendConfig( defaultAuthProfileId: fallbackPolicy?.defaultAuthProfileId, authEpochMode: fallbackPolicy?.authEpochMode, prepareExecution: fallbackPolicy?.prepareExecution, + resolveExecutionArgs: fallbackPolicy?.resolveExecutionArgs, nativeToolMode: fallbackPolicy?.nativeToolMode, }; } diff --git a/src/agents/cli-runner.spawn.test.ts b/src/agents/cli-runner.spawn.test.ts index b994402f5c0..9099f994e2e 100644 --- a/src/agents/cli-runner.spawn.test.ts +++ b/src/agents/cli-runner.spawn.test.ts @@ -59,9 +59,11 @@ function buildPreparedCliRunContext(params: { sessionId?: string; sessionKey?: string; backend?: Partial; + resolveExecutionArgs?: PreparedCliRunContext["backendResolved"]["resolveExecutionArgs"]; config?: PreparedCliRunContext["params"]["config"]; mcpConfigHash?: string; skillsSnapshot?: PreparedCliRunContext["params"]["skillsSnapshot"]; + thinkLevel?: PreparedCliRunContext["params"]["thinkLevel"]; workspaceDir?: string; }): PreparedCliRunContext { const workspaceDir = params.workspaceDir ?? "/tmp"; @@ -103,6 +105,7 @@ function buildPreparedCliRunContext(params: { prompt: params.prompt ?? "hi", provider: params.provider, model: params.model, + thinkLevel: params.thinkLevel, timeoutMs: 1_000, runId: params.runId, skillsSnapshot: params.skillsSnapshot, @@ -114,6 +117,7 @@ function buildPreparedCliRunContext(params: { config: backend, bundleMcp: params.provider === "claude-cli", pluginId: params.provider === "claude-cli" ? "anthropic" : "openai", + resolveExecutionArgs: params.resolveExecutionArgs, }, preparedBackend: { backend, @@ -329,6 +333,35 @@ describe("runCliAgent spawn path", () => { expect(input.argv).not.toContain("hi"); }); + it("applies backend-owned per-run args before spawning", async () => { + mockSuccessfulCliRun(); + const resolveExecutionArgs = vi.fn(({ baseArgs }) => [...baseArgs, "--effort", "high"]); + + await executePreparedCliRun( + buildPreparedCliRunContext({ + provider: "claude-cli", + model: "sonnet", + runId: "run-claude-thinking-args", + thinkLevel: "high", + resolveExecutionArgs, + }), + ); + + expect(resolveExecutionArgs).toHaveBeenCalledWith( + expect.objectContaining({ + provider: "claude-cli", + modelId: "sonnet", + thinkingLevel: "high", + useResume: false, + baseArgs: ["-p", "--output-format", "stream-json"], + }), + ); + const input = supervisorSpawnMock.mock.calls[0]?.[0] as { argv?: string[] }; + const effortArgIndex = input.argv?.indexOf("--effort") ?? -1; + expect(effortArgIndex).toBeGreaterThanOrEqual(0); + expect(input.argv?.[effortArgIndex + 1]).toBe("high"); + }); + it("passes OpenClaw skills to Claude as a session plugin", async () => { const workspaceDir = await fs.mkdtemp(path.join(os.tmpdir(), "openclaw-cli-skills-")); const skillDir = path.join(workspaceDir, "skills", "weather"); diff --git a/src/agents/cli-runner/execute.ts b/src/agents/cli-runner/execute.ts index e3a265a6dad..b043fb616a1 100644 --- a/src/agents/cli-runner/execute.ts +++ b/src/agents/cli-runner/execute.ts @@ -279,12 +279,24 @@ export async function executePreparedCliRun( skillsSnapshot: params.skillsSnapshot, }); let claudeSkillsPluginCleanupOwned = false; + const baseArgsWithSkills = + claudeSkillsPlugin.args.length > 0 + ? [...resolvedArgs, ...claudeSkillsPlugin.args] + : resolvedArgs; + const executionBaseArgs = + context.backendResolved.resolveExecutionArgs?.({ + config: params.config, + workspaceDir: context.workspaceDir, + provider: params.provider, + modelId: context.modelId, + authProfileId: context.effectiveAuthProfileId, + thinkingLevel: params.thinkLevel, + useResume, + baseArgs: baseArgsWithSkills, + }) ?? baseArgsWithSkills; const args = buildCliArgs({ backend, - baseArgs: - claudeSkillsPlugin.args.length > 0 - ? [...resolvedArgs, ...claudeSkillsPlugin.args] - : resolvedArgs, + baseArgs: Array.from(executionBaseArgs), modelId: context.normalizedModel, sessionId: resolvedSessionId, systemPrompt: systemPromptArg, diff --git a/src/plugin-sdk/cli-backend.ts b/src/plugin-sdk/cli-backend.ts index 738165d4e29..82191e48381 100644 --- a/src/plugin-sdk/cli-backend.ts +++ b/src/plugin-sdk/cli-backend.ts @@ -6,6 +6,9 @@ export type { CliBackendPlugin, CliBackendPreparedExecution, CliBackendPrepareExecutionContext, + CliBackendResolveExecutionArgs, + CliBackendResolveExecutionArgsContext, + CliBackendThinkingLevel, } from "../plugins/types.js"; export { CLI_FRESH_WATCHDOG_DEFAULTS, diff --git a/src/plugins/cli-backend.types.ts b/src/plugins/cli-backend.types.ts index 97492e4a834..01771a80292 100644 --- a/src/plugins/cli-backend.types.ts +++ b/src/plugins/cli-backend.types.ts @@ -33,6 +33,31 @@ export type CliBackendPreparedExecution = { cleanup?: () => Promise; }; +export type CliBackendThinkingLevel = + | "off" + | "minimal" + | "low" + | "medium" + | "high" + | "xhigh" + | "adaptive" + | "max"; + +export type CliBackendResolveExecutionArgsContext = { + config?: OpenClawConfig; + workspaceDir: string; + provider: string; + modelId: string; + authProfileId?: string; + thinkingLevel?: CliBackendThinkingLevel; + useResume: boolean; + baseArgs: readonly string[]; +}; + +export type CliBackendResolveExecutionArgs = ( + ctx: CliBackendResolveExecutionArgsContext, +) => readonly string[] | null | undefined; + export type CliBackendAuthEpochMode = "combined" | "profile-only"; export type CliBackendNativeToolMode = "none" | "always-on"; @@ -141,6 +166,14 @@ export type CliBackendPlugin = { | CliBackendPreparedExecution | null | undefined; + /** + * Backend-owned per-run argv rewrite. + * + * Use this for request-scoped CLI dialect flags that should not be modeled + * as static config, such as mapping OpenClaw thinking levels to a backend's + * native effort flag. + */ + resolveExecutionArgs?: CliBackendResolveExecutionArgs; /** * Whether this CLI backend can expose native tools outside OpenClaw's tool * catalog. Backends that cannot provide a true no-tools mode must mark diff --git a/src/plugins/types.ts b/src/plugins/types.ts index b7df4b8b781..3718330c388 100644 --- a/src/plugins/types.ts +++ b/src/plugins/types.ts @@ -84,6 +84,9 @@ import type { CliBackendNormalizeConfigContext, CliBackendPreparedExecution, CliBackendPrepareExecutionContext, + CliBackendResolveExecutionArgs, + CliBackendResolveExecutionArgsContext, + CliBackendThinkingLevel, CliBackendPlugin, CliBundleMcpMode, PluginTextReplacement, @@ -194,6 +197,9 @@ export type { CliBackendNativeToolMode, CliBackendPreparedExecution, CliBackendPrepareExecutionContext, + CliBackendResolveExecutionArgs, + CliBackendResolveExecutionArgsContext, + CliBackendThinkingLevel, CliBackendPlugin, CliBundleMcpMode, PluginTextReplacement,