Files
AgentCompany/tests/integration/skill-aware-assignment.spec.ts
T
2026-04-17 14:03:56 -04:00

227 lines
6.7 KiB
TypeScript

import { mkdtemp, rm } from "node:fs/promises";
import { join } from "node:path";
import { tmpdir } from "node:os";
import { afterEach, describe, expect, it } from "vitest";
import { randomUUID } from "node:crypto";
import { AppDatabase } from "../../src/main/database";
import { buildTaskPrompt } from "../../src/main/prompt-builder";
const tempDirs: string[] = [];
async function createTempDir(prefix: string) {
const dir = await mkdtemp(join(tmpdir(), prefix));
tempDirs.push(dir);
return dir;
}
afterEach(async () => {
await Promise.all(tempDirs.splice(0).map((dir) => rm(dir, { recursive: true, force: true })));
});
describe("skill-aware capability registry", () => {
it("autoAssignTask prefers an agent whose assigned skill matches the task, even when capability text is generic", async () => {
const profileDir = await createTempDir("agentcompany-skill-assign-");
const db = new AppDatabase(profileDir);
db.init();
db.updateConnectorHealth({
id: "openai-codex",
status: "ready",
authState: "authenticated",
version: "test",
lastError: null,
});
const companyId = db.saveCompany({
name: "Skill Match Co",
description: "Tests skill-aware assignment",
status: "active",
});
const workspaceId = db.saveWorkspace({
companyId,
name: "Primary",
localPath: profileDir,
repoUrl: "",
repoRef: "",
isPrimary: true,
});
db.saveAgent({
companyId,
name: "Generic Engineer",
role: "Engineer",
title: "Engineer",
status: "active",
reportsTo: null,
connectorId: "openai-codex",
workspaceId,
model: null,
capabilities: "General software delivery",
budgetMonthlyUsd: 200,
});
const styledEngineerId = db.saveAgent({
companyId,
name: "Frontend Specialist",
role: "Engineer",
title: "Frontend Specialist",
status: "active",
reportsTo: null,
connectorId: "openai-codex",
workspaceId,
model: null,
capabilities: "General software delivery",
budgetMonthlyUsd: 200,
});
const skillId = randomUUID();
const now = new Date().toISOString();
db.upsertCompanySkill({
id: skillId,
companyId,
key: "frontend/react-ui",
slug: "react-ui",
name: "React UI",
description: "Build React components with hooks, Tailwind, and accessible layouts",
markdown: "# React UI\nUse when building React components with hooks and Tailwind.",
sourceType: "local_path",
sourceLocator: null,
sourceRef: null,
trustLevel: "markdown_only",
compatibility: "compatible",
fileInventory: "[]",
metadata: null,
createdAt: now,
updatedAt: now,
});
db.assignSkillToAgent(styledEngineerId, skillId);
const taskId = db.saveTask({
companyId,
title: "Build React dashboard widget",
description: "Create an accessible React component with hooks and Tailwind styling.",
workspaceId,
priority: "high",
status: "todo",
});
const assignedId = db.autoAssignTask(taskId, companyId);
expect(assignedId).toBe(styledEngineerId);
db.close();
});
it("injects the company capability registry into the task prompt", async () => {
const profileDir = await createTempDir("agentcompany-capability-prompt-");
const db = new AppDatabase(profileDir);
db.init();
db.updateConnectorHealth({
id: "openai-codex",
status: "ready",
authState: "authenticated",
version: "test",
lastError: null,
});
const companyId = db.saveCompany({
name: "Registry Co",
description: "Tests capability registry prompt injection",
status: "active",
});
const workspaceId = db.saveWorkspace({
companyId,
name: "Primary",
localPath: profileDir,
repoUrl: "",
repoRef: "",
isPrimary: true,
});
const agentId = db.saveAgent({
companyId,
name: "CEO",
role: "CEO",
title: "Chief Executive Officer",
status: "active",
reportsTo: null,
connectorId: "openai-codex",
workspaceId,
model: null,
capabilities: "Lead the company",
budgetMonthlyUsd: 250,
});
const skillId = randomUUID();
const now = new Date().toISOString();
db.upsertCompanySkill({
id: skillId,
companyId,
key: "frontend/react-ui",
slug: "react-ui",
name: "React UI",
description: "Use when building React interfaces",
markdown: "# React UI\nUse when building React interfaces.",
sourceType: "local_path",
sourceLocator: null,
sourceRef: null,
trustLevel: "markdown_only",
compatibility: "compatible",
fileInventory: "[]",
metadata: null,
createdAt: now,
updatedAt: now,
});
const snapshot = db.listSnapshot();
const prompt = buildTaskPrompt({
agent: db.getAgent(agentId),
apiUrl: "http://127.0.0.1:3210",
apiKey: "token",
runId: "run-1",
task: null,
companyName: "Registry Co",
companyDescription: "Tests capability registry prompt injection",
goals: [],
projects: [],
directReports: [],
chainOfCommand: [],
assignedTasks: [],
allAgents: snapshot.agents.filter((entry) => entry.companyId === companyId),
pendingApprovals: [],
tasksAwaitingReview: [],
wakeReason: "assignment",
allTasks: [],
recentComments: [],
socialAccounts: [],
allConnectors: snapshot.connectors
.filter((connector) => connector.id === "openai-codex")
.map((connector) => ({ id: connector.id, label: connector.label, status: connector.status, enabledModels: ["gpt-5.4"] })),
companySkillCatalog: db.listCompanySkills(companyId).map((skill) => ({
name: skill.name,
slug: skill.slug,
description: skill.description,
})),
companyWorkspaces: snapshot.workspaces
.filter((workspace) => workspace.companyId === companyId)
.map((workspace) => ({ name: workspace.name, localPath: workspace.localPath })),
companyDocuments: [],
skills: [
{
name: "react-standards",
description: "Use when building React UI with hooks and Tailwind.",
filePath: "/tmp/react-standards/SKILL.md",
baseDir: "/tmp/react-standards",
},
],
});
expect(prompt).toContain("# Company Capability Registry");
expect(prompt).toContain("React UI (`react-ui`)");
expect(prompt).toContain("Primary:");
expect(prompt).toContain("Ready Connectors");
expect(prompt).toContain("<available_skills>");
expect(prompt).toContain("<name>react-standards</name>");
db.close();
});
});