char-fork/llama.cpp

git clone https://git.t4t.associates/char-fork/llama.cpp

Joe RowellAdd support for Laguna XS.2 & M.1 (#25165)1f66c3ce1

char/aliceai-t5-moe
6.1 KiB132 linesraw
1{#- Iteration on laguna_glm_thinking_v5/chat_template.jinja -#}
2{#- Adds a default system message (used when no system message is provided in `messages`). -#}
3{{- "〈|EOS|〉" -}}
4{%- set enable_thinking = enable_thinking | default(false) -%}
5{%- set render_assistant_messages_raw = render_assistant_messages_raw | default(false) -%}
6{%- set add_generation_prompt = add_generation_prompt | default(false) -%}
7
8{#- ───── header (system message) ───── -#}
9{%- set system_message = "You are a helpful, conversationally-fluent assistant made by Poolside. You are here to be helpful to users through natural language conversations." -%}
10{%- if messages and messages[0].role == "system" -%}
11  {%- set system_message = messages[0].content -%}
12{%- endif -%}
13
14{%- if (system_message and system_message.strip()) or tools -%}
15  {{- "<system>\n" -}}
16
17  {%- if system_message and system_message.strip() -%}
18    {{- "\n" -}}
19    {{- system_message.rstrip() -}}
20  {%- endif -%}
21
22  {%- if tools -%}
23    {{- "\n\n### Tools\n\n" -}}
24    {%- set ns = namespace(tool_string="You may call functions to assist with the user query.\n"
25          ~ "All available function signatures are listed below:\n"
26          ~ "<available_tools>\n") -%}
27    {%- for tool in tools -%}
28      {%- set ns.tool_string = ns.tool_string ~ (tool | tojson) ~ "\n" -%}
29    {%- endfor -%}
30    {%- if enable_thinking -%}
31      {%- set tool_string = ns.tool_string + "</available_tools>\n\n" ~
32            "Wrap your thinking in '<think>', '</think>' tags, followed by a function call. For each function call, return an unescaped XML-like object with function name and arguments within '<tool_call>' and '</tool_call>' tags, like here:\n" ~
33            "<think> your thoughts here </think>\n" ~
34            "<tool_call>function-name\n<arg_key>argument-key</arg_key>\n<arg_value>value-of-argument-key</arg_value>\n" ~
35            "</tool_call>" -%}
36    {%- else -%}
37      {%- set tool_string = ns.tool_string + "</available_tools>\n\n" ~
38            "For each function call, return an unescaped XML-like object " ~
39            "with function name and arguments within '<tool_call>' and '</tool_call>' tags, like here:\n" ~
40            "<tool_call>function-name\n<arg_key>argument-key</arg_key>\n<arg_value>value-of-argument-key</arg_value>\n" ~
41            "</tool_call>" -%}
42    {%- endif -%}
43    {{- tool_string -}}
44  {%- endif -%}
45
46  {{- "\n</system>\n" -}}
47{%- endif -%}
48
49{#- ───── main loop ───── -#}
50{%- for message in messages -%}
51  {%- set content = message.content if message.content is string else "" -%}
52  {%- if message.role == "user" -%}
53    {{- "<user>\n" + content + "\n</user>\n" -}}
54  {%- elif message.role == "assistant" -%}
55    {%- generation -%}
56      {{- "<assistant>\n" -}}
57      {%- if render_assistant_messages_raw -%}
58        {#- Raw mode: prepend the generation prompt token, then dump content verbatim. -#}
59        {#- The generation prompt is <think> when enable_thinking, </think> otherwise. -#}
60        {#- Only prepend if content doesn't already start with it. -#}
61        {%- if enable_thinking -%}
62          {%- if not content.startswith('<think>') -%}
63            {{- '<think>' -}}
64          {%- endif -%}
65        {%- else -%}
66          {%- if not content.startswith('</think>') -%}
67            {{- '</think>' -}}
68          {%- endif -%}
69        {%- endif -%}
70        {{- content -}}
71        {#- Append closing tag if content doesn't already end with it. -#}
72        {%- if not content.endswith('</assistant>\n') and not content.endswith('</assistant>') -%}
73          {{- '\n</assistant>' -}}
74        {%- endif -%}
75        {{- "\n" -}}
76      {%- else -%}
77        {#- Extract reasoning content from message.reasoning (vLLM field name) or message.reasoning_content, or from <think> tags -#}
78        {%- set reasoning_content = '' %}
79        {%- if message.reasoning is string %}
80          {%- set reasoning_content = message.reasoning %}
81        {%- elif message.reasoning_content is string %}
82          {%- set reasoning_content = message.reasoning_content %}
83        {%- endif %}
84        {#- Always strip <think> tags from content if present to avoid duplication -#}
85        {%- if '</think>' in content %}
86          {%- if not reasoning_content %}
87            {%- set reasoning_content = content.split('</think>')[0].rstrip('\n').split('<think>')[-1].lstrip('\n') %}
88          {%- endif %}
89          {%- set content = content.split('</think>')[-1].lstrip('\n') %}
90        {%- endif %}
91        {#- Display reasoning content for all messages -#}
92        {%- if reasoning_content -%}
93          {{- '<think>\n' + reasoning_content.strip() + '\n</think>\n' -}}
94        {%- else -%}
95          {{- '</think>\n' -}}
96        {%- endif -%}
97        {#- Display main content -#}
98        {%- if content.strip() -%}
99          {{- content.strip() ~ "\n" -}}
100        {%- endif -%}
101        {%- if message.tool_calls -%}
102          {%- for tool_call in message.tool_calls -%}
103            {%- set function_data = tool_call.function -%}
104            {{- '<tool_call>' + function_data.name }}
105            {% set _args = function_data.arguments %}
106            {%- for k, v in _args.items() -%}
107              {{- "<arg_key>" ~ k ~ "</arg_key>\n" -}}
108              {{- "<arg_value>"}}{{ v | tojson(ensure_ascii=False) if v is not string else v }}{{ "</arg_value>\n" -}}
109            {%- endfor -%}
110            {{- "</tool_call>\n" -}}
111          {%- endfor -%}
112        {%- endif -%}
113        {{- "</assistant>\n" -}}
114      {%- endif -%}
115    {%- endgeneration -%}
116  {%- elif message.role == "tool" -%}
117    {{- "<tool_response>\n" + content + "\n</tool_response>\n" -}}
118  {%- elif message.role == "system" and loop.index0 != 0 -%}
119    {#- Render additional system messages (skip the first one which is handled separately in the header) -#}
120    {{- "<system>\n" + content + "\n</system>\n" -}}
121  {%- endif -%}
122{%- endfor -%}
123{#- ───── generation prompt ───── -#}
124{%- if add_generation_prompt -%}
125  {{- "<assistant>\n" -}}
126  {#- ───── Include reasoning mode directive ───── -#}
127  {%- if not enable_thinking %}
128    {{- '</think>' -}}
129  {%- else %}
130    {{- '<think>' -}}
131  {%- endif %}
132{%- endif -%}