fix(agents): move lean local-model mode behind experimental flag

This commit is contained in:
Vincent Koc
2026-04-15 11:39:44 +01:00
parent 7883412294
commit f09a4d9ba0
11 changed files with 66 additions and 37 deletions

View File

@@ -116,7 +116,7 @@ describe("applyModelProviderToolPolicy", () => {
expect(toolNames(filtered)).toEqual(["read", "web_search", "exec"]);
});
it("drops heavyweight tools when lean local-model mode is enabled", () => {
it("drops heavyweight tools when the experimental lean local-model flag is enabled", () => {
const filtered = __testing.applyModelProviderToolPolicy(
[
{ name: "read" },
@@ -129,7 +129,9 @@ describe("applyModelProviderToolPolicy", () => {
config: {
agents: {
defaults: {
localModelMode: "lean",
experimental: {
localModelLean: true,
},
},
},
},
@@ -142,7 +144,7 @@ describe("applyModelProviderToolPolicy", () => {
expect(toolNames(filtered)).toEqual(["read", "exec"]);
});
it("keeps heavyweight tools when lean local-model mode is not enabled", () => {
it("keeps heavyweight tools when the experimental lean local-model flag is not enabled", () => {
const filtered = __testing.applyModelProviderToolPolicy(
[
{ name: "read" },
@@ -155,7 +157,9 @@ describe("applyModelProviderToolPolicy", () => {
config: {
agents: {
defaults: {
localModelMode: "default",
experimental: {
localModelLean: false,
},
},
},
},

View File

@@ -131,7 +131,7 @@ function applyModelProviderToolPolicy(
modelCompat?: ModelCompatConfig;
},
): AnyAgentTool[] {
if (params?.config?.agents?.defaults?.localModelMode === "lean") {
if (params?.config?.agents?.defaults?.experimental?.localModelLean === true) {
const leanDeny = new Set(["browser", "cron", "message"]);
tools = tools.filter((tool) => !leanDeny.has(tool.name));
}

View File

@@ -3243,20 +3243,20 @@ export const GENERATED_BASE_CONFIG_SCHEMA: BaseConfigSchemaResponse = {
description:
"Max total characters across all injected workspace bootstrap files (default: 150000).",
},
localModelMode: {
anyOf: [
{
type: "string",
const: "default",
experimental: {
type: "object",
properties: {
localModelLean: {
type: "boolean",
title: "Enable Lean Local Model Mode (Experimental)",
description:
"Experimental local-model prompt trim. When enabled, OpenClaw drops heavyweight default tools like browser, cron, and message for weaker or smaller local-model backends.",
},
{
type: "string",
const: "lean",
},
],
title: "Local Model Mode",
},
additionalProperties: false,
title: "Experimental Agent Flags",
description:
'Local-model prompt profile: "default" keeps the standard tool surface, while "lean" drops heavyweight non-essential tools for smaller or weaker models.',
"Experimental agent-default flags. Keep these off unless you are intentionally testing a preview surface.",
},
bootstrapPromptTruncationWarning: {
anyOf: [
@@ -24528,10 +24528,15 @@ export const GENERATED_BASE_CONFIG_SCHEMA: BaseConfigSchemaResponse = {
help: "Max total characters across all injected workspace bootstrap files (default: 150000).",
tags: ["performance"],
},
"agents.defaults.localModelMode": {
label: "Local Model Mode",
help: 'Local-model prompt profile: "default" keeps the standard tool surface, while "lean" drops heavyweight non-essential tools for smaller or weaker models.',
tags: ["advanced"],
"agents.defaults.experimental": {
label: "Experimental Agent Flags",
help: "Experimental agent-default flags. Keep these off unless you are intentionally testing a preview surface.",
tags: ["security", "advanced"],
},
"agents.defaults.experimental.localModelLean": {
label: "Enable Lean Local Model Mode (Experimental)",
help: "Experimental local-model prompt trim. When enabled, OpenClaw drops heavyweight default tools like browser, cron, and message for weaker or smaller local-model backends.",
tags: ["security", "advanced"],
},
"agents.defaults.bootstrapPromptTruncationWarning": {
label: "Bootstrap Prompt Truncation Warning",

View File

@@ -848,8 +848,10 @@ export const FIELD_HELP: Record<string, string> = {
"Max characters of each workspace bootstrap file injected into the system prompt before truncation (default: 20000).",
"agents.defaults.bootstrapTotalMaxChars":
"Max total characters across all injected workspace bootstrap files (default: 150000).",
"agents.defaults.localModelMode":
'Local-model prompt profile: "default" keeps the standard tool surface, while "lean" drops heavyweight non-essential tools for smaller or weaker models.',
"agents.defaults.experimental":
"Experimental agent-default flags. Keep these off unless you are intentionally testing a preview surface.",
"agents.defaults.experimental.localModelLean":
"Experimental local-model prompt trim. When enabled, OpenClaw drops heavyweight default tools like browser, cron, and message for weaker or smaller local-model backends.",
"agents.defaults.bootstrapPromptTruncationWarning":
'Inject agent-visible warning text when bootstrap files are truncated: "off", "once" (default), or "always".',
"agents.defaults.startupContext":

View File

@@ -343,7 +343,8 @@ export const FIELD_LABELS: Record<string, string> = {
"agents.defaults.contextInjection": "Context Injection",
"agents.defaults.bootstrapMaxChars": "Bootstrap Max Chars",
"agents.defaults.bootstrapTotalMaxChars": "Bootstrap Total Max Chars",
"agents.defaults.localModelMode": "Local Model Mode",
"agents.defaults.experimental": "Experimental Agent Flags",
"agents.defaults.experimental.localModelLean": "Enable Lean Local Model Mode (Experimental)",
"agents.defaults.bootstrapPromptTruncationWarning": "Bootstrap Prompt Truncation Warning",
"agents.defaults.startupContext": "Startup Context",
"agents.defaults.startupContext.enabled": "Enable Startup Context",

View File

@@ -13,7 +13,6 @@ import type { MemorySearchConfig } from "./types.tools.js";
export type AgentContextInjection = "always" | "continuation-skip";
export type EmbeddedPiExecutionContract = "default" | "strict-agentic";
export type LocalModelMode = "default" | "lean";
export type AgentModelEntryConfig = {
alias?: string;
@@ -199,12 +198,14 @@ export type AgentDefaultsConfig = {
bootstrapMaxChars?: number;
/** Max total chars across all injected bootstrap files (default: 150000). */
bootstrapTotalMaxChars?: number;
/**
* Optional local-model prompt profile:
* - default: keep the standard tool surface
* - lean: drop heavyweight non-essential tools for smaller or weaker models
*/
localModelMode?: LocalModelMode;
/** Experimental agent-default flags. Keep off unless you are intentionally testing a preview surface. */
experimental?: {
/**
* Drop heavyweight non-essential default tools for weaker or smaller local
* model backends. Experimental preview only.
*/
localModelLean?: boolean;
};
/**
* Agent-visible bootstrap truncation warning mode:
* - off: do not inject warning text

View File

@@ -32,6 +32,15 @@ describe("agent defaults schema", () => {
).not.toThrow();
});
it("accepts experimental.localModelLean", () => {
const result = AgentDefaultsSchema.parse({
experimental: {
localModelLean: true,
},
})!;
expect(result.experimental?.localModelLean).toBe(true);
});
it("accepts contextInjection: always", () => {
const result = AgentDefaultsSchema.parse({ contextInjection: "always" })!;
expect(result.contextInjection).toBe("always");

View File

@@ -52,7 +52,12 @@ export const AgentDefaultsSchema = z
contextInjection: z.union([z.literal("always"), z.literal("continuation-skip")]).optional(),
bootstrapMaxChars: z.number().int().positive().optional(),
bootstrapTotalMaxChars: z.number().int().positive().optional(),
localModelMode: z.union([z.literal("default"), z.literal("lean")]).optional(),
experimental: z
.object({
localModelLean: z.boolean().optional(),
})
.strict()
.optional(),
bootstrapPromptTruncationWarning: z
.union([z.literal("off"), z.literal("once"), z.literal("always")])
.optional(),