forked from bai/curriculum-project-hub
122 lines
4.2 KiB
TypeScript
122 lines
4.2 KiB
TypeScript
import { afterAll, beforeEach, describe, expect, it } from "vitest";
|
|
import { DatabaseRuntimeSettings } from "../../src/settings/runtime.js";
|
|
import { DEFAULT_ORG_ID, prisma, resetDb, seedTestOrganization, testSecretEnvelope } from "./helpers.js";
|
|
|
|
describe("Organization-scoped Agent runtime configuration", () => {
|
|
beforeEach(async () => {
|
|
await resetDb();
|
|
});
|
|
|
|
afterAll(async () => {
|
|
await prisma.$disconnect();
|
|
});
|
|
|
|
it("resolves role prompt, model, tools and skills from the project Organization", async () => {
|
|
await seedTestOrganization("org_other", "other");
|
|
await Promise.all([
|
|
prisma.project.create({
|
|
data: { id: "project-a", organizationId: DEFAULT_ORG_ID, name: "A", workspaceDir: "/tmp/a" },
|
|
}),
|
|
prisma.project.create({
|
|
data: { id: "project-b", organizationId: "org_other", name: "B", workspaceDir: "/tmp/b" },
|
|
}),
|
|
]);
|
|
const [skillA, skillB] = await Promise.all([
|
|
prisma.organizationAgentSkill.create({
|
|
data: {
|
|
id: "skill-a",
|
|
organizationId: DEFAULT_ORG_ID,
|
|
name: "typst",
|
|
version: "0.15.0",
|
|
contentDigest: "a".repeat(64),
|
|
},
|
|
}),
|
|
prisma.organizationAgentSkill.create({
|
|
data: {
|
|
id: "skill-b",
|
|
organizationId: "org_other",
|
|
name: "typst",
|
|
version: "other",
|
|
contentDigest: "b".repeat(64),
|
|
},
|
|
}),
|
|
]);
|
|
const [roleA, roleB] = await Promise.all([
|
|
prisma.organizationAgentRole.create({
|
|
data: {
|
|
id: "role-a",
|
|
organizationId: DEFAULT_ORG_ID,
|
|
roleId: "draft",
|
|
label: "A Draft",
|
|
defaultModel: "anthropic/claude-sonnet-5",
|
|
systemPrompt: "prompt-a",
|
|
tools: ["read_file", "cph_build"],
|
|
},
|
|
}),
|
|
prisma.organizationAgentRole.create({
|
|
data: {
|
|
id: "role-b",
|
|
organizationId: "org_other",
|
|
roleId: "draft",
|
|
label: "B Draft",
|
|
systemPrompt: "prompt-b",
|
|
tools: [],
|
|
},
|
|
}),
|
|
]);
|
|
await Promise.all([
|
|
prisma.organizationAgentRoleSkill.create({
|
|
data: { organizationId: DEFAULT_ORG_ID, agentRoleId: roleA.id, agentSkillId: skillA.id },
|
|
}),
|
|
prisma.organizationAgentRoleSkill.create({
|
|
data: { organizationId: "org_other", agentRoleId: roleB.id, agentSkillId: skillB.id },
|
|
}),
|
|
]);
|
|
const settings = new DatabaseRuntimeSettings(prisma, testSecretEnvelope, {});
|
|
|
|
const registryA = await settings.modelRegistry({ projectId: "project-a" });
|
|
const registryB = await settings.modelRegistry({ projectId: "project-b" });
|
|
|
|
expect(registryA.role("draft")).toMatchObject({
|
|
label: "A Draft",
|
|
systemPrompt: "prompt-a",
|
|
tools: ["read_file", "cph_build"],
|
|
skills: [{ name: "typst", version: "0.15.0", contentDigest: "a".repeat(64) }],
|
|
});
|
|
expect(registryB.role("draft")).toMatchObject({
|
|
label: "B Draft",
|
|
systemPrompt: "prompt-b",
|
|
tools: [],
|
|
skills: [{ name: "typst", version: "other", contentDigest: "b".repeat(64) }],
|
|
});
|
|
});
|
|
|
|
it("fails closed for missing scope and disabled role skills", async () => {
|
|
await prisma.project.create({
|
|
data: { id: "project-a", organizationId: DEFAULT_ORG_ID, name: "A", workspaceDir: "/tmp/a" },
|
|
});
|
|
const skill = await prisma.organizationAgentSkill.create({
|
|
data: {
|
|
id: "skill-disabled",
|
|
organizationId: DEFAULT_ORG_ID,
|
|
name: "typst",
|
|
version: "0.15.0",
|
|
contentDigest: "c".repeat(64),
|
|
disabledAt: new Date(),
|
|
},
|
|
});
|
|
const role = await prisma.organizationAgentRole.create({
|
|
data: { id: "role-a", organizationId: DEFAULT_ORG_ID, roleId: "draft", label: "Draft" },
|
|
});
|
|
await prisma.organizationAgentRoleSkill.create({
|
|
data: { organizationId: DEFAULT_ORG_ID, agentRoleId: role.id, agentSkillId: skill.id },
|
|
});
|
|
const settings = new DatabaseRuntimeSettings(prisma, testSecretEnvelope, {});
|
|
|
|
await expect(settings.modelRegistry()).rejects.toThrow("projectId is required");
|
|
await expect(settings.modelRegistry({ projectId: "project-a" })).rejects.toThrow(
|
|
"role draft selects disabled skill typst",
|
|
);
|
|
});
|
|
});
|