-- Add the latest coding-agent text models from server-main and official docs. -- Alias values that become EasyAI-facing model names must avoid spaces. INSERT INTO model_catalog_providers ( provider_key, provider_code, provider_type, display_name, icon_path, source, capability_schema, default_rate_limit_policy, metadata, status ) VALUES ( 'moonshot-openai', 'moonshot-openai', 'openai', 'Kimi(OpenAI兼容)', 'https://static.51easyai.com/kimi-logo-124.png', 'server-main.integration-platform', '{}'::jsonb, '{}'::jsonb, jsonb_build_object( 'seed', 'server-main-provider-defaults', 'syncSource', 'server-main.integration-platform', 'sourceCode', 'moonshot-openai', 'sourceSpecType', 'openai' ), 'active' ) ON CONFLICT (provider_key) DO UPDATE SET provider_code = EXCLUDED.provider_code, provider_type = EXCLUDED.provider_type, display_name = EXCLUDED.display_name, icon_path = EXCLUDED.icon_path, source = EXCLUDED.source, metadata = model_catalog_providers.metadata || EXCLUDED.metadata, status = EXCLUDED.status, updated_at = now(); UPDATE model_catalog_providers SET default_base_url = 'https://api.moonshot.cn/v1', default_auth_type = 'APIKey', metadata = metadata || jsonb_build_object( 'defaultConnectionSource', 'server-main.integration-platform', 'defaultBaseUrlSynced', 'https://api.moonshot.cn/v1', 'defaultAuthTypeSynced', 'APIKey' ), updated_at = now() WHERE provider_key = 'moonshot-openai'; UPDATE base_model_catalog b SET canonical_model_key = 'easyai:Doubao-Seed-2.0-Code-Preview', updated_at = now() WHERE b.canonical_model_key = 'easyai:Doubao Seed 2.0 Code Preview' AND NOT EXISTS ( SELECT 1 FROM base_model_catalog existing WHERE existing.canonical_model_key = 'easyai:Doubao-Seed-2.0-Code-Preview' ); WITH doubao_alias(old_alias, new_alias, volces_model_name) AS ( VALUES ( 'Doubao Seed 2.0 Code Preview', 'Doubao-Seed-2.0-Code-Preview', 'doubao-seed-2-0-code-preview-260215' ) ), targets AS ( SELECT b.id, b.provider_key, b.canonical_model_key, b.provider_model_name, d.old_alias, d.new_alias, d.volces_model_name FROM base_model_catalog b CROSS JOIN doubao_alias d WHERE ( b.provider_key = 'easyai' AND b.provider_model_name IN (d.old_alias, d.new_alias) ) OR ( b.provider_key = 'volces-openai' AND b.provider_model_name = d.volces_model_name ) ) UPDATE base_model_catalog b SET provider_model_name = CASE WHEN targets.provider_key = 'easyai' THEN targets.new_alias ELSE b.provider_model_name END, display_name = targets.new_alias, metadata = jsonb_set( jsonb_set( COALESCE(b.metadata, '{}'::jsonb), '{alias}', to_jsonb(targets.new_alias), true ), '{rawModel}', COALESCE(b.metadata -> 'rawModel', '{}'::jsonb) || jsonb_build_object('alias', targets.new_alias) || CASE WHEN targets.provider_key = 'easyai' THEN jsonb_build_object('name', targets.new_alias) ELSE '{}'::jsonb END, true ), default_snapshot = CASE WHEN b.default_snapshot IS NULL THEN NULL ELSE jsonb_set( COALESCE(b.default_snapshot, '{}'::jsonb) || jsonb_build_object( 'canonicalModelKey', CASE WHEN targets.provider_key = 'easyai' THEN 'easyai:' || targets.new_alias ELSE b.canonical_model_key END, 'providerModelName', CASE WHEN targets.provider_key = 'easyai' THEN targets.new_alias ELSE b.provider_model_name END, 'modelAlias', targets.new_alias, 'displayName', targets.new_alias ), '{metadata}', jsonb_set( jsonb_set( COALESCE(b.default_snapshot -> 'metadata', '{}'::jsonb), '{alias}', to_jsonb(targets.new_alias), true ), '{rawModel}', COALESCE(b.default_snapshot -> 'metadata' -> 'rawModel', '{}'::jsonb) || jsonb_build_object('alias', targets.new_alias) || CASE WHEN targets.provider_key = 'easyai' THEN jsonb_build_object('name', targets.new_alias) ELSE '{}'::jsonb END, true ), true ) END, updated_at = now() FROM targets WHERE b.id = targets.id; WITH doubao_alias(old_alias, new_alias, volces_model_name) AS ( VALUES ( 'Doubao Seed 2.0 Code Preview', 'Doubao-Seed-2.0-Code-Preview', 'doubao-seed-2-0-code-preview-260215' ) ) UPDATE platform_models pm SET model_name = doubao_alias.new_alias, updated_at = now() FROM integration_platforms p, doubao_alias WHERE pm.platform_id = p.id AND p.provider = 'easyai' AND pm.model_name = doubao_alias.old_alias AND NOT EXISTS ( SELECT 1 FROM platform_models existing WHERE existing.platform_id = pm.platform_id AND existing.model_name = doubao_alias.new_alias ); WITH doubao_alias(old_alias, new_alias, volces_model_name) AS ( VALUES ( 'Doubao Seed 2.0 Code Preview', 'Doubao-Seed-2.0-Code-Preview', 'doubao-seed-2-0-code-preview-260215' ) ) UPDATE platform_models pm SET provider_model_name = CASE WHEN p.provider = 'easyai' THEN doubao_alias.new_alias ELSE pm.provider_model_name END, model_alias = doubao_alias.new_alias, display_name = doubao_alias.new_alias, updated_at = now() FROM integration_platforms p, doubao_alias WHERE pm.platform_id = p.id AND ( ( p.provider = 'easyai' AND pm.model_name IN (doubao_alias.old_alias, doubao_alias.new_alias) ) OR ( p.provider = 'volces-openai' AND ( pm.model_name = doubao_alias.volces_model_name OR pm.provider_model_name = doubao_alias.volces_model_name ) ) ); WITH model_defs AS ( SELECT * FROM ( VALUES ( 'easyai', 'easyai', 'EasyAI', 'easyai', 'easyai:GLM-5.2', 'GLM-5.2', 'GLM-5.2', 'GLM-5.2', 'GLM-5.2', '旗舰 Coding 模型,文本输入/输出,1M 上下文,最大输出 128K,支持思考模式、工具调用与结构化输出。', 'https://static.51easyai.com/chatglm-color.webp', jsonb_build_array('text_generate', 'tools_call'), '{ "text_generate": {"max_context_tokens": 1000000, "max_output_tokens": 131072, "supportTool": true, "supportThinking": true, "supportThinkingModeSwitch": true, "supportStructuredOutput": true}, "tools_call": {"max_context_tokens": 1000000, "max_output_tokens": 131072, "supportTool": true, "supportThinking": true, "supportThinkingModeSwitch": true, "supportStructuredOutput": true}, "originalTypes": ["text_generate", "tools_call"] }'::jsonb, 'easyai:GLM-4.7' ), ( 'zhipu-openai', 'zhipu-openai', '智谱AI', 'openai', 'zhipu-openai:glm-5.2', 'glm-5.2', 'glm-5.2', 'GLM-5.2', 'GLM-5.2', '旗舰 Coding 模型,文本输入/输出,1M 上下文,最大输出 128K,支持思考模式、工具调用与结构化输出。', 'https://static.51easyai.com/chatglm-color.webp', jsonb_build_array('text_generate', 'tools_call'), '{ "text_generate": {"max_context_tokens": 1000000, "max_output_tokens": 131072, "supportTool": true, "supportThinking": true, "supportThinkingModeSwitch": true, "supportStructuredOutput": true}, "tools_call": {"max_context_tokens": 1000000, "max_output_tokens": 131072, "supportTool": true, "supportThinking": true, "supportThinkingModeSwitch": true, "supportStructuredOutput": true}, "originalTypes": ["text_generate", "tools_call"] }'::jsonb, 'zhipu-openai:glm-4.7' ), ( 'easyai', 'easyai', 'EasyAI', 'easyai', 'easyai:Kimi-K2.7-Code', 'Kimi-K2.7-Code', 'Kimi-K2.7-Code', 'Kimi-K2.7-Code', 'Kimi-K2.7-Code', 'Kimi 最强 Coding 模型,支持文本、图片与视频输入,思考模式、对话与 Agent 任务,256K 上下文,默认最大输出 32K。', 'https://static.51easyai.com/kimi-logo-124.png', jsonb_build_array('text_generate', 'image_analysis', 'video_understanding', 'tools_call'), '{ "text_generate": {"max_context_tokens": 262144, "max_output_tokens": 32768, "supportTool": true, "supportThinking": true}, "image_analysis": {"max_context_tokens": 262144, "max_output_tokens": 32768, "supportThinking": true}, "video_understanding": {"max_context_tokens": 262144, "max_output_tokens": 32768, "supportThinking": true}, "tools_call": {"max_context_tokens": 262144, "max_output_tokens": 32768, "supportTool": true, "supportThinking": true}, "originalTypes": ["text_generate", "image_analysis", "video_understanding", "tools_call"] }'::jsonb, 'easyai:DeepSeek-V4-Pro' ), ( 'moonshot-openai', 'moonshot-openai', 'Kimi(OpenAI兼容)', 'openai', 'moonshot-openai:kimi-k2.7-code', 'kimi-k2.7-code', 'kimi-k2.7-code', 'Kimi-K2.7-Code', 'Kimi-K2.7-Code', 'Kimi 最强 Coding 模型,支持文本、图片与视频输入,思考模式、对话与 Agent 任务,256K 上下文,默认最大输出 32K。', 'https://static.51easyai.com/kimi-logo-124.png', jsonb_build_array('text_generate', 'image_analysis', 'video_understanding', 'tools_call'), '{ "text_generate": {"max_context_tokens": 262144, "max_output_tokens": 32768, "supportTool": true, "supportThinking": true}, "image_analysis": {"max_context_tokens": 262144, "max_output_tokens": 32768, "supportThinking": true}, "video_understanding": {"max_context_tokens": 262144, "max_output_tokens": 32768, "supportThinking": true}, "tools_call": {"max_context_tokens": 262144, "max_output_tokens": 32768, "supportTool": true, "supportThinking": true}, "originalTypes": ["text_generate", "image_analysis", "video_understanding", "tools_call"] }'::jsonb, 'deepseek-openai:deepseek-v4-pro' ), ( 'easyai', 'easyai', 'EasyAI', 'easyai', 'easyai:MiniMax-M3', 'MiniMax-M3', 'MiniMax-M3', 'MiniMax-M3', 'MiniMax-M3', '原生多模态、1M 上下文的 Frontier Coding 模型,适用于 Agent 推理、工具调用、代码和长上下文任务。', 'https://static.51easyai.com/minimax-color.png', jsonb_build_array('text_generate', 'image_analysis', 'video_understanding', 'tools_call'), '{ "text_generate": {"max_context_tokens": 1000000, "supportTool": true, "supportThinking": true, "supportThinkingModeSwitch": true}, "image_analysis": {"max_context_tokens": 1000000, "supportThinking": true, "supportThinkingModeSwitch": true}, "video_understanding": {"max_context_tokens": 1000000, "supportThinking": true, "supportThinkingModeSwitch": true}, "tools_call": {"max_context_tokens": 1000000, "supportTool": true, "supportThinking": true, "supportThinkingModeSwitch": true}, "originalTypes": ["text_generate", "image_analysis", "video_understanding", "tools_call"] }'::jsonb, 'easyai:MiniMax M2.7' ), ( 'minimax-openai', 'minimax-openai', 'MiniMax(OpenAI兼容)', 'openai', 'minimax-openai:MiniMax-M3', 'MiniMax-M3', 'MiniMax-M3', 'MiniMax-M3', 'MiniMax-M3', '原生多模态、1M 上下文的 Frontier Coding 模型,适用于 Agent 推理、工具调用、代码和长上下文任务。', 'https://static.51easyai.com/minimax-color.png', jsonb_build_array('text_generate', 'image_analysis', 'video_understanding', 'tools_call'), '{ "text_generate": {"max_context_tokens": 1000000, "supportTool": true, "supportThinking": true, "supportThinkingModeSwitch": true}, "image_analysis": {"max_context_tokens": 1000000, "supportThinking": true, "supportThinkingModeSwitch": true}, "video_understanding": {"max_context_tokens": 1000000, "supportThinking": true, "supportThinkingModeSwitch": true}, "tools_call": {"max_context_tokens": 1000000, "supportTool": true, "supportThinking": true, "supportThinkingModeSwitch": true}, "originalTypes": ["text_generate", "image_analysis", "video_understanding", "tools_call"] }'::jsonb, 'minimax-openai:MiniMax-M2.7' ) ) AS defs( provider_key, source_provider_code, source_provider_name, source_spec_type, canonical_model_key, provider_model_name, raw_model_name, display_name, model_alias, description, icon_path, model_type, capabilities, template_key ) ), source_rows AS ( SELECT providers.id AS provider_id, model_defs.provider_key, model_defs.source_provider_code, model_defs.source_provider_name, model_defs.source_spec_type, model_defs.canonical_model_key, model_defs.provider_model_name, model_defs.raw_model_name, model_defs.display_name, model_defs.model_alias, model_defs.description, model_defs.icon_path, model_defs.model_type, model_defs.capabilities, COALESCE( template.base_billing_config, '{"text":{"basePrice":0.01,"baseWeight":1},"image":{"basePrice":10,"baseWeight":1},"video":{"basePrice":100,"baseWeight":1},"currency":"resource"}'::jsonb ) AS base_billing_config, COALESCE( template.default_rate_limit_policy, jsonb_build_object('platformLimits', jsonb_build_object('max_concurrent_requests', 5)) ) AS default_rate_limit_policy, COALESCE( template.pricing_rule_set_id, (SELECT id FROM model_pricing_rule_sets WHERE rule_set_key = 'default-multimodal-v1' LIMIT 1) ) AS pricing_rule_set_id, COALESCE( template.runtime_policy_set_id, (SELECT id FROM model_runtime_policy_sets WHERE policy_key = 'default-runtime-v1' LIMIT 1) ) AS runtime_policy_set_id, COALESCE(template.runtime_policy_override, '{}'::jsonb) AS runtime_policy_override, COALESCE(template.pricing_version, 1) AS pricing_version FROM model_defs LEFT JOIN model_catalog_providers providers ON providers.provider_key = model_defs.provider_key OR providers.provider_code = model_defs.provider_key LEFT JOIN base_model_catalog template ON template.canonical_model_key = model_defs.template_key ), payload AS ( SELECT source_rows.*, jsonb_build_object( 'source', 'server-main.integration-platform', 'sourceProviderCode', source_provider_code, 'sourceProviderName', source_provider_name, 'sourceSpecType', source_spec_type, 'originalTypes', model_type, 'alias', model_alias, 'description', description, 'iconPath', icon_path, 'billingType', 'external-api', 'billingMode', '', 'referenceModel', '', 'modelWeight', NULL, 'selectable', true, 'rawModel', jsonb_build_object( 'name', raw_model_name, 'types', model_type, 'alias', model_alias, 'description', description, 'icon_path', icon_path, 'capabilities', capabilities - 'originalTypes' ) ) AS metadata FROM source_rows ), snapshot AS ( SELECT payload.*, jsonb_build_object( 'providerKey', provider_key, 'canonicalModelKey', canonical_model_key, 'providerModelName', provider_model_name, 'modelType', model_type, 'modelAlias', model_alias, 'displayName', display_name, 'capabilities', capabilities, 'baseBillingConfig', base_billing_config, 'defaultRateLimitPolicy', default_rate_limit_policy, 'pricingRuleSetId', COALESCE(pricing_rule_set_id::text, ''), 'runtimePolicySetId', COALESCE(runtime_policy_set_id::text, ''), 'runtimePolicyOverride', runtime_policy_override, 'metadata', metadata, 'pricingVersion', pricing_version, 'status', 'active' ) AS default_snapshot FROM payload ) INSERT INTO base_model_catalog ( provider_id, provider_key, canonical_model_key, provider_model_name, model_type, display_name, capabilities, base_billing_config, default_rate_limit_policy, pricing_rule_set_id, runtime_policy_set_id, runtime_policy_override, metadata, catalog_type, default_snapshot, pricing_version, status ) SELECT provider_id, provider_key, canonical_model_key, provider_model_name, model_type, display_name, capabilities, base_billing_config, default_rate_limit_policy, pricing_rule_set_id, runtime_policy_set_id, runtime_policy_override, metadata, 'system', default_snapshot, pricing_version, 'active' FROM snapshot ON CONFLICT (canonical_model_key) DO UPDATE SET provider_id = EXCLUDED.provider_id, provider_key = EXCLUDED.provider_key, provider_model_name = CASE WHEN base_model_catalog.customized_at IS NULL THEN EXCLUDED.provider_model_name ELSE base_model_catalog.provider_model_name END, model_type = CASE WHEN base_model_catalog.customized_at IS NULL THEN EXCLUDED.model_type ELSE base_model_catalog.model_type END, display_name = CASE WHEN base_model_catalog.customized_at IS NULL THEN EXCLUDED.display_name ELSE base_model_catalog.display_name END, capabilities = CASE WHEN base_model_catalog.customized_at IS NULL THEN EXCLUDED.capabilities ELSE base_model_catalog.capabilities END, base_billing_config = CASE WHEN base_model_catalog.customized_at IS NULL THEN EXCLUDED.base_billing_config ELSE base_model_catalog.base_billing_config END, default_rate_limit_policy = CASE WHEN base_model_catalog.customized_at IS NULL THEN EXCLUDED.default_rate_limit_policy ELSE base_model_catalog.default_rate_limit_policy END, pricing_rule_set_id = COALESCE(base_model_catalog.pricing_rule_set_id, EXCLUDED.pricing_rule_set_id), runtime_policy_set_id = COALESCE(base_model_catalog.runtime_policy_set_id, EXCLUDED.runtime_policy_set_id), runtime_policy_override = CASE WHEN base_model_catalog.customized_at IS NULL THEN EXCLUDED.runtime_policy_override ELSE base_model_catalog.runtime_policy_override END, metadata = CASE WHEN base_model_catalog.customized_at IS NULL THEN EXCLUDED.metadata ELSE base_model_catalog.metadata END, catalog_type = 'system', default_snapshot = EXCLUDED.default_snapshot, pricing_version = CASE WHEN base_model_catalog.customized_at IS NULL THEN EXCLUDED.pricing_version ELSE base_model_catalog.pricing_version END, status = CASE WHEN base_model_catalog.customized_at IS NULL THEN 'active' ELSE base_model_catalog.status END, updated_at = now(); INSERT INTO platform_models ( platform_id, base_model_id, model_name, provider_model_name, model_alias, model_type, display_name, capabilities, pricing_mode, billing_config, retry_policy, rate_limit_policy, enabled ) SELECT p.id, b.id, b.provider_model_name, b.provider_model_name, b.display_name, b.model_type, b.display_name, b.capabilities, 'inherit_discount', b.base_billing_config, '{"enabled":true,"maxAttempts":1}'::jsonb, b.default_rate_limit_policy, true FROM integration_platforms p JOIN base_model_catalog b ON b.provider_key = p.provider WHERE b.canonical_model_key IN ( 'easyai:GLM-5.2', 'zhipu-openai:glm-5.2', 'easyai:Kimi-K2.7-Code', 'moonshot-openai:kimi-k2.7-code', 'easyai:MiniMax-M3', 'minimax-openai:MiniMax-M3' ) AND p.deleted_at IS NULL ON CONFLICT (platform_id, model_name) DO UPDATE SET base_model_id = EXCLUDED.base_model_id, provider_model_name = EXCLUDED.provider_model_name, model_alias = EXCLUDED.model_alias, display_name = EXCLUDED.display_name, model_type = EXCLUDED.model_type, capabilities = EXCLUDED.capabilities, pricing_mode = EXCLUDED.pricing_mode, billing_config = EXCLUDED.billing_config, retry_policy = EXCLUDED.retry_policy, rate_limit_policy = EXCLUDED.rate_limit_policy, enabled = EXCLUDED.enabled, updated_at = now();