From 8fb4873eaca1ddbc7abe22852560e65bc4c6f186 Mon Sep 17 00:00:00 2001 From: 134 Date: Sun, 9 Aug 2026 18:36:49 +0800 Subject: [PATCH] fix(ai): store provider model metadata as jsonb objects --- scripts/consolidate-ai-providers.ts | 36 ++++++++++++++++++----------- 1 file changed, 23 insertions(+), 13 deletions(-) diff --git a/scripts/consolidate-ai-providers.ts b/scripts/consolidate-ai-providers.ts index 7913736ca..c43118560 100644 --- a/scripts/consolidate-ai-providers.ts +++ b/scripts/consolidate-ai-providers.ts @@ -66,6 +66,10 @@ function stableHash(value: unknown) { return createHash("sha256").update(JSON.stringify(value)).digest("hex"); } +function toJsonValue(value: unknown): postgres.JSONValue { + return JSON.parse(JSON.stringify(value)) as postgres.JSONValue; +} + function sortById(rows: T[]) { return [...rows].sort((left, right) => left.id.localeCompare(right.id)); } @@ -290,20 +294,19 @@ async function main() { where "providerId" = ${targetProviderId}::uuid and "modelId" = ${preset.modelId} order by "createdAt" limit 1 `; - const values = { - description: preset.description, - capabilities: JSON.stringify(preset.capabilities), - defaultParams: JSON.stringify(preset.defaultParams), - imageGenConfig: preset.imageGenConfig ? JSON.stringify(preset.imageGenConfig) : null, - }; + const capabilitiesJson = tx.json(toJsonValue(preset.capabilities)); + const defaultParamsJson = tx.json(toJsonValue(preset.defaultParams)); + const imageGenConfigJson = preset.imageGenConfig + ? tx.json(toJsonValue(preset.imageGenConfig)) + : null; if (existing[0]) { await tx` update "AiModel" set - "displayName" = ${preset.displayName}, description = ${values.description}, + "displayName" = ${preset.displayName}, description = ${preset.description}, "supportsVision" = ${preset.supportsVision}, "supportsImageGen" = ${preset.supportsImageGen}, "isEnabled" = true, "isHidden" = ${preset.isHidden}, "sortOrder" = ${preset.sortOrder}, - capabilities = ${values.capabilities}::jsonb, "defaultParams" = ${values.defaultParams}::jsonb, - "imageGenConfig" = ${values.imageGenConfig}::jsonb, "updatedAt" = now() + capabilities = ${capabilitiesJson}, "defaultParams" = ${defaultParamsJson}, + "imageGenConfig" = ${imageGenConfigJson}, "updatedAt" = now() where id = ${existing[0].id}::uuid `; modelDbIds.set(preset.modelId, existing[0].id); @@ -314,10 +317,10 @@ async function main() { "supportsImageGen", "isEnabled", "isHidden", "sortOrder", capabilities, "defaultParams", "imageGenConfig", "isDefault", "isDefaultTextEditModel" ) values ( - ${targetProviderId}::uuid, ${preset.modelId}, ${preset.displayName}, ${values.description}, + ${targetProviderId}::uuid, ${preset.modelId}, ${preset.displayName}, ${preset.description}, ${preset.supportsVision}, ${preset.supportsImageGen}, true, ${preset.isHidden}, - ${preset.sortOrder}, ${values.capabilities}::jsonb, ${values.defaultParams}::jsonb, - ${values.imageGenConfig}::jsonb, false, false + ${preset.sortOrder}, ${capabilitiesJson}, ${defaultParamsJson}, + ${imageGenConfigJson}, false, false ) returning id `; if (!created) throw new Error(`Failed to create VIP98K model ${preset.modelId}`); @@ -441,7 +444,14 @@ async function main() { ); const invalidVipModels = remainingModels.filter((model) => { if (!vipProviderIds.has(model.providerId)) return false; - const capabilities = model.capabilities as Record | null; + if ( + !model.capabilities || + typeof model.capabilities !== "object" || + Array.isArray(model.capabilities) + ) { + return true; + } + const capabilities = model.capabilities as Record; const kind = String(capabilities?.kind || "").trim().toLowerCase(); if (["video", "model-3d", "world", "chat"].includes(kind)) { return model.supportsImageGen;