您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

118 行
5.0KB

  1. # encoding:utf-8
  2. from bot.bot import Bot
  3. from bot.session_manager import SessionManager
  4. from bridge.context import ContextType
  5. from bridge.reply import Reply, ReplyType
  6. from common.log import logger
  7. from config import conf, load_config
  8. from .dashscope_session import DashscopeSession
  9. import os
  10. import dashscope
  11. from http import HTTPStatus
  12. dashscope_models = {
  13. "qwen-turbo": dashscope.Generation.Models.qwen_turbo,
  14. "qwen-plus": dashscope.Generation.Models.qwen_plus,
  15. "qwen-max": dashscope.Generation.Models.qwen_max,
  16. "qwen-bailian-v1": dashscope.Generation.Models.bailian_v1
  17. }
  18. # ZhipuAI对话模型API
  19. class DashscopeBot(Bot):
  20. def __init__(self):
  21. super().__init__()
  22. self.sessions = SessionManager(DashscopeSession, model=conf().get("model") or "qwen-plus")
  23. self.model_name = conf().get("model") or "qwen-plus"
  24. self.api_key = conf().get("dashscope_api_key")
  25. os.environ["DASHSCOPE_API_KEY"] = self.api_key
  26. self.client = dashscope.Generation
  27. def reply(self, query, context=None):
  28. # acquire reply content
  29. if context.type == ContextType.TEXT:
  30. logger.info("[DASHSCOPE] query={}".format(query))
  31. session_id = context["session_id"]
  32. reply = None
  33. clear_memory_commands = conf().get("clear_memory_commands", ["#清除记忆"])
  34. if query in clear_memory_commands:
  35. self.sessions.clear_session(session_id)
  36. reply = Reply(ReplyType.INFO, "记忆已清除")
  37. elif query == "#清除所有":
  38. self.sessions.clear_all_session()
  39. reply = Reply(ReplyType.INFO, "所有人记忆已清除")
  40. elif query == "#更新配置":
  41. load_config()
  42. reply = Reply(ReplyType.INFO, "配置已更新")
  43. if reply:
  44. return reply
  45. session = self.sessions.session_query(query, session_id)
  46. logger.debug("[DASHSCOPE] session query={}".format(session.messages))
  47. reply_content = self.reply_text(session)
  48. logger.debug(
  49. "[DASHSCOPE] new_query={}, session_id={}, reply_cont={}, completion_tokens={}".format(
  50. session.messages,
  51. session_id,
  52. reply_content["content"],
  53. reply_content["completion_tokens"],
  54. )
  55. )
  56. if reply_content["completion_tokens"] == 0 and len(reply_content["content"]) > 0:
  57. reply = Reply(ReplyType.ERROR, reply_content["content"])
  58. elif reply_content["completion_tokens"] > 0:
  59. self.sessions.session_reply(reply_content["content"], session_id, reply_content["total_tokens"])
  60. reply = Reply(ReplyType.TEXT, reply_content["content"])
  61. else:
  62. reply = Reply(ReplyType.ERROR, reply_content["content"])
  63. logger.debug("[DASHSCOPE] reply {} used 0 tokens.".format(reply_content))
  64. return reply
  65. else:
  66. reply = Reply(ReplyType.ERROR, "Bot不支持处理{}类型的消息".format(context.type))
  67. return reply
  68. def reply_text(self, session: DashscopeSession, retry_count=0) -> dict:
  69. """
  70. call openai's ChatCompletion to get the answer
  71. :param session: a conversation session
  72. :param session_id: session id
  73. :param retry_count: retry count
  74. :return: {}
  75. """
  76. try:
  77. dashscope.api_key = self.api_key
  78. response = self.client.call(
  79. dashscope_models[self.model_name],
  80. messages=session.messages,
  81. result_format="message"
  82. )
  83. if response.status_code == HTTPStatus.OK:
  84. content = response.output.choices[0]["message"]["content"]
  85. return {
  86. "total_tokens": response.usage["total_tokens"],
  87. "completion_tokens": response.usage["output_tokens"],
  88. "content": content,
  89. }
  90. else:
  91. logger.error('Request id: %s, Status code: %s, error code: %s, error message: %s' % (
  92. response.request_id, response.status_code,
  93. response.code, response.message
  94. ))
  95. result = {"completion_tokens": 0, "content": "我现在有点累了,等会再来吧"}
  96. need_retry = retry_count < 2
  97. result = {"completion_tokens": 0, "content": "我现在有点累了,等会再来吧"}
  98. if need_retry:
  99. return self.reply_text(session, retry_count + 1)
  100. else:
  101. return result
  102. except Exception as e:
  103. logger.exception(e)
  104. need_retry = retry_count < 2
  105. result = {"completion_tokens": 0, "content": "我现在有点累了,等会再来吧"}
  106. if need_retry:
  107. return self.reply_text(session, retry_count + 1)
  108. else:
  109. return result