test(model-fallback): use real provider transform in hook 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:
@@ -1,9 +1,38 @@
|
|||||||
import { unsafeTestValue } from "../../../test-support/unsafe-test-value"
|
import { unsafeTestValue } from "../../../test-support/unsafe-test-value"
|
||||||
declare const require: (name: string) => any
|
|
||||||
|
type TestCallback = () => void | Promise<void>
|
||||||
|
|
||||||
|
type ExpectResult = {
|
||||||
|
toBe: (expected: unknown) => void
|
||||||
|
toEqual: (expected: unknown) => void
|
||||||
|
toBeUndefined: () => void
|
||||||
|
}
|
||||||
|
|
||||||
|
type BunMockFunction<Args extends readonly unknown[], Return> = ((...args: Args) => Return) & {
|
||||||
|
mockReturnValue: (value: Return) => void
|
||||||
|
mockClear: () => void
|
||||||
|
mockImplementation: (implementation: (...args: Args) => Return) => void
|
||||||
|
}
|
||||||
|
|
||||||
|
type BunMock = {
|
||||||
|
<Args extends readonly unknown[], Return>(implementation: (...args: Args) => Return): BunMockFunction<Args, Return>
|
||||||
|
restore: () => void
|
||||||
|
module: (specifier: string, factory: () => Record<string, unknown>) => void
|
||||||
|
}
|
||||||
|
|
||||||
|
declare const require: (name: "bun:test") => {
|
||||||
|
beforeEach: (callback: TestCallback) => void
|
||||||
|
describe: (name: string, callback: TestCallback) => void
|
||||||
|
expect: (value: unknown) => ExpectResult
|
||||||
|
mock: BunMock
|
||||||
|
test: (name: string, callback: TestCallback) => void
|
||||||
|
afterAll: (callback: TestCallback) => void
|
||||||
|
}
|
||||||
|
|
||||||
const { beforeEach, describe, expect, mock, test, afterAll } = require("bun:test")
|
const { beforeEach, describe, expect, mock, test, afterAll } = require("bun:test")
|
||||||
|
|
||||||
const readConnectedProvidersCacheMock = mock(() => null)
|
const readConnectedProvidersCacheMock = mock<[], string[] | null>(() => null)
|
||||||
const readProviderModelsCacheMock = mock(() => null)
|
const readProviderModelsCacheMock = mock<[], null>(() => null)
|
||||||
const selectFallbackProviderMock = mock((providers: string[], preferredProviderID?: string) => {
|
const selectFallbackProviderMock = mock((providers: string[], preferredProviderID?: string) => {
|
||||||
const connectedProviders = readConnectedProvidersCacheMock()
|
const connectedProviders = readConnectedProvidersCacheMock()
|
||||||
if (connectedProviders) {
|
if (connectedProviders) {
|
||||||
@@ -22,25 +51,6 @@ const selectFallbackProviderMock = mock((providers: string[], preferredProviderI
|
|||||||
|
|
||||||
return providers[0] || preferredProviderID || "opencode"
|
return providers[0] || preferredProviderID || "opencode"
|
||||||
})
|
})
|
||||||
const transformModelForProviderMock = mock((provider: string, model: string) => {
|
|
||||||
if (provider === "github-copilot") {
|
|
||||||
return model
|
|
||||||
.replace("claude-opus-4-7", "claude-opus-4.7")
|
|
||||||
.replace("claude-sonnet-4-6", "claude-sonnet-4.6")
|
|
||||||
.replace("claude-sonnet-4-5", "claude-sonnet-4.5")
|
|
||||||
.replace("claude-haiku-4-5", "claude-haiku-4.5")
|
|
||||||
.replace("claude-sonnet-4", "claude-sonnet-4")
|
|
||||||
.replace(/gemini-3\.1-pro(?!-)/g, "gemini-3.1-pro-preview")
|
|
||||||
.replace(/gemini-3-flash(?!-)/g, "gemini-3-flash-preview")
|
|
||||||
}
|
|
||||||
if (provider === "google") {
|
|
||||||
return model
|
|
||||||
.replace(/gemini-3\.1-pro(?!-)/g, "gemini-3.1-pro-preview")
|
|
||||||
.replace(/gemini-3-flash(?!-)/g, "gemini-3-flash-preview")
|
|
||||||
}
|
|
||||||
return model
|
|
||||||
})
|
|
||||||
|
|
||||||
afterAll(() => {
|
afterAll(() => {
|
||||||
mock.restore()
|
mock.restore()
|
||||||
})
|
})
|
||||||
@@ -51,10 +61,6 @@ async function importFreshModelFallbackHookModule() {
|
|||||||
readProviderModelsCache: readProviderModelsCacheMock,
|
readProviderModelsCache: readProviderModelsCacheMock,
|
||||||
}))
|
}))
|
||||||
|
|
||||||
mock.module("../../shared/provider-model-id-transform", () => ({
|
|
||||||
transformModelForProvider: transformModelForProviderMock,
|
|
||||||
}))
|
|
||||||
|
|
||||||
mock.module("../../shared/model-error-classifier", () => ({
|
mock.module("../../shared/model-error-classifier", () => ({
|
||||||
selectFallbackProvider: selectFallbackProviderMock,
|
selectFallbackProvider: selectFallbackProviderMock,
|
||||||
}))
|
}))
|
||||||
@@ -118,7 +124,7 @@ describe("model fallback hook", () => {
|
|||||||
|
|
||||||
expect(output.message["model"]).toEqual({
|
expect(output.message["model"]).toEqual({
|
||||||
providerID: "anthropic",
|
providerID: "anthropic",
|
||||||
modelID: "claude-opus-4-7",
|
modelID: "claude-opus-4.7",
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -147,14 +153,14 @@ describe("model fallback hook", () => {
|
|||||||
|
|
||||||
expect(firstOutput.message["model"]).toEqual({
|
expect(firstOutput.message["model"]).toEqual({
|
||||||
providerID: "anthropic",
|
providerID: "anthropic",
|
||||||
modelID: "claude-opus-4-7",
|
modelID: "claude-opus-4.7",
|
||||||
})
|
})
|
||||||
|
|
||||||
expect(
|
expect(
|
||||||
setPendingModelFallback(modelFallback, sessionID, "Sisyphus - Ultraworker", "anthropic", "claude-opus-4-7"),
|
setPendingModelFallback(modelFallback, sessionID, "Sisyphus - Ultraworker", "anthropic", "claude-opus-4-7"),
|
||||||
).toBe(true)
|
).toBe(true)
|
||||||
|
|
||||||
const secondOutput = {
|
const secondOutput: { message: Record<string, unknown>; parts: Array<{ type: string; text?: string }> } = {
|
||||||
message: {
|
message: {
|
||||||
model: { providerID: "anthropic", modelID: "claude-opus-4-7" },
|
model: { providerID: "anthropic", modelID: "claude-opus-4-7" },
|
||||||
},
|
},
|
||||||
@@ -362,8 +368,8 @@ describe("model fallback hook", () => {
|
|||||||
output: { message: Record<string, unknown>; parts: Array<{ type: string; text?: string }> },
|
output: { message: Record<string, unknown>; parts: Array<{ type: string; text?: string }> },
|
||||||
) => Promise<void>
|
) => Promise<void>
|
||||||
}>(createModelFallbackHook({
|
}>(createModelFallbackHook({
|
||||||
toast: async ({ title, message }) => {
|
toast: async (toastInput: { title: string; message: string }) => {
|
||||||
toastCalls.push({ title, message })
|
toastCalls.push({ title: toastInput.title, message: toastInput.message })
|
||||||
},
|
},
|
||||||
}))
|
}))
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user