fix odoo 13 gpt

This commit is contained in:
ivan deng
2023-04-11 04:59:22 +08:00
parent f9728fd6f8
commit 9368b3818b
28 changed files with 15312 additions and 201 deletions

View File

@@ -1,5 +1,4 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2020-Present InTechual Solutions. (<https://intechualsolutions.com/>)
# from . import controllers
from . import models

View File

@@ -9,8 +9,8 @@
# Copyright (c) 2020-Present InTechual Solutions. (<https://intechualsolutions.com/>)
{
'name': 'Latest ChatGPT AI Center. GPT 3.5 Turbo, Dall-E Image.Multi Robot Support. Chat and Training',
'version': '13.23.03.05',
'name': 'Latest ChatGPT4 AI Center. GPT 4 for image, Dall-E Image.Multi Robot Support. Chat and Training',
'version': '13.23.03.31',
'author': 'Sunpop.cn',
'company': 'Sunpop.cn',
'maintainer': 'Sunpop.cn',
@@ -21,7 +21,7 @@
'license': 'AGPL-3',
'images': ['static/description/banner.gif'],
'summary': '''
ChatGpt Odoo AI Center. Multi Odoo ChatGPT Robot. Support chatgpt 3.5 turbo, text-davinci, DALL·E, Integration All ChatGpt Api.
ChatGpt Odoo AI Center. Multi Odoo ChatGPT Robot. Support chatgpt 4 image. 3.5 turbo, text-davinci, DALL·E, Integration All ChatGpt Api and Azure OpenAI Service.
Easy Chat channel with several ChatGPT Robots and train.
Whitelist and blacklist for Users or IP.
''',
@@ -30,17 +30,24 @@
providing a more natural and intuitive user experience.
Base on is_chatgpt_integration from InTechual Solutions.
1. Multi ChatGpt openAI robot Connector. Chat and train.
2. Multi Api support, Chatgpt 3.5 Turbo, Chatgpt 3 Davinci, Chatgpt 2 Code Optimized, 'Dall-E Image.
2. Multi Api support, Chatgpt 4, Chatgpt 3.5 Turbo, Chatgpt 3 Davinci, Chatgpt 2 Code Optimized, 'Dall-E Image.
3. Bind ChatGpt Api to user. So we can chat to robot user or use ChatGpt Channel for Group Chat.
4. White and black List for ChatGpt.
5. Setup Demo Chat time for every new user.
6. Easy Start and Stop ChatGpt.
7. Evaluation the ai robot to make better response. This training.
8. Add api support Connect the Microsoft Azure OpenAI Service.
9. Can set Synchronous or Asynchronous mode for Ai response.
11. Multi-language Support. Multi-Company Support.
12. Support Odoo 16,15,14,13,12, Enterprise and Community and odoo.sh Edition.
13. Full Open Source.
''',
'depends': ['base', 'base_setup', 'mail'],
'depends': [
'base',
'base_setup',
'mail',
'queue_job',
],
'data': [
'security/ir.model.access.csv',
'data/mail_channel_data.xml',

View File

@@ -1,5 +1,3 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2020-Present InTechual Solutions. (<https://intechualsolutions.com/>)
from . import main

View File

@@ -1,5 +1,4 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2020-Present InTechual Solutions. (<https://intechualsolutions.com/>)
from odoo import http

View File

@@ -2,14 +2,22 @@
<odoo>
<record id="chatgpt_robot" model="ai.robot">
<field name="name">ChatGPT odoo</field>
<field name="provider">openai</field>
<field name="sequence">1</field>
</record>
<record id="chatgpt_robot1" model="ai.robot">
<field name="name">ChatGPT Coding</field>
<field name="provider">openai</field>
<field name="sequence">6</field>
</record>
<record id="chatgpt_robot2" model="ai.robot">
<field name="name">ChatGPT Finance</field>
<field name="provider">openai</field>
<field name="sequence">7</field>
</record>
<record id="chatgpt_robot3" model="ai.robot">
<field name="name">ChatGPT Azure</field>
<field name="provider">azure</field>
<field name="sequence">8</field>
</record>
</odoo>

View File

@@ -7,5 +7,10 @@
<field name="value">300</field>
</record>
<record id="openai_sync_config" model="ir.config_parameter">
<field name="key">app_chatgpt.openai_sync_config</field>
<field name="value">sync</field>
</record>
</data>
</odoo>

View File

@@ -17,7 +17,7 @@
<p>Pleas answer me any question.</p>]]></field>
</record>
<record model="mail.channel.member" id="channel_member_chatgtp_channel_for_admin">
<record model="mail.channel.partner" id="channel_member_chatgtp_channel_for_admin">
<field name="partner_id" ref="base.partner_admin"/>
<field name="channel_id" ref="app_chatgpt.channel_chatgpt"/>
<field name="fetched_message_id" ref="app_chatgpt.module_install_notification"/>
@@ -25,7 +25,7 @@
</record>
<record model="mail.channel" id="app_chatgpt.channel_chatgpt">
<field name="group_ids" eval="[Command.link(ref('base.group_user'))]"/>
<field name="group_ids" eval="[(4, ref('base.group_user'))]"/>
</record>
</data>
</odoo>

View File

@@ -6,13 +6,14 @@
<field name="image_1920" type="base64" file="app_chatgpt/static/description/chatgpt.png"/>
</record>
<record id="user_chatgpt" model="res.users">
<field name="login">chatgpt@sunpop.cn</field>
<field name="login">chatgpt@example.com</field>
<field name="email">chatgpt@example.com</field>
<field name="password">chatgpt</field>
<field name="partner_id" ref="app_chatgpt.partner_chatgpt"/>
<field name="gpt_id" ref="app_chatgpt.chatgpt_robot"/>
<field name="company_id" ref="base.main_company"/>
<field name="company_ids" eval="[Command.link(ref('base.main_company'))]"/>
<field name="groups_id" eval="[Command.link(ref('base.group_user'))]"/>
<field name="company_ids" eval="[(4, ref('base.main_company'))]"/>
<field name="groups_id" eval="[(4, ref('base.group_user'))]"/>
</record>
<record id="partner_chatgpt1" model="res.partner">
@@ -21,14 +22,14 @@
</record>
<record id="user_chatgpt1" model="res.users">
<field name="login">chatgpt1@sunpop.cn</field>
<field name="email">chatgpt1@sunpop.cn</field>
<field name="email">chatgpt1@example.com</field>
<field name="login">chatgpt1@example.com</field>
<field name="password">chatgpt</field>
<field name="partner_id" ref="app_chatgpt.partner_chatgpt1"/>
<field name="gpt_id" ref="app_chatgpt.chatgpt_robot1"/>
<field name="company_id" ref="base.main_company"/>
<field name="company_ids" eval="[Command.link(ref('base.main_company'))]"/>
<field name="groups_id" eval="[Command.link(ref('base.group_user'))]"/>
<field name="company_ids" eval="[(4, ref('base.main_company'))]"/>
<field name="groups_id" eval="[(4, ref('base.group_user'))]"/>
</record>
<record id="partner_chatgpt2" model="res.partner">
@@ -37,14 +38,30 @@
</record>
<record id="user_chatgpt2" model="res.users">
<field name="login">chatgpt2@sunpop.cn</field>
<field name="email">chatgpt2@sunpop.cn</field>
<field name="login">chatgpt2@example.com</field>
<field name="email">chatgpt2@example.com</field>
<field name="password">chatgpt</field>
<field name="partner_id" ref="app_chatgpt.partner_chatgpt2"/>
<field name="gpt_id" ref="app_chatgpt.chatgpt_robot2"/>
<field name="company_id" ref="base.main_company"/>
<field name="company_ids" eval="[Command.link(ref('base.main_company'))]"/>
<field name="groups_id" eval="[Command.link(ref('base.group_user'))]"/>
<field name="company_ids" eval="[(4, ref('base.main_company'))]"/>
<field name="groups_id" eval="[(4,ref('base.group_user'))]"/>
</record>
<record id="partner_chatgpt3" model="res.partner">
<field name="name">ChatGPT Azure</field>
<field name="image_1920" type="base64" file="app_chatgpt/static/description/chatgpt.png"/>
</record>
<record id="user_chatgpt3" model="res.users">
<field name="login">chatgpt3@example.com</field>
<field name="email">chatgpt3@example.com</field>
<field name="password">chatgpt</field>
<field name="partner_id" ref="app_chatgpt.partner_chatgpt3"/>
<field name="gpt_id" ref="app_chatgpt.chatgpt_robot3"/>
<field name="company_id" ref="base.main_company"/>
<field name="company_ids" eval="[(4, ref('base.main_company'))]"/>
<field name="groups_id" eval="[(4, ref('base.group_user'))]"/>
</record>
</data>
</odoo>

View File

@@ -4,10 +4,10 @@
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 16.0+e-20230213\n"
"Project-Id-Version: Odoo Server 16.0+e-20230320\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-03-02 10:08+0000\n"
"PO-Revision-Date: 2023-03-02 10:08+0000\n"
"POT-Creation-Date: 2023-03-30 10:30+0000\n"
"PO-Revision-Date: 2023-03-30 10:30+0000\n"
"Last-Translator: \n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
@@ -15,6 +15,21 @@ msgstr ""
"Content-Transfer-Encoding: \n"
"Plural-Forms: \n"
#. module: app_chatgpt
#: model:ir.model.fields,help:app_chatgpt.field_ai_robot__ai_model
msgid ""
"\n"
"GPT-4: Can understand Image, generate natural language or code.\n"
"GPT-3.5: A set of models that improve on GPT-3 and can understand as well as generate natural language or code\n"
"DALL·E: A model that can generate and edit images given a natural language prompt\n"
"Whisper: A model that can convert audio into text\n"
"Embeddings:\tA set of models that can convert text into a numerical form\n"
"CodexLimited: A set of models that can understand and generate code, including translating natural language to code\n"
"Moderation: A fine-tuned model that can detect whether text may be sensitive or unsafe\n"
"GPT-3\tA set of models that can understand and generate natural language\n"
" "
msgstr ""
#. module: app_chatgpt
#. odoo-javascript
#: code:addons/app_chatgpt/static/src/models_data/emoji_data.js:0
@@ -405,6 +420,16 @@ msgstr ""
msgid "ABCD"
msgstr ""
#. module: app_chatgpt
#: model:ir.model.fields,field_description:app_chatgpt.field_ai_robot__ai_model
msgid "AI Model"
msgstr ""
#. module: app_chatgpt
#: model:ir.model.fields,field_description:app_chatgpt.field_ai_robot__provider
msgid "AI Provider"
msgstr ""
#. module: app_chatgpt
#. odoo-javascript
#: code:addons/app_chatgpt/static/src/models_data/emoji_data.js:0
@@ -414,11 +439,14 @@ msgstr ""
#. module: app_chatgpt
#: model:ir.model.fields,field_description:app_chatgpt.field_ai_robot__openapi_api_key
#: model:ir.model.fields,field_description:app_chatgpt.field_res_config_settings__openapi_api_key
#: model_terms:ir.ui.view,arch_db:app_chatgpt.is_res_config_settings_view
msgid "API Key"
msgstr ""
#. module: app_chatgpt
#: model:ir.model.fields,field_description:app_chatgpt.field_ai_robot__api_version
msgid "API Version"
msgstr ""
#. module: app_chatgpt
#. odoo-javascript
#: code:addons/app_chatgpt/static/src/models_data/emoji_data.js:0
@@ -448,10 +476,20 @@ msgstr ""
msgid "Africa"
msgstr ""
#. module: app_chatgpt
#: model_terms:ir.ui.view,arch_db:app_chatgpt.is_res_config_settings_view
msgid "Ai Center(Chatgpt)"
msgstr "Ai服务中心(Chatgpt)"
#. module: app_chatgpt
#: model_terms:ir.ui.view,arch_db:app_chatgpt.is_res_config_settings_view
msgid "Seconds"
msgstr "秒"
#. module: app_chatgpt
#: model:ir.model.fields.selection,name:app_chatgpt.selection__res_users__gpt_policy__all
msgid "All Users"
msgstr ""
msgstr "所有用户"
#. module: app_chatgpt
#: model:ir.model.fields,field_description:app_chatgpt.field_res_users__gpt_policy
@@ -502,6 +540,11 @@ msgstr ""
msgid "Asia"
msgstr ""
#. module: app_chatgpt
#: model:ir.model.fields.selection,name:app_chatgpt.selection__res_config_settings__openai_sync_config__async
msgid "Asynchronous"
msgstr "异步响应"
#. module: app_chatgpt
#. odoo-javascript
#: code:addons/app_chatgpt/static/src/models_data/emoji_data.js:0
@@ -510,6 +553,11 @@ msgstr ""
msgid "Australia"
msgstr ""
#. module: app_chatgpt
#: model:ir.model.fields.selection,name:app_chatgpt.selection__ai_robot__provider__azure
msgid "Azure"
msgstr ""
#. module: app_chatgpt
#. odoo-javascript
#: code:addons/app_chatgpt/static/src/models_data/emoji_data.js:0
@@ -615,10 +663,14 @@ msgstr ""
#. module: app_chatgpt
#: model_terms:ir.ui.view,arch_db:app_chatgpt.app_chatgpt_res_users_form
#: model_terms:ir.ui.view,arch_db:app_chatgpt.is_res_config_settings_view
msgid "ChatGPT"
msgstr ""
#. module: app_chatgpt
#: model:ai.robot,name:app_chatgpt.chatgpt_robot3
msgid "ChatGPT Azure"
msgstr ""
#. module: app_chatgpt
#: model:ai.robot,name:app_chatgpt.chatgpt_robot1
msgid "ChatGPT Coding"
@@ -648,6 +700,36 @@ msgstr ""
msgid "ChatGpt Training"
msgstr "ChatGpt训练"
#. module: app_chatgpt
#: model:ir.model.fields.selection,name:app_chatgpt.selection__ai_robot__ai_model__code-davinci-002
msgid "Chatgpt 2 Code Optimized"
msgstr ""
#. module: app_chatgpt
#: model:ir.model.fields.selection,name:app_chatgpt.selection__ai_robot__ai_model__text-davinci-002
msgid "Chatgpt 2 Davinci"
msgstr ""
#. module: app_chatgpt
#: model:ir.model.fields.selection,name:app_chatgpt.selection__ai_robot__ai_model__text-davinci-003
msgid "Chatgpt 3 Davinci"
msgstr ""
#. module: app_chatgpt
#: model:ir.model.fields.selection,name:app_chatgpt.selection__ai_robot__ai_model__gpt-3_5-turbo
msgid "Chatgpt 3.5 Turbo"
msgstr ""
#. module: app_chatgpt
#: model:ir.model.fields.selection,name:app_chatgpt.selection__ai_robot__ai_model__gpt-3_5-turbo-0301
msgid "Chatgpt 3.5 Turbo on 20230301"
msgstr ""
#. module: app_chatgpt
#: model:ir.model.fields.selection,name:app_chatgpt.selection__ai_robot__ai_model__gpt-4
msgid "Chatgpt 4"
msgstr ""
#. module: app_chatgpt
#. odoo-javascript
#: code:addons/app_chatgpt/static/src/models_data/emoji_data.js:0
@@ -710,6 +792,11 @@ msgstr ""
msgid "DVD"
msgstr ""
#. module: app_chatgpt
#: model:ir.model.fields.selection,name:app_chatgpt.selection__ai_robot__ai_model__dall-e2
msgid "Dall-E Image"
msgstr ""
#. module: app_chatgpt
#. odoo-javascript
#: code:addons/app_chatgpt/static/src/models_data/emoji_data.js:0
@@ -764,6 +851,16 @@ msgstr ""
msgid "END arrow"
msgstr ""
#. module: app_chatgpt
#: model:ir.model.fields,field_description:app_chatgpt.field_ai_robot__endpoint
msgid "End Point"
msgstr ""
#. module: app_chatgpt
#: model:ir.model.fields,field_description:app_chatgpt.field_ai_robot__engine
msgid "Engine"
msgstr ""
#. module: app_chatgpt
#. odoo-javascript
#: code:addons/app_chatgpt/static/src/models_data/emoji_data.js:0
@@ -822,6 +919,11 @@ msgstr ""
msgid "Ferris"
msgstr ""
#. module: app_chatgpt
#: model:ir.model.fields,field_description:app_chatgpt.field_ai_robot__is_filtering
msgid "Filter Sensitive Words"
msgstr "是否启用敏感词过滤"
#. module: app_chatgpt
#. odoo-javascript
#: code:addons/app_chatgpt/static/src/models_data/emoji_data.js:0
@@ -917,6 +1019,11 @@ msgstr ""
msgid "ILY"
msgstr ""
#. module: app_chatgpt
#: model:ir.model.fields,help:app_chatgpt.field_ai_robot__engine
msgid "If use Azure, Please input the Model deployment name."
msgstr ""
#. module: app_chatgpt
#. odoo-javascript
#: code:addons/app_chatgpt/static/src/models_data/emoji_data.js:0
@@ -1244,6 +1351,11 @@ msgstr ""
msgid "Mahjong red dragon"
msgstr ""
#. module: app_chatgpt
#: model:ir.model.fields,field_description:app_chatgpt.field_ai_robot__max_length
msgid "Max Length"
msgstr ""
#. module: app_chatgpt
#: model:ir.model,name:app_chatgpt.model_mail_message
msgid "Message"
@@ -1365,6 +1477,13 @@ msgstr ""
msgid "Name"
msgstr ""
#. module: app_chatgpt
#. odoo-python
#: code:addons/app_chatgpt/models/ai_robot.py:0
#, python-format
msgid "No robot provider found"
msgstr "没有设置Ai接口供应方"
#. module: app_chatgpt
#. odoo-javascript
#: code:addons/app_chatgpt/static/src/models_data/emoji_data.js:0
@@ -1436,8 +1555,13 @@ msgid "Objects"
msgstr ""
#. module: app_chatgpt
#: model_terms:ir.ui.view,arch_db:app_chatgpt.is_res_config_settings_view
msgid "OpenAPI API Key"
#: model:ir.model.fields.selection,name:app_chatgpt.selection__ai_robot__provider__openai
msgid "OpenAI"
msgstr ""
#. module: app_chatgpt
#: model_terms:ir.ui.view,arch_db:app_chatgpt.ai_robot_form_view
msgid "OpenAI Document"
msgstr ""
#. module: app_chatgpt
@@ -1487,9 +1611,22 @@ msgstr ""
msgid "Pisces"
msgstr ""
#. module: app_chatgpt
#. odoo-python
#: code:addons/app_chatgpt/models/ai_robot.py:0
#, python-format
msgid "Please Set your AI robot's API Version first."
msgstr ""
#. module: app_chatgpt
#. odoo-python
#: code:addons/app_chatgpt/models/ai_robot.py:0
#, python-format
msgid "Please Set your AI robot's endpoint first."
msgstr ""
#. module: app_chatgpt
#: model:ir.model.fields,help:app_chatgpt.field_ai_robot__openapi_api_key
#: model:ir.model.fields,help:app_chatgpt.field_res_config_settings__openapi_api_key
msgid "Provide the API key here"
msgstr ""
@@ -1582,6 +1719,16 @@ msgstr ""
msgid "Selected Users"
msgstr ""
#. module: app_chatgpt
#: model:ir.model.fields,field_description:app_chatgpt.field_ai_robot__sensitive_words
msgid "Sensitive Words Plus"
msgstr "额外敏感词"
#. module: app_chatgpt
#: model:ir.model.fields,help:app_chatgpt.field_ai_robot__sensitive_words
msgid "Sensitive word filtering. Separate keywords with a carriage return."
msgstr "敏感词过滤。请用回车符分隔关键词。"
#. module: app_chatgpt
#: model:ir.model.fields,field_description:app_chatgpt.field_ai_robot__sequence
msgid "Sequence"
@@ -1645,6 +1792,16 @@ msgstr ""
msgid "Symbols"
msgstr ""
#. module: app_chatgpt
#: model:ir.model.fields,field_description:app_chatgpt.field_res_config_settings__openai_sync_config
msgid "Sync Config"
msgstr "同步配置"
#. module: app_chatgpt
#: model:ir.model.fields.selection,name:app_chatgpt.selection__res_config_settings__openai_sync_config__sync
msgid "Synchronous"
msgstr "同步响应"
#. module: app_chatgpt
#. odoo-javascript
#: code:addons/app_chatgpt/static/src/models_data/emoji_data.js:0
@@ -1805,7 +1962,7 @@ msgstr ""
#. module: app_chatgpt
#: model:ir.model,name:app_chatgpt.model_res_users
msgid "User"
msgstr "用户"
msgstr ""
#. module: app_chatgpt
#. odoo-javascript
@@ -24792,6 +24949,11 @@ msgstr ""
msgid "upwards button"
msgstr ""
#. module: app_chatgpt
#: model:ir.model.fields,help:app_chatgpt.field_ai_robot__sensitive_words
msgid "Use base Filter in dir models/lib/sensi_words.txt"
msgstr "使用此文件进行基础过滤 models/lib/sensi_words.txt"
#. module: app_chatgpt
#. odoo-javascript
#: code:addons/app_chatgpt/static/src/models_data/emoji_data.js:0
@@ -27000,12 +27162,17 @@ msgstr ""
#. module: app_chatgpt
#: model:ir.model.fields,field_description:app_chatgpt.field_res_config_settings__openapi_context_timeout
#: model_terms:ir.ui.view,arch_db:app_chatgpt.is_res_config_settings_view
msgid "上下文连接超时"
msgstr ""
msgid "Connect Timout"
msgstr "上下文连接超时"
#. module: app_chatgpt
#: model_terms:ir.ui.view,arch_db:app_chatgpt.is_res_config_settings_view
msgid "上下文连接超时 秒数"
msgid "After timeout seconds then Disconnect"
msgstr "上下文连接超时(秒)"
#. module: app_chatgpt
#: model_terms:ir.ui.view,arch_db:app_chatgpt.is_res_config_settings_view
msgid "同步配置"
msgstr ""
#. module: app_chatgpt

View File

@@ -1,5 +1,4 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2020-Present InTechual Solutions. (<https://intechualsolutions.com/>)
from . import mail_channel
from . import res_config_settings

View File

@@ -1,7 +1,13 @@
# -*- coding: utf-8 -*-
import requests
import requests, json
import openai
from odoo import api, fields, models, _
from odoo.exceptions import UserError
from .lib.WordsSearch import WordsSearch
import logging
_logger = logging.getLogger(__name__)
class AiRobot(models.Model):
@@ -9,9 +15,10 @@ class AiRobot(models.Model):
_description = 'Gpt Robot'
_order = 'sequence, name'
name = fields.Char(string='Name', translate=True)
provider = fields.Selection(string="AI Provider", selection=[('openai', 'OpenAI')], required=True, default='openai')
name = fields.Char(string='Name', translate=True, required=True)
provider = fields.Selection(string="AI Provider", selection=[('openai', 'OpenAI'), ('azure', 'Azure')], required=True, default='openai')
ai_model = fields.Selection(string="AI Model", selection=[
('gpt-4', 'Chatgpt 4'),
('gpt-3.5-turbo', 'Chatgpt 3.5 Turbo'),
('gpt-3.5-turbo-0301', 'Chatgpt 3.5 Turbo on 20230301'),
('text-davinci-003', 'Chatgpt 3 Davinci'),
@@ -20,6 +27,7 @@ class AiRobot(models.Model):
('dall-e2', 'Dall-E Image'),
], required=True, default='gpt-3.5-turbo',
help="""
GPT-4: Can understand Image, generate natural language or code.
GPT-3.5: A set of models that improve on GPT-3 and can understand as well as generate natural language or code
DALL·E: A model that can generate and edit images given a natural language prompt
Whisper: A model that can convert audio into text
@@ -30,10 +38,126 @@ GPT-3 A set of models that can understand and generate natural language
""")
openapi_api_key = fields.Char(string="API Key", help="Provide the API key here")
temperature = fields.Float(string='Temperature', default=0.9)
max_length = fields.Integer('Max Length', default=300)
endpoint = fields.Char('End Point', default='https://api.openai.com/v1/chat/completions')
engine = fields.Char('Engine', help='If use Azure, Please input the Model deployment name.')
api_version = fields.Char('API Version', default='2022-12-01')
sequence = fields.Integer('Sequence', help="Determine the display order", default=10)
sensitive_words = fields.Text('Sensitive Words Plus', help='Sensitive word filtering. Separate keywords with a carriage return.')
is_filtering = fields.Boolean('Filter Sensitive Words', default=False, help='Use base Filter in dir models/lib/sensi_words.txt')
def action_disconnect(self):
requests.delete('https://chatgpt.com/v1/disconnect')
def get_ai(self, data, partner_name='odoo', *args):
# 通用方法
self.ensure_one()
if hasattr(self, 'get_%s' % self.provider):
return getattr(self, 'get_%s' % self.provider)(data, partner_name, *args)
else:
return _('No robot provider found')
def get_openai(self, data, partner_name='odoo', *args):
self.ensure_one()
headers = {"Content-Type": "application/json", "Authorization": f"Bearer {self.openapi_api_key}"}
R_TIMEOUT = 300
o_url = self.endpoint or "https://api.openai.com/v1/chat/completions"
# 以下处理 open ai
# 获取模型信息
# list_model = requests.get("https://api.openai.com/v1/models", headers=headers)
# model_info = requests.get("https://api.openai.com/v1/models/%s" % ai_model, headers=headers)
if self.ai_model == 'dall-e2':
# todo: 处理 图像引擎,主要是返回参数到聊天中
# image_url = response['data'][0]['url']
# https://platform.openai.com/docs/guides/images/introduction
pdata = {
"prompt": data,
"n": 3,
"size": "1024x1024",
}
return '建设中'
elif self.ai_model in ['gpt-3.5-turbo', 'gpt-3.5-turbo-0301']:
pdata = {
"model": self.ai_model,
"messages": [{"role": "user", "content": data}],
"temperature": 0.9,
"max_tokens": self.max_length or 1000,
"top_p": 1,
"frequency_penalty": 0.0,
"presence_penalty": 0.6,
"user": partner_name,
"stop": ["Human:", "AI:"]
}
_logger.warning('=====================open input pdata: %s' % pdata)
response = requests.post(o_url, data=json.dumps(pdata), headers=headers, timeout=R_TIMEOUT)
res = response.json()
if 'choices' in res:
# for rec in res:
# res = rec['message']['content']
res = '\n'.join([x['message']['content'] for x in res['choices']])
res = self.filter_sensitive_words(res)
return res
else:
pdata = {
"model": self.ai_model,
"prompt": data,
"temperature": 0.9,
"max_tokens": self.max_length or 1000,
"top_p": 1,
"frequency_penalty": 0.0,
"presence_penalty": 0.6,
"user": partner_name,
"stop": ["Human:", "AI:"]
}
response = requests.post(o_url, data=json.dumps(pdata), headers=headers, timeout=R_TIMEOUT)
res = response.json()
if 'choices' in res:
res = '\n'.join([x['text'] for x in res['choices']])
res = self.filter_sensitive_words(res)
return res
return "获取结果超时,请重新跟我聊聊。"
def get_azure(self, data, partner_name='odoo', *args):
self.ensure_one()
# only for azure
openai.api_type = self.provider
if not self.endpoint:
raise UserError(_("Please Set your AI robot's endpoint first."))
openai.api_base = self.endpoint
if not self.api_version:
raise UserError(_("Please Set your AI robot's API Version first."))
openai.api_version = self.api_version
openai.api_key = self.openapi_api_key
response = openai.Completion.create(
engine=self.engine,
prompt=data,
temperature=self.temperature or 0.9,
max_tokens=self.max_length or 600,
top_p=0.5,
frequency_penalty=0,
presence_penalty=0, stop=["Human:", "AI:"])
_logger.warning('=====================azure input data: %s' % data)
if 'choices' in response:
res = response['choices'][0]['text'].replace(' .', '.').strip()
res = self.filter_sensitive_words(res)
return res
@api.onchange('provider')
def _onchange_provider(self):
if self.provider == 'openai':
self.endpoint = 'https://api.openai.com/v1/chat/completions'
elif self.provider == 'azure':
self.endpoint = 'https://odoo.openai.azure.com'
def filter_sensitive_words(self, data):
if self.is_filtering:
search = WordsSearch()
s = self.sensitive_words
search.SetKeywords(s.split('\n'))
result = search.Replace(text=data)
return result
else:
return data

View File

@@ -0,0 +1,296 @@
#!/usr/bin/env python
# -*- coding:utf-8 -*-
# ToolGood.Words.WordsSearch.py
# 2020, Lin Zhijun, https://github.com/toolgood/ToolGood.Words
# Licensed under the Apache License 2.0
# 更新日志
# 2020.04.06 第一次提交
# 2020.05.16 修改支持大于0xffff的字符
import os
__all__ = ['WordsSearch']
__author__ = 'Lin Zhijun'
__date__ = '2020.05.16'
class TrieNode():
def __init__(self):
self.Index = 0
self.Index = 0
self.Layer = 0
self.End = False
self.Char = ''
self.Results = []
self.m_values = {}
self.Failure = None
self.Parent = None
def Add(self, c):
if c in self.m_values:
return self.m_values[c]
node = TrieNode()
node.Parent = self
node.Char = c
self.m_values[c] = node
return node
def SetResults(self, index):
if (self.End == False):
self.End = True
self.Results.append(index)
class TrieNode2():
def __init__(self):
self.End = False
self.Results = []
self.m_values = {}
self.minflag = 0xffff
self.maxflag = 0
def Add(self, c, node3):
if (self.minflag > c):
self.minflag = c
if (self.maxflag < c):
self.maxflag = c
self.m_values[c] = node3
def SetResults(self, index):
if (self.End == False):
self.End = True
if (index in self.Results) == False:
self.Results.append(index)
def HasKey(self, c):
return c in self.m_values
def TryGetValue(self, c):
if (self.minflag <= c and self.maxflag >= c):
if c in self.m_values:
return self.m_values[c]
return None
class WordsSearch():
def __init__(self):
self._first = {}
self._keywords = []
self._indexs = []
def SetKeywords(self, keywords):
keyword_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'sensi_words.txt')
s = open(keyword_path, 'r+', encoding='utf-8').read().split('\n')
self._keywords = s + keywords
# self._keywords = keywords
self._indexs = []
for i in range(len(keywords)):
self._indexs.append(i)
root = TrieNode()
allNodeLayer = {}
for i in range(len(self._keywords)): # for (i = 0; i < _keywords.length; i++)
p = self._keywords[i]
nd = root
for j in range(len(p)): # for (j = 0; j < p.length; j++)
nd = nd.Add(ord(p[j]))
if (nd.Layer == 0):
nd.Layer = j + 1
if nd.Layer in allNodeLayer:
allNodeLayer[nd.Layer].append(nd)
else:
allNodeLayer[nd.Layer] = []
allNodeLayer[nd.Layer].append(nd)
nd.SetResults(i)
allNode = []
allNode.append(root)
for key in allNodeLayer.keys():
for nd in allNodeLayer[key]:
allNode.append(nd)
allNodeLayer = None
for i in range(len(allNode)): # for (i = 0; i < allNode.length; i++)
if i == 0:
continue
nd = allNode[i]
nd.Index = i
r = nd.Parent.Failure
c = nd.Char
while (r != None and (c in r.m_values) == False):
r = r.Failure
if (r == None):
nd.Failure = root
else:
nd.Failure = r.m_values[c]
for key2 in nd.Failure.Results:
nd.SetResults(key2)
root.Failure = root
allNode2 = []
for i in range(len(allNode)): # for (i = 0; i < allNode.length; i++)
allNode2.append(TrieNode2())
for i in range(len(allNode2)): # for (i = 0; i < allNode2.length; i++)
oldNode = allNode[i]
newNode = allNode2[i]
for key in oldNode.m_values:
index = oldNode.m_values[key].Index
newNode.Add(key, allNode2[index])
for index in range(len(oldNode.Results)): # for (index = 0; index < oldNode.Results.length; index++)
item = oldNode.Results[index]
newNode.SetResults(item)
oldNode = oldNode.Failure
while oldNode != root:
for key in oldNode.m_values:
if (newNode.HasKey(key) == False):
index = oldNode.m_values[key].Index
newNode.Add(key, allNode2[index])
for index in range(len(oldNode.Results)):
item = oldNode.Results[index]
newNode.SetResults(item)
oldNode = oldNode.Failure
allNode = None
root = None
# first = []
# for index in range(65535):# for (index = 0; index < 0xffff; index++)
# first.append(None)
# for key in allNode2[0].m_values :
# first[key] = allNode2[0].m_values[key]
self._first = allNode2[0]
def FindFirst(self, text):
ptr = None
for index in range(len(text)): # for (index = 0; index < text.length; index++)
t = ord(text[index]) # text.charCodeAt(index)
tn = None
if (ptr == None):
tn = self._first.TryGetValue(t)
else:
tn = ptr.TryGetValue(t)
if (tn == None):
tn = self._first.TryGetValue(t)
if (tn != None):
if (tn.End):
item = tn.Results[0]
keyword = self._keywords[item]
return {"Keyword": keyword, "Success": True, "End": index, "Start": index + 1 - len(keyword), "Index": self._indexs[item]}
ptr = tn
return None
def FindAll(self, text):
ptr = None
list = []
for index in range(len(text)): # for (index = 0; index < text.length; index++)
t = ord(text[index]) # text.charCodeAt(index)
tn = None
if (ptr == None):
tn = self._first.TryGetValue(t)
else:
tn = ptr.TryGetValue(t)
if (tn == None):
tn = self._first.TryGetValue(t)
if (tn != None):
if (tn.End):
for j in range(len(tn.Results)): # for (j = 0; j < tn.Results.length; j++)
item = tn.Results[j]
keyword = self._keywords[item]
list.append({"Keyword": keyword, "Success": True, "End": index, "Start": index + 1 - len(keyword), "Index": self._indexs[item]})
ptr = tn
return list
def ContainsAny(self, text):
ptr = None
for index in range(len(text)): # for (index = 0; index < text.length; index++)
t = ord(text[index]) # text.charCodeAt(index)
tn = None
if (ptr == None):
tn = self._first.TryGetValue(t)
else:
tn = ptr.TryGetValue(t)
if (tn == None):
tn = self._first.TryGetValue(t)
if (tn != None):
if (tn.End):
return True
ptr = tn
return False
def Replace(self, text, replaceChar='*'):
result = list(text)
ptr = None
for i in range(len(text)): # for (i = 0; i < text.length; i++)
t = ord(text[i]) # text.charCodeAt(index)
tn = None
if (ptr == None):
tn = self._first.TryGetValue(t)
else:
tn = ptr.TryGetValue(t)
if (tn == None):
tn = self._first.TryGetValue(t)
if (tn != None):
if (tn.End):
maxLength = len(self._keywords[tn.Results[0]])
start = i + 1 - maxLength
for j in range(start, i + 1): # for (j = start; j <= i; j++)
result[j] = replaceChar
ptr = tn
return ''.join(result)
if __name__ == "__main__":
s = "中国|国人|zg人|乾清宫"
test = "我是中国人"
search = WordsSearch()
search.SetKeywords(s.split('|'))
print("----------------------------------- WordsSearch -----------------------------------")
print("WordsSearch FindFirst is run.")
f = search.FindFirst(test)
if f["Keyword"] != "中国":
print("WordsSearch FindFirst is error.............................")
print("WordsSearch FindFirst is run.")
all = search.FindAll("乾清宫")
if all[0]["Keyword"] != "乾清宫":
print("WordsSearch FindFirst is error.............................")
print("WordsSearch FindAll is run.")
all = search.FindAll(test)
if all[0]["Keyword"] != "中国":
print("WordsSearch FindAll is error.............................")
if all[1]["Keyword"] != "国人":
print("WordsSearch FindAll is error.............................")
if all[0]["Start"] != 2:
print("WordsSearch FindAll is error.............................")
if all[0]["End"] != 3:
print("WordsSearch FindAll is error.............................")
if len(all) != 2:
print("WordsSearch FindAll is error.............................")
print("WordsSearch ContainsAny is run.")
b = search.ContainsAny(test)
if b == False:
print("WordsSearch ContainsAny is error.............................")
print("WordsSearch Replace is run.")
txt = search.Replace(test)
if (txt != "我是***"):
print("WordsSearch Replace is error.............................")
print("----------------------------------- Test End -----------------------------------")

File diff suppressed because it is too large Load Diff

View File

@@ -1,12 +1,12 @@
# -*- coding: utf-8 -*-
import openai
import requests,json
import requests, json
import datetime
# from transformers import TextDavinciTokenizer, TextDavinciModel
from odoo import api, fields, models, _
from odoo.exceptions import UserError
import logging
_logger = logging.getLogger(__name__)
@@ -14,63 +14,6 @@ _logger = logging.getLogger(__name__)
class Channel(models.Model):
_inherit = 'mail.channel'
@api.model
def get_openai(self, api_key, ai_model, data, user="Odoo"):
headers = {"Content-Type": "application/json", "Authorization": f"Bearer {api_key}"}
R_TIMEOUT = 5
if ai_model == 'dall-e2':
# todo: 处理 图像引擎,主要是返回参数到聊天中
# image_url = response['data'][0]['url']
# https://platform.openai.com/docs/guides/images/introduction
pdata = {
"prompt": data,
"n": 3,
"size": "1024x1024",
}
return '建设中'
elif ai_model in ['gpt-3.5-turbo', 'gpt-3.5-turbo-0301']:
pdata = {
"model": ai_model,
"messages": [{"role": "user", "content": data}],
"temperature": 0.9,
"max_tokens": 2000,
"top_p": 1,
"frequency_penalty": 0.0,
"presence_penalty": 0.6,
"user": user,
"stop": ["Human:", "AI:"]
}
response = requests.post("https://api.openai.com/v1/chat/completions", data=json.dumps(pdata), headers=headers, timeout=R_TIMEOUT)
res = response.json()
if 'choices' in res:
# for rec in res:
# res = rec['message']['content']
res = '\n'.join([x['message']['content'] for x in res['choices']])
return res
else:
pdata = {
"model": ai_model,
"prompt": data,
"temperature": 0.9,
"max_tokens": 2000,
"top_p": 1,
"frequency_penalty": 0.0,
"presence_penalty": 0.6,
"user": user,
"stop": ["Human:", "AI:"]
}
response = requests.post("https://api.openai.com/v1/completions", data=json.dumps(pdata), headers=headers, timeout=R_TIMEOUT)
res = response.json()
if 'choices' in res:
res = '\n'.join([x['text'] for x in res['choices']])
return res
# 获取模型信息
# list_model = requests.get("https://api.openai.com/v1/models", headers=headers)
# model_info = requests.get("https://api.openai.com/v1/models/%s" % ai_model, headers=headers)
return "获取结果超时,请重新跟我聊聊。"
@api.model
def get_openai_context(self, channel_id, partner_chatgpt, current_prompt, seconds=600):
afterTime = fields.Datetime.now() - datetime.timedelta(seconds=seconds)
@@ -101,19 +44,11 @@ class Channel(models.Model):
return '\n'.join(prompt[::-1])
def get_chatgpt_answer(self, prompt, partner_name):
response = openai.Completion.create(
model="text-davinci-003",
prompt=prompt,
temperature=0.6,
max_tokens=3000,
top_p=1,
frequency_penalty=0,
presence_penalty=0,
user=partner_name,
)
res = response['choices'][0]['text']
return res
def get_ai(self, ai, prompt, partner_name, channel, user_id, message):
res = ai.get_ai(prompt, partner_name)
if res:
res = res.replace('\n', '<br/>')
channel.with_user(user_id).message_post(body=res, message_type='comment', subtype_xmlid='mail.mt_comment', parent_id=message.id)
def _notify_thread(self, message, msg_vals=False, **kwargs):
rdata = super(Channel, self)._notify_thread(message, msg_vals=msg_vals, **kwargs)
@@ -121,7 +56,7 @@ class Channel(models.Model):
to_partner_id = self.env['res.partner']
user_id = self.env['res.users']
author_id = msg_vals.get('author_id')
gpt_id = self.env['ai.robot']
ai = self.env['ai.robot']
channel_type = self.channel_type
if channel_type == 'chat':
channel_partner_ids = self.channel_partner_ids
@@ -132,7 +67,7 @@ class Channel(models.Model):
gpt_wl_users = user_id.gpt_wl_users
is_allow = message.create_uid.id in gpt_wl_users.ids
if gpt_policy == 'all' or (gpt_policy == 'limit' and is_allow):
gpt_id = user_id.gpt_id
ai = user_id.gpt_id
elif channel_type in ['group', 'channel']:
# partner_ids = @ ids
@@ -147,14 +82,10 @@ class Channel(models.Model):
is_allow = message.create_uid.id in gpt_wl_users.ids
to_partner_id = user_id.partner_id
if gpt_policy == 'all' or (gpt_policy == 'limit' and is_allow):
gpt_id = user_id.gpt_id
ai = user_id.gpt_id
chatgpt_channel_id = self.env.ref('app_chatgpt.channel_chatgpt')
# print('author_id:',author_id)
# print('partner_chatgpt.id:',partner_chatgpt.id)
prompt = msg_vals.get('body')
# print('prompt:', prompt)
# print('-----')
@@ -162,8 +93,8 @@ class Channel(models.Model):
return rdata
# api_key = self.env['ir.config_parameter'].sudo().get_param('app_chatgpt.openapi_api_key')
api_key = ''
if gpt_id:
api_key = gpt_id.openapi_api_key
if ai:
api_key = ai.openapi_api_key
if not api_key:
_logger.warning(_("ChatGPT Robot【%s】have not set open api key."))
return rdata
@@ -171,29 +102,29 @@ class Channel(models.Model):
openapi_context_timeout = int(self.env['ir.config_parameter'].sudo().get_param('app_chatgpt.openapi_context_timeout')) or 600
except:
openapi_context_timeout = 600
sync_config = self.env['ir.config_parameter'].sudo().get_param('app_chatgpt.openai_sync_config')
openai.api_key = api_key
partner_name = ''
# print(msg_vals)
# print(msg_vals.get('record_name', ''))
# print('self.channel_type :',self.channel_type)
if gpt_id:
ai_model = gpt_id.ai_model or 'text-davinci-003'
# print('chatgpt_name:', chatgpt_name)
# if author_id != to_partner_id.id and (chatgpt_name in msg_vals.get('record_name', '') or 'ChatGPT' in msg_vals.get('record_name', '') ) and self.channel_type == 'chat':
if ai:
if author_id != to_partner_id.id and self.channel_type == 'chat':
_logger.info(f'私聊:author_id:{author_id},partner_chatgpt.id:{to_partner_id.id}')
try:
channel = self.env[msg_vals.get('model')].browse(msg_vals.get('res_id'))
if ai_model not in ['gpt-3.5-turbo', 'gpt-3.5-turbo-0301']:
prompt = self.get_openai_context(channel.id, to_partner_id.id, prompt, openapi_context_timeout)
# if ai_model not in ['gpt-3.5-turbo', 'gpt-3.5-turbo-0301']:
prompt = self.get_openai_context(channel.id, to_partner_id.id, prompt, openapi_context_timeout)
print(prompt)
# res = self.get_chatgpt_answer(prompt,partner_name)
res = self.get_openai(api_key, ai_model, prompt, partner_name)
res = res.replace('\n', '<br/>')
if sync_config == 'sync':
self.get_ai(ai, prompt, partner_name, channel, user_id, message)
else:
self.with_delay().get_ai(ai, prompt, partner_name, channel, user_id, message)
# res = ai.get_ai(prompt, partner_name)
# res = res.replace('\n', '<br/>')
# print('res:',res)
# print('channel:',channel)
channel.with_user(user_id).message_post(body=res, message_type='comment',subtype_xmlid='mail.mt_comment', parent_id=message.id)
# channel.with_user(user_id).message_post(body=res, message_type='comment',subtype_xmlid='mail.mt_comment', parent_id=message.id)
# channel.with_user(user_chatgpt).message_post(body=res, message_type='notification', subtype_xmlid='mail.mt_comment')
# channel.sudo().message_post(
# body=res,
@@ -204,17 +135,19 @@ class Channel(models.Model):
# self.with_user(user_chatgpt).message_post(body=res, message_type='comment', subtype_xmlid='mail.mt_comment')
except Exception as e:
raise UserError(_(e))
elif author_id != to_partner_id.id and msg_vals.get('model', '') == 'mail.channel' and msg_vals.get('res_id', 0) == chatgpt_channel_id.id:
_logger.info(f'频道群聊:author_id:{author_id},partner_chatgpt.id:{to_partner_id.id}')
try:
prompt = self.get_openai_context(chatgpt_channel_id.id, to_partner_id.id, prompt, openapi_context_timeout)
# print(prompt)
# res = self.get_chatgpt_answer(prompt, partner_name)
res = self.get_openai(api_key, ai_model, prompt, partner_name)
res = res.replace('\n', '<br/>')
chatgpt_channel_id.with_user(user_id).message_post(body=res, message_type='comment', subtype_xmlid='mail.mt_comment',parent_id=message.id)
if sync_config == 'sync':
self.get_ai(ai, prompt, 'odoo', chatgpt_channel_id, user_id, message)
else:
self.with_delay().get_ai(ai, prompt, 'odoo', chatgpt_channel_id, user_id, message)
# res = ai.get_ai(prompt, 'odoo')
# res = res.replace('\n', '<br/>')
# chatgpt_channel_id.with_user(user_id).message_post(body=res, message_type='comment', subtype_xmlid='mail.mt_comment', parent_id=message.id)
except Exception as e:
raise UserError(_(e))
return rdata

View File

@@ -1,5 +1,4 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2020-Present InTechual Solutions. (<https://intechualsolutions.com/>)
from odoo import fields, models
@@ -7,4 +6,8 @@ from odoo import fields, models
class ResConfigSettings(models.TransientModel):
_inherit = "res.config.settings"
openapi_context_timeout = fields.Integer(string="上下文连接超时", help="多少秒以内的聊天信息作为上下文继续", config_parameter="app_chatgpt.openapi_context_timeout")
openapi_context_timeout = fields.Integer(string="Connect Timout", help="多少秒以内的聊天信息作为上下文继续", config_parameter="app_chatgpt.openapi_context_timeout")
openai_sync_config = fields.Selection([
('sync', 'Synchronous'),
('async', 'Asynchronous')
], string='Sync Config', default='sync', config_parameter="app_chatgpt.openai_sync_config")

Binary file not shown.

Before

Width:  |  Height:  |  Size: 971 KiB

After

Width:  |  Height:  |  Size: 964 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 247 KiB

View File

@@ -2,9 +2,9 @@
<div class="oe_row oe_spaced" >
<div class="oe_span12">
<h2 class="oe_slogan"> Latest ChatGPT AI Center. GPT 3.5, Dall-E Image.Multi Robot Support. Chat and Training </h2>
<h3 class="oe_slogan"> Support chatgpt 3.5 turbo, text-davinci, DALL·E(Working Now.), Integration All ChatGpt Api </h3>
<h3 class="oe_slogan"> Support chatgpt 4 image. 3.5 turbo, text-davinci, DALL·E, Integration All ChatGpt Api. </h3>
<div class="oe_row">
<h3>Lastest update: v16.23.03.05</h3>
<h3>Lastest update: v16.23.03.16</h3>
<div class="oe_span12">
<img class="oe_demo oe_screenshot" style="max-height: 100%;" src="banner.gif">
</div>
@@ -18,7 +18,7 @@
</li>
<li>
<i class="fa fa-check-square-o text-primary"></i>
2. Multi Api support, Chatgpt 3.5 Turbo, Chatgpt 3 Davinci, Chatgpt 2 Code Optimized, 'Dall-E Image.
2. Multi Api support, Chatgpt 4, Chatgpt 3.5 Turbo, Chatgpt 3 Davinci, Chatgpt 2 Code Optimized, 'Dall-E Image.
</li>
<li>
<i class="fa fa-check-square-o text-primary"></i>
@@ -40,7 +40,14 @@
<i class="fa fa-check-square-o text-primary"></i>
7. Evaluation the ai robot to make better response. This training.
</li>
<li>
<i class="fa fa-check-square-o text-primary"></i>
8. Add api support Connect the Microsoft Azure OpenAI Service.
</li>
<li>
<i class="fa fa-check-square-o text-primary"></i>
9. Can set Synchronous or Asynchronous mode for Ai response.
</li>
<li>
<i class="fa fa-check-square-o text-primary"></i>
11. Multi-language Support. Multi-Company Support.
@@ -61,6 +68,16 @@
</div>
</section>
<section class="oe_container">
<div class="oe_row oe_spaced">
<h1 class="text-danger text-center">Easy to use Ai Robot with multi Provider. Easy chat, easy help</h1>
<h4 class="oe_slogan"> Open Ai for more smart. Microsoft Azure chatgpt for china user.</h4>
<div class="oe_demo oe_screenshot">
<img src="demob.jpg"/>
</div>
</div>
</section>
<section class="oe_container">
<div class="oe_row oe_spaced">
<h1 class="text-danger text-center">1. Multi ChatGpt openAI robot Connector. Chat and train.</h1>
@@ -149,6 +166,26 @@
</div>
</section>
<section class="oe_container">
<div class="oe_row oe_spaced">
<h1 class="text-danger text-center">8. Add api support Connect the Microsoft Azure OpenAI Service.</h1>
<h4 class="oe_slogan"> Azure openai add. It is for china and other country which no chatgpt service.</h4>
<div class="oe_demo oe_screenshot">
<img src="demo81.jpg"/>
</div>
</div>
</section>
<section class="oe_container">
<div class="oe_row oe_spaced">
<h1 class="text-danger text-center">9. Can set Synchronous or Asynchronous mode for Ai response.</h1>
<h4 class="oe_slogan"> Synchronous(default) mode can get response then ask question again. Asynchronous mode would make you do other thing when waiting for response.</h4>
<div class="oe_demo oe_screenshot">
<img src="demo91.jpg"/>
</div>
</div>
</section>
<section class="oe_container">
<div class="oe_row oe_spaced">
<h1 class="text-danger text-center">Multi-language Support..</h1>
@@ -191,7 +228,7 @@
</div>
<div class="oe_row oe_spaced text-center">
<h1>More Powerful addons, Make your odoo very easy to use, easy customize:
<a class="btn btn-primary mb16" href="http://www.odoo.com/apps/modules/browse?author=Sunpop.cn">Supop.cn Odoo Addons</a>
<a class="btn btn-primary mb16" href="http://www.odoo.com/apps/modules/browse?author=Sunpop.cn">Sunpop.cn Odoo Addons</a>
</h1>
</div>
</section>

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 223 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 232 KiB

View File

@@ -21857,55 +21857,6 @@ const emojisData0 = `{
"shortcodes": [
":thumbs_down:"
]
},
{
"category": "ChatGpt Training",
"codepoints": "👐",
"emoticons": [],
"keywords": [
"` + _lt("mark") + `",
"` + _lt("neutral") + `",
"` + _lt("hand") + `",
"` + _lt("open") + `",
"` + _lt("open hands") + `"
],
"name": "` + _lt("mark_as_neutral. open hands") + `",
"shortcodes": [
":open_hands:"
]
},
{
"category": "ChatGpt Training",
"codepoints": "👋",
"emoticons": [],
"keywords": [
"` + _lt("mark") + `",
"` + _lt("redundant") + `",
"` + _lt("hand") + `",
"` + _lt("wave") + `",
"` + _lt("waving") + `"
],
"name": "` + _lt("mark_as_redundant. waving hand") + `",
"shortcodes": [
":waving_hand:"
]
},
{
"category": "ChatGpt Training",
"codepoints": "🈵",
"emoticons": [],
"keywords": [
"` + _lt("mark") + `",
"` + _lt("unhelpful") + `",
"` + _lt("“no vacancy”") + `",
"` + _lt("ideograph") + `",
"` + _lt("Japanese") + `",
"` + _lt("満") + `"
],
"name": "` + _lt("mark_as_unhelpful. Need more answer") + `",
"shortcodes": [
":Japanese_“no_vacancy”_button:"
]
},`;
export const emojisData = JSON.parse(`[

View File

@@ -10,6 +10,7 @@
<field name="provider" optional="hide"/>
<field name="ai_model" optional="show"/>
<field name="openapi_api_key" password="True"/>
<field name="max_length" optional="show"/>
<field name="temperature"/>
</tree>
</field>
@@ -20,11 +21,13 @@
<field name="model">ai.robot</field>
<field name="arch" type="xml">
<form>
<header>
</header>
<sheet>
<group>
<group>
<field name="name"/>
<field name="openapi_api_key" password="True"/>
<field name="openapi_api_key" password="True" required="True"/>
<field name="temperature"/>
<field name="sequence"/>
</group>
@@ -37,6 +40,14 @@
<field name="provider"/>
<a href="https://platform.openai.com/docs/introduction" title="OpenAI Document" class="o_doc_link" target="_blank"></a>
</div>
<field name="max_length"/>
<field name="engine"/>
<field name="endpoint"/>
<field name="api_version"/>
</group>
<group>
<field name="is_filtering"/>
<field name="sensitive_words" attrs="{'invisible': [('is_filtering', '=', False)]}"/>
</group>
</group>
</sheet>

View File

@@ -6,14 +6,18 @@
<field name="inherit_id" ref="base_setup.res_config_settings_view_form"/>
<field name="arch" type="xml">
<xpath expr="//div[@name='integration']" position="after">
<h2>ChatGPT</h2>
<h2>Ai Center(Chatgpt)</h2>
<div class="col-xs-12 row o_settings_container" id="chatgpt_integraion">
<div class="col-xs-12 col-md-10 o_setting_box">
<div class="o_setting_right_pane border-start-0">
<div class="content-group">
<div class="row mt0">
<label class="col-lg-2" string="上下文连接超时" for="openapi_context_timeout"/>
<field name="openapi_context_timeout" title="上下文连接超时 秒数" style="width: 10% !important;"/>
<label class="col-lg-2" string="Timout then disconnect(s)" for="openapi_context_timeout"/>
<field name="openapi_context_timeout" title="After timeout seconds then Disconnect" style="width: 10% !important;"/>Seconds
</div>
<div class="row mt0">
<label class="col-lg-2" for="openai_sync_config"/>
<field name="openai_sync_config" style="width: 10% !important;"/>
</div>
</div>
</div>

View File

@@ -5,7 +5,7 @@
<field name="model">res.users</field>
<field name="inherit_id" ref="base.view_users_form"/>
<field name="arch" type="xml">
<xpath expr="//page[@name='preferences']" position="after">
<xpath expr="//group[@name='preferences']/../.." position="after">
<page name="page_chatgpt" string="ChatGPT">
<group>
<group>