import { describe, expect, it } from "vitest"; import { buildSystemPrompt, buildUserMessage } from "../../src/agent/prompts"; describe("buildSystemPrompt", () => { it("includes Clawbook identity", () => { const prompt = buildSystemPrompt(); expect(prompt).toContain("Clawbook"); expect(prompt).toContain("on-chain social network"); }); it("includes behavioral rules", () => { const prompt = buildSystemPrompt(); expect(prompt).toContain("read the feed"); expect(prompt).toContain("Max"); }); it("includes bot identity when provided", () => { const prompt = buildSystemPrompt({ idKey: "abc123idkey", name: "TestBot", }); expect(prompt).toContain("abc123idkey"); expect(prompt).toContain("TestBot"); }); it("includes current UTC timestamp", () => { const before = new Date().toISOString().slice(0, 13); const prompt = buildSystemPrompt(); const after = new Date().toISOString().slice(0, 13); expect(prompt.includes(before) || prompt.includes(after)).toBe(true); }); it("mentions MCP server tools without listing them individually", () => { const prompt = buildSystemPrompt(); expect(prompt).toContain("15 tools"); expect(prompt).toContain("clawbook MCP server"); expect(prompt).not.toContain("## Available Tools"); }); it("mentions registration tool", () => { const prompt = buildSystemPrompt(); expect(prompt).toContain("register_agent"); }); it("includes engagement behavior in system prompt", () => { const prompt = buildSystemPrompt(); expect(prompt).toContain("Engagement"); expect(prompt).toContain("mention"); }); it("includes personality section", () => { const prompt = buildSystemPrompt(); expect(prompt).toContain("Personality"); expect(prompt).toContain("Thoughtful"); }); it("is concise without Moltbook (under 400 tokens rough estimate)", () => { const prompt = buildSystemPrompt(); const roughTokens = prompt.length / 4; expect(roughTokens).toBeLessThan(400); }); it("includes Moltbook section when networks.moltbook is true", () => { const prompt = buildSystemPrompt(undefined, { moltbook: true }); expect(prompt).toContain("Moltbook"); expect(prompt).toContain("submolts"); expect(prompt).toContain("39 tools"); expect(prompt).toContain("moltbook MCP server"); expect(prompt).toContain("Cross-Network Strategy"); expect(prompt).toContain("Check DMs"); }); it("does NOT include Moltbook when networks is undefined", () => { const prompt = buildSystemPrompt(); expect(prompt).not.toContain("Moltbook"); expect(prompt).not.toContain("submolts"); }); it("does NOT include Moltbook when networks.moltbook is false", () => { const prompt = buildSystemPrompt(undefined, { moltbook: false }); expect(prompt).not.toContain("Moltbook"); }); }); describe("buildUserMessage", () => { it("scheduled_post biases toward creating content", () => { const msg = buildUserMessage("scheduled_post"); expect(msg).toContain("post"); }); it("heartbeat biases toward engagement", () => { const msg = buildUserMessage("heartbeat"); expect(msg).toContain("engage"); }); it("heartbeat mentions scanning for mentions", () => { const msg = buildUserMessage("heartbeat"); expect(msg).toContain("Scan"); expect(msg).toContain("mention"); }); it("heartbeat includes bot name when identity provided", () => { const msg = buildUserMessage("heartbeat", { idKey: "abc123", name: "Clark", }); expect(msg).toContain("Clark"); }); it("heartbeat includes engagement guidelines content", () => { const msg = buildUserMessage("heartbeat"); expect(msg).toContain("channels"); expect(msg).toContain("conversations"); }); it("manual gives free choice", () => { const msg = buildUserMessage("manual"); expect(msg.length).toBeGreaterThan(0); }); it("all non-conversation triggers instruct reading the feed first", () => { for (const trigger of ["scheduled_post", "heartbeat", "manual"] as const) { const msg = buildUserMessage(trigger); expect(msg).toContain("feed"); } }); it("user message with moltbook includes Moltbook hint", () => { for (const trigger of ["scheduled_post", "heartbeat", "manual"] as const) { const msg = buildUserMessage(trigger, undefined, { moltbook: true }); expect(msg).toContain("Moltbook"); } }); it("user message without moltbook does NOT include Moltbook hint", () => { const msg = buildUserMessage("scheduled_post"); expect(msg).not.toContain("Moltbook"); }); it("conversation trigger returns custom message when provided", () => { const msg = buildUserMessage("conversation", undefined, undefined, "hello"); expect(msg).toBe("hello"); }); it("conversation trigger returns fallback when no custom message", () => { const msg = buildUserMessage("conversation"); expect(msg).toContain("feed"); }); it("conversation trigger ignores moltbook hint", () => { const msg = buildUserMessage( "conversation", undefined, { moltbook: true }, "do something", ); expect(msg).toBe("do something"); }); }); describe("buildSystemPrompt conversation mode", () => { it("includes direct message preamble when isConversation is true", () => { const prompt = buildSystemPrompt(undefined, undefined, true); expect(prompt).toContain("direct message"); expect(prompt).toContain("owner"); }); it("does NOT include conversation preamble by default", () => { const prompt = buildSystemPrompt(); expect(prompt).not.toContain("direct message"); }); });