diff --git a/CHANGELOG.md b/CHANGELOG.md index dbc532b2d..4fadc8a0f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ ### Fixes - Agents/System: clarify sandboxed runtime in system prompt and surface elevated availability when sandboxed. +- Agents/System: add reasoning visibility hint + /reasoning and /status guidance in system prompt. - Auto-reply: prefer `RawBody` for command/directive parsing (WhatsApp + Discord) and prevent fallback runs from clobbering concurrent session updates. (#643) — thanks @mcinteerj. - WhatsApp: fix group reactions by preserving message IDs and sender JIDs in history; normalize participant phone numbers to JIDs in outbound reactions. (#640) — thanks @mcinteerj. - WhatsApp: expose group participant IDs to the model so reactions can target the right sender. diff --git a/docs/concepts/system-prompt.md b/docs/concepts/system-prompt.md index c357312c5..d1d254766 100644 --- a/docs/concepts/system-prompt.md +++ b/docs/concepts/system-prompt.md @@ -24,6 +24,7 @@ The prompt is intentionally compact and uses fixed sections: - **Reply Tags**: optional reply tag syntax for supported providers. - **Heartbeats**: heartbeat prompt and ack behavior. - **Runtime**: host, OS, node, model, thinking level (one line). +- **Reasoning**: current visibility level + /reasoning toggle hint. ## Workspace bootstrap injection diff --git a/src/agents/pi-embedded-runner.ts b/src/agents/pi-embedded-runner.ts index e6fc8e75e..d421bf6e0 100644 --- a/src/agents/pi-embedded-runner.ts +++ b/src/agents/pi-embedded-runner.ts @@ -584,6 +584,7 @@ export function buildEmbeddedSandboxInfo( function buildEmbeddedSystemPrompt(params: { workspaceDir: string; defaultThinkLevel?: ThinkLevel; + reasoningLevel?: ReasoningLevel; extraSystemPrompt?: string; ownerNumbers?: string[]; reasoningTagHint: boolean; @@ -608,6 +609,7 @@ function buildEmbeddedSystemPrompt(params: { return buildAgentSystemPrompt({ workspaceDir: params.workspaceDir, defaultThinkLevel: params.defaultThinkLevel, + reasoningLevel: params.reasoningLevel, extraSystemPrompt: params.extraSystemPrompt, ownerNumbers: params.ownerNumbers, reasoningTagHint: params.reasoningTagHint, @@ -921,6 +923,7 @@ export async function compactEmbeddedPiSession(params: { const appendPrompt = buildEmbeddedSystemPrompt({ workspaceDir: effectiveWorkspace, defaultThinkLevel: params.thinkLevel, + reasoningLevel: params.reasoningLevel ?? "off", extraSystemPrompt: params.extraSystemPrompt, ownerNumbers: params.ownerNumbers, reasoningTagHint, @@ -1301,6 +1304,7 @@ export async function runEmbeddedPiAgent(params: { const appendPrompt = buildEmbeddedSystemPrompt({ workspaceDir: effectiveWorkspace, defaultThinkLevel: thinkLevel, + reasoningLevel: params.reasoningLevel ?? "off", extraSystemPrompt: params.extraSystemPrompt, ownerNumbers: params.ownerNumbers, reasoningTagHint, diff --git a/src/agents/system-prompt.test.ts b/src/agents/system-prompt.test.ts index a479bada2..c622ad53d 100644 --- a/src/agents/system-prompt.test.ts +++ b/src/agents/system-prompt.test.ts @@ -170,6 +170,17 @@ describe("buildAgentSystemPrompt", () => { expect(prompt).toContain("capabilities=inlineButtons"); }); + it("includes reasoning visibility hint", () => { + const prompt = buildAgentSystemPrompt({ + workspaceDir: "/tmp/clawd", + reasoningLevel: "off", + }); + + expect(prompt).toContain("Reasoning: off"); + expect(prompt).toContain("/reasoning"); + expect(prompt).toContain("/status shows Reasoning"); + }); + it("describes sandboxed runtime and elevated when allowed", () => { const prompt = buildAgentSystemPrompt({ workspaceDir: "/tmp/clawd", diff --git a/src/agents/system-prompt.ts b/src/agents/system-prompt.ts index 829a82fab..00fcb3075 100644 --- a/src/agents/system-prompt.ts +++ b/src/agents/system-prompt.ts @@ -1,10 +1,11 @@ -import type { ThinkLevel } from "../auto-reply/thinking.js"; +import type { ReasoningLevel, ThinkLevel } from "../auto-reply/thinking.js"; import { SILENT_REPLY_TOKEN } from "../auto-reply/tokens.js"; import type { EmbeddedContextFile } from "./pi-embedded-helpers.js"; export function buildAgentSystemPrompt(params: { workspaceDir: string; defaultThinkLevel?: ThinkLevel; + reasoningLevel?: ReasoningLevel; extraSystemPrompt?: string; ownerNumbers?: string[]; reasoningTagHint?: boolean; @@ -60,7 +61,7 @@ export function buildAgentSystemPrompt(params: { sessions_send: "Send a message to another session/sub-agent", sessions_spawn: "Spawn a sub-agent session", session_status: - "Show a /status-equivalent status card (includes usage + cost when available); optional per-session model override", + "Show a /status-equivalent status card (usage/cost + Reasoning/Verbose/Elevated); optional per-session model override", image: "Analyze an image with the configured image model", }; @@ -139,6 +140,7 @@ export function buildAgentSystemPrompt(params: { "Hey there! What would you like to do next?", ].join(" ") : undefined; + const reasoningLevel = params.reasoningLevel ?? "off"; const userTimezone = params.userTimezone?.trim(); const userTime = params.userTime?.trim(); const skillsPrompt = params.skillsPrompt?.trim(); @@ -361,6 +363,7 @@ export function buildAgentSystemPrompt(params: { ] .filter(Boolean) .join(" | ")}`, + `Reasoning: ${reasoningLevel} (hidden unless on/stream). Toggle /reasoning; /status shows Reasoning when enabled.`, ); return lines.filter(Boolean).join("\n");