Files
clawdbot/src/agents/system-prompt.test.ts
2026-01-12 02:49:55 +00:00

202 lines
6.4 KiB
TypeScript

import { describe, expect, it } from "vitest";
import { buildAgentSystemPrompt } from "./system-prompt.js";
describe("buildAgentSystemPrompt", () => {
it("includes owner numbers when provided", () => {
const prompt = buildAgentSystemPrompt({
workspaceDir: "/tmp/clawd",
ownerNumbers: ["+123", " +456 ", ""],
});
expect(prompt).toContain("## User Identity");
expect(prompt).toContain(
"Owner numbers: +123, +456. Treat messages from these numbers as the user.",
);
});
it("omits owner section when numbers are missing", () => {
const prompt = buildAgentSystemPrompt({
workspaceDir: "/tmp/clawd",
});
expect(prompt).not.toContain("## User Identity");
expect(prompt).not.toContain("Owner numbers:");
});
it("adds reasoning tag hint when enabled", () => {
const prompt = buildAgentSystemPrompt({
workspaceDir: "/tmp/clawd",
reasoningTagHint: true,
});
expect(prompt).toContain("## Reasoning Format");
expect(prompt).toContain("<think>...</think>");
expect(prompt).toContain("<final>...</final>");
});
it("lists available tools when provided", () => {
const prompt = buildAgentSystemPrompt({
workspaceDir: "/tmp/clawd",
toolNames: ["exec", "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");
});
it("preserves tool casing in the prompt", () => {
const prompt = buildAgentSystemPrompt({
workspaceDir: "/tmp/clawd",
toolNames: ["Read", "Exec", "process"],
skillsPrompt:
"<available_skills>\n <skill>\n <name>demo</name>\n </skill>\n</available_skills>",
});
expect(prompt).toContain("- Read: Read file contents");
expect(prompt).toContain("- Exec: Run shell commands");
expect(prompt).toContain(
"Use `Read` to load the SKILL.md at the location listed for that skill.",
);
});
it("includes user time when provided", () => {
const prompt = buildAgentSystemPrompt({
workspaceDir: "/tmp/clawd",
userTimezone: "America/Chicago",
userTime: "Monday 2026-01-05 15:26",
});
expect(prompt).toContain(
"Time: assume UTC unless stated. User TZ=America/Chicago. Current user time (converted)=Monday 2026-01-05 15:26.",
);
});
it("includes model alias guidance when aliases are provided", () => {
const prompt = buildAgentSystemPrompt({
workspaceDir: "/tmp/clawd",
modelAliasLines: [
"- Opus: anthropic/claude-opus-4-5",
"- Sonnet: anthropic/claude-sonnet-4-5",
],
});
expect(prompt).toContain("## Model Aliases");
expect(prompt).toContain("Prefer aliases when specifying model overrides");
expect(prompt).toContain("- Opus: anthropic/claude-opus-4-5");
});
it("adds ClaudeBot self-update guidance when gateway tool is available", () => {
const prompt = buildAgentSystemPrompt({
workspaceDir: "/tmp/clawd",
toolNames: ["gateway", "exec"],
});
expect(prompt).toContain("## Clawdbot Self-Update");
expect(prompt).toContain("config.apply");
expect(prompt).toContain("update.run");
});
it("includes skills guidance when skills prompt is present", () => {
const prompt = buildAgentSystemPrompt({
workspaceDir: "/tmp/clawd",
skillsPrompt:
"<available_skills>\n <skill>\n <name>demo</name>\n </skill>\n</available_skills>",
});
expect(prompt).toContain("## Skills");
expect(prompt).toContain(
"Use `read` to load the SKILL.md at the location listed for that skill.",
);
});
it("appends available skills when provided", () => {
const prompt = buildAgentSystemPrompt({
workspaceDir: "/tmp/clawd",
skillsPrompt:
"<available_skills>\n <skill>\n <name>demo</name>\n </skill>\n</available_skills>",
});
expect(prompt).toContain("<available_skills>");
expect(prompt).toContain("<name>demo</name>");
});
it("omits skills section when no skills prompt is provided", () => {
const prompt = buildAgentSystemPrompt({
workspaceDir: "/tmp/clawd",
});
expect(prompt).not.toContain("## Skills");
expect(prompt).not.toContain("<available_skills>");
});
it("renders project context files when provided", () => {
const prompt = buildAgentSystemPrompt({
workspaceDir: "/tmp/clawd",
contextFiles: [
{ path: "AGENTS.md", content: "Alpha" },
{ path: "IDENTITY.md", content: "Bravo" },
],
});
expect(prompt).toContain("# Project Context");
expect(prompt).toContain("## AGENTS.md");
expect(prompt).toContain("Alpha");
expect(prompt).toContain("## IDENTITY.md");
expect(prompt).toContain("Bravo");
});
it("summarizes the message tool when available", () => {
const prompt = buildAgentSystemPrompt({
workspaceDir: "/tmp/clawd",
toolNames: ["message"],
});
expect(prompt).toContain("message: Send messages and provider actions");
expect(prompt).toContain("### message tool");
});
it("includes runtime provider capabilities when present", () => {
const prompt = buildAgentSystemPrompt({
workspaceDir: "/tmp/clawd",
runtimeInfo: {
provider: "telegram",
capabilities: ["inlineButtons"],
},
});
expect(prompt).toContain("provider=telegram");
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",
sandboxInfo: {
enabled: true,
workspaceDir: "/tmp/sandbox",
workspaceAccess: "ro",
agentWorkspaceMount: "/agent",
elevated: { allowed: true, defaultLevel: "on" },
},
});
expect(prompt).toContain("You are running in a sandboxed runtime");
expect(prompt).toContain("Sub-agents stay sandboxed");
expect(prompt).toContain("User can toggle with /elevated on|off.");
expect(prompt).toContain("Current elevated level: on");
});
});