新增官方调用名、供应商真实名、显示名和兼容别名的独立契约,调整路由、目录聚合、管理端与 OpenAPI。 增加 Gemini、Qwen、DeepSeek、Claude 和 MiniMax 生命周期迁移、别名观测及引用保护,并补充数据库与聚合测试。
174 lines
6.2 KiB
PL/PgSQL
174 lines
6.2 KiB
PL/PgSQL
ALTER TABLE base_model_catalog
|
|
ADD COLUMN IF NOT EXISTS invocation_name text;
|
|
|
|
UPDATE base_model_catalog
|
|
SET invocation_name = COALESCE(
|
|
NULLIF(metadata->>'officialModelId', ''),
|
|
NULLIF(provider_model_name, ''),
|
|
canonical_model_key
|
|
)
|
|
WHERE invocation_name IS NULL OR trim(invocation_name) = '';
|
|
|
|
UPDATE base_model_catalog
|
|
SET display_name = COALESCE(
|
|
NULLIF(metadata->>'officialDisplayName', ''),
|
|
NULLIF(default_snapshot->>'displayName', ''),
|
|
NULLIF(display_name, ''),
|
|
invocation_name
|
|
)
|
|
WHERE catalog_type = 'system';
|
|
|
|
ALTER TABLE base_model_catalog
|
|
ALTER COLUMN invocation_name SET NOT NULL;
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_base_model_catalog_invocation_name
|
|
ON base_model_catalog(invocation_name);
|
|
|
|
CREATE TABLE IF NOT EXISTS model_compatibility_aliases (
|
|
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
base_model_id uuid NOT NULL REFERENCES base_model_catalog(id) ON DELETE CASCADE,
|
|
alias text NOT NULL,
|
|
model_type text NOT NULL,
|
|
active boolean NOT NULL DEFAULT true,
|
|
expires_at timestamptz,
|
|
created_at timestamptz NOT NULL DEFAULT now(),
|
|
updated_at timestamptz NOT NULL DEFAULT now(),
|
|
CONSTRAINT model_compatibility_aliases_nonempty CHECK (trim(alias) <> ''),
|
|
CONSTRAINT model_compatibility_aliases_unique UNIQUE (base_model_id, alias, model_type)
|
|
);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_model_compatibility_aliases_lookup
|
|
ON model_compatibility_aliases(alias, model_type)
|
|
WHERE active = true;
|
|
|
|
CREATE TABLE IF NOT EXISTS model_alias_usage_metrics (
|
|
alias text NOT NULL,
|
|
canonical_model_key text NOT NULL,
|
|
model_type text NOT NULL,
|
|
hit_count bigint NOT NULL DEFAULT 0,
|
|
first_used_at timestamptz NOT NULL DEFAULT now(),
|
|
last_used_at timestamptz NOT NULL DEFAULT now(),
|
|
PRIMARY KEY (alias, canonical_model_key, model_type)
|
|
);
|
|
|
|
-- Preserve unambiguous historical card/call names for the 14-day compatibility
|
|
-- window. Ambiguous names are deliberately not inferred: they must be resolved
|
|
-- to one canonical identity by an administrator before they can be registered.
|
|
WITH alias_candidates AS (
|
|
SELECT b.id AS base_model_id,
|
|
old_name.alias,
|
|
model_type.value AS model_type,
|
|
b.invocation_name
|
|
FROM base_model_catalog b
|
|
CROSS JOIN LATERAL jsonb_array_elements_text(b.model_type) AS model_type(value)
|
|
CROSS JOIN LATERAL (
|
|
SELECT b.display_name AS alias
|
|
UNION
|
|
SELECT b.canonical_model_key AS alias
|
|
) old_name
|
|
WHERE trim(COALESCE(old_name.alias, '')) <> ''
|
|
AND old_name.alias <> b.invocation_name
|
|
), unambiguous AS (
|
|
SELECT alias, model_type, min(base_model_id::text)::uuid AS base_model_id
|
|
FROM alias_candidates
|
|
GROUP BY alias, model_type
|
|
HAVING count(DISTINCT invocation_name) = 1
|
|
)
|
|
INSERT INTO model_compatibility_aliases (base_model_id, alias, model_type, expires_at)
|
|
SELECT base_model_id, alias, model_type, now() + interval '14 days'
|
|
FROM unambiguous
|
|
ON CONFLICT (base_model_id, alias, model_type) DO NOTHING;
|
|
|
|
-- Keep the old platform model_name/model_alias values as explicit compatibility
|
|
-- aliases before canonical invocation names are written to platform_models.
|
|
WITH platform_alias_candidates AS (
|
|
SELECT b.id AS base_model_id,
|
|
old_name.alias,
|
|
model_type.value AS model_type,
|
|
b.invocation_name
|
|
FROM platform_models pm
|
|
JOIN base_model_catalog b ON b.id = pm.base_model_id
|
|
CROSS JOIN LATERAL jsonb_array_elements_text(pm.model_type) AS model_type(value)
|
|
CROSS JOIN LATERAL (
|
|
SELECT pm.model_name AS alias
|
|
UNION
|
|
SELECT pm.model_alias AS alias
|
|
) old_name
|
|
WHERE trim(COALESCE(old_name.alias, '')) <> ''
|
|
AND old_name.alias <> b.invocation_name
|
|
), unambiguous AS (
|
|
SELECT alias, model_type, min(base_model_id::text)::uuid AS base_model_id
|
|
FROM platform_alias_candidates
|
|
GROUP BY alias, model_type
|
|
HAVING count(DISTINCT invocation_name) = 1
|
|
)
|
|
INSERT INTO model_compatibility_aliases (base_model_id, alias, model_type, expires_at)
|
|
SELECT base_model_id, alias, model_type, now() + interval '14 days'
|
|
FROM unambiguous
|
|
ON CONFLICT (base_model_id, alias, model_type) DO NOTHING;
|
|
|
|
WITH ranked_targets AS (
|
|
SELECT pm.id,
|
|
b.invocation_name,
|
|
COALESCE(NULLIF(b.display_name, ''), b.invocation_name) AS display_name,
|
|
row_number() OVER (
|
|
PARTITION BY pm.platform_id, b.invocation_name
|
|
ORDER BY CASE WHEN pm.model_name = b.invocation_name THEN 0 ELSE 1 END,
|
|
pm.created_at ASC,
|
|
pm.id ASC
|
|
) AS identity_rank
|
|
FROM platform_models pm
|
|
JOIN base_model_catalog b ON b.id = pm.base_model_id
|
|
)
|
|
UPDATE platform_models pm
|
|
SET model_name = target.invocation_name,
|
|
model_alias = target.invocation_name,
|
|
display_name = target.display_name,
|
|
updated_at = now()
|
|
FROM ranked_targets target
|
|
WHERE target.id = pm.id
|
|
AND target.identity_rank = 1
|
|
AND NOT EXISTS (
|
|
SELECT 1
|
|
FROM platform_models conflict
|
|
WHERE conflict.platform_id = pm.platform_id
|
|
AND conflict.id <> pm.id
|
|
AND conflict.model_name = target.invocation_name
|
|
);
|
|
|
|
UPDATE base_model_catalog
|
|
SET default_snapshot = default_snapshot || jsonb_build_object(
|
|
'invocationName', invocation_name,
|
|
'modelAlias', invocation_name,
|
|
'displayName', display_name
|
|
)
|
|
WHERE catalog_type = 'system'
|
|
AND COALESCE(default_snapshot, '{}'::jsonb) <> '{}'::jsonb;
|
|
|
|
CREATE OR REPLACE FUNCTION fill_system_base_model_default_snapshot()
|
|
RETURNS trigger AS $$
|
|
BEGIN
|
|
IF NEW.catalog_type = 'system' AND NEW.default_snapshot IS NULL THEN
|
|
NEW.default_snapshot = jsonb_build_object(
|
|
'providerKey', NEW.provider_key,
|
|
'canonicalModelKey', NEW.canonical_model_key,
|
|
'invocationName', NEW.invocation_name,
|
|
'providerModelName', NEW.provider_model_name,
|
|
'modelType', NEW.model_type,
|
|
'modelAlias', NEW.invocation_name,
|
|
'displayName', NEW.display_name,
|
|
'capabilities', NEW.capabilities,
|
|
'baseBillingConfig', NEW.base_billing_config,
|
|
'defaultRateLimitPolicy', NEW.default_rate_limit_policy,
|
|
'pricingRuleSetId', COALESCE(NEW.pricing_rule_set_id::text, ''),
|
|
'runtimePolicySetId', COALESCE(NEW.runtime_policy_set_id::text, ''),
|
|
'runtimePolicyOverride', NEW.runtime_policy_override,
|
|
'metadata', NEW.metadata,
|
|
'pricingVersion', NEW.pricing_version,
|
|
'status', NEW.status
|
|
);
|
|
END IF;
|
|
RETURN NEW;
|
|
END;
|
|
$$ LANGUAGE plpgsql;
|