Files
openclaw/src/system-agent/assistant.test.ts
Peter Steinberger a6a0716486 feat(setup): rename Crestodian to OpenClaw system agent
User-facing name is now OpenClaw (the system speaks); internal code name is
system-agent. Gateway methods crestodian.* -> openclaw.chat/openclaw.setup.*,
agent tool -> openclaw, reserved agent ids openclaw + retired crestodian.
openclaw setup routes: onboarding flags -> onboard, -m/--yes -> system agent,
bare configured interactive -> OpenClaw chat, unconfigured -> onboarding.
Hidden crestodian CLI and /crestodian TUI aliases kept; docs moved to
docs/cli/openclaw.md with redirect stub. macOS/Android strings in lockstep.

Refs #107237
2026-07-14 11:03:02 -07:00

115 lines
3.5 KiB
TypeScript

// OpenClaw assistant tests cover plan parsing and inference prompt construction.
import { describe, expect, it } from "vitest";
import {
buildSystemAgentAssistantUserPrompt,
parseSystemAgentAssistantPlanText,
} from "./assistant.js";
import type { SystemAgentOverview } from "./overview.js";
function overview(overrides: Partial<SystemAgentOverview["tools"]> = {}): SystemAgentOverview {
return {
config: {
path: "/tmp/openclaw.json",
exists: false,
valid: false,
issues: [],
hash: null,
},
agents: [],
defaultAgentId: "default",
tools: {
codex: { command: "codex", found: false },
claude: { command: "claude", found: false },
gemini: { command: "gemini", found: false },
apiKeys: { openai: false, anthropic: false },
...overrides,
},
gateway: {
url: "ws://127.0.0.1:14567",
source: "local loopback",
reachable: false,
},
references: {
docsUrl: "https://docs.openclaw.ai",
sourceUrl: "https://github.com/openclaw/openclaw",
},
};
}
describe("OpenClaw assistant", () => {
it("parses the first compact JSON command", () => {
expect(
parseSystemAgentAssistantPlanText(
'thinking... {"reply":"Aye aye.","command":"restart gateway"}',
),
).toEqual({
reply: "Aye aye.",
command: "restart gateway",
});
});
it("rejects non-JSON and empty plans but accepts chat-only replies", () => {
expect(parseSystemAgentAssistantPlanText("I would edit config directly.")).toBeNull();
expect(parseSystemAgentAssistantPlanText("{}")).toBeNull();
expect(parseSystemAgentAssistantPlanText('{"reply":"just chatting"}')).toEqual({
reply: "just chatting",
});
});
it("includes only operational summary context in planner prompts", () => {
const prompt = buildSystemAgentAssistantUserPrompt({
input: "fix my setup",
overview: {
...overview({
codex: { command: "codex", found: true, version: "codex 1.0.0" },
apiKeys: { openai: true, anthropic: false },
}),
config: {
path: "/tmp/openclaw.json",
exists: true,
valid: true,
issues: [],
hash: "hash",
},
agents: [
{
id: "main",
name: "Main",
isDefault: true,
model: "openai/gpt-5.5",
workspace: "/tmp/main",
},
],
defaultAgentId: "main",
defaultModel: "openai/gpt-5.5",
references: {
docsPath: "/tmp/openclaw/docs",
docsUrl: "https://docs.openclaw.ai",
sourcePath: "/tmp/openclaw",
sourceUrl: "https://github.com/openclaw/openclaw",
},
},
});
expect(prompt).toContain("User request: fix my setup");
expect(prompt).toContain("Default model: openai/gpt-5.5");
expect(prompt).toContain("id=main, name=Main, workspace=/tmp/main");
expect(prompt).toContain("OpenAI API key: found");
expect(prompt).toContain("OpenClaw docs: /tmp/openclaw/docs");
expect(prompt).toContain("OpenClaw source: /tmp/openclaw");
});
it("keeps truncated conversation history valid at a UTF-16 boundary", () => {
const prefix = "a".repeat(499);
const prompt = buildSystemAgentAssistantUserPrompt({
input: "continue",
overview: overview(),
history: [{ role: "user", text: `${prefix}🎉tail` }],
});
expect(prompt.slice(0, prompt.indexOf("User request:"))).toBe(
`Conversation so far:\nUser: ${prefix}\n\n`,
);
});
});