fix(look-at): preserve hardcoded multimodal variants
This commit is contained in:
@@ -0,0 +1,38 @@
|
||||
describe("buildMultimodalLookerFallbackChain", () => {
|
||||
it("preserves hardcoded variant metadata when dynamic and hardcoded entries share the same model", async () => {
|
||||
// given
|
||||
const { buildMultimodalLookerFallbackChain } = await import("./multimodal-fallback-chain")
|
||||
const visionCapableModels = [
|
||||
{ providerID: "openai", modelID: "gpt-5.4" },
|
||||
{ providerID: "opencode", modelID: "gpt-5.4" },
|
||||
]
|
||||
|
||||
// when
|
||||
const result = buildMultimodalLookerFallbackChain(visionCapableModels)
|
||||
const matchingEntries = result.filter((entry) => entry.model === "gpt-5.4")
|
||||
|
||||
// then
|
||||
expect(matchingEntries).toHaveLength(1)
|
||||
expect(matchingEntries[0]).toEqual({
|
||||
providers: ["openai", "opencode"],
|
||||
model: "gpt-5.4",
|
||||
variant: "medium",
|
||||
})
|
||||
})
|
||||
|
||||
it("merges missing hardcoded providers into an existing dynamic entry", async () => {
|
||||
// given
|
||||
const { buildMultimodalLookerFallbackChain } = await import("./multimodal-fallback-chain")
|
||||
const visionCapableModels = [{ providerID: "openai", modelID: "gpt-5.4" }]
|
||||
|
||||
// when
|
||||
const result = buildMultimodalLookerFallbackChain(visionCapableModels)
|
||||
|
||||
// then
|
||||
expect(result[0]).toEqual({
|
||||
providers: ["openai", "opencode"],
|
||||
model: "gpt-5.4",
|
||||
variant: "medium",
|
||||
})
|
||||
})
|
||||
})
|
||||
@@ -19,14 +19,14 @@ export function isHardcodedMultimodalFallbackModel(model: VisionCapableModel): b
|
||||
export function buildMultimodalLookerFallbackChain(
|
||||
visionCapableModels: VisionCapableModel[],
|
||||
): FallbackEntry[] {
|
||||
const seen = new Set<string>()
|
||||
const entryIndexByKey = new Map<string, number>()
|
||||
const fallbackChain: FallbackEntry[] = []
|
||||
|
||||
for (const visionCapableModel of visionCapableModels) {
|
||||
const key = getFullModelKey(visionCapableModel.providerID, visionCapableModel.modelID)
|
||||
if (seen.has(key)) continue
|
||||
if (entryIndexByKey.has(key)) continue
|
||||
|
||||
seen.add(key)
|
||||
entryIndexByKey.set(key, fallbackChain.length)
|
||||
fallbackChain.push({
|
||||
providers: [visionCapableModel.providerID],
|
||||
model: visionCapableModel.modelID,
|
||||
@@ -37,13 +37,45 @@ export function buildMultimodalLookerFallbackChain(
|
||||
const providerModelKeys = entry.providers.map((providerID) =>
|
||||
getFullModelKey(providerID, entry.model),
|
||||
)
|
||||
if (providerModelKeys.every((key) => seen.has(key))) {
|
||||
|
||||
const existingIndexes = [...new Set(
|
||||
providerModelKeys
|
||||
.map((key) => entryIndexByKey.get(key))
|
||||
.filter((index): index is number => index !== undefined),
|
||||
)]
|
||||
|
||||
if (existingIndexes.length > 0) {
|
||||
const [targetIndex, ...duplicateIndexes] = existingIndexes
|
||||
const targetEntry = fallbackChain[targetIndex]
|
||||
const mergedProviders = new Set(targetEntry.providers)
|
||||
|
||||
for (const providerID of entry.providers) {
|
||||
mergedProviders.add(providerID)
|
||||
}
|
||||
|
||||
for (const duplicateIndex of duplicateIndexes) {
|
||||
const duplicateEntry = fallbackChain[duplicateIndex]
|
||||
for (const providerID of duplicateEntry.providers) {
|
||||
mergedProviders.add(providerID)
|
||||
}
|
||||
duplicateEntry.providers = []
|
||||
}
|
||||
|
||||
targetEntry.providers = [...mergedProviders]
|
||||
targetEntry.variant ??= entry.variant
|
||||
|
||||
for (const providerID of targetEntry.providers) {
|
||||
entryIndexByKey.set(getFullModelKey(providerID, targetEntry.model), targetIndex)
|
||||
}
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
providerModelKeys.forEach((key) => seen.add(key))
|
||||
providerModelKeys.forEach((key) => {
|
||||
entryIndexByKey.set(key, fallbackChain.length)
|
||||
})
|
||||
fallbackChain.push(entry)
|
||||
}
|
||||
|
||||
return fallbackChain
|
||||
return fallbackChain.filter((entry) => entry.providers.length > 0)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user