Bots get list_hooks, pause_hook and delete_hook, which act directly since they only take away. A new hook, or a new name, brief or filter, or switching a paused one back on, goes through propose_hook: it stores a hook_proposals row and puts a [hook-proposal:ID] card in the reply, which the user it was proposed to confirms or rejects. The card is read from what Confirm saves, with the bot's reason labelled as its own; confirming checks everything again and saves through the Hooks modal's helpers. A new hook's URL is shown on the card once, to the user only, never in the outcome the bot is told. What calls a hook, its computers and its signing are never proposed. Only chat replies propose, and a hook call's own run gets no hook tools, so a caller's payload can't reach them. Co-Authored-By: Claude Opus 5.5 <[email protected]>
70 lines
2.3 KiB
TypeScript
70 lines
2.3 KiB
TypeScript
import { describe, expect, test } from "bun:test";
|
|
import { CoordinatorSystemPrompt } from "./coordinator-system-prompt";
|
|
import { SiteData } from "./site-data";
|
|
|
|
/**
|
|
* The prompt's own guarantees: it is markdown that names the product, it
|
|
* keeps the real task statuses and the reply/task split, and every tool it
|
|
* names is one a coordinator actually gets.
|
|
*/
|
|
describe("CoordinatorSystemPrompt", () => {
|
|
test("is markdown that opens with the coordinator heading", () => {
|
|
expect(CoordinatorSystemPrompt.startsWith("# You Are the Coordinator")).toBe(
|
|
true,
|
|
);
|
|
expect(CoordinatorSystemPrompt).toContain("\n## 1. ");
|
|
});
|
|
|
|
test("names the product from SiteData", () => {
|
|
expect(CoordinatorSystemPrompt).toContain(SiteData["SiteName"]);
|
|
});
|
|
|
|
test("has no em dashes", () => {
|
|
expect(CoordinatorSystemPrompt).not.toContain(String.fromCharCode(0x2014));
|
|
});
|
|
|
|
test("uses the real task statuses, not invented ones", () => {
|
|
for (const status of ["todo", "doing", "blocked", "done", "cancelled"]) {
|
|
expect(CoordinatorSystemPrompt).toContain(status);
|
|
}
|
|
|
|
// Words from the previous draft that no tool accepts.
|
|
for (const stale of ["Verified:", "**Requested:**", "**Queued:**"]) {
|
|
expect(CoordinatorSystemPrompt).not.toContain(stale);
|
|
}
|
|
});
|
|
|
|
test("names the tools it tells the coordinator to use", () => {
|
|
const tools = [
|
|
"start_task",
|
|
"delegate_task",
|
|
"hand_over_schedule",
|
|
"create_bot",
|
|
"create_workspace",
|
|
"update_workspace",
|
|
"set_bot_workspace_instructions",
|
|
"update_instructions",
|
|
"update_memory",
|
|
"list_tasks",
|
|
"update_task",
|
|
"create_schedule",
|
|
"list_schedules",
|
|
"update_schedule",
|
|
"delete_schedule",
|
|
"propose_hook",
|
|
"list_hooks",
|
|
"pause_hook",
|
|
"delete_hook",
|
|
"search_computers",
|
|
"ask_user_to_take_over",
|
|
"write_file",
|
|
"make_pdf",
|
|
"generate_image",
|
|
];
|
|
|
|
for (const tool of tools) {
|
|
expect(CoordinatorSystemPrompt).toContain(tool);
|
|
}
|
|
});
|
|
});
|