Files
openclaw/src/plugins/cli-backend.types.ts
stain lu 74ab62c6a2 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 be17754009.
- Required merge gates passed before the squash merge.

Prepared head SHA: be17754009
Review: https://github.com/openclaw/openclaw/pull/77410#issuecomment-4372812685

Co-authored-by: stainlu <stainlu@newtype-ai.org>
2026-05-04 18:13:53 +00:00

185 lines
5.5 KiB
TypeScript

import type { CliBackendConfig } from "../config/types.js";
import type { OpenClawConfig } from "../config/types.openclaw.js";
export type PluginTextReplacement = {
from: string | RegExp;
to: string;
};
export type PluginTextTransforms = {
/** Rewrites applied to outbound prompt text before provider/CLI transport. */
input?: PluginTextReplacement[];
/** Rewrites applied to inbound assistant text before OpenClaw consumes it. */
output?: PluginTextReplacement[];
};
export type CliBundleMcpMode =
| "claude-config-file"
| "codex-config-overrides"
| "gemini-system-settings";
export type CliBackendPrepareExecutionContext = {
config?: OpenClawConfig;
workspaceDir: string;
agentDir?: string;
provider: string;
modelId: string;
authProfileId?: string;
};
export type CliBackendPreparedExecution = {
env?: Record<string, string>;
clearEnv?: string[];
cleanup?: () => Promise<void>;
};
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";
export type CliBackendNormalizeConfigContext = {
config?: OpenClawConfig;
backendId: string;
agentId?: string;
};
/** Plugin-owned CLI backend defaults used by the text-only CLI runner. */
export type CliBackendPlugin = {
/** Provider id used in model refs, for example `claude-cli/opus`. */
id: string;
/** Default backend config before user overrides from `agents.defaults.cliBackends`. */
config: CliBackendConfig;
/**
* Optional live-smoke metadata owned by the backend plugin.
*
* Keep provider-specific test wiring here instead of scattering it across
* Docker wrappers, docs, and gateway live tests.
*/
liveTest?: {
defaultModelRef?: string;
defaultImageProbe?: boolean;
defaultMcpProbe?: boolean;
docker?: {
npmPackage?: string;
binaryName?: string;
};
};
/**
* Whether OpenClaw should inject bundle MCP config for this backend.
*
* Keep this opt-in. Only backends that explicitly consume OpenClaw's bundle
* MCP bridge should enable it.
*/
bundleMcp?: boolean;
/**
* Provider-owned bundle MCP integration strategy.
*
* Different CLIs wire MCP through different surfaces:
* - Claude: `--strict-mcp-config --mcp-config`
* - Codex: `-c mcp_servers=...`
* - Gemini: system-level `settings.json`
*/
bundleMcpMode?: CliBundleMcpMode;
/**
* Optional config normalizer applied after user overrides merge.
*
* Use this for backend-specific compatibility rewrites when old config
* shapes need to stay working.
*/
normalizeConfig?: (
config: CliBackendConfig,
context?: CliBackendNormalizeConfigContext,
) => CliBackendConfig;
/**
* Backend-owned final system-prompt transform.
*
* Use this for tiny CLI-specific compatibility rewrites without replacing
* the generic CLI runner or prompt builder.
*/
transformSystemPrompt?: (ctx: {
config?: OpenClawConfig;
workspaceDir?: string;
provider: string;
modelId: string;
modelDisplay: string;
agentId?: string;
systemPrompt: string;
}) => string | null | undefined;
/**
* Backend-owned bidirectional text replacements.
*
* `input` applies to the system prompt and user prompt passed to the CLI.
* `output` applies to parsed/streamed assistant text from the CLI.
*/
textTransforms?: PluginTextTransforms;
/**
* Preferred auth-profile id when the caller did not explicitly lock one.
*
* Use this when the backend should consume a canonical OpenClaw auth profile
* rather than ambient host auth by default.
*/
defaultAuthProfileId?: string;
/**
* Session/auth epoch source policy.
*
* `combined` keeps the legacy "host credential + auth profile" fingerprint.
* `profile-only` treats the selected OpenClaw auth profile as the sole auth
* owner for session invalidation when one is present.
*/
authEpochMode?: CliBackendAuthEpochMode;
/**
* Backend-owned execution bridge.
*
* Use this on async run paths when the backend needs a generated auth/config
* bridge (for example a private CLI home directory) without teaching the core
* runner about provider-specific file formats.
*/
prepareExecution?: (
ctx: CliBackendPrepareExecutionContext,
) =>
| Promise<CliBackendPreparedExecution | null | undefined>
| 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
* themselves as `always-on` so callers that require disabled tools fail
* closed instead of launching a native harness.
*/
nativeToolMode?: CliBackendNativeToolMode;
};