models.py 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. """
  2. 数据模型定义
  3. """
  4. from typing import Literal, Optional
  5. from pydantic import BaseModel
  6. # 消息类型
  7. MessageType = Literal[
  8. "audio_chunk",
  9. "audio_end",
  10. "cancel",
  11. "text_result",
  12. "emotion",
  13. "audio_response",
  14. "error",
  15. "ping",
  16. "pong",
  17. ]
  18. # 情感类型
  19. EmotionType = Literal[
  20. # 基础情感
  21. "neutral", # 中性/平静
  22. "happy", # 开心/愉悦
  23. "sad", # 难过/悲伤
  24. "excited", # 兴奋/激动
  25. "angry", # 生气/愤怒
  26. "surprised", # 惊讶/意外
  27. "thoughtful", # 深思/沉思
  28. "encouraging", # 鼓励/支持
  29. # 扩展情感
  30. "confused", # 困惑/疑惑
  31. "worried", # 担忧/焦虑
  32. "satisfied", # 满意/满足
  33. "friendly", # 友好/亲切
  34. "sorry", # 抱歉/歉意
  35. ]
  36. # 错误代码
  37. ErrorCode = Literal[
  38. "STT_ERROR",
  39. "LLM_ERROR",
  40. "TTS_ERROR",
  41. "NETWORK_ERROR",
  42. "RATE_LIMIT",
  43. "INVALID_AUDIO",
  44. "CANCELLED",
  45. ]
  46. class BaseMessage(BaseModel):
  47. """基础消息"""
  48. type: MessageType
  49. requestId: str
  50. timestamp: int
  51. class AudioChunkMessage(BaseMessage):
  52. """音频数据块消息"""
  53. type: Literal["audio_chunk"] = "audio_chunk"
  54. data: str
  55. sampleRate: int = 16000
  56. channels: int = 1
  57. bitDepth: int = 16
  58. chunkIndex: int
  59. class AudioEndMessage(BaseMessage):
  60. """音频结束消息"""
  61. type: Literal["audio_end"] = "audio_end"
  62. totalChunks: int
  63. class CancelMessage(BaseMessage):
  64. """取消消息"""
  65. type: Literal["cancel"] = "cancel"
  66. class TextResultMessage(BaseMessage):
  67. """文本结果消息"""
  68. type: Literal["text_result"] = "text_result"
  69. text: str
  70. isFinal: bool
  71. class EmotionMessage(BaseMessage):
  72. """情感消息"""
  73. type: Literal["emotion"] = "emotion"
  74. emotion: EmotionType
  75. intensity: Optional[float] = None
  76. class AudioResponseMessage(BaseMessage):
  77. """音频响应消息"""
  78. type: Literal["audio_response"] = "audio_response"
  79. data: str
  80. sampleRate: int = 24000 # 流式 TTS 使用 24kHz
  81. channels: int = 1
  82. bitDepth: int = 16
  83. format: Literal["pcm", "wav"] = "pcm" # 音频格式:pcm(流式)或 wav(完整)
  84. chunkIndex: int
  85. isLast: bool
  86. class ErrorMessage(BaseMessage):
  87. """错误消息"""
  88. type: Literal["error"] = "error"
  89. code: ErrorCode
  90. message: str
  91. class PingMessage(BaseMessage):
  92. """Ping消息"""
  93. type: Literal["ping"] = "ping"
  94. class PongMessage(BaseMessage):
  95. """Pong消息"""
  96. type: Literal["pong"] = "pong"