import type { MessageBlock } from "@rakazo/contracts"; import { ONCE_ROUTINE_CRON } from "@rakazo/core"; import type { PrismaClient } from "@rakazo/db"; import { describe, expect, it, vi } from "vitest"; import { agentSecretScopeForRun } from "./agent-environment.js"; import { appendToolCompletionAudit, createRunExecutor, createRunWorkspaceCheckpoint, loadCurrentTurnImages, runNotificationsEnabled, selectBuiltinToolsForRun, toolCompletionAuditPayload, toolCompletionFromResult, } from "./executor.js"; import { missingTurnImagesInstruction, settleSteeringAttachmentLoads, } from "./executor-attachments.js"; import { threadContextForRun } from "./executor-completion.js"; import { serializeModelSecret } from "./pi-oauth.js"; describe("tool completion audit", () => { it("records result metadata without persisting tool contents", () => { const payload = toolCompletionAuditPayload({ name: "computer_observe", executionId: "call-1", durationMs: 12.6, result: { kind: "agent_tool_result", content: [ { type: "text", text: "Visible window" }, { type: "image", data: "image-bytes", mimeType: "image/png" }, ], details: { frameId: "frame-1", capturedAt: "2026-09-07T00:00:00.000Z", width: 1280, height: 720, activeWindow: { title: "Private window" }, }, }, }); expect(payload).toEqual({ name: "computer_observe", executionId: "call-1", durationMs: 13, outcome: "succeeded", contentTypes: ["text", "image"], frameId: "frame-1", capturedAt: "2026-09-07T00:00:00.000Z", width: 1280, height: 720, }); expect(payload).not.toHaveProperty("content"); expect(payload).not.toHaveProperty("activeWindow"); }); it("does not fail the run when the audit append fails", async () => { const append = vi.fn().mockRejectedValue(new Error("database unavailable")); await expect( appendToolCompletionAudit( { events: { append } }, { spaceId: "space-1", threadId: "thread-1", botId: "bot-1", runId: "run-1" }, { name: "destination.write", executionId: "call-1", durationMs: 4, error: new Error("Bearer secret-token"), }, ["secret-token"], ), ).resolves.toBeUndefined(); expect(append).toHaveBeenCalledWith( expect.objectContaining({ type: "agent.tool.completed", payload: expect.objectContaining({ outcome: "error", error: "Bearer [redacted]", }), }), ); }); it("records rejected scripted tool results as errors", () => { const completion = toolCompletionFromResult( { name: "destination.write", executionId: "call-1", durationMs: 4 }, { error: "destination rejected the record" }, ); expect(completion).toEqual({ name: "destination.write", executionId: "call-1", durationMs: 4, error: "destination rejected the record", paused: false, }); expect(toolCompletionAuditPayload(completion)).toMatchObject({ outcome: "error", error: "destination rejected the record", }); expect(completion).not.toHaveProperty("result"); }); }); describe("run workspace checkpoint", () => { it("skips clean turns and flushes once after a mutation", async () => { const persist = vi.fn(async () => undefined); const checkpoint = createRunWorkspaceCheckpoint(persist); await expect(checkpoint.flush()).resolves.toBe(false); checkpoint.markDirty(); await expect(checkpoint.flush()).resolves.toBe(true); await expect(checkpoint.flush()).resolves.toBe(false); expect(persist).toHaveBeenCalledOnce(); }); it("marks materialized steering files for checkpointing", async () => { const persist = vi.fn(async () => undefined); const checkpoint = createRunWorkspaceCheckpoint(persist); checkpoint.markFiles([]); await expect(checkpoint.flush()).resolves.toBe(false); checkpoint.markFiles([{ path: "attachments/result.txt" }]); await expect(checkpoint.flush()).resolves.toBe(true); }); it("keeps a failed checkpoint dirty for retry", async () => { const persist = vi .fn<() => Promise>() .mockRejectedValueOnce(new Error("checkpoint failed")) .mockResolvedValueOnce(undefined); const checkpoint = createRunWorkspaceCheckpoint(persist); checkpoint.markDirty(); await expect(checkpoint.flush()).rejects.toThrow("checkpoint failed"); await expect(checkpoint.flush()).resolves.toBe(true); expect(persist).toHaveBeenCalledTimes(2); }); }); describe("run tool selection", () => { it.each([ [false, false], [false, true], [true, false], [true, true], ])("gates page browsers (%s) independently of cloud agents (%s)", (page, cloud) => { const names = selectBuiltinToolsForRun({ graphicalToolsAllowed: false, pageBrowserAllowed: page, cloudAgentEnabled: cloud, groupId: null, trigger: "message", semanticMemoryEnabled: false, messagingChannelRun: false, }).map((tool) => tool.name); expect(names.includes("browser_snapshot")).toBe(page); expect(names.includes("cloud_agent_status")).toBe(cloud); expect(names).not.toContain("computer_act"); }); const toolNames = ( trigger: string, groupId: string | null = null, options?: { graphicalToolsAllowed?: boolean; pageBrowserAllowed?: boolean }, ) => selectBuiltinToolsForRun({ graphicalToolsAllowed: options?.graphicalToolsAllowed ?? true, pageBrowserAllowed: options?.pageBrowserAllowed ?? true, groupId, trigger, semanticMemoryEnabled: false, messagingChannelRun: false, }).map((tool) => tool.name); it("keeps page browser tools without vision, and hides them without a graphical computer", () => { const withPage = toolNames("message", null, { graphicalToolsAllowed: false, pageBrowserAllowed: true, }); expect(withPage).toEqual( expect.arrayContaining(["browser_navigate", "browser_snapshot", "browser_act"]), ); expect(withPage).not.toEqual(expect.arrayContaining(["computer_observe", "computer_act"])); const withoutPage = toolNames("message", null, { graphicalToolsAllowed: true, pageBrowserAllowed: false, }); expect(withoutPage).not.toEqual( expect.arrayContaining(["browser_navigate", "browser_snapshot", "browser_act"]), ); expect(withoutPage).toEqual(expect.arrayContaining(["computer_observe", "computer_act"])); }); it("offers delegate_task to the main bot only", () => { const options = { graphicalToolsAllowed: false, groupId: "group-main", trigger: "user", semanticMemoryEnabled: false, messagingChannelRun: false, }; const names = (mainBot?: boolean) => selectBuiltinToolsForRun({ ...options, mainBot }).map((tool) => tool.name); expect(names(true)).toContain("delegate_task"); expect(names(false)).not.toContain("delegate_task"); expect(names()).not.toContain("delegate_task"); }); it("withholds schedule creation only from routine-triggered runs", () => { expect(toolNames("routine")).not.toContain("schedule_create"); expect(toolNames("routine")).toEqual( expect.arrayContaining(["schedule_list", "schedule_cancel"]), ); expect(toolNames("user")).toContain("schedule_create"); }); it("keeps schedule tools in group chats and still blocks create on routines", () => { expect(toolNames("user", "group-1")).toEqual( expect.arrayContaining(["schedule_create", "schedule_list", "schedule_cancel"]), ); expect(toolNames("routine", "group-1")).not.toContain("schedule_create"); expect(toolNames("routine", "group-1")).toEqual( expect.arrayContaining(["schedule_list", "schedule_cancel"]), ); }); }); describe("steering attachment hydration", () => { it("keeps successful attachment parts when another part is unavailable", async () => { const imageBlocks: MessageBlock[] = [ { kind: "image", artifactId: "image-1", name: "one.png", mimeType: "image/png" }, { kind: "image", artifactId: "image-2", name: "two.png", mimeType: "image/png" }, ]; const withoutImage = await settleSteeringAttachmentLoads( Promise.reject(new Error("image missing")), Promise.resolve(["attachment.pdf"]), ); expect(withoutImage).toMatchObject({ images: undefined, files: ["attachment.pdf"] }); expect(withoutImage.unavailableInstruction).toContain("do not guess its contents"); const withoutFile = await settleSteeringAttachmentLoads( Promise.resolve(["image.png"]), Promise.reject(new Error("file missing")), ); expect(withoutFile).toMatchObject({ images: ["image.png"], files: [] }); expect(withoutFile.unavailableInstruction).toContain("do not guess its contents"); const partiallyHydratedImages = await loadCurrentTurnImages( { artifacts: { get: vi.fn(async () => new Uint8Array([1])) }, prisma: { artifact: { findMany: vi.fn(async () => [{ id: "image-1", storageKey: "one.png" }]), }, }, } as never, imageBlocks, { operationId: "run-1", traceId: "run-1", spaceId: "space-1", userId: "user-1", botId: "bot-1", runId: "run-1", signal: new AbortController().signal, }, ); expect(partiallyHydratedImages).toHaveLength(1); const withPartiallyMissingImages = await settleSteeringAttachmentLoads( Promise.resolve(partiallyHydratedImages), Promise.resolve([]), imageBlocks, ); expect(withPartiallyMissingImages).toMatchObject({ images: partiallyHydratedImages, files: [], }); expect(withPartiallyMissingImages.unavailableInstruction).toContain( "do not guess its contents", ); const withAllImagesMissing = await settleSteeringAttachmentLoads( Promise.resolve(undefined), Promise.resolve([]), imageBlocks.slice(0, 1), ); expect(withAllImagesMissing.unavailableInstruction).toContain("do not guess its contents"); const withoutMissingImages = await settleSteeringAttachmentLoads( Promise.resolve(["image.png"]), Promise.resolve([]), imageBlocks.slice(0, 1), ); expect(withoutMissingImages.unavailableInstruction).toBe(""); const withoutExpectedImages = await settleSteeringAttachmentLoads( Promise.resolve(undefined), Promise.resolve([]), ); expect(withoutExpectedImages.unavailableInstruction).toBe(""); }); it("propagates cancellation while steering attachments settle", async () => { const controller = new AbortController(); const cancellation = new Error("cancelled"); controller.abort(); await expect( settleSteeringAttachmentLoads( Promise.reject(cancellation), Promise.resolve([]), undefined, controller.signal, ), ).rejects.toBe(cancellation); }); it("treats unreadable image bytes as missing instead of failing hydration", async () => { const blocks: MessageBlock[] = [ { kind: "image", artifactId: "image-1", name: "one.png", mimeType: "image/png" }, { kind: "image", artifactId: "image-2", name: "two.png", mimeType: "image/png" }, ]; const images = await loadCurrentTurnImages( { artifacts: { get: vi.fn(async (storageKey: string) => { if (storageKey === "bad.png") throw new Error("read failed"); return new Uint8Array([1]); }), }, prisma: { artifact: { findMany: vi.fn(async () => [ { id: "image-1", storageKey: "one.png" }, { id: "image-2", storageKey: "bad.png" }, ]), }, }, } as never, blocks, { operationId: "run-1", traceId: "run-1", spaceId: "space-1", userId: "user-1", botId: "bot-1", runId: "run-1", signal: new AbortController().signal, }, ); expect(images).toHaveLength(1); expect(missingTurnImagesInstruction(blocks, images)).toContain("do not guess its contents"); const settled = await settleSteeringAttachmentLoads( Promise.resolve(images), Promise.resolve([]), blocks, ); expect(settled.unavailableInstruction).toContain("do not guess its contents"); }); it("does not swallow image hydration cancellation", async () => { const controller = new AbortController(); const cancellation = new Error("cancelled"); controller.abort(cancellation); await expect( loadCurrentTurnImages( { artifacts: { get: vi.fn(async () => Promise.reject(cancellation)) }, prisma: { artifact: { findMany: vi.fn(async () => [{ id: "image-1", storageKey: "one.png" }]), }, }, } as never, [{ kind: "image", artifactId: "image-1", name: "one.png", mimeType: "image/png" }], { operationId: "run-1", traceId: "run-1", spaceId: "space-1", userId: "user-1", botId: "bot-1", runId: "run-1", signal: controller.signal, }, ), ).rejects.toBe(cancellation); }); it("warns when an ordinary turn expects more images than were loaded", () => { const blocks: MessageBlock[] = [ { kind: "image", artifactId: "image-1", name: "one.png", mimeType: "image/png" }, { kind: "image", artifactId: "image-2", name: "two.png", mimeType: "image/png" }, ]; expect(missingTurnImagesInstruction(blocks, [{ name: "one.png" } as never])).toContain( "do not guess its contents", ); expect( missingTurnImagesInstruction(blocks, [ { name: "one.png" } as never, { name: "two.png" } as never, ]), ).toBe(""); expect(missingTurnImagesInstruction(blocks, undefined)).toContain("do not guess its contents"); expect(missingTurnImagesInstruction(undefined, undefined)).toBe(""); }); }); function modelPreference({ provider, secretId, modelId, isDefault, }: { provider: string; secretId: string; modelId: string; isDefault: boolean; }) { const now = new Date("2026-08-30T00:00:00.000Z"); return { id: `preference-${provider}`, isDefault, modelId, credential: { id: `credential-${provider}`, userId: "user-1", provider, label: provider, secretId, createdAt: now, updatedAt: now, }, }; } describe("run notification preference", () => { it("silences direct messages but leaves group notifications enabled", async () => { let source: { bot: { notifyOnFinish: boolean }; thread: { groupId: string | null } } | null = { bot: { notifyOnFinish: false }, thread: { groupId: null }, }; const findFirst = vi.fn(async () => source); const prisma = { run: { findFirst } } as unknown as PrismaClient; await expect( runNotificationsEnabled(prisma, { botId: "bot-1", threadId: "thread-1", spaceId: "workspace-1", userId: "user-1", }), ).resolves.toBe(false); expect(findFirst).toHaveBeenCalledWith({ where: { botId: "bot-1", threadId: "thread-1", spaceId: "workspace-1", userId: "user-1", }, select: { bot: { select: { notifyOnFinish: true } }, thread: { select: { groupId: true } }, }, }); source = { bot: { notifyOnFinish: false }, thread: { groupId: "group-1" } }; await expect( runNotificationsEnabled(prisma, { botId: "bot-1", threadId: "thread-1", spaceId: "workspace-1", userId: "user-1", }), ).resolves.toBe(true); }); }); describe("createRunExecutor", () => { it("excludes private summaries and memory tools from group messaging runs", () => { const messages = [{ role: "user", content: "Group request" }]; expect( threadContextForRun( "messaging", { messages, summary: "Private test detail", historyCompactedUpToSeq: 12, }, true, ), ).toEqual({ messages, summary: null, historyCompactedUpToSeq: null, includeSemanticRecall: false, }); const tools = selectBuiltinToolsForRun({ graphicalToolsAllowed: false, groupId: null, trigger: "messaging", semanticMemoryEnabled: true, messagingChannelRun: true, }).map((tool) => tool.name); expect(tools).not.toContain("recall_memory"); expect(tools).not.toContain("remember"); expect(tools).not.toContain("save_memory"); expect(tools.some((tool) => tool.startsWith("scratchpad_"))).toBe(false); expect(tools).toContain("web_fetch"); }); it("isolates routine runs from every thread-history source", () => { const threadContext = { messages: [{ role: "user", content: "Create this routine" }], summary: "The user just configured this routine.", historyCompactedUpToSeq: 4, }; expect(threadContextForRun("routine", threadContext, false)).toEqual({ messages: [], summary: null, historyCompactedUpToSeq: null, includeSemanticRecall: false, }); expect(threadContextForRun("user", threadContext, false)).toEqual({ ...threadContext, includeSemanticRecall: true, }); }); it("deactivates one-shot routines after wake without scheduling another wakeup", async () => { const scheduledAt = new Date(Date.now() - 1_000); const enqueue = vi.fn(async () => undefined); const cancel = vi.fn(async () => undefined); const append = vi.fn(async () => undefined); const updateMany = vi.fn(async () => ({ count: 1 })); const taskCreate = vi.fn(async () => ({ id: "task-1" })); const runCreate = vi.fn(async () => ({ id: "run-1" })); const prisma = { routine: { findUnique: vi.fn(async () => ({ id: "routine-1", spaceId: "ws-1", botId: "bot-1", userId: "user-1", prompt: "say hi", crons: [ONCE_ROUTINE_CRON], timezone: "UTC", active: true, nextRunAt: scheduledAt, threadId: "group-thread-1", })), }, bot: { findUnique: vi.fn(async () => ({ id: "bot-1", thread: { id: "thread-1" }, })), }, thread: { findFirst: vi.fn(async () => ({ id: "group-thread-1" })), }, agentSkill: { findMany: vi.fn(async () => []), }, $transaction: vi.fn(async (callback: (tx: unknown) => Promise) => callback({ routine: { updateMany }, task: { create: taskCreate }, run: { create: runCreate }, }), ), } as unknown as PrismaClient; const executor = createRunExecutor({ prisma, jobs: { enqueue, cancel, close: vi.fn(async () => undefined) }, events: { append }, } as unknown as Parameters[0]); await executor.wakeRoutine("routine-1", scheduledAt.toISOString()); expect(updateMany).toHaveBeenCalledWith( expect.objectContaining({ data: expect.objectContaining({ active: false, nextRunAt: null }), }), ); expect(cancel).toHaveBeenCalledWith("routine:routine-1"); expect(enqueue).toHaveBeenCalledTimes(1); expect(enqueue).toHaveBeenCalledWith(expect.objectContaining({ name: "run.continue" })); expect(taskCreate).toHaveBeenCalledWith( expect.objectContaining({ data: expect.objectContaining({ threadId: "group-thread-1" }) }), ); expect(runCreate).toHaveBeenCalledWith( expect.objectContaining({ data: expect.objectContaining({ threadId: "group-thread-1" }) }), ); expect(append).toHaveBeenCalledWith( expect.objectContaining({ type: "routine.fired", runId: "run-1", threadId: "group-thread-1", }), ); }); it("wakes a tool-created group routine into the group thread, not the bot DM", async () => { const scheduledAt = new Date(Date.now() - 1_000); const taskCreate = vi.fn(async () => ({ id: "task-1" })); const runCreate = vi.fn(async () => ({ id: "run-1" })); const append = vi.fn(async () => undefined); const findFirst = vi.fn(async () => ({ id: "group-thread-1" })); const prisma = { routine: { findUnique: vi.fn(async () => ({ id: "routine-1", spaceId: "ws-1", botId: "bot-1", userId: "user-1", prompt: "remind the group", crons: [ONCE_ROUTINE_CRON], timezone: "UTC", active: true, nextRunAt: scheduledAt, threadId: "group-thread-1", })), }, bot: { findUnique: vi.fn(async () => ({ id: "bot-1", thread: { id: "dm-thread-1" }, })), }, thread: { findFirst }, agentSkill: { findMany: vi.fn(async () => []) }, $transaction: vi.fn(async (callback: (tx: unknown) => Promise) => callback({ routine: { updateMany: vi.fn(async () => ({ count: 1 })) }, task: { create: taskCreate }, run: { create: runCreate }, }), ), } as unknown as PrismaClient; const executor = createRunExecutor({ prisma, jobs: { enqueue: vi.fn(async () => undefined), cancel: vi.fn(async () => undefined), close: vi.fn(async () => undefined), }, events: { append }, } as unknown as Parameters[0]); await executor.wakeRoutine("routine-1", scheduledAt.toISOString()); expect(findFirst).toHaveBeenCalledWith( expect.objectContaining({ where: expect.objectContaining({ id: "group-thread-1", spaceId: "ws-1" }), }), ); expect(taskCreate).toHaveBeenCalledWith( expect.objectContaining({ data: expect.objectContaining({ threadId: "group-thread-1" }) }), ); expect(runCreate).toHaveBeenCalledWith( expect.objectContaining({ data: expect.objectContaining({ threadId: "group-thread-1" }) }), ); expect(append).toHaveBeenCalledWith( expect.objectContaining({ type: "routine.fired", threadId: "group-thread-1" }), ); }); it("wakes a tool-created 1:1 routine into the bot DM thread", async () => { const scheduledAt = new Date(Date.now() - 1_000); const taskCreate = vi.fn(async () => ({ id: "task-1" })); const runCreate = vi.fn(async () => ({ id: "run-1" })); const append = vi.fn(async () => undefined); const findFirst = vi.fn(async () => ({ id: "dm-thread-1" })); const prisma = { routine: { findUnique: vi.fn(async () => ({ id: "routine-1", spaceId: "ws-1", botId: "bot-1", userId: "user-1", prompt: "remind me", crons: [ONCE_ROUTINE_CRON], timezone: "UTC", active: true, nextRunAt: scheduledAt, threadId: "dm-thread-1", })), }, bot: { findUnique: vi.fn(async () => ({ id: "bot-1", thread: { id: "dm-thread-1" }, })), }, thread: { findFirst }, agentSkill: { findMany: vi.fn(async () => []) }, $transaction: vi.fn(async (callback: (tx: unknown) => Promise) => callback({ routine: { updateMany: vi.fn(async () => ({ count: 1 })) }, task: { create: taskCreate }, run: { create: runCreate }, }), ), } as unknown as PrismaClient; const executor = createRunExecutor({ prisma, jobs: { enqueue: vi.fn(async () => undefined), cancel: vi.fn(async () => undefined), close: vi.fn(async () => undefined), }, events: { append }, } as unknown as Parameters[0]); await executor.wakeRoutine("routine-1", scheduledAt.toISOString()); expect(findFirst).toHaveBeenCalledWith( expect.objectContaining({ where: expect.objectContaining({ id: "dm-thread-1", spaceId: "ws-1" }), }), ); expect(taskCreate).toHaveBeenCalledWith( expect.objectContaining({ data: expect.objectContaining({ threadId: "dm-thread-1" }) }), ); expect(runCreate).toHaveBeenCalledWith( expect.objectContaining({ data: expect.objectContaining({ threadId: "dm-thread-1" }) }), ); expect(append).toHaveBeenCalledWith( expect.objectContaining({ type: "routine.fired", threadId: "dm-thread-1" }), ); }); it("expands @skill mentions in the routine prompt at fire time", async () => { const scheduledAt = new Date(Date.now() - 1_000); const enqueue = vi.fn(async () => undefined); let createdPrompt = ""; const taskCreate = vi.fn(async (args: { data: { prompt: string } }) => { createdPrompt = args.data.prompt; return { id: "task-1" }; }); const skillContent = `--- name: Daily standup description: Prepare standup notes --- 1. Summarize wins. `; const prisma = { routine: { findUnique: vi.fn(async () => ({ id: "routine-1", spaceId: "ws-1", botId: "bot-1", userId: "user-1", prompt: "Run @Daily standup, then email me", crons: [ONCE_ROUTINE_CRON], timezone: "UTC", active: true, nextRunAt: scheduledAt, })), }, bot: { findUnique: vi.fn(async () => ({ id: "bot-1", thread: { id: "thread-1" }, })), }, agentSkill: { findMany: vi.fn(async () => [ { id: "skill-1", name: "Daily standup", description: "Prepare standup notes", content: skillContent, source: "user", }, ]), }, $transaction: vi.fn(async (callback: (tx: unknown) => Promise) => callback({ routine: { updateMany: vi.fn(async () => ({ count: 1 })) }, task: { create: taskCreate }, run: { create: vi.fn(async () => ({ id: "run-1" })) }, }), ), } as unknown as PrismaClient; const executor = createRunExecutor({ prisma, jobs: { enqueue, cancel: vi.fn(async () => undefined), close: vi.fn(async () => undefined) }, events: { append: vi.fn(async () => undefined) }, } as unknown as Parameters[0]); await executor.wakeRoutine("routine-1", scheduledAt.toISOString()); expect(createdPrompt).toContain("Use skill: Daily standup"); expect(createdPrompt).toContain("Summarize wins"); expect(createdPrompt).not.toMatch(/@Daily standup/); }); it("still continues the run when routine.fired append fails", async () => { const scheduledAt = new Date(Date.now() - 1_000); const enqueue = vi.fn(async () => undefined); const cancel = vi.fn(async () => undefined); const append = vi.fn(async () => { throw new Error("append failed"); }); const updateMany = vi.fn(async () => ({ count: 1 })); const prisma = { routine: { findUnique: vi.fn(async () => ({ id: "routine-1", spaceId: "ws-1", botId: "bot-1", userId: "user-1", prompt: "say hi", crons: [ONCE_ROUTINE_CRON], timezone: "UTC", active: true, nextRunAt: scheduledAt, lastRunAt: null, })), }, bot: { findUnique: vi.fn(async () => ({ id: "bot-1", thread: { id: "thread-1" }, })), }, agentSkill: { findMany: vi.fn(async () => []), }, $transaction: vi.fn(async (callback: (tx: unknown) => Promise) => callback({ routine: { updateMany }, task: { create: vi.fn(async () => ({ id: "task-1" })) }, run: { create: vi.fn(async () => ({ id: "run-1", taskId: "task-1" })) }, }), ), } as unknown as PrismaClient; const executor = createRunExecutor({ prisma, jobs: { enqueue, cancel, close: vi.fn(async () => undefined) }, events: { append }, } as unknown as Parameters[0]); await expect( executor.wakeRoutine("routine-1", scheduledAt.toISOString()), ).resolves.toBeUndefined(); expect(enqueue).toHaveBeenCalledWith(expect.objectContaining({ name: "run.continue" })); expect(cancel).toHaveBeenCalledWith("routine:routine-1"); }); it("restores the routine claim when run.continue enqueue fails", async () => { const scheduledAt = new Date(Date.now() - 1_000); const previousLastRunAt = new Date(Date.now() - 60_000); const enqueue = vi.fn(async () => { throw new Error("enqueue failed"); }); const claimUpdateMany = vi.fn(async () => ({ count: 1 })); const restoreUpdateMany = vi.fn(async () => ({ count: 1 })); const deleteRunMany = vi.fn(async () => ({ count: 1 })); const deleteTaskMany = vi.fn(async () => ({ count: 1 })); let transactionCalls = 0; const prisma = { routine: { findUnique: vi.fn(async () => ({ id: "routine-1", spaceId: "ws-1", botId: "bot-1", userId: "user-1", prompt: "say hi", crons: [ONCE_ROUTINE_CRON], timezone: "UTC", active: true, nextRunAt: scheduledAt, lastRunAt: previousLastRunAt, })), }, bot: { findUnique: vi.fn(async () => ({ id: "bot-1", thread: { id: "thread-1" }, })), }, agentSkill: { findMany: vi.fn(async () => []), }, $transaction: vi.fn(async (callback: (tx: unknown) => Promise) => { transactionCalls += 1; if (transactionCalls === 1) { return callback({ routine: { updateMany: claimUpdateMany }, task: { create: vi.fn(async () => ({ id: "task-1" })) }, run: { create: vi.fn(async () => ({ id: "run-1", taskId: "task-1" })) }, }); } return callback({ routine: { updateMany: restoreUpdateMany }, task: { deleteMany: deleteTaskMany }, run: { deleteMany: deleteRunMany }, }); }), } as unknown as PrismaClient; const executor = createRunExecutor({ prisma, jobs: { enqueue, cancel: vi.fn(async () => undefined), close: vi.fn(async () => undefined) }, events: { append: vi.fn(async () => undefined) }, } as unknown as Parameters[0]); await expect(executor.wakeRoutine("routine-1", scheduledAt.toISOString())).rejects.toThrow( "enqueue failed", ); expect(deleteRunMany).toHaveBeenCalledWith({ where: { id: "run-1", status: "queued" } }); expect(deleteTaskMany).toHaveBeenCalledWith({ where: { id: "task-1", status: "queued" } }); expect(restoreUpdateMany).toHaveBeenCalledWith( expect.objectContaining({ where: expect.objectContaining({ id: "routine-1", active: false, nextRunAt: null }), data: expect.objectContaining({ nextRunAt: scheduledAt, active: true, lastRunAt: previousLastRunAt, }), }), ); }); it("consumes a persisted takeover checkpoint when claiming the run", async () => { const updateMany = vi.fn(async () => ({ count: 0 })); const prisma = { run: { findUnique: vi.fn(async () => ({ id: "run-1", botId: "bot-1", status: "queued", checkpoint: "takeover-skipped", leaseFence: 0, })), updateMany, }, } as unknown as PrismaClient; const executor = createRunExecutor({ prisma } as Parameters[0]); await executor.continueRun("run-1", "worker-1"); expect(updateMany).toHaveBeenCalledWith( expect.objectContaining({ where: expect.objectContaining({ id: "run-1", status: "queued", checkpoint: "takeover-skipped", }), data: expect.objectContaining({ checkpoint: null }), }), ); }); it("does not claim a waiting takeover after a concurrent release writes the checkpoint", async () => { let row: { status: string; checkpoint: string | null } = { status: "waiting_takeover", checkpoint: null, }; const matchesClaim = ( where: { status?: string | { in: string[] }; checkpoint?: string | null; OR?: Array<{ status?: string | { in: string[] } }>; }, current: { status: string; checkpoint: string | null }, ): boolean => { if (typeof where.status === "string" && where.status !== current.status) return false; if (where.status && typeof where.status === "object" && "in" in where.status) { if (!where.status.in.includes(current.status)) return false; } if ("checkpoint" in where && where.checkpoint !== current.checkpoint) return false; if (where.OR) return where.OR.some((clause) => matchesClaim(clause, current)); return true; }; const updateMany = vi.fn(async (args: { where: Parameters[0] }) => { row = { status: "queued", checkpoint: "takeover" }; return { count: matchesClaim(args.where, row) ? 1 : 0 }; }); const prisma = { run: { findUnique: vi.fn(async () => ({ id: "run-1", botId: "bot-1", status: "waiting_takeover", checkpoint: null, leaseFence: 0, })), updateMany, }, } as unknown as PrismaClient; const executor = createRunExecutor({ prisma } as Parameters[0]); await executor.continueRun("run-1", "worker-1"); expect(updateMany).toHaveBeenCalledTimes(1); expect(updateMany).toHaveBeenCalledWith( expect.objectContaining({ where: expect.objectContaining({ status: "waiting_takeover", checkpoint: null, }), }), ); expect(row).toEqual({ status: "queued", checkpoint: "takeover" }); }); it("restores a takeover checkpoint when a switching computer requeues the run", async () => { const updateMany = vi.fn( async (args: { where: { checkpoint?: string | null | { in: string[] } }; data: { status?: string; checkpoint?: string | null }; }) => { if (args.data.status === "leased" || args.data.status === "running") return { count: 1 }; if (args.where.checkpoint && typeof args.where.checkpoint === "object") return { count: 0 }; return { count: 1 }; }, ); const enqueue = vi.fn(async () => undefined); const prisma = { run: { findUnique: vi.fn(async () => ({ id: "run-1", botId: "bot-1", status: "queued", checkpoint: "takeover-skipped", leaseFence: 0, })), findUniqueOrThrow: vi.fn(async () => ({ status: "leased", startedAt: null })), updateMany, }, bot: { findUniqueOrThrow: vi.fn(async () => ({ computerId: "computer-1", computerSwitching: true, })), }, } as unknown as PrismaClient; const executor = createRunExecutor({ prisma, jobs: { enqueue } } as unknown as Parameters< typeof createRunExecutor >[0]); await executor.continueRun("run-1", "worker-1"); expect(updateMany).toHaveBeenLastCalledWith( expect.objectContaining({ where: expect.objectContaining({ checkpoint: null }), data: expect.objectContaining({ status: "queued", checkpoint: "takeover-skipped", }), }), ); expect(enqueue).toHaveBeenCalledOnce(); }); it("preserves a concurrent release checkpoint when a held continue requeues", async () => { let checkpoint: string | null = null; const updateMany = vi.fn( async (args: { where: { checkpoint?: string | null | { in: string[] } }; data: { status?: string; checkpoint?: string | null }; }) => { if (args.data.status === "leased") { checkpoint = null; return { count: 1 }; } if (args.data.status === "running") { checkpoint = "takeover"; return { count: 1 }; } if (args.where.checkpoint && typeof args.where.checkpoint === "object") { return { count: args.where.checkpoint.in.includes(checkpoint ?? "") ? 1 : 0 }; } return { count: args.where.checkpoint === null && checkpoint === null ? 1 : 0 }; }, ); const enqueue = vi.fn(async () => undefined); const prisma = { run: { findUnique: vi.fn(async () => ({ id: "run-1", botId: "bot-1", status: "waiting_takeover", checkpoint: null, leaseFence: 0, })), findUniqueOrThrow: vi.fn(async () => ({ status: "leased", startedAt: null })), updateMany, }, bot: { findUniqueOrThrow: vi.fn(async () => ({ computerId: "computer-1", computerSwitching: true, })), }, } as unknown as PrismaClient; const executor = createRunExecutor({ prisma, jobs: { enqueue } } as unknown as Parameters< typeof createRunExecutor >[0]); await executor.continueRun("run-1", "worker-1"); expect(checkpoint).toBe("takeover"); expect(enqueue).toHaveBeenCalledOnce(); expect(updateMany).toHaveBeenCalledWith( expect.objectContaining({ where: expect.objectContaining({ checkpoint: { in: ["takeover", "takeover-skipped"] }, }), data: expect.objectContaining({ status: "queued" }), }), ); expect(updateMany.mock.calls.some((call) => call[0].data?.status === "waiting_takeover")).toBe( false, ); expect( updateMany.mock.calls.some( (call) => call[0].data?.status === "queued" && call[0].data?.checkpoint === null, ), ).toBe(false); }); it("returns a held takeover to waiting_takeover when the computer is switching", async () => { const updateMany = vi.fn( async (args: { where: { checkpoint?: string | null | { in: string[] } }; data: { status?: string; checkpoint?: string | null }; }) => { if (args.data.status === "leased" || args.data.status === "running") return { count: 1 }; if (args.where.checkpoint && typeof args.where.checkpoint === "object") return { count: 0 }; return { count: 1 }; }, ); const enqueue = vi.fn(async () => undefined); const prisma = { run: { findUnique: vi.fn(async () => ({ id: "run-1", botId: "bot-1", status: "waiting_takeover", checkpoint: null, leaseFence: 0, })), findUniqueOrThrow: vi.fn(async () => ({ status: "leased", startedAt: null })), updateMany, }, bot: { findUniqueOrThrow: vi.fn(async () => ({ computerId: "computer-1", computerSwitching: true, })), }, } as unknown as PrismaClient; const executor = createRunExecutor({ prisma, jobs: { enqueue } } as unknown as Parameters< typeof createRunExecutor >[0]); await executor.continueRun("run-1", "worker-1"); expect(updateMany).toHaveBeenLastCalledWith( expect.objectContaining({ where: expect.objectContaining({ checkpoint: null }), data: expect.objectContaining({ status: "waiting_takeover", checkpoint: null, }), }), ); expect(enqueue).toHaveBeenCalledOnce(); }); it("fails a run clearly without calling the real runtime when no model is configured", async () => { let status = "queued"; const runtimeRun = vi.fn(); const finalizeRun = vi.fn(async () => { status = "failed"; return { continuationRunId: null }; }); const run = { id: "run-1", botId: "bot-1", threadId: "thread-1", taskId: "task-1", userId: "user-1", spaceId: "ws-1", status: "queued", trigger: "user", routineId: null, sourceMessageId: null, checkpoint: null, leaseFence: 0, }; const botLookup = vi.fn(async (args: { select?: { computerId?: boolean } }) => args.select?.computerId ? { computerId: "computer-1", computerSwitching: false } : { id: "bot-1", name: "Assistant", modelProvider: null, modelId: null, thinkingLevel: null, memoryScope: "isolated", computer: { id: "computer-1", scope: "private" }, }, ); const prisma = { run: { findUnique: vi.fn(async () => run), findUniqueOrThrow: vi.fn(async () => ({ status: "leased", startedAt: null })), updateMany: vi.fn(async () => ({ count: 1 })), }, bot: { findUniqueOrThrow: botLookup }, computer: { findUniqueOrThrow: vi.fn(async () => ({ scope: "private", state: "running" })), }, attempt: { create: vi.fn(async () => ({ id: "attempt-1" })), updateMany: vi.fn(async () => ({ count: 1 })), }, thread: { findUniqueOrThrow: vi.fn(async () => ({ id: "thread-1", groupId: null, historyCompactionSummary: null, historyCompactedUpToSeq: null, historyCompactionGeneration: 0, })), }, message: { findMany: vi.fn(async () => []) }, task: { findUniqueOrThrow: vi.fn(async () => ({ id: "task-1", prompt: "hello" })) }, connection: { findMany: vi.fn(async () => []) }, spaceModelPreference: { findFirst: vi.fn(async () => null) }, userModelCredential: { findFirst: vi.fn(async () => null) }, deploymentSettings: { findUnique: vi.fn(async () => null) }, taughtSkill: { findMany: vi.fn(async () => []) }, agentSecret: { findMany: vi.fn(async () => []) }, user: { findUnique: vi.fn(async () => null) }, userProfile: { findUnique: vi.fn(async () => null) }, userFact: { findMany: vi.fn(async () => []) }, agentSkill: { findMany: vi.fn(async () => []) }, scratchpadItem: { findMany: vi.fn(async () => []) }, } as unknown as PrismaClient; const executor = createRunExecutor({ prisma, runtime: { describe: () => ({ capabilities: { scripted: false } }), run: runtimeRun, }, memoryProviders: { resolve: vi.fn(async () => null) }, memory: { read: vi.fn(async () => ({ documents: [] })) }, events: { append: vi.fn(async () => undefined), finalizeRun }, jobs: { enqueue: vi.fn(async () => undefined) }, secrets: [], } as unknown as Parameters[0]); await executor.continueRun("run-1", "worker-1"); expect(status).toBe("failed"); expect(finalizeRun).toHaveBeenCalledWith( expect.objectContaining({ outcome: "failed", error: "Connect a model in Settings before running bots.", }), ); expect(runtimeRun).not.toHaveBeenCalled(); }); it("scopes agent secrets to the run owner when loading the environment", async () => { const agentSecretFindMany = vi.fn(async () => []); const run = { id: "run-1", botId: "bot-1", threadId: "thread-1", taskId: "task-1", userId: "member-user", spaceId: "shared-ws", status: "queued", trigger: "user", routineId: null, sourceMessageId: null, checkpoint: null, leaseFence: 0, }; const botLookup = vi.fn(async (args: { select?: { computerId?: boolean } }) => args.select?.computerId ? { computerId: "computer-1", computerSwitching: false } : { id: "bot-1", name: "Assistant", modelProvider: null, modelId: null, thinkingLevel: null, memoryScope: "isolated", computer: { id: "computer-1", scope: "private" }, }, ); const prisma = { run: { findUnique: vi.fn(async () => run), findUniqueOrThrow: vi.fn(async () => ({ status: "leased", startedAt: null })), updateMany: vi.fn(async () => ({ count: 1 })), }, bot: { findUniqueOrThrow: botLookup }, computer: { findUniqueOrThrow: vi.fn(async () => ({ scope: "private", state: "running" })), }, attempt: { create: vi.fn(async () => ({ id: "attempt-1" })), updateMany: vi.fn(async () => ({ count: 1 })), }, thread: { findUniqueOrThrow: vi.fn(async () => ({ id: "thread-1", groupId: null, historyCompactionSummary: null, historyCompactedUpToSeq: null, historyCompactionGeneration: 0, })), }, message: { findMany: vi.fn(async () => []) }, task: { findUniqueOrThrow: vi.fn(async () => ({ id: "task-1", prompt: "hello" })) }, connection: { findMany: vi.fn(async () => []) }, spaceModelPreference: { findFirst: vi.fn(async () => null) }, userModelCredential: { findFirst: vi.fn(async () => null) }, deploymentSettings: { findUnique: vi.fn(async () => null) }, taughtSkill: { findMany: vi.fn(async () => []) }, agentSecret: { findMany: agentSecretFindMany }, user: { findUnique: vi.fn(async () => null) }, userProfile: { findUnique: vi.fn(async () => null) }, userFact: { findMany: vi.fn(async () => []) }, agentSkill: { findMany: vi.fn(async () => []) }, scratchpadItem: { findMany: vi.fn(async () => []) }, } as unknown as PrismaClient; const executor = createRunExecutor({ prisma, runtime: { describe: () => ({ capabilities: { scripted: false } }), run: vi.fn(), }, memoryProviders: { resolve: vi.fn(async () => null) }, memory: { read: vi.fn(async () => ({ documents: [] })) }, events: { append: vi.fn(async () => undefined), finalizeRun: vi.fn(async () => ({ continuationRunId: null })), }, jobs: { enqueue: vi.fn(async () => undefined) }, secrets: [], } as unknown as Parameters[0]); await executor.continueRun("run-1", "worker-1"); expect(agentSecretFindMany).toHaveBeenCalledWith( expect.objectContaining({ where: agentSecretScopeForRun("shared-ws", "member-user"), }), ); }); it("resolves a per-bot model override with that provider’s credential", async () => { const findFirst = vi.fn( async (args: { where: { credential?: { provider?: string }; isDefault?: boolean } }) => { if (args.where.credential?.provider === "xai") { return modelPreference({ provider: "xai", secretId: "secret-xai", modelId: "grok-4.6", isDefault: false, }); } if (args.where.isDefault) { return modelPreference({ provider: "openrouter", secretId: "secret-or", modelId: "deepseek/deepseek-v4-flash-0731", isDefault: true, }); } return null; }, ); const prisma = { bot: { findFirst: vi.fn(async () => ({ modelProvider: "xai", modelId: "grok-4.6", thinkingLevel: "high", })), }, spaceModelPreference: { findFirst }, userModelCredential: { findFirst: vi.fn(async () => null) }, deploymentSettings: { findUnique: vi.fn(async () => null) }, secret: { findFirst: vi.fn(async () => null), findUnique: vi.fn(async () => null) }, } as unknown as PrismaClient; const executor = createRunExecutor({ prisma, secretStore: { load: vi.fn(), put: vi.fn() }, } as unknown as Parameters[0]); const model = await executor.resolveModel({ userId: "user-1", spaceId: "ws-1", botId: "bot-1", }); expect(model).toMatchObject({ provider: "xai", id: "grok-4.6", thinkingLevel: "high", }); expect(findFirst).toHaveBeenCalledWith( expect.objectContaining({ where: expect.objectContaining({ credential: { provider: "xai" } }), }), ); }); it("resolves an explicit subagent model within the active user and space", async () => { const preference = modelPreference({ provider: "xai", secretId: "secret-xai", modelId: "grok-4.6", isDefault: false, }); const findFirst = vi.fn( async (args: { where: { credential?: { provider?: string }; modelId?: string } }) => { if (args.where.credential?.provider !== "xai") return null; if (args.where.modelId && args.where.modelId !== "grok-4.6") return null; return preference; }, ); const prisma = { spaceModelPreference: { findFirst }, userModelCredential: { findFirst: vi.fn(async () => null) }, secret: { findFirst: vi.fn(async () => null), findUnique: vi.fn(async () => null) }, } as unknown as PrismaClient; const executor = createRunExecutor({ prisma, secretStore: { load: vi.fn(), put: vi.fn() }, } as unknown as Parameters[0]); const model = await executor.resolveConnectedModel( { userId: "user-1", spaceId: "ws-1" }, "xai", "grok-4.6", ); expect(model).toMatchObject({ provider: "xai", id: "grok-4.6", thinkingLevel: null }); expect(findFirst).toHaveBeenCalledWith( expect.objectContaining({ where: expect.objectContaining({ spaceId: "ws-1", userId: "user-1", modelId: "grok-4.6", credential: { provider: "xai" }, }), }), ); }); it("rejects a free-form selection when the owning preference disappears", async () => { const preference = modelPreference({ provider: "openai-compatible", secretId: "secret-compat", modelId: "newest-model", isDefault: true, }); const findFirst = vi.fn( async (args: { where: { credential?: { provider?: string; userId?: string }; modelId?: string }; select?: unknown; }) => { if (args.select) { return args.where.modelId === "private-model" ? { id: "saved" } : null; } if (args.where.modelId === "private-model") return null; if (args.where.credential?.provider === "openai-compatible") return preference; return null; }, ); const prisma = { spaceModelPreference: { findFirst }, userModelCredential: { findFirst: vi.fn(async () => null) }, secret: { findFirst: vi.fn(async () => null), findUnique: vi.fn(async () => null) }, } as unknown as PrismaClient; const executor = createRunExecutor({ prisma, secretStore: { load: vi.fn(), put: vi.fn() }, } as unknown as Parameters[0]); await expect( executor.resolveConnectedModel( { userId: "user-1", spaceId: "ws-1" }, "openai-compatible", "private-model", ), ).rejects.toThrow("Unknown model for that provider"); }); it("keeps image support for a separately enabled bot model override", async () => { const provider = "openai-compatible"; const findFirst = vi.fn( async (args: { where: { credential?: { provider?: string }; isDefault?: boolean } }) => { if (args.where.credential?.provider === provider || args.where.isDefault) { return modelPreference({ provider, secretId: "secret-openai-compatible", modelId: "space-model", isDefault: Boolean(args.where.isDefault), }); } return null; }, ); const plaintext = serializeModelSecret({ kind: "openai_compatible", baseUrl: "http://127.0.0.1:8000/v1", visionModelIds: ["bot-vision-model"], maxImagesPerPrompt: 1, maxTokens: 8192, contextWindow: 65536, }); const bot = { modelProvider: provider, modelId: "bot-vision-model", thinkingLevel: null, }; const prisma = { bot: { findFirst: vi.fn(async () => bot) }, spaceModelPreference: { findFirst }, userModelCredential: { findFirst: vi.fn(async () => null) }, deploymentSettings: { findUnique: vi.fn(async () => null) }, secret: { findFirst: vi.fn(async () => ({ id: "secret-openai-compatible", ciphertext: plaintext, })), findUnique: vi.fn(async () => null), }, } as unknown as PrismaClient; const executor = createRunExecutor({ prisma, secretStore: { load: vi.fn(() => plaintext), put: vi.fn() }, } as unknown as Parameters[0]); await expect( executor.resolveModel({ userId: "user-1", spaceId: "ws-1", botId: "bot-1" }), ).resolves.toMatchObject({ provider, id: "bot-vision-model", acceptsImages: true, maxImagesPerPrompt: 1, maxTokens: 8192, contextWindow: 65536, }); bot.modelId = "text-only-model"; await expect( executor.resolveModel({ userId: "user-1", spaceId: "ws-1", botId: "bot-1" }), ).resolves.toMatchObject({ provider, id: "text-only-model", acceptsImages: false, }); }); it("falls back to the Space default when the override provider has no credential", async () => { const findFirst = vi.fn( async (args: { where: { credential?: { provider?: string }; isDefault?: boolean } }) => { if (args.where.credential?.provider === "xai") return null; if (args.where.isDefault) { return modelPreference({ provider: "openrouter", secretId: "secret-or", modelId: "deepseek/deepseek-v4-flash-0731", isDefault: true, }); } return null; }, ); const prisma = { bot: { findFirst: vi.fn(async () => ({ modelProvider: "xai", modelId: "grok-4.6", thinkingLevel: "high", })), }, spaceModelPreference: { findFirst }, userModelCredential: { findFirst: vi.fn(async () => null) }, deploymentSettings: { findUnique: vi.fn(async () => null) }, secret: { findFirst: vi.fn(async () => null), findUnique: vi.fn(async () => null) }, } as unknown as PrismaClient; const executor = createRunExecutor({ prisma, secretStore: { load: vi.fn(), put: vi.fn() }, deploymentModelKey: "deployment-openrouter-key", } as unknown as Parameters[0]); const model = await executor.resolveModel({ userId: "user-1", spaceId: "ws-1", botId: "bot-1", }); expect(model).toMatchObject({ provider: "openrouter", id: "deepseek/deepseek-v4-flash-0731", // Override thinking must drop with the override provider/credential unit. thinkingLevel: null, }); expect(findFirst).toHaveBeenCalledWith( expect.objectContaining({ where: expect.objectContaining({ credential: { provider: "xai" } }), }), ); expect(findFirst).toHaveBeenCalledWith( expect.objectContaining({ where: expect.objectContaining({ isDefault: true }), }), ); }); it("withholds the deployment key when settings name a different provider", async () => { const prisma = { bot: { findFirst: vi.fn(async () => null) }, spaceModelPreference: { findFirst: vi.fn(async () => null) }, userModelCredential: { findFirst: vi.fn(async () => null) }, deploymentSettings: { findUnique: vi.fn(async () => ({ defaultModelProvider: "anthropic", defaultModelId: "claude-sonnet-5", })), }, secret: { findFirst: vi.fn(async () => null), findUnique: vi.fn(async () => null) }, } as unknown as PrismaClient; const executor = createRunExecutor({ prisma, secretStore: { load: vi.fn(), put: vi.fn() }, // PI_DEFAULT_PROVIDER is unset here, so this key belongs to OpenRouter. deploymentModelKey: "deployment-openrouter-key", } as unknown as Parameters[0]); const model = await executor.resolveModel({ userId: "user-1", spaceId: "ws-1" }); expect(model.provider).toBe("anthropic"); expect(model.apiKey).toBeUndefined(); }); it("keeps per-bot thinking when using the Space default model", async () => { const findFirst = vi.fn(async (args: { where: { isDefault?: boolean } }) => { if (!args.where.isDefault) return null; return modelPreference({ provider: "openrouter", secretId: "secret-or", modelId: "deepseek/deepseek-v4-flash-0731", isDefault: true, }); }); const prisma = { bot: { findFirst: vi.fn(async () => ({ modelProvider: null, modelId: null, thinkingLevel: "high", })), }, spaceModelPreference: { findFirst }, userModelCredential: { findFirst: vi.fn(async () => null) }, deploymentSettings: { findUnique: vi.fn(async () => null) }, secret: { findFirst: vi.fn(async () => null), findUnique: vi.fn(async () => null) }, } as unknown as PrismaClient; const executor = createRunExecutor({ prisma, secretStore: { load: vi.fn(), put: vi.fn() }, } as unknown as Parameters[0]); const model = await executor.resolveModel({ userId: "user-1", spaceId: "ws-1", botId: "bot-1", }); expect(model).toMatchObject({ provider: "openrouter", id: "deepseek/deepseek-v4-flash-0731", thinkingLevel: "high", }); }); });