116 lines
4.8 KiB
Python
116 lines
4.8 KiB
Python
# -*- 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
|
||
|