fix(api): 补全模型能力继承与响应推导
- 合并 base model 默认能力与平台覆盖项 - 在模型响应中补齐 text_generate 的上下文与推理能力字段 - 为相关逻辑补充测试和迁移脚本
This commit is contained in:
@@ -0,0 +1,165 @@
|
||||
-- 为内置文本模型补充上下文窗口配置,并为官方明确支持
|
||||
-- reasoning_effort / thinking_level 的模型补充可用推理深度。
|
||||
|
||||
CREATE OR REPLACE FUNCTION pg_temp._tmp_merge_model_capability_defaults(base jsonb, patch jsonb)
|
||||
RETURNS jsonb AS $$
|
||||
DECLARE
|
||||
out jsonb := COALESCE(base, '{}'::jsonb);
|
||||
patch_key text;
|
||||
patch_value jsonb;
|
||||
BEGIN
|
||||
IF patch IS NULL OR patch = '{}'::jsonb THEN
|
||||
RETURN out;
|
||||
END IF;
|
||||
|
||||
FOR patch_key, patch_value IN SELECT key, value FROM jsonb_each(patch) LOOP
|
||||
IF jsonb_typeof(patch_value) = 'object' AND jsonb_typeof(out -> patch_key) = 'object' THEN
|
||||
-- 仅补默认值,保留已有/人工配置的精确模型能力。
|
||||
out := jsonb_set(out, ARRAY[patch_key], patch_value || (out -> patch_key), true);
|
||||
ELSIF NOT out ? patch_key THEN
|
||||
out := jsonb_set(out, ARRAY[patch_key], patch_value, true);
|
||||
END IF;
|
||||
END LOOP;
|
||||
|
||||
RETURN out;
|
||||
END;
|
||||
$$ LANGUAGE plpgsql;
|
||||
|
||||
CREATE OR REPLACE FUNCTION pg_temp._tmp_model_capability_patches()
|
||||
RETURNS TABLE(provider_key text, provider_model_name text, capability_patch jsonb) AS $$
|
||||
WITH patch_defs(patch_key, capability_patch) AS (
|
||||
VALUES
|
||||
('doubao_seed_2', '{
|
||||
"text_generate": {"max_context_tokens": 262144, "max_input_tokens": 262144, "max_output_tokens": 131072, "max_thinking_tokens": 131072, "supportThinking": true, "supportThinkingModeSwitch": true},
|
||||
"image_analysis": {"max_context_tokens": 262144, "max_input_tokens": 262144, "max_output_tokens": 131072, "max_thinking_tokens": 131072, "supportThinking": true, "supportThinkingModeSwitch": true},
|
||||
"tools_call": {"max_context_tokens": 262144, "max_input_tokens": 262144, "max_output_tokens": 131072, "max_thinking_tokens": 131072, "supportTool": true, "supportThinking": true, "supportThinkingModeSwitch": true}
|
||||
}'::jsonb),
|
||||
('doubao_seed_18', '{
|
||||
"text_generate": {"max_context_tokens": 262144, "max_input_tokens": 229376, "max_output_tokens": 32768, "max_thinking_tokens": 32768, "supportThinking": true, "supportThinkingModeSwitch": true, "supportStructuredOutput": true},
|
||||
"image_analysis": {"max_context_tokens": 262144, "max_input_tokens": 229376, "max_output_tokens": 32768, "max_thinking_tokens": 32768, "supportThinking": true, "supportThinkingModeSwitch": true},
|
||||
"tools_call": {"max_context_tokens": 262144, "max_input_tokens": 229376, "max_output_tokens": 32768, "max_thinking_tokens": 32768, "supportTool": true, "supportThinking": true, "supportThinkingModeSwitch": true, "supportStructuredOutput": true}
|
||||
}'::jsonb),
|
||||
('glm_47', '{
|
||||
"text_generate": {"max_context_tokens": 204800, "max_input_tokens": 204800, "max_output_tokens": 131072, "max_thinking_tokens": 131072, "supportThinking": true, "supportThinkingModeSwitch": true},
|
||||
"image_analysis": {"max_context_tokens": 204800, "max_input_tokens": 204800, "max_output_tokens": 131072, "max_thinking_tokens": 131072, "supportThinking": true, "supportThinkingModeSwitch": true},
|
||||
"tools_call": {"max_context_tokens": 204800, "max_input_tokens": 204800, "max_output_tokens": 131072, "max_thinking_tokens": 131072, "supportTool": true, "supportThinking": true, "supportThinkingModeSwitch": true}
|
||||
}'::jsonb),
|
||||
('glm_47_text_tools', '{
|
||||
"text_generate": {"max_context_tokens": 204800, "max_input_tokens": 204800, "max_output_tokens": 131072, "max_thinking_tokens": 131072, "supportThinking": true, "supportThinkingModeSwitch": true},
|
||||
"tools_call": {"max_context_tokens": 204800, "max_input_tokens": 204800, "max_output_tokens": 131072, "max_thinking_tokens": 131072, "supportTool": true, "supportThinking": true, "supportThinkingModeSwitch": true}
|
||||
}'::jsonb),
|
||||
('gemini_3_text', '{
|
||||
"text_generate": {"thinkingEffortLevels": ["minimal", "low", "medium", "high"]},
|
||||
"tools_call": {"thinkingEffortLevels": ["minimal", "low", "medium", "high"]},
|
||||
"omni": {"thinkingEffortLevels": ["minimal", "low", "medium", "high"]}
|
||||
}'::jsonb),
|
||||
('deepseek_v4', '{
|
||||
"text_generate": {"thinkingEffortLevels": ["high", "max"]},
|
||||
"tools_call": {"thinkingEffortLevels": ["high", "max"]}
|
||||
}'::jsonb)
|
||||
),
|
||||
model_patches(provider_key, provider_model_name, patch_key) AS (
|
||||
VALUES
|
||||
('easyai', 'Doubao Seed 2.0 Pro', 'doubao_seed_2'),
|
||||
('easyai', 'Doubao Seed 2.0 Lite', 'doubao_seed_2'),
|
||||
('easyai', 'Doubao Seed 2.0 Mini', 'doubao_seed_2'),
|
||||
('easyai', 'Doubao Seed 2.0 Code Preview', 'doubao_seed_2'),
|
||||
('volces-openai', 'doubao-seed-2-0-pro-260215', 'doubao_seed_2'),
|
||||
('volces-openai', 'doubao-seed-2-0-lite-260215', 'doubao_seed_2'),
|
||||
('volces-openai', 'doubao-seed-2-0-mini-260215', 'doubao_seed_2'),
|
||||
('volces-openai', 'doubao-seed-2-0-code-preview-260215', 'doubao_seed_2'),
|
||||
|
||||
('easyai', 'Doubao Seed 1.8', 'doubao_seed_18'),
|
||||
('volces-openai', 'doubao-seed-1-8-251228', 'doubao_seed_18'),
|
||||
|
||||
('easyai', 'GLM-4.7', 'glm_47'),
|
||||
('volces-openai', 'glm-4-7-251222', 'glm_47'),
|
||||
('zhipu-openai', 'glm-4.7', 'glm_47_text_tools'),
|
||||
|
||||
('easyai', 'Gemini-3 Pro 预览版', 'gemini_3_text'),
|
||||
('easyai', 'Gemini-3 Flash 预览版', 'gemini_3_text'),
|
||||
('easyai', 'Gemini-3.1 Flash Lite 预览版', 'gemini_3_text'),
|
||||
('easyai', 'Gemini-3.1 Pro 预览版', 'gemini_3_text'),
|
||||
('gemini', 'gemini-3-pro-preview', 'gemini_3_text'),
|
||||
('gemini', 'gemini-3-flash-preview', 'gemini_3_text'),
|
||||
('gemini', 'gemini-3.1-flash-lite-preview', 'gemini_3_text'),
|
||||
('gemini', 'gemini-3.1-pro-preview', 'gemini_3_text'),
|
||||
('gemini-openai', 'gemini-3-pro-preview', 'gemini_3_text'),
|
||||
('gemini-openai', 'gemini-3-flash-preview', 'gemini_3_text'),
|
||||
('gemini-openai', 'gemini-3.1-flash-lite-preview', 'gemini_3_text'),
|
||||
('gemini-openai', 'gemini-3.1-pro-preview', 'gemini_3_text'),
|
||||
|
||||
('easyai', 'DeepSeek-V4-Pro', 'deepseek_v4'),
|
||||
('easyai', 'DeepSeek-V4-Flash', 'deepseek_v4'),
|
||||
('aliyun-bailian-openai', 'deepseek-v4-pro', 'deepseek_v4'),
|
||||
('aliyun-bailian-openai', 'deepseek-v4-flash', 'deepseek_v4'),
|
||||
('deepseek-openai', 'deepseek-v4-pro', 'deepseek_v4'),
|
||||
('deepseek-openai', 'deepseek-v4-flash', 'deepseek_v4')
|
||||
)
|
||||
SELECT model_patches.provider_key, model_patches.provider_model_name, patch_defs.capability_patch
|
||||
FROM model_patches
|
||||
JOIN patch_defs ON patch_defs.patch_key = model_patches.patch_key;
|
||||
$$ LANGUAGE sql;
|
||||
|
||||
UPDATE base_model_catalog b
|
||||
SET capabilities = pg_temp._tmp_merge_model_capability_defaults(b.capabilities, patches.capability_patch),
|
||||
default_snapshot = CASE
|
||||
WHEN COALESCE(b.default_snapshot, '{}'::jsonb) = '{}'::jsonb THEN b.default_snapshot
|
||||
WHEN jsonb_typeof(b.default_snapshot->'metadata'->'rawModel') = 'object' THEN jsonb_set(
|
||||
jsonb_set(
|
||||
b.default_snapshot,
|
||||
'{capabilities}',
|
||||
pg_temp._tmp_merge_model_capability_defaults(
|
||||
COALESCE(b.default_snapshot->'capabilities', '{}'::jsonb),
|
||||
patches.capability_patch
|
||||
),
|
||||
true
|
||||
),
|
||||
'{metadata,rawModel,capabilities}',
|
||||
pg_temp._tmp_merge_model_capability_defaults(
|
||||
COALESCE(b.default_snapshot->'metadata'->'rawModel'->'capabilities', '{}'::jsonb),
|
||||
patches.capability_patch
|
||||
),
|
||||
true
|
||||
)
|
||||
ELSE jsonb_set(
|
||||
b.default_snapshot,
|
||||
'{capabilities}',
|
||||
pg_temp._tmp_merge_model_capability_defaults(
|
||||
COALESCE(b.default_snapshot->'capabilities', '{}'::jsonb),
|
||||
patches.capability_patch
|
||||
),
|
||||
true
|
||||
)
|
||||
END,
|
||||
metadata = CASE
|
||||
WHEN jsonb_typeof(b.metadata->'rawModel') = 'object' THEN jsonb_set(
|
||||
b.metadata,
|
||||
'{rawModel,capabilities}',
|
||||
pg_temp._tmp_merge_model_capability_defaults(
|
||||
COALESCE(b.metadata->'rawModel'->'capabilities', '{}'::jsonb),
|
||||
patches.capability_patch
|
||||
),
|
||||
true
|
||||
)
|
||||
ELSE b.metadata
|
||||
END,
|
||||
updated_at = now()
|
||||
FROM pg_temp._tmp_model_capability_patches() patches
|
||||
WHERE b.provider_key = patches.provider_key
|
||||
AND b.provider_model_name = patches.provider_model_name
|
||||
AND b.catalog_type = 'system';
|
||||
|
||||
UPDATE platform_models m
|
||||
SET capabilities = pg_temp._tmp_merge_model_capability_defaults(m.capabilities, patches.capability_patch),
|
||||
updated_at = now()
|
||||
FROM integration_platforms p, pg_temp._tmp_model_capability_patches() patches
|
||||
WHERE m.platform_id = p.id
|
||||
AND p.provider = patches.provider_key
|
||||
AND (
|
||||
m.model_name = patches.provider_model_name
|
||||
OR m.provider_model_name = patches.provider_model_name
|
||||
);
|
||||
|
||||
DROP FUNCTION pg_temp._tmp_model_capability_patches();
|
||||
DROP FUNCTION pg_temp._tmp_merge_model_capability_defaults(jsonb, jsonb);
|
||||
Reference in New Issue
Block a user