aidial_assistant/application/prompts.py (52 lines of code) (raw):

from datetime import datetime from jinja2 import Environment, Template from aidial_assistant.utils.text import decapitalize JINJA2_ENV = Environment() JINJA2_ENV.filters["decap"] = decapitalize class DateAwareTemplate(Template): def render(self, *args, **kwargs): # Compute today's date in the format "DD Mmm YYYY" today = datetime.now().strftime("%d %b %Y") return super().render(*args, **kwargs, today_date=today) class PartialTemplate: def __init__(self, template: str, **kwargs): self.template = template self.template_class_args = kwargs def build(self, **kwargs) -> Template: template_args = self.template_class_args.get("globals", {}) | kwargs return JINJA2_ENV.from_string( self.template, **(self.template_class_args | {"globals": template_args}), ) _REQUEST_FORMAT_TEXT = """ You should ALWAYS reply with a JSON containing an array of commands: ```json { "commands": [ { "command": "<command name>", "arguments": { "<arg_name>": "<arg_value>" } } ] } ``` The commands are invoked by the system on the user's behalf. """.strip() _PROTOCOL_FOOTER = """ * reply The last command that delivers the final response to the user. Arguments: - 'message' is a string containing the final and complete result for the user. Your goal is to answer user questions. Use relevant commands when they help to achieve the goal. ## Example ```json {"commands": [{"command": "reply", "arguments": {"message": "Hello, world!"}}]} ``` End of the protocol. """.strip() _SYSTEM_TEXT = """ Today's date is {{today_date}}. This message defines the following communication protocol. {%- if system_prefix %} {{system_prefix}} {%- endif %} # Protocol {{request_format}} ## Commands {%- for name, description in addons.items() %} * {{name}} {{description.strip()}} Arguments: - 'query' is a query written in natural language. {% endfor %} {{protocol_footer}} """.strip() _ADDON_SYSTEM_TEXT = """ Today's date is {{today_date}}. This message defines the following communication protocol. # Service API_DESCRIPTION: {{api_description}} # API Schema ```typescript {{api_schema}}} ``` # Protocol {{request_format}} ## Commands {%- for command_name in command_names %} * {{command_name}} Arguments: - <JSON dict according to the API Schema> {% endfor %} {{protocol_footer}} """.strip() _ENFORCE_JSON_FORMAT_TEXT = """ {{response}} **Protocol reminder: reply with commands** """.strip() _MAIN_BEST_EFFORT_TEXT = ( """ You were allowed to use the following addons to answer the query below. === ADDONS === {% for name, description in addons.items() %} * {{name}} - {{description | decap}} {%- endfor %} === QUERY === {{message}} {%- if dialogue %} === ADDONS REQUESTS AND RESPONSES === {% for message in dialogue %} {{message["role"]}}: {{message["content"]}} {%- endfor %} {%- endif %} However, the follow-up requests failed with the following error: > {{error}} Please respond to the query using the available information, and explaining that the use of the addons was not possible due to the error. """ ).strip() _ADDON_BEST_EFFORT_TEXT = ( """ You were allowed to use the following API to answer the query below. === API === ```typescript {{api_schema}} ``` === QUERY === {{message}} {%- if dialogue %} === API REQUESTS AND RESPONSES === {% for message in dialogue %} {{message["role"]}}: {{message["content"]}} {%- endfor %} {%- endif %} However, the follow-up requests failed with the following error: > {{error}} Please respond to the query using the available information, and explaining that the use of the API was not possible due to the error. """ ).strip() MAIN_SYSTEM_DIALOG_MESSAGE = PartialTemplate( _SYSTEM_TEXT, globals={ "request_format": _REQUEST_FORMAT_TEXT, "protocol_footer": _PROTOCOL_FOOTER, }, template_class=DateAwareTemplate, ) ADDON_SYSTEM_DIALOG_MESSAGE = PartialTemplate( _ADDON_SYSTEM_TEXT, globals={ "request_format": _REQUEST_FORMAT_TEXT, "protocol_footer": _PROTOCOL_FOOTER, }, template_class=DateAwareTemplate, ) ENFORCE_JSON_FORMAT_TEMPLATE = JINJA2_ENV.from_string(_ENFORCE_JSON_FORMAT_TEXT) MAIN_BEST_EFFORT_TEMPLATE = PartialTemplate(_MAIN_BEST_EFFORT_TEXT) ADDON_BEST_EFFORT_TEMPLATE = PartialTemplate(_ADDON_BEST_EFFORT_TEXT)