From 88402f67d3c235a2394176c37e423b27ed3fd229 Mon Sep 17 00:00:00 2001 From: wangbo Date: Sat, 27 Jun 2026 17:11:48 +0800 Subject: [PATCH] feat: seed latest coding models --- .../0054_coding_agent_text_models.sql | 589 ++++++++++++++++++ 1 file changed, 589 insertions(+) create mode 100644 apps/api/migrations/0054_coding_agent_text_models.sql diff --git a/apps/api/migrations/0054_coding_agent_text_models.sql b/apps/api/migrations/0054_coding_agent_text_models.sql new file mode 100644 index 0000000..d49c3a0 --- /dev/null +++ b/apps/api/migrations/0054_coding_agent_text_models.sql @@ -0,0 +1,589 @@ +-- 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();