From 7d897ad9bb5ee46839ec91992cbbf4593168f119 Mon Sep 17 00:00:00 2001 From: YurenHao0426 Date: Fri, 13 Feb 2026 03:02:36 +0000 Subject: Add Claude provider, OpenRouter fallback, and GFM markdown support - Add Claude (Anthropic) as third LLM provider with streaming support - Add OpenRouter as transparent fallback when official API keys are missing or fail - Add remark-gfm to ReactMarkdown for table/strikethrough rendering - Claude models: sonnet-4.5, opus-4, opus-4.5, opus-4.6 - Backend: new stream_claude(), stream_openrouter(), provider routing, API key CRUD - Frontend: model selectors, API key inputs for Claude and OpenRouter - Auto-migration for new DB columns (claude_api_key, openrouter_api_key) Co-Authored-By: Claude Opus 4.6 --- backend/app/auth/models.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'backend/app/auth/models.py') diff --git a/backend/app/auth/models.py b/backend/app/auth/models.py index 8477ba2..14f5bb3 100644 --- a/backend/app/auth/models.py +++ b/backend/app/auth/models.py @@ -1,5 +1,5 @@ import os -from sqlalchemy import Column, Integer, String, DateTime, Text, create_engine +from sqlalchemy import Column, Integer, String, DateTime, Text, create_engine, text from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.orm import sessionmaker from datetime import datetime @@ -26,12 +26,22 @@ class User(Base): # API Keys (stored encrypted in production, plain for simplicity here) openai_api_key = Column(Text, nullable=True) gemini_api_key = Column(Text, nullable=True) + claude_api_key = Column(Text, nullable=True) + openrouter_api_key = Column(Text, nullable=True) def init_db(): """Initialize database tables""" os.makedirs(DATA_ROOT, exist_ok=True) Base.metadata.create_all(bind=engine) + # Migrate: add columns that may be missing in existing SQLite databases + with engine.connect() as conn: + for col in ("claude_api_key", "openrouter_api_key"): + try: + conn.execute(text(f"ALTER TABLE users ADD COLUMN {col} TEXT")) + conn.commit() + except Exception: + pass # Column already exists def get_db(): -- cgit v1.2.3