7 | This module adds a connector for OpenAI API 8 |
17 | 7 | This module adds an AI Bot user to chat with like in ChatGPT. 8 |
17 | 7 | This module allows to generate tags for a product with OpenAI's GTP3 model from product's description. 8 |
17 | 7 | This module allows to generate tags for a product with OpenAI's GTP3 model from product's description. 8 |
17 | 7 | This module allows to generate a product sales description with OpenAI's GTP3 model from product tags, attributes or any other product information. 8 |
17 |
](https://github.com/myrrkel)
38 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/openai_connector/views/res_config_settings_views.xml:
--------------------------------------------------------------------------------
1 |
2 |
](https://github.com/myrrkel)
38 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/openai_connector/__manifest__.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Copyright (C) 2022 - Michel Perrocheau (https://github.com/myrrkel).
3 | # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
4 | {
5 | 'name': 'OpenAI Connector',
6 | 'version': '16.2.0.0',
7 | 'author': 'Michel Perrocheau',
8 | 'website': 'https://github.com/myrrkel',
9 | 'summary': "Connector for OpenAI API",
10 | 'sequence': 0,
11 | 'certificate': '',
12 | 'license': 'AGPL-3',
13 | 'depends': [
14 | 'base',
15 | 'mail',
16 | ],
17 | 'external_dependencies': {
18 | 'python': ['openai'],
19 | },
20 | 'category': 'OpenAI',
21 | 'complexity': 'easy',
22 | 'qweb': [
23 | ],
24 | 'demo': [
25 | ],
26 | 'images': [
27 | ],
28 | 'data': [
29 | 'security/ir.model.access.csv',
30 | 'security/security.xml',
31 | 'views/res_config_settings_views.xml',
32 | 'views/openai_completion_views.xml',
33 | 'views/openai_completion_result_views.xml',
34 | 'views/openai_image_views.xml',
35 | 'views/openai_image_result_views.xml',
36 | 'views/openai_question_answer_views.xml',
37 | 'views/openai_fine_tuning_views.xml',
38 | ],
39 | 'assets': {
40 | 'web.assets_backend': [
41 | 'openai_connector/static/src/scss/style.scss',
42 | ],
43 | },
44 |
45 | 'auto_install': False,
46 | 'installable': True,
47 | 'application': False,
48 | }
49 |
--------------------------------------------------------------------------------
/openai_chat/README.md:
--------------------------------------------------------------------------------
1 | [](http://www.gnu.org/licenses/agpl-3.0-standalone.html)
2 |
3 | OpenAI Chat
4 | ===================
5 |
6 | [
](https://github.com/myrrkel)
54 |
55 |
56 |
57 |
--------------------------------------------------------------------------------
/openai_connector/security/ir.model.access.csv:
--------------------------------------------------------------------------------
1 | "id","name","model_id:id","group_id:id","perm_read","perm_write","perm_create","perm_unlink"
2 | access_openai_completion_user,access_openai_completion user,openai_connector.model_openai_completion,base.group_user,1,0,0,0
3 | access_openai_completion_admin,access_openai_completion admin,openai_connector.model_openai_completion,base.group_erp_manager,1,1,1,1
4 | access_openai_completion_result_user,access_openai_completion_result user,openai_connector.model_openai_completion_result,base.group_user,1,1,1,1
5 | access_openai_image_user,access_openai_image user,openai_connector.model_openai_image,base.group_user,1,0,0,0
6 | access_openai_image_admin,access_openai_image admin,openai_connector.model_openai_image,base.group_erp_manager,1,1,1,1
7 | access_openai_image_result_user,access_openai_image_result user,openai_connector.model_openai_image_result,base.group_user,1,1,1,1
8 | access_openai_question_answer_user,access_openai_question_answer user,openai_connector.model_openai_question_answer,base.group_user,1,1,1,1
9 | access_openai_fine_tuning_user,access_openai_fine_tuning user,openai_connector.model_openai_fine_tuning,base.group_user,1,0,0,0
10 | access_openai_fine_tuning_admin,access_openai_fine_tuning admin,openai_connector.model_openai_fine_tuning,base.group_erp_manager,1,1,1,1
11 | access_openai_tool_user,access_openai_tool user,openai_connector.model_openai_tool,base.group_user,1,0,0,0
12 | access_openai_tool_admin,access_openai_tool admin,openai_connector.model_openai_tool,base.group_erp_manager,1,1,1,1
13 | access_openai_tool_property_user,access_openai_tool_property user,openai_connector.model_openai_tool_property,base.group_user,1,0,0,0
14 | access_openai_tool_property_admin,access_openai_tool_property admin,openai_connector.model_openai_tool_property,base.group_erp_manager,1,1,1,1
--------------------------------------------------------------------------------
/openai_connector/models/openai_image_result.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Copyright (C) 2022 - Michel Perrocheau (https://github.com/myrrkel).
3 | # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
4 |
5 | from odoo import models, fields, api, _
6 | import logging
7 |
8 | _logger = logging.getLogger(__name__)
9 |
10 |
11 | class OpenAiImageResult(models.Model):
12 | _name = 'openai.image.result'
13 | _description = 'OpenAI Image Result'
14 | _inherit = ['openai.result.mixin']
15 |
16 | image_id = fields.Many2one('openai.image', string='OpenAI Action', readonly=True, ondelete='cascade')
17 | original_image = fields.Image(compute='_compute_original_image')
18 | method = fields.Char()
19 | answer = fields.Image(readonly=False)
20 |
21 | def _compute_name(self):
22 | for rec in self:
23 | if hasattr(rec.resource_ref, 'name'):
24 | name = f'{rec.image_id.name} - {rec.resource_ref.name}'
25 | elif hasattr(rec.resource_ref, 'display_name'):
26 | name = f'{rec.image_id.name} - {rec.resource_ref.display_name}'
27 | else:
28 | name = f'{rec.image_id.name} - {rec.model_id.name} ({self.res_id})'
29 | if rec.test_result:
30 | name = '%s (%s)' % (name, _('TEST'))
31 | rec.name = name
32 |
33 | def _compute_original_image(self):
34 | for rec in self:
35 | try:
36 | record_id = self.env[rec.model_id.model].browse(rec.res_id)
37 | if rec.image_id.source_image_field_id:
38 | res = record_id[rec.image_id.source_image_field_id.name]
39 | if res:
40 | rec.original_image = res
41 | continue
42 | rec.original_image = None
43 | except Exception as err:
44 | _logger.error(err)
45 | pass
46 |
--------------------------------------------------------------------------------
/openai_edit_product_image/models/product.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Copyright (C) 2023 - Michel Perrocheau (https://github.com/myrrkel).
3 | # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
4 |
5 | from odoo import models, fields, api, _
6 | import logging
7 |
8 | _logger = logging.getLogger(__name__)
9 |
10 |
11 | class ProductTemplate(models.Model):
12 | _inherit = 'product.template'
13 |
14 | openai_source_image = fields.Image("OpenAI Source Image", max_width=2000, max_height=2000)
15 | openai_mask_image = fields.Image("OpenAI Mask Image", max_width=2000, max_height=2000)
16 | image_ratio = fields.Float()
17 | image_description = fields.Char()
18 |
19 | def action_openai_create_product_edit_image(self):
20 | for rec in self:
21 | image_edit_id = self.env.ref('openai_edit_product_image.edit_product_image')
22 | if rec.openai_source_image:
23 | method = 'create_edit'
24 | elif rec.image_description:
25 | method = 'create'
26 | elif rec.image_1920:
27 | method = 'create_variation'
28 | else:
29 | continue
30 | image_edit_id.apply(rec.id, method=method)
31 | if image_edit_id.save_on_target_field:
32 | return {
33 | 'type': 'ir.actions.client',
34 | 'tag': 'display_notification',
35 | 'params': {
36 | 'message': _("Product image created."),
37 | 'type': 'success',
38 | 'sticky': False,
39 | 'next': {'type': 'ir.actions.client', 'tag': 'reload'},
40 | }
41 | }
42 | else:
43 | action_name = 'openai_edit_product_image.openai_product_edit_image_action'
44 | action = self.env['ir.actions.act_window']._for_xml_id(action_name)
45 | action['domain'] = [('res_id', 'in', self.ids)]
46 | return action
47 |
--------------------------------------------------------------------------------
/openai_edit_product_image/README.md:
--------------------------------------------------------------------------------
1 | [](http://www.gnu.org/licenses/agpl-3.0-standalone.html)
2 |
3 | OpenAI Edit Product Image
4 | =========================
5 |
6 | [
](https://github.com/myrrkel)
62 |
63 |
64 |
65 |
--------------------------------------------------------------------------------
/openai_product_tags/views/openai_product_result_views.xml:
--------------------------------------------------------------------------------
1 |
2 | 34 | No OpenAI Product Tags Result 35 |
36 |34 | No DALL-E Product Image Result 35 |
36 |34 | No OpenAI Product Sales Description Result 35 |
36 |46 | No OpenAI Question Answers 47 |
48 |59 | No OpenAI Image Result 60 |
61 |
](https://github.com/myrrkel)
91 |
92 |
93 |
94 |
--------------------------------------------------------------------------------
/openai_connector/models/openai_fine_tuning.py:
--------------------------------------------------------------------------------
1 | # Copyright (C) 2024 - Michel Perrocheau (https://github.com/myrrkel).
2 | # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
3 |
4 | import json
5 | from tempfile import NamedTemporaryFile
6 | from odoo import models, fields, api, _
7 | from odoo.tools.safe_eval import safe_eval
8 | from odoo.addons.base.models.ir_model import SAFE_EVAL_BASE
9 |
10 | import logging
11 |
12 | _logger = logging.getLogger(__name__)
13 |
14 |
15 | class OpenAiFineTuning(models.Model):
16 | _name = 'openai.fine.tuning'
17 | _description = 'OpenAI Fine-Tuning'
18 |
19 | def _get_training_model_list(self):
20 | return [('gpt-3.5-turbo', 'gpt-3.5-turbo'),
21 | ('gpt-3.5-turbo-1106', 'gpt-3.5-turbo-1106'),
22 | ('gpt-3.5-turbo-0613', 'gpt-3.5-turbo-0613'),
23 | ('gpt-4-0613', 'gpt-4-0613'),
24 | ('babbage-002', 'babbage-002'),
25 | ('davinci-002', 'davinci-002')]
26 |
27 | name = fields.Char()
28 | training_model = fields.Selection(selection=_get_training_model_list, default='gpt-3.5-turbo')
29 | training_file_id = fields.Char('Training File ID')
30 | fine_tuning_job_id = fields.Char('Fine-Tuning Job ID')
31 | fine_tuned_model = fields.Char('Fine-Tuned Model')
32 | question_answer_domain = fields.Char()
33 | question_answer_ids = fields.Many2many('openai.question.answer', string='Questions /Answers',
34 | compute='_compute_question_answers',
35 | store=False)
36 | system_role_content = fields.Char()
37 |
38 | def _compute_question_answers(self):
39 | for rec in self:
40 | domain = safe_eval(rec.question_answer_domain,
41 | SAFE_EVAL_BASE,
42 | {'self': rec}) if rec.question_answer_domain else []
43 | rec.question_answer_ids = self.env['openai.question.answer'].search(domain)
44 |
45 | def get_training_content(self):
46 | content = ''
47 | for question_answer_id in self.question_answer_ids:
48 | messages = {
49 | 'messages': [
50 | {'role': 'system', 'content': self.system_role_content},
51 | {'role': 'user', 'content': question_answer_id.name},
52 | {'role': 'assistant', 'content': question_answer_id.answer}
53 | ]
54 | }
55 | content += json.dumps(messages) + '\n'
56 | return bytes(content, 'utf-8')
57 |
58 | def create_training_file(self):
59 | client = self.env['openai.mixin'].get_openai()
60 | file = ('training_%s' % self.id, self.get_training_content())
61 | res = client.files.create(file=file, purpose='fine-tune')
62 | self.training_file_id = res.id
63 |
64 | def create_fine_tuning(self):
65 | client = self.env['openai.mixin'].get_openai()
66 | res = client.fine_tuning.jobs.create(training_file=self.training_file_id, model=self.training_model)
67 | self.fine_tuning_job_id = res.id
68 | _logger.info(res)
69 |
70 | def update_fine_tuned_model(self):
71 | client = self.env['openai.mixin'].get_openai()
72 | res = client.fine_tuning.jobs.retrieve(self.fine_tuning_job_id)
73 | self.fine_tuned_model = res.fine_tuned_model
74 | _logger.info(res)
75 |
76 | def action_create_training_file(self):
77 | for rec in self:
78 | rec.create_training_file()
79 |
80 | def action_create_fine_tuning(self):
81 | for rec in self:
82 | rec.create_fine_tuning()
83 |
84 | def action_update_fine_tuned_model(self):
85 | for rec in self:
86 | rec.update_fine_tuned_model()
87 |
--------------------------------------------------------------------------------
/openai_connector/views/openai_completion_result_views.xml:
--------------------------------------------------------------------------------
1 |
2 | 72 | No OpenAI Completion Result 73 |
74 |48 | No OpenAI Fine-Tunings 49 |
50 |113 | Create a new OpenAI Completion 114 |
115 |124 | Create a new OpenAI Image 125 |
126 |