Files
enterprise-addons/ai/models/mail_render_mixin.py
T

82 lines
3.5 KiB
Python

# Part of Odoo. See LICENSE file for full copyright and licensing details.
import logging
import lxml.html
from odoo import models, api
_logger = logging.getLogger(__name__)
class MailRenderMixinAI(models.AbstractModel):
_inherit = "mail.render.mixin"
@api.model
def _render_template_get_valid_options(self):
return super()._render_template_get_valid_options() | {"eval_ai_prompts"}
def _valid_field_parameter(self, field, name):
return name == "eval_ai_prompts" or super()._valid_field_parameter(field, name)
@api.model
def _render_template(self, template_src, model, res_ids, engine='inline_template', add_context=None, options=None):
result = super()._render_template(
template_src, model, res_ids,
engine=engine,
add_context=add_context,
options=options,
)
if not (options or {}).get("eval_ai_prompts"):
return result
# check if there are html with AI prompts to evaluate, short-circuit if not
has_ai_prompts = False
for rendered in result.values():
if rendered and lxml.html.fromstring(rendered).xpath("//div[hasclass('o_editor_prompt')]"):
has_ai_prompts = True
break
if not has_ai_prompts:
return result
ai_composer = self.env.ref("ai.ai_mail_template_prompt_evaluator", raise_if_not_found=False)
if not ai_composer:
_logger.warning("The AI composer record used to evaluate AI prompts for mails is missing. The prompts are removed.")
default_agent = self.env.ref("ai.ai_default_agent", raise_if_not_found=False) or self.env["ai.agent"]
if not default_agent:
_logger.warning("The default AI agent is missing. The prompts are removed.")
author = self.env.user.partner_id
if self and 'author_id' in self and len(self) == 1:
author = self.author_id
for res_id in result:
ai_context = ""
if ai_composer:
ai_context += ai_composer.default_prompt or ""
ai_context += "\n\nUse the following information when necessary to generate the response:\n\n"
# TODO: How about the recipients list?
ai_context += f"\nSender: {author.name}"
# `lang` is already set in the context by _render_field which calls this method.
ai_context += f"\nRecipient language: {self.env.context.get('lang', 'en_US')}"
result[res_id] = default_agent._eval_ai_prompts(result[res_id],
remove_prompts=not (ai_composer and default_agent),
ai_context=ai_context)
return result
def _render_field(self, field, res_ids, engine='inline_template',
# lang options
compute_lang=False, res_ids_lang=False, set_lang=False,
# rendering context and options
add_context=None, options=None):
# Use the field's eval_ai_prompts attr if no 'eval_ai_prompts' option is provided
if getattr(self._fields[field], "eval_ai_prompts", False) and "eval_ai_prompts" not in (options or {}):
options = {**(options or {}), 'eval_ai_prompts': True}
return super()._render_field(
field, res_ids, engine=engine,
compute_lang=compute_lang, set_lang=set_lang, res_ids_lang=res_ids_lang,
add_context=add_context, options=options,
)