diff --git a/surfsense_backend/alembic/versions/20_add_openrouter_to_litellmprovider_enum.py b/surfsense_backend/alembic/versions/20_add_openrouter_to_litellmprovider_enum.py new file mode 100644 index 000000000..d5d7d7930 --- /dev/null +++ b/surfsense_backend/alembic/versions/20_add_openrouter_to_litellmprovider_enum.py @@ -0,0 +1,47 @@ +"""Add OPENROUTER to LiteLLMProvider enum + +Revision ID: 20 +Revises: 19 +""" + +from collections.abc import Sequence + +from alembic import op + +# revision identifiers, used by Alembic. +revision: str = "20" +down_revision: str | None = "19" +branch_labels: str | Sequence[str] | None = None +depends_on: str | Sequence[str] | None = None + + +def upgrade() -> None: + """Add OPENROUTER to LiteLLMProvider enum.""" + + # Add OPENROUTER to the enum if it doesn't already exist + op.execute( + """ + DO $$ + BEGIN + IF NOT EXISTS ( + SELECT 1 FROM pg_enum + WHERE enumtypid = 'litellmprovider'::regtype + AND enumlabel = 'OPENROUTER' + ) THEN + ALTER TYPE litellmprovider ADD VALUE 'OPENROUTER'; + END IF; + END$$; + """ + ) + + +def downgrade() -> None: + """Remove OPENROUTER from LiteLLMProvider enum. + + Note: PostgreSQL doesn't support removing enum values directly. + This would require recreating the enum type and updating all dependent objects. + For safety, this downgrade is a no-op. + """ + # PostgreSQL doesn't support removing enum values directly + # This would require a complex migration recreating the enum + pass diff --git a/surfsense_backend/app/db.py b/surfsense_backend/app/db.py index 488503e68..17339f30a 100644 --- a/surfsense_backend/app/db.py +++ b/surfsense_backend/app/db.py @@ -87,6 +87,7 @@ class LiteLLMProvider(str, Enum): OLLAMA = "OLLAMA" MISTRAL = "MISTRAL" TOGETHER_AI = "TOGETHER_AI" + OPENROUTER = "OPENROUTER" REPLICATE = "REPLICATE" PALM = "PALM" VERTEX_AI = "VERTEX_AI" diff --git a/surfsense_backend/app/services/llm_service.py b/surfsense_backend/app/services/llm_service.py index 54ea17885..cbf967791 100644 --- a/surfsense_backend/app/services/llm_service.py +++ b/surfsense_backend/app/services/llm_service.py @@ -80,6 +80,7 @@ async def get_user_llm_instance( "OLLAMA": "ollama", "MISTRAL": "mistral", "AZURE_OPENAI": "azure", + "OPENROUTER": "openrouter", # Add more mappings as needed } provider_prefix = provider_map.get( diff --git a/surfsense_web/components/onboard/add-provider-step.tsx b/surfsense_web/components/onboard/add-provider-step.tsx index db8c75b78..af8d486e8 100644 --- a/surfsense_web/components/onboard/add-provider-step.tsx +++ b/surfsense_web/components/onboard/add-provider-step.tsx @@ -36,6 +36,7 @@ const LLM_PROVIDERS = [ { value: "MISTRAL", label: "Mistral", example: "mistral-large-latest, mistral-medium" }, { value: "TOGETHER_AI", label: "Together AI", example: "togethercomputer/llama-2-70b-chat" }, { value: "REPLICATE", label: "Replicate", example: "meta/llama-2-70b-chat" }, + { value: "OPENROUTER", label: "OpenRouter", example: "anthropic/claude-opus-4.1, openai/gpt-5" }, { value: "CUSTOM", label: "Custom Provider", example: "your-custom-model" }, ]; diff --git a/surfsense_web/components/settings/model-config-manager.tsx b/surfsense_web/components/settings/model-config-manager.tsx index e1e757f16..a7f5d2dec 100644 --- a/surfsense_web/components/settings/model-config-manager.tsx +++ b/surfsense_web/components/settings/model-config-manager.tsx @@ -112,6 +112,12 @@ const LLM_PROVIDERS = [ example: "meta/llama-2-70b-chat", description: "Run models via API", }, + { + value: "OPENROUTER", + label: "OpenRouter", + example: "anthropic/claude-opus-4.1, openai/gpt-5", + description: "API gateway and LLM marketplace that provides unified access ", + }, { value: "CUSTOM", label: "Custom Provider",