preset.py 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. """ presets 对话预设"""
  2. import os
  3. import yaml
  4. import common
  5. class Preset():
  6. """ 代表一个预设AI人格"""
  7. name:str
  8. sys_prompt:str
  9. msg_format:str
  10. def __init__(self, name:str, desc:str, sys_prompt:str, msg_format:str) -> None:
  11. self.name = name
  12. self.desc = desc
  13. self.sys_prompt = sys_prompt
  14. self.msg_format = msg_format
  15. def construct_msg(self, msg:str, wxcode:str, nickname:str) -> str:
  16. """ 根据预设格式构造发送给AI的消息"""
  17. # 发送给 AI 的消息格式, 用于对消息进行包装后发送. 省略则发送源消息
  18. # 可用变量:
  19. # $message=原消息, $wxcode=发送者微信号, $nickname=发送者微信昵称
  20. if self.msg_format is None:
  21. return msg
  22. text = self.msg_format.format(message=msg, wxcode=wxcode, nickname=nickname)
  23. return text
  24. def read_preset(name:str) -> Preset:
  25. """ 从presets目录的yaml配置文件读取指定名称
  26. Args:
  27. name (str): 预设名称, 即不包含'.yaml'的文件名
  28. Returns:
  29. Preset: preset对象, 如果失败返回None
  30. """
  31. try:
  32. file = common.get_path(common.PRESET_DIR) / f"{name}.yaml"
  33. with open(file, "rb") as f:
  34. yaml_preset:dict = yaml.safe_load(f)
  35. desc = yaml_preset.get("desc", "")
  36. sys_prompt = yaml_preset.get("sys_prompt", None)
  37. msg_format = yaml_preset.get("msg_format", None)
  38. return Preset(name, desc, sys_prompt, msg_format)
  39. except Exception as e:
  40. common.logger().error('无法读取预设文件. 错误:%s', common.error_trace(e))
  41. return None
  42. def list_preset() -> str:
  43. """ 列出可用预设 """
  44. text = "可用预设列表"
  45. for file in os.listdir(common.PRESET_DIR):
  46. if file.endswith(".yaml"):
  47. pr_name = file.removesuffix(".yaml")
  48. pr = read_preset(pr_name)
  49. if pr:
  50. text = text + f"\n{pr_name}: {pr.desc}"
  51. return text
  52. def get_default_preset() -> Preset:
  53. """ 返回默认preset. 如果没有, 则返回全None Preset"""
  54. default_preset = read_preset('default') # 对话默认采用预设
  55. if default_preset is None:
  56. common.logger().warn('无法读取默认预设default.yaml, 用None preset代替')
  57. return Preset("None", None, "你是一个AI助理", None)
  58. else:
  59. return default_preset
  60. if __name__ == "__main__":
  61. # Test
  62. pr = read_preset('default')
  63. print(pr.name)
  64. print(pr.desc)
  65. print(pr.sys_prompt)
  66. print(pr.msg_format)