Skip to content

Commit ae21ac4

Browse files
committed
fix(agents): guard lean tool name reads
1 parent 2c92973 commit ae21ac4

2 files changed

Lines changed: 39 additions & 1 deletion

File tree

src/agents/local-model-lean.test.ts

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,33 @@ describe("local model lean tool filtering", () => {
3636
).toEqual(["read", "exec"]);
3737
});
3838

39+
it("omits unreadable tool names while lean filtering stays active", () => {
40+
const cfg: OpenClawConfig = {
41+
agents: {
42+
defaults: {
43+
experimental: {
44+
localModelLean: true,
45+
},
46+
},
47+
},
48+
};
49+
const readTool = { name: "read" } as AnyAgentTool;
50+
const unreadableTool = {} as AnyAgentTool;
51+
Object.defineProperty(unreadableTool, "name", {
52+
get() {
53+
throw new Error("local model lean tool name getter exploded");
54+
},
55+
});
56+
const execTool = { name: "exec" } as AnyAgentTool;
57+
58+
expect(
59+
filterLocalModelLeanTools({
60+
tools: [readTool, unreadableTool, { name: "cron" } as AnyAgentTool, execTool],
61+
config: cfg,
62+
}),
63+
).toEqual([readTool, execTool]);
64+
});
65+
3966
it("keeps explicitly preserved tools when lean mode is enabled", () => {
4067
const cfg: OpenClawConfig = {
4168
agents: {

src/agents/local-model-lean.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,14 @@ function resolvePreservedLocalModelLeanToolNames(names?: Iterable<string>): Set<
1717
);
1818
}
1919

20+
function readNormalizedLocalModelLeanToolName(tool: AnyAgentTool): string | undefined {
21+
try {
22+
return normalizeToolName(tool.name) || undefined;
23+
} catch {
24+
return undefined;
25+
}
26+
}
27+
2028
export function resolveLocalModelLeanPreserveToolNames(params?: {
2129
toolNames?: Iterable<string>;
2230
forceMessageTool?: boolean;
@@ -74,7 +82,10 @@ export function filterLocalModelLeanTools(params: {
7482
}
7583
const preservedToolNames = resolvePreservedLocalModelLeanToolNames(params.preserveToolNames);
7684
return params.tools.filter((tool) => {
77-
const normalizedName = normalizeToolName(tool.name);
85+
const normalizedName = readNormalizedLocalModelLeanToolName(tool);
86+
if (!normalizedName) {
87+
return false;
88+
}
7889
return (
7990
preservedToolNames.has(normalizedName) ||
8091
!LOCAL_MODEL_LEAN_DENY_TOOL_NAMES.has(normalizedName)

0 commit comments

Comments
 (0)