File size: 7,672 Bytes
bd26458
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
{# ---------------------------------------------------------------------- #}
{# ƛƬ Default setup and flags                                             #}
{# ---------------------------------------------------------------------- #}
{%- set messages = messages or [] -%}
{%- set tools = tools or [] -%}
{%- set add_generation_prompt = add_generation_prompt or false -%}
{%- set available_tool_string, add_tool_id = '', true -%}
{%- set add_thoughts = false -%}            {# whether to include <thinking> reasoning blocks #}
{%- set add_generation_prompt = true -%}      {# whether to emit reasoning starter before assistant response #}
{# Optional token placeholders (safe defaults) #}
{%- set bos_token = bos_token if (bos_token is defined) else '' -%}
{%- set eos_token = eos_token if (eos_token is defined) else '' -%}
{# ---------------------------------------------------------------------- #}
{# Core reasoning prompt and assistant reasoning prefix                 #}
{# ---------------------------------------------------------------------- #}
{%- set reasoning_prompt = 
    'You are a thoughtful, systematic AI assistant from ServiceNow Language Models (SLAM) lab. '
    'Analyze each question carefully, present your reasoning step-by-step, then provide the final '
    'response after the marker [BEGIN FINAL RESPONSE].'
-%}
{%- set reasoning_asst_turn_start = 'Here are my reasoning steps:\n' -%}
{# ---------------------------------------------------------------------- #}
{# Tool list and tool call output format                                  #}
{# ---------------------------------------------------------------------- #}
{%- if tools is not none and tools|length > 0 -%}
    {%- set available_tool_string -%}
        You are provided with function signatures within <available_tools></available_tools> XML tags.
        You may call one or more functions to assist with the user query.
        Don't make assumptions about the arguments. You should infer the argument values from previous
        user responses and the system message.
        Here are the available tools: 
        <available_tools>
        {% for tool in tools %}{{ tool|string }}{% endfor %}
        
        </available_tools>.

        Return all function calls as a list of JSON objects within <tool_calls></tool_calls> XML tags.
        Each JSON object should contain a function name and arguments as follows:
        <tool_calls>[
            {"name": <function-name-1>, "arguments": <args-dict-1>},
            {"name": <function-name-2>, "arguments": <args-dict-2>},
            ...
        ]</tool_calls>
    {%- endset -%}
{%- endif -%}
{# ---------------------------------------------------------------------- #}
{# Start system block if first message is not system                      #}
{# ---------------------------------------------------------------------- #}
{%- if messages|length > 0 and messages[0]['role'] != 'system' -%}
    {%- if tools is not none and tools|length > 0 -%}
        {{ bos_token + '<|begin_system|>\n' + reasoning_prompt + '\n' + available_tool_string + '\n' }}
    {%- else -%}
        {{ bos_token + '<|begin_system|>\n' + reasoning_prompt + '\n' }}
    {%- endif -%}
{%- endif -%}
{# ---------------------------------------------------------------------- #}
{# Iterate through messages                                             #}
{# ---------------------------------------------------------------------- #}
{%- for message in messages -%}

    {# ---------------- USER MESSAGE ---------------- #}
    {%- if message['role'] == 'user' -%}
        {{ '<|begin_user|>\n' }}
        {%- if message['content'] is not string -%}
            {%- for chunk in message['content'] -%}
                {%- if chunk['type'] == 'text' -%}
                    {{ chunk['text'] }}
                {%- elif chunk['type'] in ['image', 'image_url'] -%}
                    {{ '[IMG]' }}
                {%- else -%}
                    {{ raise_exception('Unrecognized content type!') }}
                {%- endif -%}
            {%- endfor -%}
        {%- else -%}
            {{ message['content'] }}
        {%- endif -%}

    {# ---------------- SYSTEM MESSAGE ---------------- #}
    {%- elif message['role'] == 'system' -%}
        {%- if message['content'] is not none and message['content']|length > 0 -%}
            {%- if message['content'] is string -%}
                {%- set system_message = message['content'] -%}
            {%- else -%}
                {%- set system_message = message['content'][0]['text'] -%}
            {%- endif -%}
        {%- else -%}
            {%- set system_message = '' -%}
        {%- endif -%}

        {%- if tools is not none and tools|length > 0 -%}
            {{ bos_token + '<|begin_system|>\n' + reasoning_prompt + '\n' + system_message + '\n' + available_tool_string + '\n' }}
        {%- else -%}
            {{ bos_token + '<|begin_system|>\n' + reasoning_prompt + '\n' + system_message + '\n' }}
        {%- endif -%}

    {# ---------------- ASSISTANT MESSAGE ---------------- #}
    {%- elif message['role'] == 'assistant' -%}
        {%- if loop.last -%}
            {%- set add_tool_id = false -%}
        {%- endif -%}

        {{ '\n<|begin_assistant|>\n' }}

        {%- if add_thoughts and 'thought' in message and message['thought'] is not none -%}
            <thinking>{{ message['thought'] }}</thinking>
        {%- endif -%}

        {%- if message['content'] is not none and message['content']|length > 0 -%}
            {%- if message['content'] is not string -%}
                {{ message['content'][0]['text'] }}
            {%- else -%}
                {{ message['content'] }}
            {%- endif -%}
        {%- elif message['chosen'] is not none and message['chosen']|length > 0 -%}
            {{ message['chosen'][0] }}
        {%- endif -%}

        {# Tool call output #}
        {%- if message['tool_calls'] is not none and message['tool_calls']|length > 0 -%}
            {{ '\n<tool_calls>[' }}
            {%- for tool_call in message['tool_calls'] -%}
                {{ '{"name": "' + tool_call['function']['name'] + '", "arguments": ' + tool_call['function']['arguments']|string }}
                {%- if add_tool_id == true and 'id' in tool_call -%}
                    {{ ', "id": "' + tool_call['id'] + '"' }}
                {%- endif -%}
                {{ '}' }}
                {%- if not loop.last -%}{{ ', ' }}{%- endif -%}
            {%- endfor -%}
            {{ ']</tool_calls>' }}
        {%- endif -%}

        {%- if not loop.last or training_prompt -%}
            {{ '\n<|end|>\n' }}
        {%- endif -%}

    {# ---------------- TOOL RESULT MESSAGE ---------------- #}
    {%- elif message['role'] == 'tool' -%}
        {%- if message['content'] is string -%}
            {%- set tool_message = message['content'] -%}
        {%- else -%}
            {%- set tool_message = message['content'][0]['text'] -%}
        {%- endif -%}
        {{ '<|begin_tool_result|>\n' + tool_message|string + '\n' }}

    {# ---------------- CONTENT MESSAGE ---------------- #}
    {%- elif message['role'] == 'content' -%}
        {%- if message['content'] is not string -%}
            {{ '<|begin_content|>\n' + message['content'][0]['text'] + '\n' }}
        {%- else -%}
            {{ '<|begin_content|>\n' + message['content'] + '\n' }}
        {%- endif -%}
    {%- endif -%}

    {# ---------------- REASONING PROMPT BEFORE NEXT ASSISTANT ---------------- #}
    {%- if loop.last and add_generation_prompt and message['role'] != 'assistant' -%}
        {{ '\n<|begin_assistant|>\n' + reasoning_asst_turn_start }}
    {%- endif -%} 

{%- endfor -%}