config.py 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. """
  2. 配置管理模块
  3. """
  4. import os
  5. from pathlib import Path
  6. from pydantic_settings import BaseSettings
  7. from dotenv import load_dotenv
  8. # 加载环境变量
  9. load_dotenv()
  10. class Settings(BaseSettings):
  11. """应用配置"""
  12. # 应用基础配置
  13. APP_NAME: str = "Tolan Voice Assistant"
  14. APP_VERSION: str = "1.0.0"
  15. DEBUG: bool = False
  16. # 服务器配置
  17. HOST: str = os.getenv("HOST", "0.0.0.0")
  18. PORT: int = int(os.getenv("PORT", "8000"))
  19. host: str = os.getenv("HOST", "0.0.0.0") # 别名,兼容小写
  20. port: int = int(os.getenv("PORT", "8000")) # 别名,兼容小写
  21. # WebSocket配置
  22. WS_HEARTBEAT_INTERVAL: int = 30 # 心跳间隔(秒)
  23. WS_TIMEOUT: int = 60 # 超时时间(秒)
  24. # DashScope API配置(阿里云)
  25. dashscope_api_key: str = os.getenv("DASHSCOPE_API_KEY", "")
  26. # LLM配置
  27. llm_model: str = os.getenv("LLM_MODEL", "qwen-turbo")
  28. # TTS配置
  29. tts_model: str = os.getenv("TTS_MODEL", "qwen3-tts-flash")
  30. tts_voice: str = os.getenv("TTS_VOICE", "Cherry") # 女声(支持:Cherry, Stella)
  31. tts_speech_rate: float = float(os.getenv("TTS_SPEECH_RATE", "1.1")) # 语速:1.1 = 10%加速(优化延迟)
  32. # TTS重试配置(处理API速率限制)
  33. TTS_MAX_RETRIES: int = int(os.getenv("TTS_MAX_RETRIES", "3")) # 最大重试次数
  34. TTS_RETRY_DELAY: float = float(os.getenv("TTS_RETRY_DELAY", "5.0")) # 初始重试延迟(秒)- 增加到5秒
  35. TTS_RETRY_BACKOFF: float = float(os.getenv("TTS_RETRY_BACKOFF", "2.0")) # 指数退避系数
  36. # TTS速率控制(预防性措施,避免触发API限制)
  37. TTS_MIN_INTERVAL: float = float(os.getenv("TTS_MIN_INTERVAL", "0.8")) # 两次TTS调用的最小间隔(秒)
  38. # 豆包API超时配置
  39. DOUBAO_RECV_TIMEOUT: int = 15 # 接收消息超时(秒)
  40. DOUBAO_CONNECT_TIMEOUT: int = 10 # 连接超时(秒)
  41. DOUBAO_RESPONSE_TIMEOUT: int = 20 # 响应超时(秒)
  42. # 豆包API配置
  43. DOUBAO_API_KEY: str = os.getenv("DOUBAO_API_KEY", "")
  44. DOUBAO_APP_ID: str = os.getenv("DOUBAO_APP_ID", "")
  45. DOUBAO_API_URL: str = os.getenv("DOUBAO_API_URL", "wss://openspeech.bytedance.com/api/v3/realtime/dialogue")
  46. DOUBAO_OUTPUT_FORMAT: str = os.getenv("DOUBAO_OUTPUT_FORMAT", "ogg_opus") # ogg_opus 或 pcm
  47. # AI助手提示词配置
  48. LEARNER_PROFICIENCY: str = os.getenv("LEARNER_PROFICIENCY", "A1-A2")
  49. AGE_TAG: str = os.getenv("AGE_TAG", "Adult")
  50. TOPIC_TAG: str = os.getenv("TOPIC_TAG", "Daily Conversation")
  51. EXPERIMENT_TAG: str = os.getenv("EXPERIMENT_TAG", "control") # control 或 experiment
  52. USE_SIMPLIFIED_PROMPT: bool = os.getenv("USE_SIMPLIFIED_PROMPT", "false").lower() == "true" # 🔥 使用简化提示词(减少延迟)
  53. # 音频配置
  54. AUDIO_SAMPLE_RATE: int = 16000
  55. AUDIO_BIT_RATE: int = 16
  56. AUDIO_CHANNELS: int = 1
  57. # CORS配置
  58. # 支持localhost和任意IP地址访问(端口3000为Vite默认HTTPS端口)
  59. CORS_ORIGINS: list = [
  60. "http://localhost:3000",
  61. "https://localhost:3000",
  62. "http://127.0.0.1:3000",
  63. "https://127.0.0.1:3000",
  64. "http://localhost:5173",
  65. "https://localhost:5173",
  66. "http://127.0.0.1:5173",
  67. "https://127.0.0.1:5173",
  68. # 支持局域网IP访问
  69. "http://192.168.2.112:3000",
  70. "https://192.168.2.112:3000",
  71. "http://192.168.2.112:5173",
  72. "https://192.168.2.112:5173",
  73. "http://192.168.43.35:3000",
  74. "https://192.168.43.35:3000",
  75. "http://192.168.43.35:5173",
  76. "https://192.168.43.35:5173",
  77. ]
  78. # 是否允许所有来源(开发环境可设为True,生产环境务必设为False)
  79. CORS_ALLOW_ALL: bool = os.getenv("CORS_ALLOW_ALL", "true").lower() == "true"
  80. # 日志配置
  81. LOG_LEVEL: str = "INFO"
  82. LOG_DIR: str = "logs"
  83. LOG_ROTATION: str = "500 MB"
  84. LOG_RETENTION: str = "10 days"
  85. # SSL配置(可选,生产环境建议由nginx统一管理SSL)
  86. SSL_KEYFILE: str = os.getenv("SSL_KEYFILE", "")
  87. SSL_CERTFILE: str = os.getenv("SSL_CERTFILE", "")
  88. class Config:
  89. env_file = ".env"
  90. case_sensitive = True
  91. extra = "ignore" # 忽略额外的环境变量(如旧的连接池配置)
  92. # 创建全局配置实例
  93. settings = Settings()
  94. # 确保日志目录存在
  95. Path(settings.LOG_DIR).mkdir(parents=True, exist_ok=True)