mirror of
https://github.com/alkimake/paperclip.git
synced 2026-06-16 02:40:39 +09:00
124 lines
4.4 KiB
TypeScript
124 lines
4.4 KiB
TypeScript
|
|
import fs from "node:fs/promises";
|
||
|
|
import os from "node:os";
|
||
|
|
import path from "node:path";
|
||
|
|
import { afterEach, describe, expect, it } from "vitest";
|
||
|
|
import { agentInstructionsService } from "../services/agent-instructions.js";
|
||
|
|
|
||
|
|
type TestAgent = {
|
||
|
|
id: string;
|
||
|
|
companyId: string;
|
||
|
|
name: string;
|
||
|
|
adapterConfig: Record<string, unknown>;
|
||
|
|
};
|
||
|
|
|
||
|
|
async function makeTempDir(prefix: string) {
|
||
|
|
return fs.mkdtemp(path.join(os.tmpdir(), prefix));
|
||
|
|
}
|
||
|
|
|
||
|
|
function makeAgent(adapterConfig: Record<string, unknown>): TestAgent {
|
||
|
|
return {
|
||
|
|
id: "agent-1",
|
||
|
|
companyId: "company-1",
|
||
|
|
name: "Agent 1",
|
||
|
|
adapterConfig,
|
||
|
|
};
|
||
|
|
}
|
||
|
|
|
||
|
|
describe("agent instructions service", () => {
|
||
|
|
const originalPaperclipHome = process.env.PAPERCLIP_HOME;
|
||
|
|
const originalPaperclipInstanceId = process.env.PAPERCLIP_INSTANCE_ID;
|
||
|
|
const cleanupDirs = new Set<string>();
|
||
|
|
|
||
|
|
afterEach(async () => {
|
||
|
|
if (originalPaperclipHome === undefined) delete process.env.PAPERCLIP_HOME;
|
||
|
|
else process.env.PAPERCLIP_HOME = originalPaperclipHome;
|
||
|
|
if (originalPaperclipInstanceId === undefined) delete process.env.PAPERCLIP_INSTANCE_ID;
|
||
|
|
else process.env.PAPERCLIP_INSTANCE_ID = originalPaperclipInstanceId;
|
||
|
|
|
||
|
|
await Promise.all([...cleanupDirs].map(async (dir) => {
|
||
|
|
await fs.rm(dir, { recursive: true, force: true });
|
||
|
|
cleanupDirs.delete(dir);
|
||
|
|
}));
|
||
|
|
});
|
||
|
|
|
||
|
|
it("copies the existing bundle into the managed root when switching to managed mode", async () => {
|
||
|
|
const paperclipHome = await makeTempDir("paperclip-agent-instructions-home-");
|
||
|
|
const externalRoot = await makeTempDir("paperclip-agent-instructions-external-");
|
||
|
|
cleanupDirs.add(paperclipHome);
|
||
|
|
cleanupDirs.add(externalRoot);
|
||
|
|
process.env.PAPERCLIP_HOME = paperclipHome;
|
||
|
|
process.env.PAPERCLIP_INSTANCE_ID = "test-instance";
|
||
|
|
|
||
|
|
await fs.writeFile(path.join(externalRoot, "AGENTS.md"), "# External Agent\n", "utf8");
|
||
|
|
await fs.mkdir(path.join(externalRoot, "docs"), { recursive: true });
|
||
|
|
await fs.writeFile(path.join(externalRoot, "docs", "TOOLS.md"), "## Tools\n", "utf8");
|
||
|
|
|
||
|
|
const svc = agentInstructionsService();
|
||
|
|
const agent = makeAgent({
|
||
|
|
instructionsBundleMode: "external",
|
||
|
|
instructionsRootPath: externalRoot,
|
||
|
|
instructionsEntryFile: "AGENTS.md",
|
||
|
|
instructionsFilePath: path.join(externalRoot, "AGENTS.md"),
|
||
|
|
});
|
||
|
|
|
||
|
|
const result = await svc.updateBundle(agent, { mode: "managed" });
|
||
|
|
|
||
|
|
expect(result.bundle.mode).toBe("managed");
|
||
|
|
expect(result.bundle.managedRootPath).toBe(
|
||
|
|
path.join(
|
||
|
|
paperclipHome,
|
||
|
|
"instances",
|
||
|
|
"test-instance",
|
||
|
|
"companies",
|
||
|
|
"company-1",
|
||
|
|
"agents",
|
||
|
|
"agent-1",
|
||
|
|
"instructions",
|
||
|
|
),
|
||
|
|
);
|
||
|
|
expect(result.bundle.files.map((file) => file.path)).toEqual(["AGENTS.md", "docs/TOOLS.md"]);
|
||
|
|
await expect(fs.readFile(path.join(result.bundle.managedRootPath, "AGENTS.md"), "utf8")).resolves.toBe("# External Agent\n");
|
||
|
|
await expect(fs.readFile(path.join(result.bundle.managedRootPath, "docs", "TOOLS.md"), "utf8")).resolves.toBe("## Tools\n");
|
||
|
|
});
|
||
|
|
|
||
|
|
it("creates the target entry file when switching to a new external root", async () => {
|
||
|
|
const paperclipHome = await makeTempDir("paperclip-agent-instructions-home-");
|
||
|
|
const managedRoot = path.join(
|
||
|
|
paperclipHome,
|
||
|
|
"instances",
|
||
|
|
"test-instance",
|
||
|
|
"companies",
|
||
|
|
"company-1",
|
||
|
|
"agents",
|
||
|
|
"agent-1",
|
||
|
|
"instructions",
|
||
|
|
);
|
||
|
|
const externalRoot = await makeTempDir("paperclip-agent-instructions-new-external-");
|
||
|
|
cleanupDirs.add(paperclipHome);
|
||
|
|
cleanupDirs.add(externalRoot);
|
||
|
|
process.env.PAPERCLIP_HOME = paperclipHome;
|
||
|
|
process.env.PAPERCLIP_INSTANCE_ID = "test-instance";
|
||
|
|
|
||
|
|
await fs.mkdir(managedRoot, { recursive: true });
|
||
|
|
await fs.writeFile(path.join(managedRoot, "AGENTS.md"), "# Managed Agent\n", "utf8");
|
||
|
|
|
||
|
|
const svc = agentInstructionsService();
|
||
|
|
const agent = makeAgent({
|
||
|
|
instructionsBundleMode: "managed",
|
||
|
|
instructionsRootPath: managedRoot,
|
||
|
|
instructionsEntryFile: "AGENTS.md",
|
||
|
|
instructionsFilePath: path.join(managedRoot, "AGENTS.md"),
|
||
|
|
});
|
||
|
|
|
||
|
|
const result = await svc.updateBundle(agent, {
|
||
|
|
mode: "external",
|
||
|
|
rootPath: externalRoot,
|
||
|
|
entryFile: "docs/AGENTS.md",
|
||
|
|
});
|
||
|
|
|
||
|
|
expect(result.bundle.mode).toBe("external");
|
||
|
|
expect(result.bundle.rootPath).toBe(externalRoot);
|
||
|
|
await expect(fs.readFile(path.join(externalRoot, "docs", "AGENTS.md"), "utf8")).resolves.toBe("# Managed Agent\n");
|
||
|
|
});
|
||
|
|
});
|