diff --git a/apps/api/migrations/0072_glm52_text_capability_sync.sql b/apps/api/migrations/0072_glm52_text_capability_sync.sql new file mode 100644 index 0000000..5e24be9 --- /dev/null +++ b/apps/api/migrations/0072_glm52_text_capability_sync.sql @@ -0,0 +1,102 @@ +-- GLM-5.2 is a text-only foundation model. The official model page lists text +-- as both its input and output modality; vision belongs to the separate GLM-5V +-- family. Keep the base catalog, snapshots, and already-created platform rows +-- authoritative so stale/customized image_analysis metadata cannot leak back +-- into model discovery. +-- Source: https://docs.bigmodel.cn/cn/guide/models/text/glm-5.2 + +WITH glm52_contract AS ( + SELECT + '["text_generate","tools_call"]'::jsonb AS model_type, + '{ + "text_generate": { + "supportedApiProtocols": ["openai_chat_completions"], + "max_context_tokens": 1000000, + "max_output_tokens": 131072, + "supportTool": true, + "supportThinking": true, + "supportThinkingModeSwitch": true, + "thinkingEffortLevels": ["none", "high", "max"], + "supportStructuredOutput": true + }, + "tools_call": { + "supportedApiProtocols": ["openai_chat_completions"], + "max_context_tokens": 1000000, + "max_output_tokens": 131072, + "supportTool": true, + "supportThinking": true, + "supportThinkingModeSwitch": true, + "thinkingEffortLevels": ["none", "high", "max"], + "supportStructuredOutput": true + }, + "originalTypes": ["text_generate", "tools_call"] + }'::jsonb AS capabilities, + '旗舰 Coding 文本模型(不支持图像/视频理解),1M 上下文,最大输出 128K;支持思考及推理强度、流式输出/工具调用、结构化输出与隐式上下文缓存。'::text AS description +), +updated_base_models AS ( + UPDATE base_model_catalog base_model + SET model_type = contract.model_type, + capabilities = contract.capabilities, + metadata = COALESCE(base_model.metadata, '{}'::jsonb) + || jsonb_build_object( + 'originalTypes', contract.model_type, + 'description', contract.description, + 'rawModel', COALESCE(base_model.metadata->'rawModel', '{}'::jsonb) + || jsonb_build_object( + 'types', contract.model_type, + 'description', contract.description, + 'capabilities', contract.capabilities - 'originalTypes' + ) + ), + default_snapshot = CASE + WHEN COALESCE(base_model.default_snapshot, '{}'::jsonb) = '{}'::jsonb THEN base_model.default_snapshot + ELSE COALESCE(base_model.default_snapshot, '{}'::jsonb) + || jsonb_build_object( + 'modelType', contract.model_type, + 'capabilities', contract.capabilities, + 'metadata', COALESCE(base_model.default_snapshot->'metadata', '{}'::jsonb) + || jsonb_build_object( + 'originalTypes', contract.model_type, + 'description', contract.description, + 'rawModel', COALESCE(base_model.default_snapshot->'metadata'->'rawModel', '{}'::jsonb) + || jsonb_build_object( + 'types', contract.model_type, + 'description', contract.description, + 'capabilities', contract.capabilities - 'originalTypes' + ) + ) + ) + END, + updated_at = now() + FROM glm52_contract contract + WHERE ( + base_model.canonical_model_key IN ('easyai:GLM-5.2', 'zhipu-openai:glm-5.2') + OR ( + base_model.provider_key = 'easyai' + AND lower(base_model.provider_model_name) = 'glm-5.2' + ) + OR ( + base_model.provider_key = 'zhipu-openai' + AND lower(base_model.provider_model_name) = 'glm-5.2' + ) + ) + RETURNING base_model.id +) +UPDATE platform_models platform_model +SET model_type = contract.model_type, + capabilities = contract.capabilities, + capability_override = (COALESCE(platform_model.capability_override, '{}'::jsonb) - 'image_analysis' - 'video_understanding' - 'originalTypes'), + updated_at = now() +FROM integration_platforms platform +CROSS JOIN glm52_contract contract +WHERE platform_model.platform_id = platform.id + AND platform.deleted_at IS NULL + AND ( + platform_model.base_model_id IN ( + SELECT id FROM updated_base_models + ) + OR ( + platform.provider IN ('easyai', 'zhipu-openai') + AND lower(COALESCE(NULLIF(platform_model.provider_model_name, ''), platform_model.model_name)) = 'glm-5.2' + ) + );