From ea4dac265ba3ec150e251ef23c8a5d3f68302b8c Mon Sep 17 00:00:00 2001 From: Acbox Date: Tue, 7 Apr 2026 01:44:09 +0800 Subject: [PATCH] fix: revert canonical schema to use llm_providers for migration compatibility MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The CI migrations workflow (up → down → up) failed because 0061 down renames `providers` back to `llm_providers`, but 0001 down only dropped `providers` — leaving `llm_providers` as a remnant. On the second migrate up, 0010 found the stale `llm_providers` and tried to reference `models.llm_provider_id` which no longer existed. Revert 0001 canonical schema to use original names (llm_providers, tts_providers, tts_models) so incremental migrations work naturally and 0061 handles the final rename. Remove EXECUTE wrappers and unnecessary guards from migrations that now always operate on llm_providers. --- db/migrations/0001_init.down.sql | 3 +- db/migrations/0001_init.up.sql | 61 ++++++++-------- .../0010_client_type_to_model.up.sql | 51 +++++++------- .../0013_model_id_unique_per_provider.up.sql | 9 +-- db/migrations/0029_tts_provider.up.sql | 69 ++++++++----------- .../0030_drop_tts_model_unique.up.sql | 9 +-- .../0041_provider_model_refactor.up.sql | 64 +++++++++-------- db/migrations/0042_provider_enable.up.sql | 9 +-- db/migrations/0046_llm_provider_oauth.up.sql | 53 +++++--------- .../0047_add_openai_codex_client_type.up.sql | 25 +++---- db/migrations/0050_tts_provider_enable.up.sql | 8 +-- 11 files changed, 152 insertions(+), 209 deletions(-) diff --git a/db/migrations/0001_init.down.sql b/db/migrations/0001_init.down.sql index 883608f6..aa30486f 100644 --- a/db/migrations/0001_init.down.sql +++ b/db/migrations/0001_init.down.sql @@ -20,13 +20,12 @@ DROP TABLE IF EXISTS email_outbox; DROP TABLE IF EXISTS bot_email_bindings; DROP TABLE IF EXISTS email_oauth_tokens; DROP TABLE IF EXISTS email_providers; -DROP TABLE IF EXISTS provider_oauth_tokens; DROP TABLE IF EXISTS bots; DROP TABLE IF EXISTS memory_providers; DROP TABLE IF EXISTS model_variants; DROP TABLE IF EXISTS models; DROP TABLE IF EXISTS search_providers; -DROP TABLE IF EXISTS providers; +DROP TABLE IF EXISTS llm_providers; DROP TABLE IF EXISTS user_channel_bindings; DROP TABLE IF EXISTS channel_identities; DROP TABLE IF EXISTS users; diff --git a/db/migrations/0001_init.up.sql b/db/migrations/0001_init.up.sql index 4a8dcf3e..37df88f5 100644 --- a/db/migrations/0001_init.up.sql +++ b/db/migrations/0001_init.up.sql @@ -57,21 +57,19 @@ CREATE TABLE IF NOT EXISTS user_channel_bindings ( CREATE INDEX IF NOT EXISTS idx_user_channel_bindings_user_id ON user_channel_bindings(user_id); -CREATE TABLE IF NOT EXISTS providers ( +CREATE TABLE IF NOT EXISTS llm_providers ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), name TEXT NOT NULL, + base_url TEXT NOT NULL, + api_key TEXT NOT NULL, client_type TEXT NOT NULL DEFAULT 'openai-completions', icon TEXT, enable BOOLEAN NOT NULL DEFAULT true, - config JSONB NOT NULL DEFAULT '{}'::jsonb, metadata JSONB NOT NULL DEFAULT '{}'::jsonb, created_at TIMESTAMPTZ NOT NULL DEFAULT now(), updated_at TIMESTAMPTZ NOT NULL DEFAULT now(), - CONSTRAINT providers_name_unique UNIQUE (name), - CONSTRAINT providers_client_type_check CHECK (client_type IN ( - 'openai-responses', 'openai-completions', 'anthropic-messages', - 'google-generative-ai', 'openai-codex', 'edge-speech' - )) + CONSTRAINT llm_providers_name_unique UNIQUE (name), + CONSTRAINT llm_providers_client_type_check CHECK (client_type IN ('openai-responses', 'openai-completions', 'anthropic-messages', 'google-generative-ai', 'openai-codex')) ); CREATE TABLE IF NOT EXISTS search_providers ( @@ -89,13 +87,13 @@ CREATE TABLE IF NOT EXISTS models ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), model_id TEXT NOT NULL, name TEXT, - provider_id UUID NOT NULL REFERENCES providers(id) ON DELETE CASCADE, + llm_provider_id UUID NOT NULL REFERENCES llm_providers(id) ON DELETE CASCADE, type TEXT NOT NULL DEFAULT 'chat', config JSONB NOT NULL DEFAULT '{}'::jsonb, created_at TIMESTAMPTZ NOT NULL DEFAULT now(), updated_at TIMESTAMPTZ NOT NULL DEFAULT now(), - CONSTRAINT models_provider_id_model_id_unique UNIQUE (provider_id, model_id), - CONSTRAINT models_type_check CHECK (type IN ('chat', 'embedding', 'speech')) + CONSTRAINT models_provider_model_id_unique UNIQUE (llm_provider_id, model_id), + CONSTRAINT models_type_check CHECK (type IN ('chat', 'embedding')) ); CREATE TABLE IF NOT EXISTS model_variants ( @@ -122,6 +120,30 @@ CREATE TABLE IF NOT EXISTS memory_providers ( CONSTRAINT memory_providers_name_unique UNIQUE (name) ); +-- tts_providers: pluggable TTS service backends +CREATE TABLE IF NOT EXISTS tts_providers ( + id UUID PRIMARY KEY DEFAULT gen_random_uuid(), + name TEXT NOT NULL, + provider TEXT NOT NULL, + config JSONB NOT NULL DEFAULT '{}'::jsonb, + enable BOOLEAN NOT NULL DEFAULT false, + created_at TIMESTAMPTZ NOT NULL DEFAULT now(), + updated_at TIMESTAMPTZ NOT NULL DEFAULT now(), + CONSTRAINT tts_providers_name_unique UNIQUE (name) +); + +-- tts_models: available models per TTS provider with per-model configuration +CREATE TABLE IF NOT EXISTS tts_models ( + id UUID PRIMARY KEY DEFAULT gen_random_uuid(), + model_id TEXT NOT NULL, + name TEXT, + tts_provider_id UUID NOT NULL REFERENCES tts_providers(id) ON DELETE CASCADE, + config JSONB NOT NULL DEFAULT '{}'::jsonb, + created_at TIMESTAMPTZ NOT NULL DEFAULT now(), + updated_at TIMESTAMPTZ NOT NULL DEFAULT now() +); + +CREATE INDEX IF NOT EXISTS idx_tts_models_provider_id ON tts_models(tts_provider_id); CREATE TABLE IF NOT EXISTS browser_contexts ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), @@ -157,7 +179,7 @@ CREATE TABLE IF NOT EXISTS bots ( title_model_id UUID REFERENCES models(id) ON DELETE SET NULL, image_model_id UUID REFERENCES models(id) ON DELETE SET NULL, discuss_probe_model_id UUID REFERENCES models(id) ON DELETE SET NULL, - tts_model_id UUID REFERENCES models(id) ON DELETE SET NULL, + tts_model_id UUID REFERENCES tts_models(id) ON DELETE SET NULL, browser_context_id UUID REFERENCES browser_contexts(id) ON DELETE SET NULL, metadata JSONB NOT NULL DEFAULT '{}'::jsonb, created_at TIMESTAMPTZ NOT NULL DEFAULT now(), @@ -629,20 +651,3 @@ CREATE TABLE IF NOT EXISTS email_outbox ( CREATE INDEX IF NOT EXISTS idx_email_outbox_provider_id ON email_outbox(provider_id); CREATE INDEX IF NOT EXISTS idx_email_outbox_bot_id ON email_outbox(bot_id, created_at DESC); - --- provider_oauth_tokens: OAuth token storage for providers (e.g. OpenAI Codex OAuth) -CREATE TABLE IF NOT EXISTS provider_oauth_tokens ( - id UUID PRIMARY KEY DEFAULT gen_random_uuid(), - provider_id UUID NOT NULL UNIQUE REFERENCES providers(id) ON DELETE CASCADE, - access_token TEXT NOT NULL DEFAULT '', - refresh_token TEXT NOT NULL DEFAULT '', - expires_at TIMESTAMPTZ, - scope TEXT NOT NULL DEFAULT '', - token_type TEXT NOT NULL DEFAULT '', - state TEXT NOT NULL DEFAULT '', - pkce_code_verifier TEXT NOT NULL DEFAULT '', - created_at TIMESTAMPTZ NOT NULL DEFAULT now(), - updated_at TIMESTAMPTZ NOT NULL DEFAULT now() -); - -CREATE INDEX IF NOT EXISTS idx_provider_oauth_tokens_state ON provider_oauth_tokens(state) WHERE state != ''; diff --git a/db/migrations/0010_client_type_to_model.up.sql b/db/migrations/0010_client_type_to_model.up.sql index 4327c04e..c3d42622 100644 --- a/db/migrations/0010_client_type_to_model.up.sql +++ b/db/migrations/0010_client_type_to_model.up.sql @@ -1,36 +1,38 @@ -- 0010_client_type_to_model -- Move client_type from llm_providers to models, rename to new values, drop unsupported types. --- NOTE: This migration is a no-op on fresh databases where the canonical schema already applies. +-- 1) Add client_type column to models (nullable) +ALTER TABLE models ADD COLUMN IF NOT EXISTS client_type TEXT; + +-- 2-5) Only run data migration when upgrading from old schema that had client_type on llm_providers. DO $$ BEGIN - IF NOT EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = 'llm_providers') THEN - RETURN; - END IF; - - IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'models' AND column_name = 'client_type') THEN - ALTER TABLE models ADD COLUMN client_type TEXT; - END IF; - IF EXISTS ( SELECT 1 FROM information_schema.columns WHERE table_name = 'llm_providers' AND column_name = 'client_type' ) THEN - EXECUTE ' - UPDATE models SET client_type = CASE p.client_type - WHEN ''openai'' THEN ''openai-responses'' - WHEN ''openai-compat'' THEN ''openai-completions'' - WHEN ''anthropic'' THEN ''anthropic-messages'' - WHEN ''google'' THEN ''google-generative-ai'' - END - FROM llm_providers p - WHERE models.llm_provider_id = p.id - AND p.client_type IN (''openai'', ''openai-compat'', ''anthropic'', ''google'')'; + -- Migrate data from provider to model with name mapping + UPDATE models SET client_type = CASE p.client_type + WHEN 'openai' THEN 'openai-responses' + WHEN 'openai-compat' THEN 'openai-completions' + WHEN 'anthropic' THEN 'anthropic-messages' + WHEN 'google' THEN 'google-generative-ai' + END + FROM llm_providers p + WHERE models.llm_provider_id = p.id + AND p.client_type IN ('openai', 'openai-compat', 'anthropic', 'google'); - EXECUTE 'DELETE FROM models WHERE client_type IS NULL AND type = ''chat'''; - EXECUTE 'DELETE FROM llm_providers WHERE client_type NOT IN (''openai'', ''openai-compat'', ''anthropic'', ''google'')'; + -- Delete models whose provider had an unsupported client_type + DELETE FROM models WHERE client_type IS NULL AND type = 'chat'; + + -- Delete providers with unsupported client_type + DELETE FROM llm_providers WHERE client_type NOT IN ('openai', 'openai-compat', 'anthropic', 'google'); END IF; +END $$; +-- 6) Add CHECK constraints (skip if already present from init migration) +DO $$ +BEGIN IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'models_client_type_check') THEN ALTER TABLE models ADD CONSTRAINT models_client_type_check CHECK (client_type IS NULL OR client_type IN ('openai-responses', 'openai-completions', 'anthropic-messages', 'google-generative-ai')); @@ -39,7 +41,8 @@ BEGIN ALTER TABLE models ADD CONSTRAINT models_chat_client_type_check CHECK (type != 'chat' OR client_type IS NOT NULL); END IF; - - EXECUTE 'ALTER TABLE llm_providers DROP CONSTRAINT IF EXISTS llm_providers_client_type_check'; - EXECUTE 'ALTER TABLE llm_providers DROP COLUMN IF EXISTS client_type'; END $$; + +-- 7) Drop client_type from llm_providers +ALTER TABLE llm_providers DROP CONSTRAINT IF EXISTS llm_providers_client_type_check; +ALTER TABLE llm_providers DROP COLUMN IF EXISTS client_type; diff --git a/db/migrations/0013_model_id_unique_per_provider.up.sql b/db/migrations/0013_model_id_unique_per_provider.up.sql index 7928a599..91612a91 100644 --- a/db/migrations/0013_model_id_unique_per_provider.up.sql +++ b/db/migrations/0013_model_id_unique_per_provider.up.sql @@ -1,6 +1,5 @@ -- 0013_model_id_unique_per_provider -- Change model_id uniqueness from global to per provider. --- NOTE: On fresh databases the canonical schema already has the correct constraint. DO $$ BEGIN @@ -8,11 +7,9 @@ BEGIN ALTER TABLE models DROP CONSTRAINT models_model_id_unique; END IF; - IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'models_provider_model_id_unique') - AND NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'models_provider_id_model_id_unique') THEN - IF EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'models' AND column_name = 'llm_provider_id') THEN - EXECUTE 'ALTER TABLE models ADD CONSTRAINT models_provider_model_id_unique UNIQUE (llm_provider_id, model_id)'; - END IF; + IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'models_provider_model_id_unique') THEN + ALTER TABLE models + ADD CONSTRAINT models_provider_model_id_unique UNIQUE (llm_provider_id, model_id); END IF; END $$; diff --git a/db/migrations/0029_tts_provider.up.sql b/db/migrations/0029_tts_provider.up.sql index aea40003..f2cb2e66 100644 --- a/db/migrations/0029_tts_provider.up.sql +++ b/db/migrations/0029_tts_provider.up.sql @@ -1,54 +1,41 @@ -- 0029_tts_provider -- Add TTS provider/model tables and bots.tts_model_id for existing databases. --- NOTE: On fresh databases these tables are replaced by unified providers/models via 0061. -DO $$ -BEGIN - IF EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = 'tts_providers') THEN - RETURN; - END IF; +CREATE TABLE IF NOT EXISTS tts_providers ( + id UUID PRIMARY KEY DEFAULT gen_random_uuid(), + name TEXT NOT NULL, + provider TEXT NOT NULL, + config JSONB NOT NULL DEFAULT '{}'::jsonb, + created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), + updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), + CONSTRAINT tts_providers_name_unique UNIQUE (name) +); - IF NOT EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = 'providers') THEN - EXECUTE ' - CREATE TABLE IF NOT EXISTS tts_providers ( - id UUID PRIMARY KEY DEFAULT gen_random_uuid(), - name TEXT NOT NULL, - provider TEXT NOT NULL, - config JSONB NOT NULL DEFAULT ''{}''::jsonb, - created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), - updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), - CONSTRAINT tts_providers_name_unique UNIQUE (name) - )'; +CREATE TABLE IF NOT EXISTS tts_models ( + id UUID PRIMARY KEY DEFAULT gen_random_uuid(), + model_id TEXT NOT NULL, + name TEXT, + tts_provider_id UUID NOT NULL REFERENCES tts_providers(id) ON DELETE CASCADE, + config JSONB NOT NULL DEFAULT '{}'::jsonb, + created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), + updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), + CONSTRAINT tts_models_provider_model_id_unique UNIQUE (tts_provider_id, model_id) +); - EXECUTE ' - CREATE TABLE IF NOT EXISTS tts_models ( - id UUID PRIMARY KEY DEFAULT gen_random_uuid(), - model_id TEXT NOT NULL, - name TEXT, - tts_provider_id UUID NOT NULL REFERENCES tts_providers(id) ON DELETE CASCADE, - config JSONB NOT NULL DEFAULT ''{}''::jsonb, - created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), - updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), - CONSTRAINT tts_models_provider_model_id_unique UNIQUE (tts_provider_id, model_id) - )'; +CREATE INDEX IF NOT EXISTS idx_tts_models_provider_id ON tts_models(tts_provider_id); - EXECUTE 'CREATE INDEX IF NOT EXISTS idx_tts_models_provider_id ON tts_models(tts_provider_id)'; - END IF; -END $$; - -ALTER TABLE bots ADD COLUMN IF NOT EXISTS tts_model_id UUID; +ALTER TABLE bots + ADD COLUMN IF NOT EXISTS tts_model_id UUID; DO $$ BEGIN IF NOT EXISTS ( - SELECT 1 FROM pg_constraint WHERE conname = 'bots_tts_model_id_fkey' + SELECT 1 + FROM pg_constraint + WHERE conname = 'bots_tts_model_id_fkey' ) THEN - IF EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = 'tts_models') THEN - EXECUTE 'ALTER TABLE bots ADD CONSTRAINT bots_tts_model_id_fkey FOREIGN KEY (tts_model_id) REFERENCES tts_models(id) ON DELETE SET NULL'; - ELSE - ALTER TABLE bots - ADD CONSTRAINT bots_tts_model_id_fkey - FOREIGN KEY (tts_model_id) REFERENCES models(id) ON DELETE SET NULL; - END IF; + ALTER TABLE bots + ADD CONSTRAINT bots_tts_model_id_fkey + FOREIGN KEY (tts_model_id) REFERENCES tts_models(id) ON DELETE SET NULL; END IF; END $$; diff --git a/db/migrations/0030_drop_tts_model_unique.up.sql b/db/migrations/0030_drop_tts_model_unique.up.sql index b26b4036..abd4cba4 100644 --- a/db/migrations/0030_drop_tts_model_unique.up.sql +++ b/db/migrations/0030_drop_tts_model_unique.up.sql @@ -1,11 +1,6 @@ -- 0030_drop_tts_model_unique -- Drop unique constraint on (tts_provider_id, model_id) to allow multiple -- models with the same model_id under one provider (different configs). --- NOTE: No-op on fresh databases where tts_models no longer exists. -DO $$ -BEGIN - IF EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = 'tts_models') THEN - EXECUTE 'ALTER TABLE tts_models DROP CONSTRAINT IF EXISTS tts_models_provider_model_id_unique'; - END IF; -END $$; +ALTER TABLE tts_models + DROP CONSTRAINT IF EXISTS tts_models_provider_model_id_unique; diff --git a/db/migrations/0041_provider_model_refactor.up.sql b/db/migrations/0041_provider_model_refactor.up.sql index 671194d0..1adabbfb 100644 --- a/db/migrations/0041_provider_model_refactor.up.sql +++ b/db/migrations/0041_provider_model_refactor.up.sql @@ -1,37 +1,39 @@ -- 0041_provider_model_refactor -- Move client_type to llm_providers, add icon, replace model columns with config JSONB. --- NOTE: This migration is a no-op on fresh databases where the canonical schema already applies. -DO $$ -BEGIN - IF NOT EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = 'llm_providers') THEN - RETURN; - END IF; - - EXECUTE 'ALTER TABLE llm_providers ADD COLUMN IF NOT EXISTS client_type TEXT NOT NULL DEFAULT ''openai-completions'''; - EXECUTE 'ALTER TABLE llm_providers ADD COLUMN IF NOT EXISTS icon TEXT'; +-- 1. Add client_type and icon to llm_providers +ALTER TABLE llm_providers + ADD COLUMN IF NOT EXISTS client_type TEXT NOT NULL DEFAULT 'openai-completions', + ADD COLUMN IF NOT EXISTS icon TEXT; +-- 2–6. Backfill and migrate only when old columns exist (idempotent for fresh DBs). +DO $$ BEGIN + -- Back-fill provider client_type from models.client_type (old column) IF EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'models' AND column_name = 'client_type') THEN - EXECUTE ' - UPDATE llm_providers p - SET client_type = sub.client_type - FROM ( - SELECT DISTINCT ON (llm_provider_id) llm_provider_id, client_type - FROM models - WHERE client_type IS NOT NULL AND client_type != '''' - ORDER BY llm_provider_id, created_at ASC - ) sub - WHERE p.id = sub.llm_provider_id'; + UPDATE llm_providers p + SET client_type = sub.client_type + FROM ( + SELECT DISTINCT ON (llm_provider_id) llm_provider_id, client_type + FROM models + WHERE client_type IS NOT NULL AND client_type != '' + ORDER BY llm_provider_id, created_at ASC + ) sub + WHERE p.id = sub.llm_provider_id; END IF; + -- Add CHECK constraint (skip if already present) IF NOT EXISTS (SELECT 1 FROM information_schema.table_constraints WHERE constraint_name = 'llm_providers_client_type_check') THEN - EXECUTE 'ALTER TABLE llm_providers ADD CONSTRAINT llm_providers_client_type_check CHECK (client_type IN (''openai-responses'', ''openai-completions'', ''anthropic-messages'', ''google-generative-ai''))'; + ALTER TABLE llm_providers + ADD CONSTRAINT llm_providers_client_type_check + CHECK (client_type IN ('openai-responses', 'openai-completions', 'anthropic-messages', 'google-generative-ai')); END IF; + -- Add config JSONB to models IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'models' AND column_name = 'config') THEN ALTER TABLE models ADD COLUMN config JSONB NOT NULL DEFAULT '{}'::jsonb; END IF; + -- Migrate existing columns into config (only when old columns exist) IF EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'models' AND column_name = 'dimensions') THEN UPDATE models SET config = jsonb_strip_nulls(jsonb_build_object( 'dimensions', dimensions, @@ -49,16 +51,12 @@ BEGIN END IF; END $$; -DO $$ -BEGIN - IF NOT EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = 'llm_providers') THEN - RETURN; - END IF; - ALTER TABLE models DROP CONSTRAINT IF EXISTS models_client_type_check; - ALTER TABLE models DROP CONSTRAINT IF EXISTS models_chat_client_type_check; - ALTER TABLE models DROP CONSTRAINT IF EXISTS models_dimensions_check; - ALTER TABLE models DROP COLUMN IF EXISTS client_type; - ALTER TABLE models DROP COLUMN IF EXISTS dimensions; - ALTER TABLE models DROP COLUMN IF EXISTS input_modalities; - ALTER TABLE models DROP COLUMN IF EXISTS supports_reasoning; -END $$; +-- Drop old columns and constraints (IF EXISTS makes these safe on fresh DBs) +ALTER TABLE models DROP CONSTRAINT IF EXISTS models_client_type_check; +ALTER TABLE models DROP CONSTRAINT IF EXISTS models_chat_client_type_check; +ALTER TABLE models DROP CONSTRAINT IF EXISTS models_dimensions_check; + +ALTER TABLE models DROP COLUMN IF EXISTS client_type; +ALTER TABLE models DROP COLUMN IF EXISTS dimensions; +ALTER TABLE models DROP COLUMN IF EXISTS input_modalities; +ALTER TABLE models DROP COLUMN IF EXISTS supports_reasoning; diff --git a/db/migrations/0042_provider_enable.up.sql b/db/migrations/0042_provider_enable.up.sql index d99cb1eb..6911f311 100644 --- a/db/migrations/0042_provider_enable.up.sql +++ b/db/migrations/0042_provider_enable.up.sql @@ -1,10 +1,5 @@ -- 0042_provider_enable -- Add enable column to llm_providers for built-in provider registry support. --- NOTE: This migration is a no-op on fresh databases where the canonical schema already applies. -DO $$ -BEGIN - IF EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = 'llm_providers') THEN - EXECUTE 'ALTER TABLE llm_providers ADD COLUMN IF NOT EXISTS enable BOOLEAN NOT NULL DEFAULT true'; - END IF; -END $$; +ALTER TABLE llm_providers + ADD COLUMN IF NOT EXISTS enable BOOLEAN NOT NULL DEFAULT true; diff --git a/db/migrations/0046_llm_provider_oauth.up.sql b/db/migrations/0046_llm_provider_oauth.up.sql index 5197f486..e556976e 100644 --- a/db/migrations/0046_llm_provider_oauth.up.sql +++ b/db/migrations/0046_llm_provider_oauth.up.sql @@ -1,39 +1,18 @@ -- 0046_llm_provider_oauth --- Add OAuth token storage for providers to support OpenAI Codex OAuth. --- NOTE: On fresh databases, table is named provider_oauth_tokens via 0061. +-- Add OAuth token storage for LLM providers to support OpenAI Codex OAuth. -DO $$ -BEGIN - IF EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = 'llm_providers') THEN - EXECUTE ' - CREATE TABLE IF NOT EXISTS llm_provider_oauth_tokens ( - id UUID PRIMARY KEY DEFAULT gen_random_uuid(), - llm_provider_id UUID NOT NULL UNIQUE REFERENCES llm_providers(id) ON DELETE CASCADE, - access_token TEXT NOT NULL DEFAULT '''', - refresh_token TEXT NOT NULL DEFAULT '''', - expires_at TIMESTAMPTZ, - scope TEXT NOT NULL DEFAULT '''', - token_type TEXT NOT NULL DEFAULT '''', - state TEXT NOT NULL DEFAULT '''', - pkce_code_verifier TEXT NOT NULL DEFAULT '''', - created_at TIMESTAMPTZ NOT NULL DEFAULT now(), - updated_at TIMESTAMPTZ NOT NULL DEFAULT now() - )'; - EXECUTE 'CREATE INDEX IF NOT EXISTS idx_llm_provider_oauth_tokens_state ON llm_provider_oauth_tokens(state) WHERE state != '''''; - ELSIF NOT EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = 'provider_oauth_tokens') THEN - CREATE TABLE IF NOT EXISTS provider_oauth_tokens ( - id UUID PRIMARY KEY DEFAULT gen_random_uuid(), - provider_id UUID NOT NULL UNIQUE REFERENCES providers(id) ON DELETE CASCADE, - access_token TEXT NOT NULL DEFAULT '', - refresh_token TEXT NOT NULL DEFAULT '', - expires_at TIMESTAMPTZ, - scope TEXT NOT NULL DEFAULT '', - token_type TEXT NOT NULL DEFAULT '', - state TEXT NOT NULL DEFAULT '', - pkce_code_verifier TEXT NOT NULL DEFAULT '', - created_at TIMESTAMPTZ NOT NULL DEFAULT now(), - updated_at TIMESTAMPTZ NOT NULL DEFAULT now() - ); - CREATE INDEX IF NOT EXISTS idx_provider_oauth_tokens_state ON provider_oauth_tokens(state) WHERE state != ''; - END IF; -END $$; +CREATE TABLE IF NOT EXISTS llm_provider_oauth_tokens ( + id UUID PRIMARY KEY DEFAULT gen_random_uuid(), + llm_provider_id UUID NOT NULL UNIQUE REFERENCES llm_providers(id) ON DELETE CASCADE, + access_token TEXT NOT NULL DEFAULT '', + refresh_token TEXT NOT NULL DEFAULT '', + expires_at TIMESTAMPTZ, + scope TEXT NOT NULL DEFAULT '', + token_type TEXT NOT NULL DEFAULT '', + state TEXT NOT NULL DEFAULT '', + pkce_code_verifier TEXT NOT NULL DEFAULT '', + created_at TIMESTAMPTZ NOT NULL DEFAULT now(), + updated_at TIMESTAMPTZ NOT NULL DEFAULT now() +); + +CREATE INDEX IF NOT EXISTS idx_llm_provider_oauth_tokens_state ON llm_provider_oauth_tokens(state) WHERE state != ''; diff --git a/db/migrations/0047_add_openai_codex_client_type.up.sql b/db/migrations/0047_add_openai_codex_client_type.up.sql index 6c0e150d..37d7b527 100644 --- a/db/migrations/0047_add_openai_codex_client_type.up.sql +++ b/db/migrations/0047_add_openai_codex_client_type.up.sql @@ -1,21 +1,12 @@ -- 0047_add_openai_codex_client_type -- Add openai-codex as a first-class client_type and migrate existing codex-oauth providers. --- NOTE: This migration is a no-op on fresh databases where the canonical schema already applies. -DO $$ -BEGIN - IF NOT EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = 'llm_providers') THEN - RETURN; - END IF; +ALTER TABLE llm_providers DROP CONSTRAINT IF EXISTS llm_providers_client_type_check; +ALTER TABLE llm_providers ADD CONSTRAINT llm_providers_client_type_check + CHECK (client_type IN ('openai-responses', 'openai-completions', 'anthropic-messages', 'google-generative-ai', 'openai-codex')); - EXECUTE 'ALTER TABLE llm_providers DROP CONSTRAINT IF EXISTS llm_providers_client_type_check'; - EXECUTE 'ALTER TABLE llm_providers ADD CONSTRAINT llm_providers_client_type_check - CHECK (client_type IN (''openai-responses'', ''openai-completions'', ''anthropic-messages'', ''google-generative-ai'', ''openai-codex''))'; - - EXECUTE ' - UPDATE llm_providers - SET client_type = ''openai-codex'', - updated_at = now() - WHERE client_type = ''openai-responses'' - AND metadata->>''auth_type'' = ''openai-codex-oauth'''; -END $$; +UPDATE llm_providers +SET client_type = 'openai-codex', + updated_at = now() +WHERE client_type = 'openai-responses' + AND metadata->>'auth_type' = 'openai-codex-oauth'; diff --git a/db/migrations/0050_tts_provider_enable.up.sql b/db/migrations/0050_tts_provider_enable.up.sql index 15dd0c5b..88a0bc63 100644 --- a/db/migrations/0050_tts_provider_enable.up.sql +++ b/db/migrations/0050_tts_provider_enable.up.sql @@ -1,10 +1,4 @@ -- 0050_tts_provider_enable -- Add enable column to tts_providers table for toggling providers on/off. --- NOTE: No-op on fresh databases where tts_providers no longer exists. -DO $$ -BEGIN - IF EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = 'tts_providers') THEN - EXECUTE 'ALTER TABLE tts_providers ADD COLUMN IF NOT EXISTS enable BOOLEAN NOT NULL DEFAULT false'; - END IF; -END $$; +ALTER TABLE tts_providers ADD COLUMN IF NOT EXISTS enable BOOLEAN NOT NULL DEFAULT false;