server/bot-overview.test.ts
Rama main · réplica de lectura del repositorio original.
import { describe, expect, it } from "vitest";
import { buildBotOverview, connectedAppsFacts, grantsSummary, setupSteps, soulLead, type OverviewFacts } from "./bot-overview.ts";
function baseFacts(overrides: Partial<OverviewFacts> = {}): OverviewFacts {
return {
bot: {
name: "Kiwi",
title: "Tracker",
description: "Files bugs.",
soul: "",
computer: "off",
cloudBackend: undefined,
cwd: undefined,
autoApprove: false,
composio: undefined,
browser: undefined,
chiefOfStaff: undefined,
},
routines: [],
runs: [],
webhooks: [],
skills: [],
engine: null,
connectedApps: { configured: false, authoritative: true, services: [] },
sectionPeers: 0,
timeZone: "UTC",
recent: [],
...overrides,
};
}
const WONT_ORDER = [
"Command approvals use Ask mode; saved permissions and provider rules still apply.",
"Has no connected apps.",
"Can't use a computer.",
"Won't act on a schedule.",
"Profile proposal cards require your approval.",
];
describe("buildBotOverview", () => {
it("describes additional departments only for an authorized Chief", () => {
const facts = baseFacts({ bot: { ...baseFacts().bot, chiefOfStaff: true, managedSections: ["Engineering", "Research"] }, engine: { agentsMcp: true }, sectionPeers: 3 });
expect(buildBotOverview(facts).reaches).toContain("Also in charge of these departments: Engineering, Research.");
expect(buildBotOverview(facts).managedSections).toEqual(facts.bot.managedSections);
facts.bot.chiefOfStaff = false;
expect(buildBotOverview(facts).reaches.join(" ")).not.toContain("Engineering");
});
it("says a bot can talk to every other bot", () => {
const open = baseFacts({ bot: baseFacts().bot, engine: { agentsMcp: true }, sectionPeers: 3 });
expect(buildBotOverview(open).reaches).toContain("Can talk to all 3 other bots, in any department.");
expect(buildBotOverview({ ...open, sectionPeers: 1 }).reaches).toContain("Can talk to the other bot.");
});
it("yields all five wont lines in order and no does lines for a bot on Ask", () => {
const overview = buildBotOverview(baseFacts({ bot: { ...baseFacts().bot, approvalMode: "ask" } }));
expect(overview.wont).toEqual(WONT_ORDER);
expect(overview.does).toEqual([]);
});
it("describes a fresh bot at the default level, Full access", () => {
expect(buildBotOverview(baseFacts()).wont).toEqual(WONT_ORDER.slice(1, -1));
});
it("drops the first wont line when autoApprove is on", () => {
const overview = buildBotOverview(baseFacts({ bot: { ...baseFacts().bot, autoApprove: true } }));
expect(overview.wont).toEqual(WONT_ORDER.slice(1));
});
it("uses the effective approval level rather than the legacy Auto bit", () => {
const bot = { ...baseFacts().bot, approvalMode: "full" as const, autoApprove: false };
expect(buildBotOverview(baseFacts({ bot })).wont).not.toContain(WONT_ORDER[0]);
expect(buildBotOverview(baseFacts({ bot: { ...bot, approvalMode: "custom" } })).wont)
.toContain("Command approvals follow the provider's custom configuration.");
});
it("does not promise profile approvals in Full Access", () => {
const bot = { ...baseFacts().bot, approvalMode: "full" as const, autoApprove: false };
expect(buildBotOverview(baseFacts({ bot })).wont).not.toContain("Profile proposal cards require your approval.");
for (const approvalMode of ["ask", "custom"] as const) {
expect(buildBotOverview(baseFacts({ bot: { ...bot, approvalMode, autoApprove: true } })).wont).toContain("Profile proposal cards require your approval.");
}
});
it("does not advertise a browser disabled globally or unsupported by the engine", () => {
const facts = baseFacts({ bot: { ...baseFacts().bot, computer: "browser" }, browserEnabled: true, engine: { browserMcp: false } });
expect(buildBotOverview(facts).reaches).not.toContain("Has the built-in browser.");
facts.engine = { browserMcp: true };
facts.browserEnabled = false;
expect(buildBotOverview(facts).reaches).not.toContain("Has the built-in browser.");
facts.browserEnabled = true;
expect(buildBotOverview(facts).reaches).toContain("Has the built-in browser.");
});
it("renders an enabled interval routine with its last completed run", () => {
const facts = baseFacts({
routines: [
{
id: "r1",
name: "Triage Discord",
enabled: true,
schedule: { type: "interval", everyMinutes: 5, anchorAt: 1_000 },
nextRunAt: 2_000,
},
],
runs: [
{ routineId: "r1", status: "completed", finishedAt: 1_500, scheduledFor: 1_000 },
],
});
const overview = buildBotOverview(facts);
expect(overview.does).toHaveLength(1);
expect(overview.does[0]).toMatch(/^Every 5 minutes: Triage Discord\./);
expect(overview.does[0]).not.toContain("UTC");
expect(overview.does[0]).not.toContain("anchored");
expect(overview.does[0]).toContain("Last run completed at");
expect(overview.does[0]).toContain("Next run");
expect(overview.wont).not.toContain("Won't act on a schedule.");
expect(overview.doesRoutines).toEqual([{ name: "Triage Discord", schedule: { type: "interval", everyMinutes: 5, anchorAt: 1_000 }, nextRunAt: 2_000, lastRun: { status: "completed", at: 1_500 } }]);
});
it("renders a paused routine as Paused: name", () => {
const facts = baseFacts({
routines: [
{
id: "r2",
name: "Nightly Backup",
enabled: false,
schedule: { type: "daily", time: "09:00", weekdays: [1] },
nextRunAt: null,
},
],
});
const overview = buildBotOverview(facts);
expect(overview.does).toEqual(["Paused: Nightly Backup."]);
expect(overview.doesRoutines).toEqual([{ name: "Nightly Backup", paused: true, schedule: { type: "daily", time: "09:00", weekdays: [1] } }]);
expect(overview.wont).toContain("Won't act on a schedule.");
});
it("renders enabled skills and webhooks as their own does lines", () => {
const facts = baseFacts({
skills: [
{ name: "triage", description: "Triage incoming bug reports", enabled: true },
{ name: "disabled-skill", description: "Should not appear", enabled: false },
],
webhooks: [
{ name: "Linear", enabled: true },
{ name: "Disabled hook", enabled: false },
],
});
const overview = buildBotOverview(facts);
expect(overview.does).toEqual([
"Knows how to triage incoming bug reports.",
"Listens for “Linear” webhooks.",
]);
});
it("shows two connected services in reaches", () => {
const facts = baseFacts({
bot: { ...baseFacts().bot, composio: true, computer: "local" },
engine: { composioMcp: true },
connectedApps: { configured: true, authoritative: true, services: ["gmail", "linear"] },
});
const overview = buildBotOverview(facts);
expect(overview.reaches).toContain("Can use 2 connected apps: gmail, linear.");
expect(overview.wont).not.toContain("Has no connected apps.");
});
it("reports connected apps could not be checked when unauthoritative, without also claiming none connected", () => {
const facts = baseFacts({
bot: { ...baseFacts().bot, composio: true, computer: "local" },
engine: { composioMcp: true },
connectedApps: { configured: true, authoritative: false, services: [] },
});
const overview = buildBotOverview(facts);
expect(overview.reaches).toContain("Connected apps could not be checked.");
expect(overview.wont).not.toContain("Has no connected apps.");
expect(overview.reaches.some((line) => line.startsWith("Can use"))).toBe(false);
});
it("states 'Has no connected apps.' when apps are off for the bot, even if the inventory is unverifiable", () => {
// Apps off is a definite negative that needs no inventory — saying
// "could not be checked" here would imply the bot might have apps.
const facts = baseFacts({
bot: { ...baseFacts().bot, composio: false, computer: "local" },
engine: { composioMcp: true },
connectedApps: { configured: true, authoritative: false, services: [] },
});
const overview = buildBotOverview(facts);
expect(overview.wont).toContain("Has no connected apps.");
expect(overview.reaches).not.toContain("Connected apps could not be checked.");
});
it("stays silent about apps in reaches when the engine cannot mount them", () => {
const facts = baseFacts({
bot: { ...baseFacts().bot, composio: true, computer: "local" },
engine: { composioMcp: false },
connectedApps: { configured: true, authoritative: false, services: ["gmail"] },
});
const overview = buildBotOverview(facts);
expect(overview.wont).toContain("Has no connected apps.");
expect(overview.reaches.some((line) => line.includes("connected app"))).toBe(false);
});
it("uses the singular for one connected app", () => {
const facts = baseFacts({
bot: { ...baseFacts().bot, composio: true, computer: "local" },
engine: { composioMcp: true },
connectedApps: { configured: true, authoritative: true, services: ["gmail"] },
});
expect(buildBotOverview(facts).reaches).toContain("Can use 1 connected app: gmail.");
});
it("writes daily and once schedules as prose", () => {
const overview = buildBotOverview(baseFacts({
routines: [
{ id: "a", name: "Standup", enabled: true, schedule: { type: "daily", time: "09:30", weekdays: [1, 2, 3, 4, 5] }, nextRunAt: null },
{ id: "b", name: "Digest", enabled: true, schedule: { type: "daily", time: "18:00", weekdays: [0, 1, 2, 3, 4, 5, 6] }, nextRunAt: null },
{ id: "c", name: "Review", enabled: true, schedule: { type: "daily", time: "08:00", weekdays: [3] }, nextRunAt: null },
{ id: "d", name: "Launch", enabled: true, schedule: { type: "once", at: Date.UTC(2026, 8, 5, 12) }, nextRunAt: null },
{ id: "e", name: "Hourly", enabled: true, schedule: { type: "interval", everyMinutes: 60 }, nextRunAt: null },
],
}));
expect(overview.does).toEqual([
"Every weekday at 9:30 AM: Standup.",
"Every day at 6:00 PM: Digest.",
"Weekly on Wednesday at 8:00 AM: Review.",
"Once on September 5 at 12:00 PM: Launch.",
"Every hour: Hourly.",
]);
});
it("picks a computer automatically when the computer is unset", () => {
const facts = baseFacts({ bot: { ...baseFacts().bot, computer: undefined } });
const overview = buildBotOverview(facts);
expect(overview.reaches).toContain("Computer preference: Auto; availability is checked when a task starts.");
expect(overview.wont).not.toContain("Can't use a computer.");
expect(overview.wont).not.toContain("Won't contact other bots without asking.");
});
it("says a Cloud home cannot use this computer or a Local VM, and changes nothing elsewhere", () => {
const reach = (computer: OverviewFacts["bot"]["computer"], cloudHome?: boolean) =>
buildBotOverview(baseFacts({ bot: { ...baseFacts().bot, computer }, ...(cloudHome === undefined ? {} : { cloudHome }) })).reaches[0];
expect(reach("local", true)).toBe("Computer preference: this computer, which isn't available on My Cloud.");
expect(reach("vm", true)).toBe("Computer preference: Local VM, which isn't available on My Cloud.");
expect(reach("cloud", true)).toBe("Computer preference: cloud computer.");
expect(reach("browser", true)).toBe("Computer preference: browser only.");
expect(reach(undefined, true)).toBe("Computer preference: Auto; availability is checked when a task starts.");
for (const cloudHome of [undefined, false]) {
expect(reach("local", cloudHome)).toBe("Computer preference: this computer.");
expect(reach("vm", cloudHome)).toBe("Computer preference: Local VM.");
}
});
});
describe("soulLead", () => {
it("cuts at the first blank line", () => {
expect(soulLead("First paragraph.\n\nSecond paragraph.")).toBe("First paragraph.");
});
it("cuts at 240 characters", () => {
const long = "A".repeat(300);
const result = soulLead(long);
expect(result).toBe(`${"A".repeat(240)}…`);
});
it("returns an empty string for an unset soul", () => {
expect(soulLead(undefined)).toBe("");
});
});
describe("connectedAppsFacts", () => {
it("lists the connected slugs when the inventory reads cleanly", async () => {
const facts = await connectedAppsFacts(true, "configured", async () => ({
gmail: { connected: true },
linear: { connected: false },
}));
expect(facts).toEqual({ configured: true, authoritative: true, services: ["gmail"] });
});
it("marks the inventory unverified instead of throwing when the read fails", async () => {
const facts = await connectedAppsFacts(true, "configured", async () => {
throw new Error("Connected apps: HTTP 502");
});
expect(facts).toEqual({ configured: true, authoritative: false, services: [] });
});
it("never reads when the connector is unconfigured or the store was unreadable", async () => {
let reads = 0;
const read = async () => {
reads += 1;
return {};
};
expect(await connectedAppsFacts(false, "unconfigured", read)).toEqual({ configured: false, authoritative: true, services: [] });
expect(await connectedAppsFacts(false, "unreadable", read)).toEqual({ configured: false, authoritative: false, services: [] });
expect(reads).toBe(0);
});
});
describe("grantsSummary", () => {
it("stays off the wire for a bot with no grants record", () => {
expect(grantsSummary(undefined)).toBeUndefined();
expect(buildBotOverview(baseFacts()).grants).toBeUndefined();
});
it("summarizes wildcards, exact lists and an explicit no-tools record", () => {
const grants = grantsSummary({
slack: { tools: "*" },
gmail: { tools: ["GMAIL_SEND_EMAIL", "GMAIL_FETCH_EMAILS"] },
});
expect(grants).toEqual([
{ slug: "gmail", level: "partial", toolCount: 2 },
{ slug: "slack", level: "all", toolCount: 0 },
]);
// {} is the explicit no-tools record: an empty list, not an absent one
expect(grantsSummary({})).toEqual([]);
expect(buildBotOverview(baseFacts({ bot: { ...baseFacts().bot, connectorTools: {} } })).grants).toEqual([]);
});
it("rides along in the built overview for a partial grant set", () => {
const connectorTools = { gmail: { tools: ["GMAIL_SEND_EMAIL"] } };
const overview = buildBotOverview(baseFacts({ bot: { ...baseFacts().bot, connectorTools } }));
expect(overview.grants).toEqual([{ slug: "gmail", level: "partial", toolCount: 1 }]);
});
});
describe("setupSteps", () => {
it("lists optional setup ideas without inspecting conversation history", () => {
const steps = setupSteps(baseFacts({ bot: { ...baseFacts().bot, name: "New bot", title: "", description: "" } }));
expect(steps.map((step) => [step.id, step.done])).toEqual([
["identity", false],
["soul", false],
["folder", false],
["schedule", false],
]);
expect(steps.find((step) => step.id === "apps")).toBeUndefined();
expect(steps.every((step) => step.section)).toBe(true);
});
it("marks steps done from the same facts the sentences use", () => {
const facts = baseFacts({
bot: { ...baseFacts().bot, name: "Kiwi", title: "Tracker", soul: "Be brief.", cwd: "/work", composio: true },
engine: { composioMcp: true },
connectedApps: { configured: true, authoritative: true, services: ["gmail"] },
routines: [{ id: "r1", name: "Digest", enabled: true, schedule: { type: "daily", time: "09:00", weekdays: [1, 2, 3, 4, 5] }, nextRunAt: null }],
});
expect(setupSteps(facts).every((step) => step.done)).toBe(true);
expect(setupSteps(facts).map((step) => step.id)).toContain("apps");
expect(buildBotOverview(facts).setup).toEqual(setupSteps(facts));
});
it("does not count an unverified app inventory or a paused routine as done", () => {
const facts = baseFacts({
bot: { ...baseFacts().bot, composio: true },
engine: { composioMcp: true },
connectedApps: { configured: true, authoritative: false, services: ["gmail"] },
routines: [{ id: "r1", name: "Digest", enabled: false, schedule: { type: "daily", time: "09:00", weekdays: [1] }, nextRunAt: null }],
});
const byId = Object.fromEntries(setupSteps(facts).map((step) => [step.id, step.done]));
expect(byId.apps).toBe(false);
expect(byId.schedule).toBe(false);
});
});