Files
Memoh/db/migrations/0061_unify_providers.up.sql
T
Acbox a04b8fd564 refactor: unify providers and models tables
- Rename `llm_providers` → `providers`, `llm_provider_oauth_tokens` → `provider_oauth_tokens`
- Remove `tts_providers` and `tts_models` tables; speech models now live in the unified `models` table with `type = 'speech'`
- Replace top-level `api_key`/`base_url` columns with a JSONB `config` field on `providers`
- Rename `llm_provider_id` → `provider_id` across all references
- Add `edge-speech` client type and `conf/providers/edge.yaml` default provider
- Create new read-only speech endpoints (`/speech-providers`, `/speech-models`) backed by filtered views of the unified tables
- Remove old TTS CRUD handlers; simplify speech page to read-only + test
- Update registry loader to skip malformed YAML files instead of failing entirely
- Fix YAML quoting for model names containing colons in openrouter.yaml
- Regenerate sqlc, swagger, and TypeScript SDK
2026-04-07 00:26:06 +08:00

95 lines
4.0 KiB
SQL

-- 0061_unify_providers
-- Unify llm_providers and tts_providers/tts_models into a single providers/models schema.
-- Merge api_key and base_url into a config JSONB column. Add speech model type.
-- NOTE: On fresh databases the canonical schema already applies; all guards are IF EXISTS.
DO $$
BEGIN
-- Only run full migration if old llm_providers table still exists
IF NOT EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = 'llm_providers') THEN
RETURN;
END IF;
-- Step 1: Rename llm_providers → providers
ALTER TABLE llm_providers RENAME TO providers;
ALTER TABLE providers RENAME CONSTRAINT llm_providers_name_unique TO providers_name_unique;
ALTER TABLE providers DROP CONSTRAINT IF EXISTS llm_providers_client_type_check;
-- Step 2: Add config JSONB and migrate api_key + base_url into it
ALTER TABLE providers ADD COLUMN IF NOT EXISTS config JSONB NOT NULL DEFAULT '{}'::jsonb;
UPDATE providers SET config = jsonb_build_object('api_key', api_key, 'base_url', base_url)
WHERE api_key IS NOT NULL;
ALTER TABLE providers DROP COLUMN IF EXISTS api_key;
ALTER TABLE providers DROP COLUMN IF EXISTS base_url;
-- Step 3: Expand client_type CHECK
ALTER TABLE providers ADD CONSTRAINT providers_client_type_check CHECK (
client_type IN (
'openai-responses', 'openai-completions', 'anthropic-messages',
'google-generative-ai', 'openai-codex', 'edge-speech'
)
);
-- Step 4: Rename llm_provider_id → provider_id in models table
IF EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'models' AND column_name = 'llm_provider_id') THEN
ALTER TABLE models RENAME COLUMN llm_provider_id TO provider_id;
END IF;
IF EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'models_provider_model_id_unique') THEN
ALTER TABLE models RENAME CONSTRAINT models_provider_model_id_unique TO models_provider_id_model_id_unique;
END IF;
-- Step 5: Expand models type CHECK to include speech
ALTER TABLE models DROP CONSTRAINT IF EXISTS models_type_check;
ALTER TABLE models ADD CONSTRAINT models_type_check CHECK (type IN ('chat', 'embedding', 'speech'));
-- Step 6: Migrate tts_providers into providers
IF EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = 'tts_providers') THEN
INSERT INTO providers (id, name, client_type, icon, enable, config, metadata, created_at, updated_at)
SELECT
tp.id,
tp.name,
CASE WHEN tp.provider = 'edge' THEN 'edge-speech' ELSE tp.provider END,
NULL,
tp.enable,
tp.config,
'{}'::jsonb,
tp.created_at,
tp.updated_at
FROM tts_providers tp
WHERE NOT EXISTS (SELECT 1 FROM providers p WHERE p.id = tp.id);
END IF;
-- Step 7: Migrate tts_models into models
IF EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = 'tts_models') THEN
INSERT INTO models (id, model_id, name, provider_id, type, config, created_at, updated_at)
SELECT
tm.id,
tm.model_id,
tm.name,
tm.tts_provider_id,
'speech',
tm.config,
tm.created_at,
tm.updated_at
FROM tts_models tm
WHERE NOT EXISTS (SELECT 1 FROM models m WHERE m.id = tm.id);
END IF;
-- Step 8: Update bots.tts_model_id FK to reference models instead of tts_models
ALTER TABLE bots DROP CONSTRAINT IF EXISTS bots_tts_model_id_fkey;
ALTER TABLE bots ADD CONSTRAINT bots_tts_model_id_fkey
FOREIGN KEY (tts_model_id) REFERENCES models(id) ON DELETE SET NULL;
-- Step 9: Drop tts_models and tts_providers
DROP INDEX IF EXISTS idx_tts_models_provider_id;
DROP TABLE IF EXISTS tts_models;
DROP TABLE IF EXISTS tts_providers;
-- Step 10: Rename llm_provider_oauth_tokens → provider_oauth_tokens
IF EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = 'llm_provider_oauth_tokens') THEN
ALTER TABLE llm_provider_oauth_tokens RENAME TO provider_oauth_tokens;
ALTER TABLE provider_oauth_tokens RENAME COLUMN llm_provider_id TO provider_id;
ALTER INDEX IF EXISTS idx_llm_provider_oauth_tokens_state RENAME TO idx_provider_oauth_tokens_state;
END IF;
END $$;