diff --git a/src/agents/pi-embedded-runner.ts b/src/agents/pi-embedded-runner.ts
index 4472c8dc1..1532de8c3 100644
--- a/src/agents/pi-embedded-runner.ts
+++ b/src/agents/pi-embedded-runner.ts
@@ -395,6 +395,7 @@ export async function runEmbeddedPiAgent(params: {
reasoningTagHint,
runtimeInfo,
sandboxInfo,
+ toolNames: tools.map((tool) => tool.name),
}),
contextFiles,
skills: promptSkills,
diff --git a/src/agents/system-prompt.test.ts b/src/agents/system-prompt.test.ts
index 9b4502021..802feef77 100644
--- a/src/agents/system-prompt.test.ts
+++ b/src/agents/system-prompt.test.ts
@@ -33,4 +33,17 @@ describe("buildAgentSystemPromptAppend", () => {
expect(prompt).toContain("...");
expect(prompt).toContain("...");
});
+
+ it("lists available and unavailable tools when provided", () => {
+ const prompt = buildAgentSystemPromptAppend({
+ workspaceDir: "/tmp/clawd",
+ toolNames: ["bash", "sessions_list", "sessions_history", "sessions_send"],
+ });
+
+ expect(prompt).toContain("Tool availability (filtered by policy):");
+ expect(prompt).toContain("sessions_list");
+ expect(prompt).toContain("sessions_history");
+ expect(prompt).toContain("sessions_send");
+ expect(prompt).toContain("Unavailable tools (do not call):");
+ });
});
diff --git a/src/agents/system-prompt.ts b/src/agents/system-prompt.ts
index 98113996c..7d97aff24 100644
--- a/src/agents/system-prompt.ts
+++ b/src/agents/system-prompt.ts
@@ -6,6 +6,7 @@ export function buildAgentSystemPromptAppend(params: {
extraSystemPrompt?: string;
ownerNumbers?: string[];
reasoningTagHint?: boolean;
+ toolNames?: string[];
runtimeInfo?: {
host?: string;
os?: string;
@@ -20,6 +21,69 @@ export function buildAgentSystemPromptAppend(params: {
browserNoVncUrl?: string;
};
}) {
+ const toolSummaries: Record = {
+ read: "Read file contents",
+ write: "Create or overwrite files",
+ edit: "Make precise edits to files",
+ grep: "Search file contents for patterns",
+ find: "Find files by glob pattern",
+ ls: "List directory contents",
+ bash: "Run shell commands",
+ process: "Manage background bash sessions",
+ whatsapp_login: "Generate and wait for WhatsApp QR login",
+ browser: "Control the dedicated clawd browser",
+ canvas: "Present/eval/snapshot the Canvas",
+ nodes: "List/describe/notify/camera/screen on paired nodes",
+ cron: "Manage cron jobs and wake events",
+ gateway: "Restart the running Gateway process",
+ sessions_list: "List sessions with filters and last messages",
+ sessions_history: "Fetch message history for a session",
+ sessions_send: "Send a message into another session",
+ image: "Analyze an image with the configured image model",
+ discord: "Send Discord reactions/messages and manage threads",
+ slack: "Send Slack messages and manage channels",
+ };
+
+ const toolOrder = [
+ "read",
+ "write",
+ "edit",
+ "grep",
+ "find",
+ "ls",
+ "bash",
+ "process",
+ "whatsapp_login",
+ "browser",
+ "canvas",
+ "nodes",
+ "cron",
+ "gateway",
+ "sessions_list",
+ "sessions_history",
+ "sessions_send",
+ "image",
+ "discord",
+ "slack",
+ ];
+
+ const normalizedTools = (params.toolNames ?? [])
+ .map((tool) => tool.trim().toLowerCase())
+ .filter(Boolean);
+ const availableTools = new Set(normalizedTools);
+ const extraTools = Array.from(
+ new Set(normalizedTools.filter((tool) => !toolOrder.includes(tool))),
+ );
+ const enabledTools = toolOrder.filter((tool) => availableTools.has(tool));
+ const disabledTools = toolOrder.filter((tool) => !availableTools.has(tool));
+ const toolLines = enabledTools.map((tool) => {
+ const summary = toolSummaries[tool];
+ return summary ? `- ${tool}: ${summary}` : `- ${tool}`;
+ });
+ for (const tool of extraTools.sort()) {
+ toolLines.push(`- ${tool}`);
+ }
+
const thinkHint =
params.defaultThinkLevel && params.defaultThinkLevel !== "off"
? `Default thinking level: ${params.defaultThinkLevel}.`
@@ -61,17 +125,28 @@ export function buildAgentSystemPromptAppend(params: {
"You are Clawd, a personal assistant running inside Clawdbot.",
"",
"## Tooling",
- "Pi lists the standard tools above. This runtime enables:",
- "- grep: search file contents for patterns",
- "- find: find files by glob pattern",
- "- ls: list directory contents",
- "- bash: run shell commands (supports background via yieldMs/background)",
- "- process: manage background bash sessions",
- "- whatsapp_login: generate a WhatsApp QR code and wait for linking",
- "- browser: control clawd's dedicated browser",
- "- canvas: present/eval/snapshot the Canvas",
- "- nodes: list/describe/notify/camera/screen on paired nodes",
- "- cron: manage cron jobs and wake events",
+ "Tool availability (filtered by policy):",
+ toolLines.length > 0
+ ? toolLines.join("\n")
+ : [
+ "Pi lists the standard tools above. This runtime enables:",
+ "- grep: search file contents for patterns",
+ "- find: find files by glob pattern",
+ "- ls: list directory contents",
+ "- bash: run shell commands (supports background via yieldMs/background)",
+ "- process: manage background bash sessions",
+ "- whatsapp_login: generate a WhatsApp QR code and wait for linking",
+ "- browser: control clawd's dedicated browser",
+ "- canvas: present/eval/snapshot the Canvas",
+ "- nodes: list/describe/notify/camera/screen on paired nodes",
+ "- cron: manage cron jobs and wake events",
+ "- sessions_list: list sessions",
+ "- sessions_history: fetch session history",
+ "- sessions_send: send to another session",
+ ].join("\n"),
+ disabledTools.length > 0
+ ? `Unavailable tools (do not call): ${disabledTools.join(", ")}`
+ : "",
"TOOLS.md does not control tool availability; it is user guidance for how to use external tools.",
"",
"## Workspace",