fix(adapters): scope spawnBot replay to spawning member in shared Spaces
spawnKey is unique per Space, not per user. createBot already rejects cross-member replay, but spawnBot caught that error and returned the other member's bot anyway. Match createBot by requiring existing.userId === spawnedBy.userId before treating a spawnKey conflict as idempotent. Co-authored-by: cynarAI <cynarAI@users.noreply.github.com>
This commit is contained in:
parent
33ce657201
commit
4264ef682f
@ -41,6 +41,7 @@ describe("spawned bot creation", () => {
|
||||
id: "child-1",
|
||||
name: "Scout",
|
||||
title: "Venue researcher",
|
||||
userId: "user-1",
|
||||
thread: { id: "thread-1" },
|
||||
});
|
||||
const enqueue = vi.fn().mockResolvedValue(undefined);
|
||||
@ -95,6 +96,45 @@ describe("spawned bot creation", () => {
|
||||
expect(enqueue).toHaveBeenCalledOnce();
|
||||
});
|
||||
|
||||
it("rejects a spawnKey that belongs to another member in the shared Space", async () => {
|
||||
const conflict = new Error("unique spawn key");
|
||||
const findUnique = vi.fn().mockResolvedValue({
|
||||
id: "child-owner",
|
||||
name: "Scout",
|
||||
title: "Venue researcher",
|
||||
userId: "owner-user",
|
||||
thread: { id: "thread-owner" },
|
||||
});
|
||||
const createBot = vi.fn().mockRejectedValue(conflict);
|
||||
const createReposSpy = vi.spyOn(await import("@rakazo/db"), "createRepos").mockReturnValue({
|
||||
createBot,
|
||||
} as unknown as ReturnType<typeof createRepos>);
|
||||
|
||||
await expect(
|
||||
spawnBot(
|
||||
{
|
||||
prisma: { bot: { findUnique } } as unknown as PrismaClient,
|
||||
jobs: { enqueue: vi.fn() } as unknown as JobPublisher,
|
||||
},
|
||||
{
|
||||
spawnedBy: {
|
||||
id: "parent-2",
|
||||
name: "Other",
|
||||
spaceId: "workspace-1",
|
||||
userId: "other-user",
|
||||
},
|
||||
runId: "run-2",
|
||||
spawnKey: "tool-call-shared",
|
||||
name: "Scout",
|
||||
},
|
||||
),
|
||||
).rejects.toThrow("unique spawn key");
|
||||
|
||||
expect(createBot).toHaveBeenCalledOnce();
|
||||
expect(findUnique).toHaveBeenCalledOnce();
|
||||
createReposSpy.mockRestore();
|
||||
});
|
||||
|
||||
it("passes computerMode through to createBot", async () => {
|
||||
const createBot = vi.fn().mockResolvedValue({
|
||||
id: "child-2",
|
||||
|
||||
@ -94,6 +94,7 @@ export async function spawnBot(
|
||||
include: { thread: true },
|
||||
});
|
||||
if (!existing) throw error;
|
||||
if (existing.userId !== input.spawnedBy.userId) throw error;
|
||||
if (!existing.thread) throw new Error(`Spawned bot ${existing.id} is missing its thread`);
|
||||
duplicate = true;
|
||||
created = {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user