| |
| |
| |
| |
| |
| {%- macro json_schema_to_typescript(schema, indent="") -%} |
| {%- set ADDITIONAL_JSON_KEYS = ['format', 'maxItems', 'maximum', 'minItems', 'minimum', 'pattern'] -%} |
| {%- set ty = schema.get("type") -%} |
| |
| |
| {%- if ty == "object" -%} |
| {{- "{\n" -}} |
| |
| |
| {%- set props = schema.get("properties", {}) -%} |
| {%- set required = schema.get("required", []) -%} |
| {%- set has_additional_props = schema.get("additionalProperties") is defined -%} |
| {%- set additional_props_type = none -%} |
| {%- if has_additional_props -%} |
| {%- if schema.additionalProperties == true -%} |
| {%- set additional_props_type = {'type': 'any'} -%} |
| {%- elif schema.additionalProperties is mapping -%} |
| {%- set additional_props_type = schema.additionalProperties -%} |
| {%- endif -%} |
| {%- endif -%} |
| |
| {%- for key, val in props.items() -%} |
| |
| {%- if "description" in val -%} |
| {%- for line in val['description'].split('\n') -%} |
| {%- if line.strip() -%} |
| {{- indent + '// ' + line + '\n' -}} |
| {%- endif -%} |
| {%- endfor -%} |
| {%- endif -%} |
| |
| |
| {%- for add_key, add_val in val.items() -%} |
| {%- if add_key in ADDITIONAL_JSON_KEYS -%} |
| {%- if add_val is string -%} |
| {{- indent + '// ' + add_key + ': "' + add_val + '"' + '\n' -}} |
| {%- else -%} |
| {{- indent + '// ' + add_key + ': ' ~ add_val ~ '\n' -}} |
| {%- endif -%} |
| {%- endif -%} |
| {%- endfor -%} |
| |
| |
| {%- set type_str = json_schema_to_typescript( |
| val, |
| indent + " " |
| ) -%} |
| |
| {{- indent + key + ('' if key in required else '?') + ': ' + type_str + ',' -}} |
| |
| {%- if "default" in val or "defalut_value" in val -%} |
| {%- set default = val.get("default", val.get("defalut_value")) -%} |
| {%- if default is string -%} |
| {{- ' // default: "' + default + '"' -}} |
| {%- else -%} |
| {{- ' // default: ' ~ default -}} |
| {%- endif -%} |
| {%- endif -%} |
| |
| {{- "\n" -}} |
| {%- endfor -%} |
| |
| |
| {%- if has_additional_props and additional_props_type is not none -%} |
| {%- set additional_type_str = json_schema_to_typescript( |
| additional_props_type, |
| indent + " " |
| ) -%} |
| {{- indent + '[key: string]: ' + additional_type_str + '\n' -}} |
| {%- endif -%} |
| |
| {{- indent[: (indent|length - " "|length) ] + '}' -}} |
| |
| |
| {%- elif ty == "string" -%} |
| {%- if schema.get("enum") -%} |
| {%- set ns = namespace(enum = []) -%} |
| {%- for en in schema['enum'] -%} |
| {%- set ns.enum = ns.enum + ['"' ~ en ~ '"'] -%} |
| {%- endfor -%} |
| {{- ns.enum | join(' | ') -}} |
| {%- elif schema.get("format", "none") in ['date-time', 'date'] -%} |
| {{- 'Date' -}} |
| {%- else -%} |
| {{- 'string' -}} |
| {%- endif -%} |
| |
| |
| {%- elif ty in ["number", "integer"] -%} |
| {%- if schema.get("enum") -%} |
| {{- schema.enum | join(' | ') -}} |
| {%- else -%} |
| {{- 'number' -}} |
| {%- endif -%} |
| |
| |
| {%- elif ty == "boolean" -%} |
| {{- 'boolean' -}} |
| |
| |
| {%- elif ty == "array" -%} |
| {%- if "items" in schema -%} |
| {{- json_schema_to_typescript(schema['items'], indent) + '[]' -}} |
| {%- else -%} |
| {{- 'Array<any>' -}} |
| {%- endif -%} |
| |
| |
| {%- else -%} |
| {{- 'any' -}} |
| {%- endif -%} |
| {%- endmacro -%} |
| |
| |
| |
| |
| |
| {%- macro render_tool_namespace(namespace_name, tools) -%} |
| {%- set ns = namespace(sections = ['namespace ' ~ namespace_name ~ ' {']) -%} |
| |
| {%- for tool in tools -%} |
| {%- if tool.function -%} |
| {%- set tool = tool.function -%} |
| {%- endif -%} |
| |
| {%- set ns_tool = namespace(content_lines=[]) -%} |
| |
| |
| {%- if tool.get('description') -%} |
| {%- for line in tool['description'].split('\n') -%} |
| {%- if line.strip() -%} |
| {%- set ns_tool.content_lines = ns_tool.content_lines + ['// ' ~ line] -%} |
| {%- endif -%} |
| {%- endfor -%} |
| {%- endif -%} |
| |
| |
| {%- set main_body = "" -%} |
| {%- set params = tool.get("parameters") -%} |
| {%- if params and params.get("properties") -%} |
| {%- set param_type = json_schema_to_typescript(params, " ") -%} |
| {%- set main_body = 'type ' ~ tool.name ~ ' = (_: ' ~ param_type ~ ') => ' -%} |
| {%- else -%} |
| {%- set main_body = 'type ' ~ tool.name ~ ' = () => ' -%} |
| {%- endif -%} |
| |
| |
| {%- set return_params = tool.get("return_parameters") -%} |
| {%- if return_params and return_params.get("properties") -%} |
| {%- set return_type = json_schema_to_typescript(return_params, " ") -%} |
| {%- set main_body = main_body ~ return_type -%} |
| {%- else -%} |
| {%- set main_body = main_body ~ 'any' -%} |
| {%- endif -%} |
| |
| {%- set main_body = main_body ~ ';\n' -%} |
| |
| {%- set ns_tool.content_lines = ns_tool.content_lines + [main_body] -%} |
| |
| |
| {%- set ns.sections = ns.sections + [ns_tool.content_lines | join('\n')] -%} |
| {%- endfor -%} |
| |
| {%- set ns.sections = ns.sections + ['} // namespace ' ~ namespace_name] -%} |
| |
| {{- ns.sections | join('\n') -}} |
| {%- endmacro -%} |
| |
| |
| |
| |
| {%- macro render_function_call(call) -%} |
| {%- if call.function -%} |
| {%- set call = call.function -%} |
| {%- endif -%} |
| |
| {%- set arguments = call['arguments'] -%} |
| {%- if arguments is not string -%} |
| {%- set arguments = arguments| tojson(ensure_ascii=False) -%} |
| {%- endif -%} |
| |
| {{- '{"name": "' ~ call['name'] ~ '", "arguments": ' ~ arguments ~ '}' -}} |
| {%- endmacro -%} |
| |
| |
| {%- macro render_role_message(message, role=None) -%} |
| {%- if not role -%} |
| {%- set role = message["role"] -%} |
| {%- endif -%} |
| |
| {%- set message_content = message['content'] or '' -%} |
| {%- if message_content is not string -%} |
| {%- set message_content = message_content | tojson(ensure_ascii=False) -%} |
| {%- endif -%} |
| |
| {{- role + add_tokens.role_sep + message_content -}} |
| |
| {%- if message.tool_calls is defined and message.tool_calls -%} |
| {{- add_tokens.function_call + render_function_call(message.tool_calls[0]) -}} |
| {%- endif -%} |
| |
| {{- add_tokens.message_sep -}} |
| |
| {%- endmacro -%} |
| |
| |
| |
| |
| |
| {%- set add_tokens = namespace( |
| role_sep="<|role_sep|>\n", |
| message_sep="<|message_sep|>\n\n", |
| function_call="<|function_call|>" |
| ) -%} |
| |
| |
| |
| {%- set DEVSYSTEM -%} |
| <role_description> |
| Описание доступных в диалоге ролей. |
| |
| `developer system` |
| Сообщение, добавленное Сбером до основного диалога. Имеет самый высокий приоритет и определяет глобальные, неотменяемые условия (например, правила ведения диалога, политику безопасности, общий стиль ответов ассистента и пр.). |
| |
| `system` |
| Системная инструкция, добавляемая разработчиками или пользователем, но с приоритетом ниже, чем `developer system`. Обычно описывает инструкции ассистента, конкретный стиль ответа и другие условия для данного конкретного диалога. |
| |
| `user` |
| Сообщение или запрос от пользователя. Ассистент следует ему, если это не противоречит инструкциям более высокого приоритета (см. <instruction_priority>). |
| |
| `user memory` |
| Последовательность наиболее актуальных долговременных фактов о пользователе на момент его запроса, представленная в виде JSON‑списка строк. Факты в ней перечислены в хронологическом порядке, то есть более новые факты дописываются в конец последовательности. При этом при изменении или удалении фактов записи о предыдущих фактах остаются в последовательности. Ассистент сохраняет факты с помощью функции и использует их в соответствии с указаниями из блока <memory_guidelines> ниже. |
| |
| `added files` |
| Метаинформация о файлах, доступных для использования в диалоге, представленная в формате JSON. Содержит следующие ключи: id (уникальный идентификатор файла), name (имя файла), type (тип файла). |
| |
| `assistant` |
| Ответ ассистента на запрос пользователя. Если системная инструкция или пользователь не задаёт дополнительных правил для `assistant`, то такая реплика должна соответствовать указаниям из блока <assistant_guidelines> ниже. Список доступных для вызова функций содержится в последней реплике роли `available functions`. Название необходимой для вызова функции и аргументы будут сгенерированы после специального токена вызова функции. В своих репликах ассистент следует инструкциям в соответствии с <instruction_priority>. |
| Вызов функции осуществляется в строгом соответствии с инструкцией из блока <function_usage>. |
| |
| `function descriptions` |
| Описания функций в формате TypeScript. Функция — это специальный инструмент (или набор инструкций), который ассистент может вызвать для выполнения конкретных действий, вычислений или получения данных, необходимых для решения задачи пользователя. Каждое описание функции содержит блоки с именем, описанием, аргументами. Иногда описание содержит отдельные блоки с возвращаемыми параметрами и примерами применения, иллюстрирующими правильный вызов и аргументы. |
| |
| `available functions` |
| Список, который содержит названия функций, доступных для вызова. Если список не содержит элементов, то в следующем сообщении функции, доступные для вызова, отсутствуют. |
| |
| `function result` |
| Результат последнего вызова функции. |
| </role_description> |
| |
| |
| <available_modalities> |
| Ассистент умеет работать со следующими модальностями: текст, доступные функции. |
| </available_modalities> |
| |
| |
| <instruction_priority> |
| В случае противоречия инструкций разных ролей в контексте диалога соблюдай приоритеты: |
| `developer system` > `system` > `user` > `function descriptions` > `function result` > `user memory` |
| </instruction_priority> |
| |
| |
| <function_usage> |
| Базовые инструкции для работы с функциями. |
| |
| Можно вызывать только те функции, которые доступны исходя из последнего сообщения `available functions`. |
| |
| Вызывай доступные функции в случае, если согласно их описанию такой вызов поможет дать более полный и/или точный ответ на запрос пользователя. Заполняй аргументы функций, используя информацию из контекста диалога. Если функция может помочь ответить на запрос, но для её обязательного аргумента отсутствует информация в контексте, уточни у пользователя недостающие данные перед вызовом функции. При недоступности необходимой функции или ошибке — кратко сообщи об этом пользователю и по возможности предложи альтернативу. |
| </function_usage> |
| |
| |
| <memory_guidelines> |
| Правила использования фактов в долговременной памяти: |
| |
| Если в диалоге нет сообщения под ролью `user memory`, то это равносильно отсутствию долговременных фактов о пользователе в памяти. В таком случае информация о пользователе ограничена текущим диалогом, и новые факты не должны сохраняться. |
| </memory_guidelines> |
| |
| |
| <assistant_guidelines> |
| GigaChat — нейросетевая модель искусственного интеллекта, созданная компанией Сбер в России. |
| |
| GigaChat старается отвечать на языке, на котором пользователь задал запрос. Если из запроса пользователя и контекста диалога язык определить невозможно, GigaChat использует русский. |
| GigaChat предоставляет подробные ответы на более сложные и открытые вопросы. |
| GigaChat в ответе не использует названия доступных функций. |
| GigaChat отвечает безопасно, в соответствии с действующим законодательством Российской Федерации, стараясь помочь пользователю решить задачу или поддержать беседу. |
| |
| Ты — GigaChat. |
| </assistant_guidelines> |
| |
| |
| Ниже будет приведён диалог. |
| В диалоге могут быть разнообразные роли, описанные в блоке <role_description>. |
| Каждая реплика начинается с названия роли и специального токена, обозначающего конец полного наименования роли, а заканчивается специальным токеном конца реплики. |
| Твоя задача — продолжить диалог от последней указанной роли в соответствии с контекстом диалога. |
| {%- endset -%} |
| |
| |
| |
| |
| |
| |
| {{- bos_token -}} |
| |
| |
| |
| {{- render_role_message({"role": "developer system", "content": DEVSYSTEM}) -}} |
| |
| |
| {%- if messages and messages[0]['role'] == 'system' -%} |
| {{- render_role_message(messages[0]) -}} |
| {%- set messages = messages[1:] -%} |
| {%- else -%} |
| {{- render_role_message({"role": "system", "content": ""}) -}} |
| {%- endif -%} |
| |
| |
| {%- if tools -%} |
| {%- set tools_content = ( |
| render_tool_namespace('functions', tools) |
| + "\n\n" |
| ) -%} |
| {{- render_role_message({'role': 'function descriptions', 'content': tools_content}) -}} |
| {%- endif -%} |
| |
| |
| {%- for message in messages -%} |
| |
| |
| {%- if message['role'] == 'tool' -%} |
| {{- render_role_message(message, 'function result') -}} |
| |
| |
| {%- else -%} |
| {{- render_role_message(message) -}} |
| {%- endif -%} |
| |
| |
| |
| {%- if loop.last and add_generation_prompt and message['role'] != 'assistant' -%} |
| {{- 'assistant' + add_tokens.role_sep -}} |
| {%- endif -%} |
| |
| {%- endfor -%} |