# -*- coding: utf-8 -*- import datetime from http import HTTPStatus import dashscope import pytz from bs4 import BeautifulSoup from dashscope import Generation from odoo import models, fields class ResConfigSettings(models.TransientModel): _inherit = ['res.config.settings'] apikey_qwen = fields.Char(string='Qwen API Key', config_parameter='qwen_api_key') class ResUsers(models.Model): _inherit = 'res.users' odoobot_state = fields.Selection(selection_add=[('chatgpt', 'ChatGPT')]) class MailBot(models.AbstractModel): _inherit = 'mail.bot' def _get_answer(self, record, body, values, command): odoobot_state = self.env.user.odoobot_state odoobot_mode = self.env['ir.config_parameter'].sudo().get_param('odoobot_mode') if body == "#enable": self.env.user.odoobot_state = 'chatgpt' return "ChatGpt enabled" if body == "#disable": self.env.user.odoobot_state = 'disabled' return "ChatGpt disabled" exclusion = {'o_mail_notification', 'o_mail_redirect', 'o_channel_redirect'} msg_sys = [ele for ele in exclusion if (ele in body)] if odoobot_state == 'chatgpt' and not msg_sys: lang = self.env.user.lang tz = self.env.user.tz local = pytz.timezone(tz) now = datetime.datetime.strftime(pytz.utc.localize(datetime.datetime.utcnow()).astimezone(local), "%Y-%m-%d %H:%M:%S") lang = self.env['res.lang'].search([('code', '=', lang)]).name app = self.env['ir.module.module'].search([('state', '=', 'installed'), ('application', '=', True)]).mapped('name') message_ids = self.env['mail.channel'].search([('id', '=', record.id)]).message_ids.ids message_ids = self.env['mail.message'].search([('id', 'in', message_ids)], order='id desc', limit=32, offset=1) message_ids = list(reversed(message_ids)) length = len(message_ids) bot_id = self.env.ref("base.partner_root") messages_history = [] i = 0 for message_id in message_ids: i += 1 if message_id.author_id.id != bot_id.id and i != length: message_user = BeautifulSoup(message_id.body, 'html.parser').get_text() if message_ids[i].author_id.id == bot_id.id: message_assistant = BeautifulSoup(message_ids[i].body, 'html.parser').get_text() if message_user and message_assistant: messages_history.append({"role": "user", "content": message_user}) messages_history.append({"role": "assistant", "content": message_assistant}) prompt = f""" You are an assistant and work for this company with name {self.env.company.name}; 你是{self.env.company.name}助手; the date and time now is {now} with timezone {tz}; 当前日期和时间 {now} 时区 {tz}; Apps installed: {str(app)}; 已经安装的应用: {str(app)}; answer in: {lang}; 回答使用: {lang} """ message_new = [ {'role': 'system', 'content': prompt} ] for item in messages_history: message_new.append(item) message_new.append({"role": "user", "content": body}) if odoobot_mode == 'streaming': self.with_delay().respond(odoobot_mode, record, message_new) else: return self.respond(odoobot_mode, record, message_new) else: return super(MailBot, self)._get_answer(record, body, values, command) def respond(self, mode, record, messages): dashscope.api_key = self.env['ir.config_parameter'].sudo().get_param('qwen_api_key') gen = Generation() response = gen.call('qwen-14b-chat', messages=messages, result_format='message', enable_search=True) if response.status_code == HTTPStatus.OK: content = response.output.choices[0]['message']['content'] if mode == 'streaming': odoobot_id = self.env.ref("base.partner_root") mod_response = self.env['mail.channel'].with_context(chatgpt=True).browse(record.id).message_post( body=content, message_type='comment', subtype_xmlid='mail.mt_comment', author_id=odoobot_id.id ) return mod_response else: return content else: msg = ('Request id: %s, Status code: %s, error code: %s, error message: %s' % ( response.request_id, response.status_code, response.code, response.message )) return msg