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:
@@ -82,7 +82,7 @@ export async function resolveCategoryExecution(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const availableModels = await getAvailableModelsForDelegateTask(client)
|
const availableModels = executorCtx.availableModelsOverride ?? await getAvailableModelsForDelegateTask(client)
|
||||||
|
|
||||||
const resolved = resolveCategoryConfig(categoryName, {
|
const resolved = resolveCategoryConfig(categoryName, {
|
||||||
userCategories,
|
userCategories,
|
||||||
|
|||||||
@@ -13,6 +13,11 @@ export interface ExecutorContext {
|
|||||||
browserProvider?: BrowserAutomationProvider
|
browserProvider?: BrowserAutomationProvider
|
||||||
agentOverrides?: AgentOverrides
|
agentOverrides?: AgentOverrides
|
||||||
sisyphusAgentConfig?: SisyphusAgentConfig
|
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
|
modelFallbackControllerAccessor?: ModelFallbackControllerAccessor
|
||||||
onSyncSessionCreated?: (event: { sessionID: string; parentID: string; title: string }) => Promise<void>
|
onSyncSessionCreated?: (event: { sessionID: string; parentID: string; title: string }) => Promise<void>
|
||||||
syncPollTimeoutMs?: number
|
syncPollTimeoutMs?: number
|
||||||
|
|||||||
@@ -191,7 +191,7 @@ Create the work plan directly - that's your job as the planning agent.`,
|
|||||||
?? agentCategoryConfig?.fallback_models
|
?? agentCategoryConfig?.fallback_models
|
||||||
)
|
)
|
||||||
|
|
||||||
const availableModels = await getAvailableModelsForDelegateTask(client)
|
const availableModels = executorCtx.availableModelsOverride ?? await getAvailableModelsForDelegateTask(client)
|
||||||
|
|
||||||
if (agentOverride?.model || agentCategoryModel || agentRequirement || matchedAgent.model) {
|
if (agentOverride?.model || agentCategoryModel || agentRequirement || matchedAgent.model) {
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
/// <reference types="bun-types" />
|
/// <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 { DelegateTaskArgs } from "../types"
|
||||||
import type { ExecutorContext } from "../executor-types"
|
import type { ExecutorContext } from "../executor-types"
|
||||||
|
import * as connectedProvidersCache from "../../../shared/connected-providers-cache"
|
||||||
|
|
||||||
type SubagentResolverModule = typeof import("../subagent-resolver")
|
type SubagentResolverModule = typeof import("../subagent-resolver")
|
||||||
|
|
||||||
@@ -30,6 +31,36 @@ type ClaudeCodeAgentRecord = Record<
|
|||||||
const loadUserAgentsMock = mock((): ClaudeCodeAgentRecord => ({}))
|
const loadUserAgentsMock = mock((): ClaudeCodeAgentRecord => ({}))
|
||||||
const loadProjectAgentsMock = mock((_directory?: string): 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> {
|
async function importFreshSubagentResolverModule(): Promise<SubagentResolverModule> {
|
||||||
return await import(`../subagent-resolver?test=${Date.now()}-${Math.random()}`)
|
return await import(`../subagent-resolver?test=${Date.now()}-${Math.random()}`)
|
||||||
}
|
}
|
||||||
@@ -59,6 +90,7 @@ function createExecutorContext(
|
|||||||
client,
|
client,
|
||||||
manager: {} as ExecutorContext["manager"],
|
manager: {} as ExecutorContext["manager"],
|
||||||
directory: "/tmp/test",
|
directory: "/tmp/test",
|
||||||
|
availableModelsOverride: getAvailableModelsOverride(),
|
||||||
...overrides,
|
...overrides,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -80,13 +112,7 @@ describe("resolveSubagentExecution", () => {
|
|||||||
mock.module("../../../shared/logger", () => ({
|
mock.module("../../../shared/logger", () => ({
|
||||||
log: logMock,
|
log: logMock,
|
||||||
}))
|
}))
|
||||||
mock.module("../../../shared/connected-providers-cache", () => ({
|
mockConnectedProvidersCache()
|
||||||
readConnectedProvidersCache: readConnectedProvidersCacheMock,
|
|
||||||
readProviderModelsCache: readProviderModelsCacheMock,
|
|
||||||
hasConnectedProvidersCache: () => readConnectedProvidersCacheMock() !== null,
|
|
||||||
hasProviderModelsCache: () => readProviderModelsCacheMock() !== null,
|
|
||||||
_resetMemCacheForTesting: () => {},
|
|
||||||
}))
|
|
||||||
mock.module("../../../features/claude-code-agent-loader/loader", () => ({
|
mock.module("../../../features/claude-code-agent-loader/loader", () => ({
|
||||||
loadUserAgents: loadUserAgentsMock,
|
loadUserAgents: loadUserAgentsMock,
|
||||||
loadProjectAgents: loadProjectAgentsMock,
|
loadProjectAgents: loadProjectAgentsMock,
|
||||||
@@ -1320,13 +1346,7 @@ describe("resolveSubagentExecution - agent name sanitization", () => {
|
|||||||
mock.module("../../../shared/logger", () => ({
|
mock.module("../../../shared/logger", () => ({
|
||||||
log: logMock,
|
log: logMock,
|
||||||
}))
|
}))
|
||||||
mock.module("../../../shared/connected-providers-cache", () => ({
|
mockConnectedProvidersCache()
|
||||||
readConnectedProvidersCache: readConnectedProvidersCacheMock,
|
|
||||||
readProviderModelsCache: readProviderModelsCacheMock,
|
|
||||||
hasConnectedProvidersCache: () => readConnectedProvidersCacheMock() !== null,
|
|
||||||
hasProviderModelsCache: () => readProviderModelsCacheMock() !== null,
|
|
||||||
_resetMemCacheForTesting: () => {},
|
|
||||||
}))
|
|
||||||
mock.module("../../../features/claude-code-agent-loader/loader", () => ({
|
mock.module("../../../features/claude-code-agent-loader/loader", () => ({
|
||||||
loadUserAgents: loadUserAgentsMock,
|
loadUserAgents: loadUserAgentsMock,
|
||||||
loadProjectAgents: loadProjectAgentsMock,
|
loadProjectAgents: loadProjectAgentsMock,
|
||||||
|
|||||||
Reference in New Issue
Block a user