test(FN-4517): complete Step 2 — add gating regressions for room posts
Fusion-Task-Id: FN-4517 Fusion-Task-Lineage: 4e582377-3c56-49a4-8e3c-23e652113b61
This commit is contained in:
@@ -54,7 +54,7 @@ type Harness = {
|
||||
agentId: string;
|
||||
};
|
||||
|
||||
async function createHarness(): Promise<Harness> {
|
||||
async function createHarness(permissionPolicy?: any): Promise<Harness> {
|
||||
const rootDir = mkdtempSync(join(tmpdir(), "hb-room-root-"));
|
||||
const globalDir = mkdtempSync(join(tmpdir(), "hb-room-global-"));
|
||||
const taskStore = new TaskStore(rootDir, globalDir, { inMemoryDb: true });
|
||||
@@ -66,6 +66,7 @@ async function createHarness(): Promise<Harness> {
|
||||
role: "engineer",
|
||||
soul: "Surfaces relevant room updates.",
|
||||
runtimeConfig: { enabled: true },
|
||||
...(permissionPolicy ? { permissionPolicy } : {}),
|
||||
});
|
||||
return { rootDir, globalDir, taskStore, agentStore, chatStore, agentId: agent.id };
|
||||
}
|
||||
@@ -187,8 +188,17 @@ describe("heartbeat room messages", () => {
|
||||
expect(sessionCapture.prompt).toContain("(10 more truncated)");
|
||||
});
|
||||
|
||||
it("registers fn_post_room_message and posts through the real ChatStore", async () => {
|
||||
harness = await createHarness();
|
||||
it("registers fn_post_room_message and posts through the real ChatStore under restrictive policy", async () => {
|
||||
harness = await createHarness({
|
||||
presetId: "approval-required",
|
||||
rules: {
|
||||
git_write: "require-approval",
|
||||
file_write_delete: "require-approval",
|
||||
command_execution: "require-approval",
|
||||
network_api: "require-approval",
|
||||
task_agent_mutation: "require-approval",
|
||||
},
|
||||
});
|
||||
const room = harness.chatStore.createRoom({ name: "reply-room", memberAgentIds: [harness.agentId] });
|
||||
harness.chatStore.addRoomMessage(room.id, { role: "user", content: "can you confirm?" });
|
||||
|
||||
@@ -210,7 +220,10 @@ describe("heartbeat room messages", () => {
|
||||
replyToMessageId: "rmsg-parent",
|
||||
});
|
||||
|
||||
const posted = harness.chatStore.getRoomMessages(room.id).find((message) => message.id === result.details.messageId);
|
||||
expect((result as any).isError).not.toBe(true);
|
||||
expect((result as any)?.details?.requiresApproval).not.toBe(true);
|
||||
|
||||
const posted = harness.chatStore.getRoomMessages(room.id).find((message) => message.id === (result as any).details.messageId);
|
||||
expect(posted).toMatchObject({
|
||||
senderAgentId: harness.agentId,
|
||||
content: "Confirmed.",
|
||||
|
||||
@@ -16,6 +16,7 @@ const FN_3548_COORDINATION_TOOLS = [
|
||||
"fn_agent_org_chart",
|
||||
"fn_send_message",
|
||||
"fn_read_messages",
|
||||
"fn_post_room_message",
|
||||
"fn_memory_search",
|
||||
"fn_memory_get",
|
||||
"fn_memory_append",
|
||||
|
||||
@@ -561,7 +561,9 @@ describe("wrapToolsWithPermanentAgentGating", () => {
|
||||
|
||||
it.each<[
|
||||
"locked-down" | "approval-required",
|
||||
Record<string, "block" | "require-approval">
|
||||
Record<string, "block" | "require-approval">,
|
||||
"fn_send_message" | "fn_post_room_message",
|
||||
Record<string, string>
|
||||
]>([
|
||||
["locked-down", {
|
||||
git_write: "block",
|
||||
@@ -569,19 +571,32 @@ describe("wrapToolsWithPermanentAgentGating", () => {
|
||||
command_execution: "block",
|
||||
network_api: "block",
|
||||
task_agent_mutation: "block",
|
||||
}],
|
||||
}, "fn_send_message", { message: "ping" }],
|
||||
["approval-required", {
|
||||
git_write: "require-approval",
|
||||
file_write_delete: "require-approval",
|
||||
command_execution: "require-approval",
|
||||
network_api: "require-approval",
|
||||
task_agent_mutation: "require-approval",
|
||||
}],
|
||||
])("bypasses wrapping for fn_send_message under %s policy", async (presetId, rules) => {
|
||||
const args = { message: "ping" };
|
||||
}, "fn_send_message", { message: "ping" }],
|
||||
["locked-down", {
|
||||
git_write: "block",
|
||||
file_write_delete: "block",
|
||||
command_execution: "block",
|
||||
network_api: "block",
|
||||
task_agent_mutation: "block",
|
||||
}, "fn_post_room_message", { roomId: "room-1", content: "pong" }],
|
||||
["approval-required", {
|
||||
git_write: "require-approval",
|
||||
file_write_delete: "require-approval",
|
||||
command_execution: "require-approval",
|
||||
network_api: "require-approval",
|
||||
task_agent_mutation: "require-approval",
|
||||
}, "fn_post_room_message", { roomId: "room-1", content: "pong" }],
|
||||
])("bypasses wrapping for %s under %s policy", async (presetId, rules, toolName, args) => {
|
||||
const result = { ok: true, messageId: "msg-1" };
|
||||
const execute = vi.fn().mockResolvedValue(result);
|
||||
const tool = { name: "fn_send_message", label: "Send Message", description: "", parameters: {}, execute };
|
||||
const tool = { name: toolName, label: "Message Tool", description: "", parameters: {}, execute };
|
||||
const createApprovalRequest = vi.fn();
|
||||
const findPendingApprovalRequest = vi.fn();
|
||||
const { wrapToolsWithPermanentAgentGating } = await import("../pi.js");
|
||||
@@ -771,15 +786,18 @@ describe("wrapToolsWithActionGate", () => {
|
||||
|
||||
it.each<[
|
||||
"locked-down" | "approval-required",
|
||||
typeof lockedDownRules | typeof approvalRules
|
||||
typeof lockedDownRules | typeof approvalRules,
|
||||
"fn_send_message" | "fn_post_room_message",
|
||||
Record<string, string>
|
||||
]>([
|
||||
["locked-down", lockedDownRules],
|
||||
["approval-required", approvalRules],
|
||||
])("bypasses wrapping for fn_send_message under %s policy", async (presetId, rules) => {
|
||||
const args = { message: "ping" };
|
||||
["locked-down", lockedDownRules, "fn_send_message", { message: "ping" }],
|
||||
["approval-required", approvalRules, "fn_send_message", { message: "ping" }],
|
||||
["locked-down", lockedDownRules, "fn_post_room_message", { roomId: "room-1", content: "pong" }],
|
||||
["approval-required", approvalRules, "fn_post_room_message", { roomId: "room-1", content: "pong" }],
|
||||
])("bypasses wrapping for %s under %s policy", async (presetId, rules, toolName, args) => {
|
||||
const result = { ok: true, messageId: "msg-2" };
|
||||
const execute = vi.fn().mockResolvedValue(result);
|
||||
const tool = { name: "fn_send_message", label: "Send Message", description: "", parameters: {}, execute };
|
||||
const tool = { name: toolName, label: "Message Tool", description: "", parameters: {}, execute };
|
||||
const createApprovalRequest = vi.fn();
|
||||
const pauseForApproval = vi.fn();
|
||||
const { wrapToolsWithActionGate } = await import("../pi.js");
|
||||
|
||||
Reference in New Issue
Block a user