forked from farhoodlabs/paperclip
Recover agent instructions from disk
Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
@@ -236,4 +236,42 @@ describe("agent instructions bundle routes", () => {
|
||||
expect.any(Object),
|
||||
);
|
||||
});
|
||||
|
||||
it("merges same-adapter config patches so instructions metadata is not dropped", async () => {
|
||||
mockAgentService.getById.mockResolvedValue({
|
||||
...makeAgent(),
|
||||
adapterType: "codex_local",
|
||||
adapterConfig: {
|
||||
instructionsBundleMode: "managed",
|
||||
instructionsRootPath: "/tmp/agent-1",
|
||||
instructionsEntryFile: "AGENTS.md",
|
||||
instructionsFilePath: "/tmp/agent-1/AGENTS.md",
|
||||
model: "gpt-5.4",
|
||||
},
|
||||
});
|
||||
|
||||
const res = await request(createApp())
|
||||
.patch("/api/agents/11111111-1111-4111-8111-111111111111?companyId=company-1")
|
||||
.send({
|
||||
adapterConfig: {
|
||||
command: "codex --profile engineer",
|
||||
},
|
||||
});
|
||||
|
||||
expect(res.status, JSON.stringify(res.body)).toBe(200);
|
||||
expect(mockAgentService.update).toHaveBeenCalledWith(
|
||||
"11111111-1111-4111-8111-111111111111",
|
||||
expect.objectContaining({
|
||||
adapterConfig: expect.objectContaining({
|
||||
command: "codex --profile engineer",
|
||||
model: "gpt-5.4",
|
||||
instructionsBundleMode: "managed",
|
||||
instructionsRootPath: "/tmp/agent-1",
|
||||
instructionsEntryFile: "AGENTS.md",
|
||||
instructionsFilePath: "/tmp/agent-1/AGENTS.md",
|
||||
}),
|
||||
}),
|
||||
expect.any(Object),
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -192,4 +192,88 @@ describe("agent instructions service", () => {
|
||||
expect(bundle.files.map((file) => file.path)).toEqual(["AGENTS.md"]);
|
||||
expect(exported.files).toEqual({ "AGENTS.md": "# Recovered Agent\n" });
|
||||
});
|
||||
|
||||
it("prefers the managed bundle on disk when managed metadata points at a stale root", async () => {
|
||||
const paperclipHome = await makeTempDir("paperclip-agent-instructions-stale-managed-");
|
||||
const staleRoot = await makeTempDir("paperclip-agent-instructions-stale-root-");
|
||||
cleanupDirs.add(paperclipHome);
|
||||
cleanupDirs.add(staleRoot);
|
||||
process.env.PAPERCLIP_HOME = paperclipHome;
|
||||
process.env.PAPERCLIP_INSTANCE_ID = "test-instance";
|
||||
|
||||
const managedRoot = path.join(
|
||||
paperclipHome,
|
||||
"instances",
|
||||
"test-instance",
|
||||
"companies",
|
||||
"company-1",
|
||||
"agents",
|
||||
"agent-1",
|
||||
"instructions",
|
||||
);
|
||||
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: staleRoot,
|
||||
instructionsEntryFile: "docs/MISSING.md",
|
||||
instructionsFilePath: path.join(staleRoot, "docs", "MISSING.md"),
|
||||
});
|
||||
|
||||
const bundle = await svc.getBundle(agent);
|
||||
const exported = await svc.exportFiles(agent);
|
||||
|
||||
expect(bundle.mode).toBe("managed");
|
||||
expect(bundle.rootPath).toBe(managedRoot);
|
||||
expect(bundle.entryFile).toBe("AGENTS.md");
|
||||
expect(bundle.files.map((file) => file.path)).toEqual(["AGENTS.md"]);
|
||||
expect(bundle.warnings).toEqual([
|
||||
`Recovered managed instructions from disk at ${managedRoot}; ignoring stale configured root ${staleRoot}.`,
|
||||
"Recovered managed instructions entry file from disk as AGENTS.md; previous entry docs/MISSING.md was missing.",
|
||||
]);
|
||||
expect(exported.files).toEqual({ "AGENTS.md": "# Managed Agent\n" });
|
||||
});
|
||||
|
||||
it("recovers the managed bundle when stale root metadata is present but mode is missing", async () => {
|
||||
const paperclipHome = await makeTempDir("paperclip-agent-instructions-partial-managed-");
|
||||
const staleRoot = await makeTempDir("paperclip-agent-instructions-partial-root-");
|
||||
cleanupDirs.add(paperclipHome);
|
||||
cleanupDirs.add(staleRoot);
|
||||
process.env.PAPERCLIP_HOME = paperclipHome;
|
||||
process.env.PAPERCLIP_INSTANCE_ID = "test-instance";
|
||||
|
||||
const managedRoot = path.join(
|
||||
paperclipHome,
|
||||
"instances",
|
||||
"test-instance",
|
||||
"companies",
|
||||
"company-1",
|
||||
"agents",
|
||||
"agent-1",
|
||||
"instructions",
|
||||
);
|
||||
await fs.mkdir(managedRoot, { recursive: true });
|
||||
await fs.writeFile(path.join(managedRoot, "AGENTS.md"), "# Managed Agent\n", "utf8");
|
||||
|
||||
const svc = agentInstructionsService();
|
||||
const agent = makeAgent({
|
||||
instructionsRootPath: staleRoot,
|
||||
instructionsEntryFile: "docs/MISSING.md",
|
||||
});
|
||||
|
||||
const bundle = await svc.getBundle(agent);
|
||||
const exported = await svc.exportFiles(agent);
|
||||
|
||||
expect(bundle.mode).toBe("managed");
|
||||
expect(bundle.rootPath).toBe(managedRoot);
|
||||
expect(bundle.entryFile).toBe("AGENTS.md");
|
||||
expect(bundle.files.map((file) => file.path)).toEqual(["AGENTS.md"]);
|
||||
expect(bundle.warnings).toEqual([
|
||||
`Recovered managed instructions from disk at ${managedRoot}; ignoring stale configured root ${staleRoot}.`,
|
||||
"Recovered managed instructions entry file from disk as AGENTS.md; previous entry docs/MISSING.md was missing.",
|
||||
]);
|
||||
expect(exported.files).toEqual({ "AGENTS.md": "# Managed Agent\n" });
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user