bed5c7abef
- Separate workspace landing from login for better UX - Referral system rewards both parties with Pro days - Quota enforcement prevents abuse without breaking endpoints - 7-day free trial with auto-downgrade on expiry - Admin-managed search provider config (SearXNG, Bing) - 15% discount on annual subscriptions - MCP search server wrapping opencode search - Fix discovery module field name mismatch causing 422
114 lines
3.6 KiB
Python
114 lines
3.6 KiB
Python
from pydantic_settings import BaseSettings
|
|
from typing import Optional
|
|
from pathlib import Path
|
|
|
|
|
|
PROJECT_ROOT = Path(__file__).resolve().parents[2]
|
|
ENV_FILE = PROJECT_ROOT / ".env"
|
|
|
|
|
|
class Settings(BaseSettings):
|
|
model_config = {
|
|
"env_file": str(ENV_FILE),
|
|
"env_file_encoding": "utf-8",
|
|
"extra": "ignore",
|
|
}
|
|
|
|
APP_NAME: str = "TradeMate"
|
|
|
|
SECRET_KEY: str
|
|
JWT_ALGORITHM: str = "HS256"
|
|
ACCESS_TOKEN_EXPIRE_MINUTES: int = 60
|
|
REFRESH_TOKEN_EXPIRE_DAYS: int = 30
|
|
|
|
DATABASE_URL: str
|
|
DB_ECHO: bool = False
|
|
|
|
REDIS_URL: str = "redis://localhost:6379/0"
|
|
|
|
CELERY_BROKER_URL: str = "redis://localhost:6379/1"
|
|
CELERY_RESULT_BACKEND: str = "redis://localhost:6379/2"
|
|
|
|
OPENAI_API_KEY: Optional[str] = None
|
|
ANTHROPIC_API_KEY: Optional[str] = None
|
|
DEEPL_API_KEY: Optional[str] = None
|
|
|
|
SENSENOVA_API_KEY: Optional[str] = None
|
|
SENSENOVA_BASE_URL: str = "https://token.sensenova.cn/v1"
|
|
SENSENOVA_MODEL: str = "sensenova-6.7-flash-lite"
|
|
|
|
IFLYTEK_API_KEY: Optional[str] = None
|
|
IFLYTEK_API_BASE: str = "https://maas-api.cn-huabei-1.xf-yun.com/v2"
|
|
IFLYTEK_MODEL: str = "astron-code-latest"
|
|
|
|
LOCAL_MODEL_ENABLED: bool = False
|
|
LOCAL_MODEL_URL: str = "http://localhost:8001"
|
|
|
|
OPENCODE_GO_API_KEY: Optional[str] = None
|
|
OPENCODE_GO_BASE_URL: str = "https://opencode.ai/zen/go/v1"
|
|
OPENCODE_GO_MODEL: str = "minimax-m2.7"
|
|
|
|
NVIDIA_API_KEY: Optional[str] = None
|
|
NVIDIA_BASE_URL: str = "https://integrate.api.nvidia.com/v1"
|
|
NVIDIA_MODEL: str = "stepfun-ai/step-3.5-flash"
|
|
|
|
WHATSAPP_API_TOKEN: Optional[str] = None
|
|
WHATSAPP_PHONE_NUMBER_ID: Optional[str] = None
|
|
WHATSAPP_WEBHOOK_VERIFY_TOKEN: Optional[str] = None
|
|
|
|
ALIBABA_ACCESS_KEY_ID: Optional[str] = None
|
|
ALIBABA_ACCESS_KEY_SECRET: Optional[str] = None
|
|
|
|
WECHAT_APP_ID: Optional[str] = None
|
|
WECHAT_APP_SECRET: Optional[str] = None
|
|
WECHAT_PUSH_TEMPLATE_ID: Optional[str] = None
|
|
|
|
WECHAT_PAY_MCH_ID: Optional[str] = None
|
|
WECHAT_PAY_API_KEY: Optional[str] = None
|
|
WECHAT_PAY_SERIAL_NO: Optional[str] = None
|
|
WECHAT_PAY_CERT_DIR: str = "./certs"
|
|
WECHAT_PAY_NOTIFY_URL: str = "https://example.com/api/v1/payment/notify"
|
|
WECHAT_PAY_API_BASE: str = "https://api.mch.weixin.qq.com"
|
|
|
|
EXCHANGE_RATE_API_KEY: Optional[str] = None
|
|
|
|
GOOGLE_API_KEY: Optional[str] = None
|
|
GOOGLE_CSE_ID: Optional[str] = None
|
|
|
|
UPLOAD_DIR: str = "./uploads"
|
|
MAX_UPLOAD_SIZE: int = 10 * 1024 * 1024
|
|
|
|
FRONTEND_URL: str = "http://localhost:3000"
|
|
BACKEND_URL: str = "http://localhost:8000"
|
|
|
|
SENTRY_DSN: Optional[str] = None
|
|
DEBUG: bool = True
|
|
|
|
AI_ROUTING: dict = {
|
|
"translate": {"primary": "alibaba-mt", "fallback": ["opencode_go", "sensenova", "openai", "local"]},
|
|
"reply": {"primary": "opencode_go", "fallback": ["sensenova", "anthropic", "local"]},
|
|
"marketing": {"primary": "opencode_go", "fallback": ["sensenova", "openai", "local"]},
|
|
"extract": {"primary": "opencode_go", "fallback": ["sensenova", "openai"]},
|
|
"quotation": {"primary": "opencode_go", "fallback": ["sensenova", "openai"]},
|
|
"chat": {"primary": "nvidia", "fallback": ["opencode_go", "openai", "sensenova"]},
|
|
}
|
|
|
|
FREE_DAILY_TRANSLATE_CHARS: int = 5000
|
|
FREE_DAILY_REPLIES: int = 20
|
|
FREE_DAILY_MARKETING: int = 5
|
|
FREE_MAX_CUSTOMERS: int = 5
|
|
FREE_MAX_PRODUCTS: int = 1
|
|
FREE_DAILY_QUOTATIONS: int = 3
|
|
|
|
TRIAL_DAYS: int = 7
|
|
|
|
PRO_DAILY_TRANSLATE_CHARS: int = 50000
|
|
PRO_DAILY_REPLIES: int = 200
|
|
PRO_DAILY_MARKETING: int = 50
|
|
PRO_MAX_CUSTOMERS: int = 100
|
|
PRO_MAX_PRODUCTS: int = 20
|
|
PRO_DAILY_QUOTATIONS: int = 30
|
|
|
|
|
|
settings = Settings()
|