Merge pull request #1509 from rooftop-Owl/fix/category-delegation-cache-format-mismatch
fix: handle both string[] and object[] formats in provider-models cache
This commit is contained in:
commit
617d7f4f67
@ -11,8 +11,16 @@ interface ConnectedProvidersCache {
|
|||||||
updatedAt: string
|
updatedAt: string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface ModelMetadata {
|
||||||
|
id: string
|
||||||
|
provider?: string
|
||||||
|
context?: number
|
||||||
|
output?: number
|
||||||
|
name?: string
|
||||||
|
}
|
||||||
|
|
||||||
interface ProviderModelsCache {
|
interface ProviderModelsCache {
|
||||||
models: Record<string, string[]>
|
models: Record<string, string[] | ModelMetadata[]>
|
||||||
connected: string[]
|
connected: string[]
|
||||||
updatedAt: string
|
updatedAt: string
|
||||||
}
|
}
|
||||||
|
|||||||
@ -619,7 +619,7 @@ describe("fetchAvailableModels with provider-models cache (whitelist-filtered)",
|
|||||||
rmSync(tempDir, { recursive: true, force: true })
|
rmSync(tempDir, { recursive: true, force: true })
|
||||||
})
|
})
|
||||||
|
|
||||||
function writeProviderModelsCache(data: { models: Record<string, string[]>; connected: string[] }) {
|
function writeProviderModelsCache(data: { models: Record<string, string[] | any[]>; connected: string[] }) {
|
||||||
const cacheDir = join(tempDir, "oh-my-opencode")
|
const cacheDir = join(tempDir, "oh-my-opencode")
|
||||||
require("fs").mkdirSync(cacheDir, { recursive: true })
|
require("fs").mkdirSync(cacheDir, { recursive: true })
|
||||||
writeFileSync(join(cacheDir, "provider-models.json"), JSON.stringify({
|
writeFileSync(join(cacheDir, "provider-models.json"), JSON.stringify({
|
||||||
@ -723,6 +723,72 @@ describe("fetchAvailableModels with provider-models cache (whitelist-filtered)",
|
|||||||
expect(result.has("anthropic/claude-opus-4-5")).toBe(false)
|
expect(result.has("anthropic/claude-opus-4-5")).toBe(false)
|
||||||
expect(result.has("google/gemini-3-pro")).toBe(false)
|
expect(result.has("google/gemini-3-pro")).toBe(false)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it("should handle object[] format with metadata (Ollama-style)", async () => {
|
||||||
|
writeProviderModelsCache({
|
||||||
|
models: {
|
||||||
|
ollama: [
|
||||||
|
{ id: "ministral-3:14b-32k-agent", provider: "ollama", context: 32768, output: 8192 },
|
||||||
|
{ id: "qwen3-coder:32k-agent", provider: "ollama", context: 32768, output: 8192 }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
connected: ["ollama"]
|
||||||
|
})
|
||||||
|
|
||||||
|
const result = await fetchAvailableModels(undefined, {
|
||||||
|
connectedProviders: ["ollama"]
|
||||||
|
})
|
||||||
|
|
||||||
|
expect(result.size).toBe(2)
|
||||||
|
expect(result.has("ollama/ministral-3:14b-32k-agent")).toBe(true)
|
||||||
|
expect(result.has("ollama/qwen3-coder:32k-agent")).toBe(true)
|
||||||
|
})
|
||||||
|
|
||||||
|
it("should handle mixed string[] and object[] formats across providers", async () => {
|
||||||
|
writeProviderModelsCache({
|
||||||
|
models: {
|
||||||
|
anthropic: ["claude-opus-4-5", "claude-sonnet-4-5"],
|
||||||
|
ollama: [
|
||||||
|
{ id: "ministral-3:14b-32k-agent", provider: "ollama" },
|
||||||
|
{ id: "qwen3-coder:32k-agent", provider: "ollama" }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
connected: ["anthropic", "ollama"]
|
||||||
|
})
|
||||||
|
|
||||||
|
const result = await fetchAvailableModels(undefined, {
|
||||||
|
connectedProviders: ["anthropic", "ollama"]
|
||||||
|
})
|
||||||
|
|
||||||
|
expect(result.size).toBe(4)
|
||||||
|
expect(result.has("anthropic/claude-opus-4-5")).toBe(true)
|
||||||
|
expect(result.has("anthropic/claude-sonnet-4-5")).toBe(true)
|
||||||
|
expect(result.has("ollama/ministral-3:14b-32k-agent")).toBe(true)
|
||||||
|
expect(result.has("ollama/qwen3-coder:32k-agent")).toBe(true)
|
||||||
|
})
|
||||||
|
|
||||||
|
it("should skip invalid entries in object[] format", async () => {
|
||||||
|
writeProviderModelsCache({
|
||||||
|
models: {
|
||||||
|
ollama: [
|
||||||
|
{ id: "valid-model", provider: "ollama" },
|
||||||
|
{ provider: "ollama" },
|
||||||
|
{ id: "", provider: "ollama" },
|
||||||
|
null,
|
||||||
|
"string-model"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
connected: ["ollama"]
|
||||||
|
})
|
||||||
|
|
||||||
|
const result = await fetchAvailableModels(undefined, {
|
||||||
|
connectedProviders: ["ollama"]
|
||||||
|
})
|
||||||
|
|
||||||
|
expect(result.size).toBe(2)
|
||||||
|
expect(result.has("ollama/valid-model")).toBe(true)
|
||||||
|
expect(result.has("ollama/string-model")).toBe(true)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe("isModelAvailable", () => {
|
describe("isModelAvailable", () => {
|
||||||
|
|||||||
@ -187,16 +187,23 @@ export async function fetchAvailableModels(
|
|||||||
if (providerCount === 0) {
|
if (providerCount === 0) {
|
||||||
log("[fetchAvailableModels] provider-models cache empty, falling back to models.json")
|
log("[fetchAvailableModels] provider-models cache empty, falling back to models.json")
|
||||||
} else {
|
} else {
|
||||||
log("[fetchAvailableModels] using provider-models cache (whitelist-filtered)")
|
log("[fetchAvailableModels] using provider-models cache (whitelist-filtered)")
|
||||||
|
|
||||||
for (const [providerId, modelIds] of Object.entries(providerModelsCache.models)) {
|
for (const [providerId, modelIds] of Object.entries(providerModelsCache.models)) {
|
||||||
if (!connectedSet.has(providerId)) {
|
if (!connectedSet.has(providerId)) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
for (const modelId of modelIds) {
|
for (const modelItem of modelIds) {
|
||||||
|
// Handle both string[] (legacy) and object[] (with metadata) formats
|
||||||
|
const modelId = typeof modelItem === 'string'
|
||||||
|
? modelItem
|
||||||
|
: (modelItem as any)?.id
|
||||||
|
|
||||||
|
if (modelId) {
|
||||||
modelSet.add(`${providerId}/${modelId}`)
|
modelSet.add(`${providerId}/${modelId}`)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
log("[fetchAvailableModels] parsed from provider-models cache", {
|
log("[fetchAvailableModels] parsed from provider-models cache", {
|
||||||
count: modelSet.size,
|
count: modelSet.size,
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user