test(delegate-task): isolate model availability fixtures

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-05-29 19:08:55 +09:00
parent 3a4f014d8b
commit d32caf3d87
4 changed files with 42 additions and 17 deletions
+1 -1
View File
@@ -82,7 +82,7 @@ export async function resolveCategoryExecution(
}
}
const availableModels = await getAvailableModelsForDelegateTask(client)
const availableModels = executorCtx.availableModelsOverride ?? await getAvailableModelsForDelegateTask(client)
const resolved = resolveCategoryConfig(categoryName, {
userCategories,
@@ -13,6 +13,11 @@ export interface ExecutorContext {
browserProvider?: BrowserAutomationProvider
agentOverrides?: AgentOverrides
sisyphusAgentConfig?: SisyphusAgentConfig
/**
* Test hook: bypass global model cache reads with an explicit available model set.
* This keeps resolver tests isolated from Bun's process-wide module cache.
*/
availableModelsOverride?: Set<string>
modelFallbackControllerAccessor?: ModelFallbackControllerAccessor
onSyncSessionCreated?: (event: { sessionID: string; parentID: string; title: string }) => Promise<void>
syncPollTimeoutMs?: number
+1 -1
View File
@@ -191,7 +191,7 @@ Create the work plan directly - that's your job as the planning agent.`,
?? agentCategoryConfig?.fallback_models
)
const availableModels = await getAvailableModelsForDelegateTask(client)
const availableModels = executorCtx.availableModelsOverride ?? await getAvailableModelsForDelegateTask(client)
if (agentOverride?.model || agentCategoryModel || agentRequirement || matchedAgent.model) {
@@ -1,8 +1,9 @@
/// <reference types="bun-types" />
import { afterEach, beforeEach, describe, expect, mock, test } from "bun:test"
import { afterEach, beforeEach, describe, expect, mock, spyOn, test } from "bun:test"
import type { DelegateTaskArgs } from "../types"
import type { ExecutorContext } from "../executor-types"
import * as connectedProvidersCache from "../../../shared/connected-providers-cache"
type SubagentResolverModule = typeof import("../subagent-resolver")
@@ -30,6 +31,36 @@ type ClaudeCodeAgentRecord = Record<
const loadUserAgentsMock = mock((): ClaudeCodeAgentRecord => ({}))
const loadProjectAgentsMock = mock((_directory?: string): ClaudeCodeAgentRecord => ({}))
function getAvailableModelsOverride(): Set<string> | undefined {
const providerModelsCache = readProviderModelsCacheMock()
if (providerModelsCache === null) {
return undefined
}
const connectedProviders = new Set(providerModelsCache.connected)
const availableModels = new Set<string>()
for (const [providerID, models] of Object.entries(providerModelsCache.models)) {
if (!connectedProviders.has(providerID)) {
continue
}
for (const modelID of models) {
availableModels.add(`${providerID}/${modelID}`)
}
}
return availableModels
}
function mockConnectedProvidersCache(): void {
spyOn(connectedProvidersCache, "readConnectedProvidersCache").mockImplementation(readConnectedProvidersCacheMock)
spyOn(connectedProvidersCache, "readProviderModelsCache").mockImplementation(readProviderModelsCacheMock)
spyOn(connectedProvidersCache, "hasConnectedProvidersCache").mockImplementation(
() => readConnectedProvidersCacheMock() !== null,
)
spyOn(connectedProvidersCache, "hasProviderModelsCache").mockImplementation(
() => readProviderModelsCacheMock() !== null,
)
}
async function importFreshSubagentResolverModule(): Promise<SubagentResolverModule> {
return await import(`../subagent-resolver?test=${Date.now()}-${Math.random()}`)
}
@@ -59,6 +90,7 @@ function createExecutorContext(
client,
manager: {} as ExecutorContext["manager"],
directory: "/tmp/test",
availableModelsOverride: getAvailableModelsOverride(),
...overrides,
}
}
@@ -80,13 +112,7 @@ describe("resolveSubagentExecution", () => {
mock.module("../../../shared/logger", () => ({
log: logMock,
}))
mock.module("../../../shared/connected-providers-cache", () => ({
readConnectedProvidersCache: readConnectedProvidersCacheMock,
readProviderModelsCache: readProviderModelsCacheMock,
hasConnectedProvidersCache: () => readConnectedProvidersCacheMock() !== null,
hasProviderModelsCache: () => readProviderModelsCacheMock() !== null,
_resetMemCacheForTesting: () => {},
}))
mockConnectedProvidersCache()
mock.module("../../../features/claude-code-agent-loader/loader", () => ({
loadUserAgents: loadUserAgentsMock,
loadProjectAgents: loadProjectAgentsMock,
@@ -1320,13 +1346,7 @@ describe("resolveSubagentExecution - agent name sanitization", () => {
mock.module("../../../shared/logger", () => ({
log: logMock,
}))
mock.module("../../../shared/connected-providers-cache", () => ({
readConnectedProvidersCache: readConnectedProvidersCacheMock,
readProviderModelsCache: readProviderModelsCacheMock,
hasConnectedProvidersCache: () => readConnectedProvidersCacheMock() !== null,
hasProviderModelsCache: () => readProviderModelsCacheMock() !== null,
_resetMemCacheForTesting: () => {},
}))
mockConnectedProvidersCache()
mock.module("../../../features/claude-code-agent-loader/loader", () => ({
loadUserAgents: loadUserAgentsMock,
loadProjectAgents: loadProjectAgentsMock,