test(tools): update MCP, delegate-task, skill, and slashcommand tests

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
YeonGyu-Kim
2026-04-10 15:53:35 +09:00
parent ca9b5fde40
commit 37057f18b9
12 changed files with 312 additions and 112 deletions
@@ -605,8 +605,8 @@ describe("executeSyncContinuation - toast cleanup error paths", () => {
})
})
test("keeps task delegation disabled during prometheus sync continuation", async () => {
//#given - a resumed prometheus session should stay unable to delegate tasks
test("keeps task delegation enabled during prometheus sync continuation", async () => {
//#given - a resumed prometheus session should keep plan-family task permission
const promptAsyncCalls: Array<{ path: { id: string }; body: Record<string, unknown> }> = []
const mockClient = {
session: {
@@ -667,7 +667,7 @@ describe("executeSyncContinuation - toast cleanup error paths", () => {
//#then
expect(promptAsyncCalls).toHaveLength(1)
expect(promptAsyncCalls[0]?.body.tools).toEqual({
task: false,
task: true,
call_omo_agent: true,
question: false,
})
@@ -1,5 +1,12 @@
const { describe, test, expect, beforeEach, afterEach, mock, spyOn } = require("bun:test")
function clearRequireCache(modulePath: string): void {
const resolvedPath = require.resolve(modulePath)
if (require.cache?.[resolvedPath]) {
delete require.cache[resolvedPath]
}
}
describe("executeSyncTask - cleanup on error paths", () => {
let removeTaskCalls: string[] = []
let addTaskCalls: any[] = []
@@ -23,6 +30,8 @@ describe("executeSyncTask - cleanup on error paths", () => {
deleteCalls = []
addCalls = []
clearRequireCache("./sync-task")
//#given - initialize real task toast manager (avoid global module mocks)
const { initTaskToastManager, _resetTaskToastManagerForTesting } = require("../../features/task-toast-manager/manager")
_resetTaskToastManagerForTesting()
+12 -2
View File
@@ -1,6 +1,16 @@
declare const require: (name: string) => any
const { describe, expect, test } = require("bun:test")
import { createDelegateTask } from "./tools"
function requireFresh<T>(modulePath: string): T {
const resolvedPath = require.resolve(modulePath)
if (require.cache?.[resolvedPath]) {
delete require.cache[resolvedPath]
}
return require(modulePath) as T
}
function createDelegateTask(...args: Parameters<typeof import("./tools").createDelegateTask>): ReturnType<typeof import("./tools").createDelegateTask> {
return requireFresh<typeof import("./tools")>("./tools").createDelegateTask(...args)
}
describe("createDelegateTask schema", () => {
test("#given category arg #when tool is created #then category accepts any string", () => {
+54 -5
View File
@@ -1,7 +1,7 @@
declare const require: (name: string) => any
declare const require: NodeJS.Require
const { describe, test, expect, beforeEach, afterEach, spyOn, mock } = require("bun:test")
import { DEFAULT_CATEGORIES, CATEGORY_PROMPT_APPENDS, CATEGORY_DESCRIPTIONS, isPlanAgent, PLAN_AGENT_NAMES, isPlanFamily, PLAN_FAMILY_NAMES } from "./constants"
import { resolveCategoryConfig } from "./tools"
import { getAgentDisplayName, getAgentListDisplayName } from "../../shared/agent-display-names"
import type { CategoryConfig } from "../../config/schema"
import type { DelegateTaskArgs } from "./types"
import { __resetModelCache } from "../../shared/model-availability"
@@ -10,6 +10,20 @@ import { __setTimingConfig, __resetTimingConfig } from "./timing"
import * as connectedProvidersCache from "../../shared/connected-providers-cache"
import * as executor from "./executor"
const runtimeRequire = require as NodeJS.Require & { cache?: Record<string, unknown> }
function clearRequireCache(modulePath: string): void {
const resolvedPath = runtimeRequire.resolve(modulePath)
if (runtimeRequire.cache?.[resolvedPath]) {
delete runtimeRequire.cache[resolvedPath]
}
}
function resolveCategoryConfig(...args: Parameters<typeof import("./tools").resolveCategoryConfig>): ReturnType<typeof import("./tools").resolveCategoryConfig> {
clearRequireCache("./tools")
return require("./tools").resolveCategoryConfig(...args)
}
const SYSTEM_DEFAULT_MODEL = "anthropic/claude-sonnet-4-6"
const TEST_CONNECTED_PROVIDERS = ["anthropic", "google", "openai"]
@@ -37,6 +51,7 @@ describe("sisyphus-task", () => {
beforeEach(() => {
mock.restore()
clearRequireCache("./tools")
__resetModelCache()
clearSkillCache()
__setTimingConfig({
@@ -253,6 +268,20 @@ describe("sisyphus-task", () => {
expect(result).toBe(true)
})
test("returns true for prometheus display name", () => {
//#given / #when
const result = isPlanFamily(getAgentDisplayName("prometheus"))
//#then
expect(result).toBe(true)
})
test("returns true for prometheus list display name with zwsp prefix", () => {
//#given / #when
const result = isPlanFamily(getAgentListDisplayName("prometheus"))
//#then
expect(result).toBe(true)
})
test("returns false for 'oracle'", () => {
//#given / #when
const result = isPlanFamily("oracle")
@@ -3608,6 +3637,26 @@ describe("sisyphus-task", () => {
expect(result).toContain("plan-family")
})
test("prometheus display name cannot delegate to plan (cross-blocking)", async () => {
//#given
const { createDelegateTask } = require("./tools")
const mockClient = {
app: { agents: async () => ({ data: [{ name: "plan", mode: "subagent" }] }) },
config: { get: async () => ({ data: { model: SYSTEM_DEFAULT_MODEL } }) },
session: { get: async () => ({ data: { directory: "/project" } }), create: async () => ({ data: { id: "s" } }), prompt: async () => ({ data: {} }), promptAsync: async () => ({ data: {} }), messages: async () => ({ data: [] }), status: async () => ({ data: {} }) },
}
const tool = createDelegateTask({ manager: { launch: async () => ({}) }, client: mockClient })
//#when
const result = await tool.execute(
{ description: "test", prompt: "Create a plan", subagent_type: "plan", run_in_background: false, load_skills: [] },
{ sessionID: "p", messageID: "m", agent: getAgentDisplayName("prometheus"), abort: new AbortController().signal }
)
//#then
expect(result).toContain("plan-family")
})
test("plan cannot delegate to prometheus (cross-blocking)", async () => {
//#given
const { createDelegateTask } = require("./tools")
@@ -4105,7 +4154,7 @@ describe("sisyphus-task", () => {
expect(promptBody.tools.task).toBe(true)
}, { timeout: 20000 })
test("prometheus subagent should NOT have task permission", async () => {
test("prometheus subagent should have task permission as part of the plan family", async () => {
//#given
const { createDelegateTask } = require("./tools")
let promptBody: any
@@ -4130,8 +4179,8 @@ describe("sisyphus-task", () => {
{ sessionID: "p", messageID: "m", agent: "sisyphus", abort: new AbortController().signal }
)
//#then
expect(promptBody.tools.task).toBe(false)
//#then - prometheus shares task permission with the plan family
expect(promptBody.tools.task).toBe(true)
}, { timeout: 20000 })
test("non-plan subagent should NOT have task permission", async () => {
@@ -1,12 +1,20 @@
declare const require: (name: string) => any
const { describe, test, expect, beforeEach, afterEach, spyOn, mock } = require("bun:test")
import { describe, test, expect, beforeEach, afterEach, mock } from "bun:test"
import type { DelegateTaskArgs } from "../types"
import type { ExecutorContext } from "../executor-types"
import * as logger from "../../../shared/logger"
import * as connectedProvidersCache from "../../../shared/connected-providers-cache"
type SubagentResolverModule = typeof import("../subagent-resolver")
const logMock = mock((..._args: unknown[]) => {})
const readConnectedProvidersCacheMock = mock(() => null as string[] | null)
const readProviderModelsCacheMock = mock(
() => null as {
models: Record<string, string[]>
connected: string[]
updatedAt: string
} | null,
)
async function importFreshSubagentResolverModule(): Promise<SubagentResolverModule> {
return await import(`../subagent-resolver?test=${Date.now()}-${Math.random()}`)
}
@@ -41,17 +49,30 @@ function createExecutorContext(
}
describe("resolveSubagentExecution", () => {
let logSpy: ReturnType<typeof spyOn> | undefined
let resolveSubagentExecution: SubagentResolverModule["resolveSubagentExecution"]
beforeEach(async () => {
mock.restore()
logSpy = spyOn(logger, "log").mockImplementation(() => {})
logMock.mockClear()
readConnectedProvidersCacheMock.mockReset()
readProviderModelsCacheMock.mockReset()
readConnectedProvidersCacheMock.mockReturnValue(null)
readProviderModelsCacheMock.mockReturnValue(null)
mock.module("../../../shared/logger", () => ({
log: logMock,
}))
mock.module("../../../shared/connected-providers-cache", () => ({
readConnectedProvidersCache: readConnectedProvidersCacheMock,
readProviderModelsCache: readProviderModelsCacheMock,
hasConnectedProvidersCache: () => readConnectedProvidersCacheMock() !== null,
hasProviderModelsCache: () => readProviderModelsCacheMock() !== null,
_resetMemCacheForTesting: () => {},
}))
;({ resolveSubagentExecution } = await importFreshSubagentResolverModule())
})
afterEach(() => {
logSpy?.mockRestore()
mock.restore()
})
test("returns delegation error when agent discovery fails instead of silently proceeding", async () => {
@@ -71,7 +92,7 @@ describe("resolveSubagentExecution", () => {
expect(result.error).toBe("Failed to delegate to agent \"oracle\": agents API unavailable")
})
test("logs failure details when subagent resolution throws", async () => {
test("returns delegation error when subagent resolution throws", async () => {
//#given
const args = createBaseArgs({ subagent_type: "review" })
const executorCtx = createExecutorContext(async () => {
@@ -79,17 +100,12 @@ describe("resolveSubagentExecution", () => {
})
//#when
await resolveSubagentExecution(args, executorCtx, "sisyphus", "deep")
const result = await resolveSubagentExecution(args, executorCtx, "sisyphus", "deep")
//#then
expect(logSpy).toHaveBeenCalledTimes(1)
const callArgs = logSpy?.mock.calls[0]
expect(callArgs?.[0]).toBe("[delegate-task] Failed to resolve subagent execution")
expect(callArgs?.[1]).toEqual({
requestedAgent: "review",
parentAgent: "sisyphus",
error: "network timeout",
})
expect(result.agentToUse).toBe("")
expect(result.categoryModel).toBeUndefined()
expect(result.error).toBe('Failed to delegate to agent "review": network timeout')
})
test("hides primary agents from task delegation lookups", async () => {
@@ -129,7 +145,7 @@ describe("resolveSubagentExecution", () => {
test("normalizes matched agent model string before returning categoryModel", async () => {
//#given
const cacheSpy = spyOn(connectedProvidersCache, "readProviderModelsCache").mockReturnValue({
readProviderModelsCacheMock.mockReturnValue({
models: { openai: ["grok-3", "gpt-5.3-codex"] },
connected: ["openai"],
updatedAt: "2026-03-03T00:00:00.000Z",
@@ -145,12 +161,11 @@ describe("resolveSubagentExecution", () => {
//#then
expect(result.error).toBeUndefined()
expect(result.categoryModel).toEqual({ providerID: "openai", modelID: "gpt-5.3-codex" })
cacheSpy.mockRestore()
})
test("uses agent override fallback_models for subagent runtime fallback chain", async () => {
//#given
const cacheSpy = spyOn(connectedProvidersCache, "readProviderModelsCache").mockReturnValue({
readProviderModelsCacheMock.mockReturnValue({
models: { quotio: ["claude-haiku-4-5"] },
connected: ["quotio"],
updatedAt: "2026-03-03T00:00:00.000Z",
@@ -178,12 +193,11 @@ describe("resolveSubagentExecution", () => {
{ providers: ["quotio"], model: "gpt-5.2", variant: undefined },
{ providers: ["quotio"], model: "glm-5", variant: "max" },
])
cacheSpy.mockRestore()
})
test("uses category fallback_models when agent override points at category", async () => {
//#given
const cacheSpy = spyOn(connectedProvidersCache, "readProviderModelsCache").mockReturnValue({
readProviderModelsCacheMock.mockReturnValue({
models: { anthropic: ["claude-haiku-4-5"] },
connected: ["anthropic"],
updatedAt: "2026-03-03T00:00:00.000Z",
@@ -215,17 +229,16 @@ describe("resolveSubagentExecution", () => {
expect(result.fallbackChain).toEqual([
{ providers: ["anthropic"], model: "claude-haiku-4-5", variant: undefined },
])
cacheSpy.mockRestore()
})
test("promotes object-style fallback model settings to categoryModel when subagent fallback becomes initial model", async () => {
//#given
const cacheSpy = spyOn(connectedProvidersCache, "readProviderModelsCache").mockReturnValue({
readProviderModelsCacheMock.mockReturnValue({
models: { openai: ["gpt-5.4"] },
connected: ["openai"],
updatedAt: "2026-03-03T00:00:00.000Z",
})
const connectedSpy = spyOn(connectedProvidersCache, "readConnectedProvidersCache").mockReturnValue(["openai"])
readConnectedProvidersCacheMock.mockReturnValue(["openai"])
const args = createBaseArgs({ subagent_type: "explore" })
const executorCtx = createExecutorContext(
async () => ([
@@ -265,18 +278,16 @@ describe("resolveSubagentExecution", () => {
maxTokens: 2048,
thinking: { type: "disabled" },
})
cacheSpy.mockRestore()
connectedSpy.mockRestore()
})
test("does not apply object-style fallback settings when the subagent primary model matches directly", async () => {
//#given
const cacheSpy = spyOn(connectedProvidersCache, "readProviderModelsCache").mockReturnValue({
readProviderModelsCacheMock.mockReturnValue({
models: { openai: ["gpt-5.4-preview"] },
connected: ["openai"],
updatedAt: "2026-03-03T00:00:00.000Z",
})
const connectedSpy = spyOn(connectedProvidersCache, "readConnectedProvidersCache").mockReturnValue(["openai"])
readConnectedProvidersCacheMock.mockReturnValue(["openai"])
const args = createBaseArgs({ subagent_type: "explore" })
const executorCtx = createExecutorContext(
async () => ([
@@ -306,18 +317,16 @@ describe("resolveSubagentExecution", () => {
providerID: "openai",
modelID: "gpt-5.4-preview",
})
cacheSpy.mockRestore()
connectedSpy.mockRestore()
})
test("matches promoted fallback settings after fuzzy model resolution", async () => {
//#given
const cacheSpy = spyOn(connectedProvidersCache, "readProviderModelsCache").mockReturnValue({
readProviderModelsCacheMock.mockReturnValue({
models: { openai: ["gpt-5.4-preview"] },
connected: ["openai"],
updatedAt: "2026-03-03T00:00:00.000Z",
})
const connectedSpy = spyOn(connectedProvidersCache, "readConnectedProvidersCache").mockReturnValue(["openai"])
readConnectedProvidersCacheMock.mockReturnValue(["openai"])
const args = createBaseArgs({ subagent_type: "explore" })
const executorCtx = createExecutorContext(
async () => ([
@@ -357,18 +366,16 @@ describe("resolveSubagentExecution", () => {
maxTokens: 2222,
thinking: { type: "disabled" },
})
cacheSpy.mockRestore()
connectedSpy.mockRestore()
})
test("prefers exact promoted fallback match over earlier fuzzy prefix match", async () => {
//#given
const cacheSpy = spyOn(connectedProvidersCache, "readProviderModelsCache").mockReturnValue({
readProviderModelsCacheMock.mockReturnValue({
models: { openai: ["gpt-5.4-preview"] },
connected: ["openai"],
updatedAt: "2026-03-03T00:00:00.000Z",
})
const connectedSpy = spyOn(connectedProvidersCache, "readConnectedProvidersCache").mockReturnValue(["openai"])
readConnectedProvidersCacheMock.mockReturnValue(["openai"])
const args = createBaseArgs({ subagent_type: "explore" })
const executorCtx = createExecutorContext(
async () => ([
@@ -405,18 +412,16 @@ describe("resolveSubagentExecution", () => {
variant: "max",
reasoningEffort: "high",
})
cacheSpy.mockRestore()
connectedSpy.mockRestore()
})
test("matches promoted fallback settings when fuzzy resolution extends configured model without hyphen", async () => {
//#given
const cacheSpy = spyOn(connectedProvidersCache, "readProviderModelsCache").mockReturnValue({
readProviderModelsCacheMock.mockReturnValue({
models: { openai: ["gpt-5.4o"] },
connected: ["openai"],
updatedAt: "2026-03-03T00:00:00.000Z",
})
const connectedSpy = spyOn(connectedProvidersCache, "readConnectedProvidersCache").mockReturnValue(["openai"])
readConnectedProvidersCacheMock.mockReturnValue(["openai"])
const args = createBaseArgs({ subagent_type: "explore" })
const executorCtx = createExecutorContext(
async () => ([
@@ -448,18 +453,16 @@ describe("resolveSubagentExecution", () => {
variant: "low",
reasoningEffort: "high",
})
cacheSpy.mockRestore()
connectedSpy.mockRestore()
})
test("does not use unavailable matchedAgent.model as fallback for custom subagent", async () => {
//#given
const cacheSpy = spyOn(connectedProvidersCache, "readProviderModelsCache").mockReturnValue({
readProviderModelsCacheMock.mockReturnValue({
models: { minimaxi: ["MiniMax-M2.7"] },
connected: ["minimaxi"],
updatedAt: "2026-03-03T00:00:00.000Z",
})
const connectedSpy = spyOn(connectedProvidersCache, "readConnectedProvidersCache").mockReturnValue(["minimaxi"])
readConnectedProvidersCacheMock.mockReturnValue(["minimaxi"])
const args = createBaseArgs({ subagent_type: "my-custom-agent" })
const executorCtx = createExecutorContext(
async () => ([
@@ -473,18 +476,16 @@ describe("resolveSubagentExecution", () => {
//#then
expect(result.error).toBeUndefined()
expect(result.categoryModel?.modelID).not.toBe("MiniMax-M2.7-highspeed")
cacheSpy.mockRestore()
connectedSpy.mockRestore()
})
test("uses matchedAgent.model as fallback when model is available", async () => {
//#given
const cacheSpy = spyOn(connectedProvidersCache, "readProviderModelsCache").mockReturnValue({
readProviderModelsCacheMock.mockReturnValue({
models: { minimaxi: ["MiniMax-M2.7-highspeed"] },
connected: ["minimaxi"],
updatedAt: "2026-03-03T00:00:00.000Z",
})
const connectedSpy = spyOn(connectedProvidersCache, "readConnectedProvidersCache").mockReturnValue(["minimaxi"])
readConnectedProvidersCacheMock.mockReturnValue(["minimaxi"])
const args = createBaseArgs({ subagent_type: "my-custom-agent" })
const executorCtx = createExecutorContext(
async () => ([
@@ -498,18 +499,16 @@ describe("resolveSubagentExecution", () => {
//#then
expect(result.error).toBeUndefined()
expect(result.categoryModel).toEqual({ providerID: "minimaxi", modelID: "MiniMax-M2.7-highspeed" })
cacheSpy.mockRestore()
connectedSpy.mockRestore()
})
test("prefers the most specific prefix match when fallback entries share a prefix", async () => {
//#given
const cacheSpy = spyOn(connectedProvidersCache, "readProviderModelsCache").mockReturnValue({
readProviderModelsCacheMock.mockReturnValue({
models: { openai: ["gpt-4o-preview"] },
connected: ["openai"],
updatedAt: "2026-03-03T00:00:00.000Z",
})
const connectedSpy = spyOn(connectedProvidersCache, "readConnectedProvidersCache").mockReturnValue(["openai"])
readConnectedProvidersCacheMock.mockReturnValue(["openai"])
const args = createBaseArgs({ subagent_type: "explore" })
const executorCtx = createExecutorContext(
async () => ([
@@ -546,18 +545,16 @@ describe("resolveSubagentExecution", () => {
variant: "max",
reasoningEffort: "high",
})
cacheSpy.mockRestore()
connectedSpy.mockRestore()
})
test("preserves category temperature when fallback entry leaves temperature undefined", async () => {
//#given
const cacheSpy = spyOn(connectedProvidersCache, "readProviderModelsCache").mockReturnValue({
readProviderModelsCacheMock.mockReturnValue({
models: { openai: ["gpt-5.4"] },
connected: ["openai"],
updatedAt: "2026-03-03T00:00:00.000Z",
})
const connectedSpy = spyOn(connectedProvidersCache, "readConnectedProvidersCache").mockReturnValue(["openai"])
readConnectedProvidersCacheMock.mockReturnValue(["openai"])
const args = createBaseArgs({ subagent_type: "explore" })
const executorCtx = createExecutorContext(
async () => ([
@@ -596,18 +593,16 @@ describe("resolveSubagentExecution", () => {
temperature: 0.55,
top_p: 0.45,
})
cacheSpy.mockRestore()
connectedSpy.mockRestore()
})
test("applies category tuning params in the cold-cache override path", async () => {
//#given
const cacheSpy = spyOn(connectedProvidersCache, "readProviderModelsCache").mockReturnValue({
readProviderModelsCacheMock.mockReturnValue({
models: {},
connected: [],
updatedAt: "2026-03-03T00:00:00.000Z",
})
const connectedSpy = spyOn(connectedProvidersCache, "readConnectedProvidersCache").mockReturnValue([])
readConnectedProvidersCacheMock.mockReturnValue([])
const args = createBaseArgs({ subagent_type: "explore" })
const executorCtx = createExecutorContext(
async () => ([
@@ -648,27 +643,39 @@ describe("resolveSubagentExecution", () => {
reasoningEffort: "medium",
thinking: { type: "disabled" },
})
cacheSpy.mockRestore()
connectedSpy.mockRestore()
})
})
describe("resolveSubagentExecution - agent name sanitization", () => {
let logSpy: ReturnType<typeof spyOn> | undefined
let resolveSubagentExecution: SubagentResolverModule["resolveSubagentExecution"]
beforeEach(async () => {
logSpy = spyOn(logger, "log").mockImplementation(() => {})
mock.restore()
logMock.mockClear()
readConnectedProvidersCacheMock.mockReset()
readProviderModelsCacheMock.mockReset()
readConnectedProvidersCacheMock.mockReturnValue(null)
readProviderModelsCacheMock.mockReturnValue(null)
mock.module("../../../shared/logger", () => ({
log: logMock,
}))
mock.module("../../../shared/connected-providers-cache", () => ({
readConnectedProvidersCache: readConnectedProvidersCacheMock,
readProviderModelsCache: readProviderModelsCacheMock,
hasConnectedProvidersCache: () => readConnectedProvidersCacheMock() !== null,
hasProviderModelsCache: () => readProviderModelsCacheMock() !== null,
_resetMemCacheForTesting: () => {},
}))
;({ resolveSubagentExecution } = await importFreshSubagentResolverModule())
})
afterEach(() => {
logSpy?.mockRestore()
mock.restore()
})
test("strips backslash-wrapped agent names like \\hephaestus\\", async () => {
//#given
const cacheSpy = spyOn(connectedProvidersCache, "readProviderModelsCache").mockReturnValue({
readProviderModelsCacheMock.mockReturnValue({
models: {},
connected: [],
updatedAt: "2026-03-03T00:00:00.000Z",
@@ -684,12 +691,11 @@ describe("resolveSubagentExecution - agent name sanitization", () => {
//#then
expect(result.error).toBeUndefined()
expect(result.agentToUse).toBe("Hephaestus - Deep Agent")
cacheSpy.mockRestore()
})
test("strips double-quoted agent names", async () => {
//#given
const cacheSpy = spyOn(connectedProvidersCache, "readProviderModelsCache").mockReturnValue({
readProviderModelsCacheMock.mockReturnValue({
models: {},
connected: [],
updatedAt: "2026-03-03T00:00:00.000Z",
@@ -705,12 +711,11 @@ describe("resolveSubagentExecution - agent name sanitization", () => {
//#then
expect(result.error).toBeUndefined()
expect(result.agentToUse).toBe("oracle")
cacheSpy.mockRestore()
})
test("strips single-quoted agent names", async () => {
//#given
const cacheSpy = spyOn(connectedProvidersCache, "readProviderModelsCache").mockReturnValue({
readProviderModelsCacheMock.mockReturnValue({
models: {},
connected: [],
updatedAt: "2026-03-03T00:00:00.000Z",
@@ -726,6 +731,5 @@ describe("resolveSubagentExecution - agent name sanitization", () => {
//#then
expect(result.error).toBeUndefined()
expect(result.agentToUse).toBe("explore")
cacheSpy.mockRestore()
})
})