Files
openclaw/src/auto-reply/status.tools.test.ts
Tak Hoffman 9c7823350b feat: add /tools runtime availability view (#54088)
* test(memory): lock qmd status counts regression

* feat: make /tools show what the agent can use right now

* fix: sync web ui slash commands with the shared registry

* feat: add profile and unavailable counts to /tools

* refine: keep /tools focused on available tools

* fix: resolve /tools review regressions

* fix: honor model compat in /tools inventory

* fix: sync generated protocol models for /tools

* fix: restore canonical slash command names

* fix: avoid ci lint drift in google helper exports

* perf: stop computing unused /tools unavailable counts

* docs: clarify /tools runtime behavior
2026-03-24 21:09:51 -05:00

147 lines
4.4 KiB
TypeScript

import { describe, expect, it, vi } from "vitest";
import type { OpenClawConfig } from "../config/config.js";
import { buildCommandsMessage, buildHelpMessage, buildToolsMessage } from "./status.js";
vi.mock("../plugins/commands.js", () => ({
listPluginCommands: () => [],
}));
describe("tools product copy", () => {
it("mentions /tools in command discovery copy", () => {
const cfg = {
commands: { config: false, debug: false },
} as unknown as OpenClawConfig;
expect(buildCommandsMessage(cfg)).toContain("/tools - List available runtime tools.");
expect(buildCommandsMessage(cfg)).toContain("More: /tools for available capabilities");
expect(buildHelpMessage(cfg)).toContain("/tools for available capabilities");
});
it("formats built-in and plugin tools for end users", () => {
const text = buildToolsMessage({
agentId: "main",
profile: "coding",
groups: [
{
id: "core",
label: "Built-in tools",
source: "core",
tools: [
{
id: "exec",
label: "Exec",
description: "Run shell commands",
rawDescription: "Run shell commands",
source: "core",
},
{
id: "web_search",
label: "Web Search",
description: "Search the web",
rawDescription: "Search the web",
source: "core",
},
],
},
{
id: "plugin",
label: "Connected tools",
source: "plugin",
tools: [
{
id: "docs_lookup",
label: "Docs Lookup",
description: "Search internal documentation",
rawDescription: "Search internal documentation",
source: "plugin",
pluginId: "docs",
},
],
},
],
});
expect(text).toContain("Available tools");
expect(text).toContain("Profile: coding");
expect(text).toContain("Built-in tools");
expect(text).toContain("exec, web_search");
expect(text).toContain("Connected tools");
expect(text).toContain("docs_lookup (docs)");
expect(text).toContain("Use /tools verbose for descriptions.");
expect(text).not.toContain("unavailable right now");
});
it("keeps detailed descriptions in verbose mode", () => {
const text = buildToolsMessage(
{
agentId: "main",
profile: "minimal",
groups: [
{
id: "core",
label: "Built-in tools",
source: "core",
tools: [
{
id: "exec",
label: "Exec",
description: "Run shell commands",
rawDescription: "Run shell commands",
source: "core",
},
],
},
],
},
{ verbose: true },
);
expect(text).toContain("What this agent can use right now:");
expect(text).toContain("Profile: minimal");
expect(text).toContain("Exec - Run shell commands");
expect(text).toContain("Tool availability depends on this agent's configuration.");
expect(text).not.toContain("unavailable right now");
});
it("trims verbose output before schema-like doc blocks", () => {
const text = buildToolsMessage(
{
agentId: "main",
profile: "coding",
groups: [
{
id: "core",
label: "Built-in tools",
source: "core",
tools: [
{
id: "cron",
label: "Cron",
description: "Schedule and manage cron jobs.",
rawDescription:
"Manage Gateway cron jobs and send wake events.\n\nACTIONS:\n- status: Check cron scheduler status\nJOB SCHEMA:\n{ ... }",
source: "core",
},
],
},
],
},
{ verbose: true },
);
expect(text).toContain("Cron - Manage Gateway cron jobs and send wake events.");
expect(text).not.toContain("ACTIONS:");
expect(text).not.toContain("JOB SCHEMA:");
});
it("returns the empty state when no tools are available", () => {
expect(
buildToolsMessage({
agentId: "main",
profile: "full",
groups: [],
}),
).toBe("No tools are available for this agent right now.\n\nProfile: full");
});
});