diff --git a/src/auto-reply/reply.directive.test.ts b/src/auto-reply/reply.directive.test.ts index 8ee37bc32..70a940ddf 100644 --- a/src/auto-reply/reply.directive.test.ts +++ b/src/auto-reply/reply.directive.test.ts @@ -190,9 +190,50 @@ describe("directive behavior", () => { }); }); - it("shows off when /think has no argument and no default set", async () => { + it("defaults /think to low for reasoning-capable models when no default set", async () => { await withTempHome(async (home) => { vi.mocked(runEmbeddedPiAgent).mockReset(); + vi.mocked(loadModelCatalog).mockResolvedValueOnce([ + { + id: "claude-opus-4-5", + name: "Opus 4.5", + provider: "anthropic", + reasoning: true, + }, + ]); + + const res = await getReplyFromConfig( + { Body: "/think", From: "+1222", To: "+1222" }, + {}, + { + agents: { + defaults: { + model: "anthropic/claude-opus-4-5", + workspace: path.join(home, "clawd"), + }, + }, + session: { store: path.join(home, "sessions.json") }, + }, + ); + + const text = Array.isArray(res) ? res[0]?.text : res?.text; + expect(text).toContain("Current thinking level: low"); + expect(text).toContain("Options: off, minimal, low, medium, high."); + expect(runEmbeddedPiAgent).not.toHaveBeenCalled(); + }); + }); + + it("shows off when /think has no argument and model lacks reasoning", async () => { + await withTempHome(async (home) => { + vi.mocked(runEmbeddedPiAgent).mockReset(); + vi.mocked(loadModelCatalog).mockResolvedValueOnce([ + { + id: "claude-opus-4-5", + name: "Opus 4.5", + provider: "anthropic", + reasoning: false, + }, + ]); const res = await getReplyFromConfig( { Body: "/think", From: "+1222", To: "+1222" }, diff --git a/src/auto-reply/reply.ts b/src/auto-reply/reply.ts index 05c2ea186..78b2b134b 100644 --- a/src/auto-reply/reply.ts +++ b/src/auto-reply/reply.ts @@ -673,7 +673,8 @@ export async function getReplyFromConfig( ) { const currentThinkLevel = (sessionEntry?.thinkingLevel as ThinkLevel | undefined) ?? - (agentCfg?.thinkingDefault as ThinkLevel | undefined); + (agentCfg?.thinkingDefault as ThinkLevel | undefined) ?? + (await modelState.resolveDefaultThinkingLevel()); const currentVerboseLevel = (sessionEntry?.verboseLevel as VerboseLevel | undefined) ?? (agentCfg?.verboseDefault as VerboseLevel | undefined);