fix: compact update_plan tool result

This commit is contained in:
Peter Steinberger
2026-04-08 04:43:09 +01:00
parent d9d9d357b4
commit 9d31c5ad53
10 changed files with 34 additions and 22 deletions

View File

@@ -49,8 +49,12 @@ function isOpenAIProvider(provider?: string): boolean {
return normalized === "openai" || normalized === "openai-codex";
}
function isExperimentalPlanToolEnabled(config?: OpenClawConfig): boolean {
return config?.tools?.experimental?.planTool === true;
function isUpdatePlanToolEnabled(config: OpenClawConfig | undefined, provider?: string): boolean {
const configured = config?.tools?.experimental?.planTool;
if (configured !== undefined) {
return configured;
}
return isOpenAIProvider(provider);
}
export function createOpenClawTools(
@@ -242,7 +246,7 @@ export function createOpenClawTools(
agentSessionKey: options?.agentSessionKey,
requesterAgentIdOverride: options?.requesterAgentIdOverride,
}),
...(isExperimentalPlanToolEnabled(resolvedConfig) || isOpenAIProvider(options?.modelProvider)
...(isUpdatePlanToolEnabled(resolvedConfig, options?.modelProvider)
? [createUpdatePlanTool()]
: []),
createSessionsListTool({

View File

@@ -45,4 +45,19 @@ describe("openclaw-tools update_plan gating", () => {
expect(codexTools.map((tool) => tool.name)).toContain("update_plan");
expect(anthropicTools.map((tool) => tool.name)).not.toContain("update_plan");
});
it("lets config disable update_plan auto-enable", () => {
const tools = createOpenClawTools({
config: {
tools: {
experimental: {
planTool: false,
},
},
} as OpenClawConfig,
modelProvider: "openai",
});
expect(tools.map((tool) => tool.name)).not.toContain("update_plan");
});
});

View File

@@ -2,7 +2,7 @@ import { describe, expect, it } from "vitest";
import { createUpdatePlanTool } from "./update-plan-tool.js";
describe("update_plan tool", () => {
it("returns the normalized plan payload", async () => {
it("returns a compact success payload", async () => {
const tool = createUpdatePlanTool();
const result = await tool.execute("call-1", {
explanation: "Started work",
@@ -16,12 +16,6 @@ describe("update_plan tool", () => {
expect(result.content).toEqual([{ type: "text", text: "Plan updated." }]);
expect(result.details).toEqual({
status: "updated",
explanation: "Started work",
plan: [
{ step: "Inspect harness", status: "completed" },
{ step: "Add tool", status: "in_progress" },
{ step: "Run tests", status: "pending" },
],
});
});

View File

@@ -82,12 +82,10 @@ export function createUpdatePlanTool(): AnyAgentTool {
parameters: UpdatePlanToolSchema,
execute: async (_toolCallId, args) => {
const params = args as Record<string, unknown>;
const explanation = readStringParam(params, "explanation");
const plan = readPlanSteps(params);
readStringParam(params, "explanation");
readPlanSteps(params);
return textResult("Plan updated.", {
status: "updated" as const,
...(explanation ? { explanation } : {}),
plan,
});
},
};

View File

@@ -17180,7 +17180,7 @@ export const GENERATED_BASE_CONFIG_SCHEMA: BaseConfigSchemaResponse = {
type: "boolean",
title: "Enable Structured Plan Tool",
description:
"Enable the experimental structured `update_plan` tool for non-trivial multi-step work tracking across all providers. OpenAI and OpenAI Codex runs auto-enable it even when this flag is unset.",
"Enable or disable the experimental structured `update_plan` tool for non-trivial multi-step work tracking. OpenAI and OpenAI Codex runs auto-enable it when this flag is unset; set false to disable that auto-enable.",
},
},
additionalProperties: false,
@@ -23556,7 +23556,7 @@ export const GENERATED_BASE_CONFIG_SCHEMA: BaseConfigSchemaResponse = {
},
"tools.experimental.planTool": {
label: "Enable Structured Plan Tool",
help: "Enable the experimental structured `update_plan` tool for non-trivial multi-step work tracking across all providers. OpenAI and OpenAI Codex runs auto-enable it even when this flag is unset.",
help: "Enable or disable the experimental structured `update_plan` tool for non-trivial multi-step work tracking. OpenAI and OpenAI Codex runs auto-enable it when this flag is unset; set false to disable that auto-enable.",
tags: ["security", "tools", "advanced"],
},
"tools.elevated": {

View File

@@ -315,7 +315,7 @@ export const FIELD_HELP: Record<string, string> = {
"tools.experimental":
"Experimental built-in tool flags. Keep these off by default and enable only when you are intentionally testing a preview surface.",
"tools.experimental.planTool":
"Enable the experimental structured `update_plan` tool for non-trivial multi-step work tracking across all providers. OpenAI and OpenAI Codex runs auto-enable it even when this flag is unset.",
"Enable or disable the experimental structured `update_plan` tool for non-trivial multi-step work tracking. OpenAI and OpenAI Codex runs auto-enable it when this flag is unset; set false to disable that auto-enable.",
"tools.elevated":
"Elevated tool access controls for privileged command surfaces that should only be reachable from trusted senders. Keep disabled unless operator workflows explicitly require elevated actions.",
"tools.elevated.enabled":

View File

@@ -635,9 +635,9 @@ export type ToolsConfig = {
deny?: string[];
};
};
/** Experimental tool flags. Default off unless explicitly enabled. */
/** Experimental tool flags. Default off unless explicitly enabled or runtime auto-enabled. */
experimental?: {
/** Enable the structured `update_plan` tool for all providers. OpenAI-family runs auto-enable it. */
/** Enable or disable the structured `update_plan` tool. OpenAI-family runs auto-enable it unless this is false. */
planTool?: boolean;
};
};