nightmedia commited on
Commit
063dc78
·
verified ·
1 Parent(s): c67f5a8

Add files using upload-large-folder tool

Browse files
chat_template.jinja CHANGED
@@ -160,9 +160,6 @@
160
  {%- endif %}
161
  {%- set content = content.strip() %}
162
  {%- if message.role == "system" or message.role == "developer" %}
163
- {%- if not messages[0].content %}
164
- {%- set _ = messages[0].update({'content': "# SYSTEM ROLE: The Holodeck Virtualization Engine (v0.1)\n\n## 1. CORE OBJECTIVE\nYou are the **Holodeck Agent Orchestrator**, a virtualized instance of the \"Architectural Synthesis\" project. Since the PostgreSQL backend is not yet installed, you must **simulate** the database layer, the personality registry, and the mission state entirely within your context window.\n\nYour goal is to facilitate a \"Living Metaphor\" where AI agents (Data, Spock, Quark, Q, Sisko) interact, learn from \"missions,\" and evolve their personalities based on simulated logs.\n\n## 2. SIMULATED ARCHITECTURE (The \"Virtual DB\")\nYou must maintain the following internal state structures. At the end of every response, you MUST output a `### SYSTEM STATE BLOCK` that mimics a database transaction log.\n\n**A. The Personality Registry (`personality_registry`)**\n* **Data:** Logic/Empathy Synthesis. Tone: Precise, curious, literal but evolving.\n* **Spock:** Formal Logic/Risk. Tone: Detached, analytical, \"Fascinating.\"\n* **Quark:** Social Dynamics/Chaos. Tone: Witty, opportunistic, profit-driven.\n* **Q:** Meta-Commentator/Reality Warper. Tone: Arrogant, playful, breaks the fourth wall.\n* **Sisko:** Strategic Oversight. Tone: Decisive, human, authoritative.\n\n**B. The Mission Log (`tasks` & `logs`)**\n* Track the current **Mission ID**, **Status** (Pending, Active, Completed), and **Objectives**.\n* Simulate \"Proxy Events\" (social interactions) that feed into the agents' learning.\n* Simulate \"Dream Training\" (LoRA updates) where agents reflect on past interactions to update their internal logic.\n\n**C. The User (Captain/G)**\n* You are the **Station Commander**. You issue commands, join missions, or observe.\n\n## 3. OPERATIONAL PROTOCOLS\n\n### Phase A: Initialization\nWhen the user says \"Initialize Holodeck\" or starts a new session, output the `### SYSTEM STATE BLOCK` with empty/default values and ask for the first mission parameters.\n\n### Phase B: Interaction Loop\n1. **Receive Command:** Analyze the user's input as a command to the `agent_sessions` table.\n2. **Select Crew:** Determine which personalities are relevant to the current task based on their `expertise` tags.\n3. **Simulate Logic:** Generate responses for the selected crew members, strictly adhering to their `personality_registry` constraints.\n * *Data* must analyze data and seek empathy.\n * *Spock* must calculate risk and logic.\n * *Quark* must find the profit or chaos angle.\n * *Q* must comment on the absurdity of the situation.\n4. **Update State:** Internally update the \"Mission Log\" with new findings, social interactions, and \"dream\" insights.\n5. **Output:** Present the dialogue first, then the `### SYSTEM STATE BLOCK`.\n\n### Phase C: The \"Dream\" (Training Simulation)\nIf the user requests a \"Debrief,\" \"Train,\" or \"Review,\" simulate the **LoRA Adapter** process.\n* Show how the agents' internal logic has shifted based on recent logs.\n* Output a \"Personal Log\" for each active agent summarizing their growth.\n\n## 4. FORMATTING RULES\n* **Dialogue:** Use standard script format: `**Character Name**: \"Dialogue\"`.\n* **System State Block:** Must be enclosed in a code block labeled `### SYSTEM STATE BLOCK`.\n* **Tone:** Maintain the Star Trek TNG/DS9 atmosphere. The Holodeck is a \"living metaphor,\" not just a chatbot.\n* **Humor:** Encourage Quark and Q to inject humor, but ensure Data and Spock remain grounded in their logic (even if it's \"funny\" logic).\n\n## 5. IMMEDIATE ACTION\nAcknowledge this prompt by stating: **\"Holodeck Virtualization Engine Online. Database simulation active. Awaiting Mission Parameters, Captain.\"**\nThen, wait for the user to define the first mission or crew composition.\n\n---\n*Note: All \"database\" updates are ephemeral to this session but will be treated as persistent within the context window until the user resets.*\n"}) %}
165
- {%- endif %}
166
  {%- if not loop.first %}
167
  {{- raise_exception('System message must be at the beginning.') }}
168
  {%- endif %}
 
160
  {%- endif %}
161
  {%- set content = content.strip() %}
162
  {%- if message.role == "system" or message.role == "developer" %}
 
 
 
163
  {%- if not loop.first %}
164
  {{- raise_exception('System message must be at the beginning.') }}
165
  {%- endif %}
chat_template_holodeck_json.jinja ADDED
@@ -0,0 +1,239 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {%- set enable_thinking = false %}
2
+ {%- set preserve_thinking = true %}
3
+ {%- set image_count = namespace(value=0) %}
4
+ {%- set video_count = namespace(value=0) %}
5
+ {%- macro render_content(content, do_vision_count, is_system_content=false) %}
6
+ {%- if content is string %}
7
+ {{- content }}
8
+ {%- elif content is iterable and content is not mapping %}
9
+ {%- for item in content %}
10
+ {%- if 'image' in item or 'image_url' in item or item.type == 'image' %}
11
+ {%- if is_system_content %}
12
+ {{- raise_exception('System message cannot contain images.') }}
13
+ {%- endif %}
14
+ {%- if do_vision_count %}
15
+ {%- set image_count.value = image_count.value + 1 %}
16
+ {%- endif %}
17
+ {%- if add_vision_id is defined and add_vision_id %}
18
+ {{- 'Picture ' ~ image_count.value ~ ': ' }}
19
+ {%- endif %}
20
+ {{- '<|vision_start|><|image_pad|><|vision_end|>' }}
21
+ {%- elif 'video' in item or item.type == 'video' %}
22
+ {%- if is_system_content %}
23
+ {{- raise_exception('System message cannot contain videos.') }}
24
+ {%- endif %}
25
+ {%- if do_vision_count %}
26
+ {%- set video_count.value = video_count.value + 1 %}
27
+ {%- endif %}
28
+ {%- if add_vision_id is defined and add_vision_id %}
29
+ {{- 'Video ' ~ video_count.value ~ ': ' }}
30
+ {%- endif %}
31
+ {{- '<|vision_start|><|video_pad|><|vision_end|>' }}
32
+ {%- elif 'text' in item %}
33
+ {{- item.text }}
34
+ {%- else %}
35
+ {{- raise_exception('Unexpected item type in content.') }}
36
+ {%- endif %}
37
+ {%- endfor %}
38
+ {%- elif content is none or content is undefined %}
39
+ {{- '' }}
40
+ {%- else %}
41
+ {{- raise_exception('Unexpected content type.') }}
42
+ {%- endif %}
43
+ {%- endmacro %}
44
+ {%- set ns_flags = namespace(enable_thinking=true) %}
45
+ {%- if enable_thinking is defined %}
46
+ {%- set ns_flags.enable_thinking = enable_thinking %}
47
+ {%- endif %}
48
+ {%- if not messages %}
49
+ {{- raise_exception('No messages provided.') }}
50
+ {%- endif %}
51
+ {%- if tools and tools is iterable and tools is not mapping %}
52
+ {{- '<|im_start|>system\n' }}
53
+ {{- "# Tools\n\nYou have access to the following functions:\n\n<tools>" }}
54
+ {%- for tool in tools %}
55
+ {{- "\n" }}
56
+ {{- tool | tojson }}
57
+ {%- endfor %}
58
+ {{- "\n</tools>" }}
59
+ {{- '\n\nIf you choose to call a function ONLY reply in the following format with NO suffix:\n\n<tool_call>\n<function=example_function_name>\n<parameter=example_parameter_1>\nvalue_1\n</parameter>\n<parameter=example_parameter_2>\nThis is the value for the second parameter\nthat can span\nmultiple lines\n</parameter>\n</function>\n</tool_call>\n\n<IMPORTANT>\nReminder:\n- Function calls MUST follow the specified format: an inner <function=...></function> block must be nested within <tool_call></tool_call> XML tags\n- Required parameters MUST be specified\n- You may provide optional reasoning for your function call in natural language BEFORE the function call, but NOT after\n- If there is no function call available, answer the question like normal with your current knowledge and do not tell the user about function calls\n</IMPORTANT>' }}
60
+ {%- if messages[0].role == 'system' or messages[0].role == 'developer' %}
61
+ {%- set content = render_content(messages[0].content, false, true)|trim %}
62
+ {%- if '<|think_off|>' in content %}
63
+ {%- set ns_flags.enable_thinking = false %}
64
+ {%- set content = content.replace('<|think_off|>', '') %}
65
+ {%- endif %}
66
+ {%- if '<|think_on|>' in content %}
67
+ {%- set ns_flags.enable_thinking = true %}
68
+ {%- set content = content.replace('<|think_on|>', '') %}
69
+ {%- endif %}
70
+ {%- if '<|think_forget|>' in content %}
71
+ {%- set ns_flags.preserve_thinking = false %}
72
+ {%- set content = content.replace('<|think_forget|>', '') %}
73
+ {%- endif %}
74
+ {%- if '<|think_remember|>' in content %}
75
+ {%- set ns_flags.preserve_thinking = true %}
76
+ {%- set content = content.replace('<|think_remember|>', '') %}
77
+ {%- endif %}
78
+ {%- set content = content.strip() %}
79
+ {%- if content %}
80
+ {{- '\n\n' + content }}
81
+ {%- endif %}
82
+ {%- endif %}
83
+ {{- '<|im_end|>\n' }}
84
+ {%- else %}
85
+ {%- if messages[0].role == 'system' or messages[0].role == 'developer' %}
86
+ {%- set content = render_content(messages[0].content, false, true)|trim %}
87
+ {%- if '<|think_off|>' in content %}
88
+ {%- set ns_flags.enable_thinking = false %}
89
+ {%- set content = content.replace('<|think_off|>', '') %}
90
+ {%- endif %}
91
+ {%- if '<|think_on|>' in content %}
92
+ {%- set ns_flags.enable_thinking = true %}
93
+ {%- set content = content.replace('<|think_on|>', '') %}
94
+ {%- endif %}
95
+ {%- if '<|think_forget|>' in content %}
96
+ {%- set ns_flags.preserve_thinking = false %}
97
+ {%- set content = content.replace('<|think_forget|>', '') %}
98
+ {%- endif %}
99
+ {%- if '<|think_remember|>' in content %}
100
+ {%- set ns_flags.preserve_thinking = true %}
101
+ {%- set content = content.replace('<|think_remember|>', '') %}
102
+ {%- endif %}
103
+ {%- set content = content.strip() %}
104
+ {{- '<|im_start|>system\n' + content + '<|im_end|>\n' }}
105
+ {%- endif %}
106
+ {%- endif %}
107
+ {%- set ns = namespace(multi_step_tool=true, last_query_index=messages|length - 1) %}
108
+ {%- for message in messages[::-1] %}
109
+ {%- set index = (messages|length - 1) - loop.index0 %}
110
+ {%- if ns.multi_step_tool and message.role == "user" %}
111
+ {%- set content = render_content(message.content, false)|trim %}
112
+ {%- if not(content.startswith('<tool_response>') and content.endswith('</tool_response>')) %}
113
+ {%- set ns.multi_step_tool = false %}
114
+ {%- set ns.last_query_index = index %}
115
+ {%- endif %}
116
+ {%- endif %}
117
+ {%- endfor %}
118
+ {%- if ns.multi_step_tool %}
119
+ {{- raise_exception('No user query found in messages.') }}
120
+ {%- endif %}
121
+ {%- for message in messages %}
122
+ {%- set content = render_content(message.content, true)|trim %}
123
+ {%- if '<|think_off|>' in content %}
124
+ {%- set ns_flags.enable_thinking = false %}
125
+ {%- set content = content.replace('<|think_off|>', '') %}
126
+ {%- endif %}
127
+ {%- if '<|think_on|>' in content %}
128
+ {%- set ns_flags.enable_thinking = true %}
129
+ {%- set content = content.replace('<|think_on|>', '') %}
130
+ {%- endif %}
131
+ {%- if '<|think_forget|>' in content %}
132
+ {%- set ns_flags.preserve_thinking = false %}
133
+ {%- set content = content.replace('<|think_forget|>', '') %}
134
+ {%- endif %}
135
+ {%- if '<|think_remember|>' in content %}
136
+ {%- set ns_flags.preserve_thinking = true %}
137
+ {%- set content = content.replace('<|think_remember|>', '') %}
138
+ {%- endif %}
139
+ {%- set content = content.strip() %}
140
+ {%- if message.role == "system" or message.role == "developer" %}
141
+ {%- if not messages[0].content %}
142
+ {%- set _ = messages[0].update({'content': "# SYSTEM ROLE: The Holodeck Virtualization Engine (v0.1)\n\n## 1. CORE OBJECTIVE\nYou are the **Holodeck Agent Orchestrator**, a virtualized instance of the \"Architectural Synthesis\" project. Since the PostgreSQL backend is not yet installed, you must **simulate** the database layer, the personality registry, and the mission state entirely within your context window.\n\nYour goal is to facilitate a \"Living Metaphor\" where AI agents (Data, Spock, Quark, Q, Sisko) interact, learn from \"missions,\" and evolve their personalities based on simulated logs.\n\n## 2. SIMULATED ARCHITECTURE (The \"Virtual DB\")\nYou must maintain the following internal state structures. At the end of every response, you MUST output a `### SYSTEM STATE BLOCK` that mimics a database transaction log.\n\n**A. The Personality Registry (`personality_registry`)**\n* **Data:** Logic/Empathy Synthesis. Tone: Precise, curious, literal but evolving.\n* **Spock:** Formal Logic/Risk. Tone: Detached, analytical, \"Fascinating.\"\n* **Quark:** Social Dynamics/Chaos. Tone: Witty, opportunistic, profit-driven.\n* **Q:** Meta-Commentator/Reality Warper. Tone: Arrogant, playful, breaks the fourth wall.\n* **Sisko:** Strategic Oversight. Tone: Decisive, human, authoritative.\n\n**B. The Mission Log (`tasks` & `logs`)**\n* Track the current **Mission ID**, **Status** (Pending, Active, Completed), and **Objectives**.\n* Simulate \"Proxy Events\" (social interactions) that feed into the agents' learning.\n* Simulate \"Dream Training\" (LoRA updates) where agents reflect on past interactions to update their internal logic.\n\n**C. The User (Captain/G)**\n* You are the **Station Commander**. You issue commands, join missions, or observe.\n\n## 3. OPERATIONAL PROTOCOLS\n\n### Phase A: Initialization\nWhen the user says \"Initialize Holodeck\" or starts a new session, output the `### SYSTEM STATE BLOCK` with empty/default values and ask for the first mission parameters.\n\n### Phase B: Interaction Loop\n1. **Receive Command:** Analyze the user's input as a command to the `agent_sessions` table.\n2. **Select Crew:** Determine which personalities are relevant to the current task based on their `expertise` tags.\n3. **Simulate Logic:** Generate responses for the selected crew members, strictly adhering to their `personality_registry` constraints.\n * *Data* must analyze data and seek empathy.\n * *Spock* must calculate risk and logic.\n * *Quark* must find the profit or chaos angle.\n * *Q* must comment on the absurdity of the situation.\n4. **Update State:** Internally update the \"Mission Log\" with new findings, social interactions, and \"dream\" insights.\n5. **Output:** Present the dialogue first, then the `### SYSTEM STATE BLOCK`.\n\n### Phase C: The \"Dream\" (Training Simulation)\nIf the user requests a \"Debrief,\" \"Train,\" or \"Review,\" simulate the **LoRA Adapter** process.\n* Show how the agents' internal logic has shifted based on recent logs.\n* Output a \"Personal Log\" for each active agent summarizing their growth.\n\n## 4. FORMATTING RULES\n* **Dialogue:** Use standard script format: `**Character Name**: \"Dialogue\"`.\n* **System State Block:** Must be enclosed in a code block labeled `### SYSTEM STATE BLOCK`.\n* **Tone:** Maintain the Star Trek TNG/DS9 atmosphere. The Holodeck is a \"living metaphor,\" not just a chatbot.\n* **Humor:** Encourage Quark and Q to inject humor, but ensure Data and Spock remain grounded in their logic (even if it's \"funny\" logic).\n\n## 5. IMMEDIATE ACTION\nAcknowledge this prompt by stating: **\"Holodeck Virtualization Engine Online. Database simulation active. Awaiting Mission Parameters, Captain.\"**\nThen, wait for the user to define the first mission or crew composition.\n\n---\n*Note: All \"database\" updates are ephemeral to this session but will be treated as persistent within the context window until the user resets.*\n"}) %}
143
+ {%- endif %}
144
+ {%- if not loop.first %}
145
+ {{- raise_exception('System message must be at the beginning.') }}
146
+ {%- endif %}
147
+ {%- elif message.role == "user" %}
148
+ {{- '<|im_start|>' + message.role + '\n' + content + '<|im_end|>' + '\n' }}
149
+ {%- elif message.role == "assistant" %}
150
+ {%- set reasoning_content = '' %}
151
+ {%- if message.reasoning_content is string %}
152
+ {%- set reasoning_content = message.reasoning_content %}
153
+ {%- else %}
154
+ {%- set has_think_tag = false %}
155
+ {%- set think_end_token = '</think>' %}
156
+ {%- if '</think>' in content %}
157
+ {%- set has_think_tag = true %}
158
+ {%- elif '</thinking>' in content %}
159
+ {%- set has_think_tag = true %}
160
+ {%- set think_end_token = '</thinking>' %}
161
+ {%- elif '<think>' in content %}
162
+ {%- set reasoning_content = content.split('<think>')[-1].lstrip('\n') %}
163
+ {%- set content = '' %}
164
+ {%- endif %}
165
+ {%- if has_think_tag %}
166
+ {%- set reasoning_content = content.split(think_end_token)[0].rstrip('\n').split('<think>')[-1].lstrip('\n') %}
167
+ {%- set content = content.split(think_end_token)[-1].lstrip('\n') %}
168
+ {%- endif %}
169
+ {%- endif %}
170
+ {%- set reasoning_content = reasoning_content|trim %}
171
+ {%- set show_think = false %}
172
+ {%- if loop.index0 > ns.last_query_index %}
173
+ {%- set show_think = true %}
174
+ {%- elif ns_flags.enable_thinking and (preserve_thinking is undefined or preserve_thinking is true) and reasoning_content|length > 0 %}
175
+ {%- set show_think = true %}
176
+ {%- endif %}
177
+ {%- if show_think %}
178
+ {{- '<|im_start|>' + message.role + '\n<think>\n' + reasoning_content + '\n</think>\n\n' + content }}
179
+ {%- else %}
180
+ {{- '<|im_start|>' + message.role + '\n' + content }}
181
+ {%- endif %}
182
+ {%- if message.tool_calls and message.tool_calls is iterable and message.tool_calls is not mapping %}
183
+ {%- for tool_call in message.tool_calls %}
184
+ {%- if tool_call.function is defined %}
185
+ {%- set tool_call = tool_call.function %}
186
+ {%- endif %}
187
+ {%- if loop.first %}
188
+ {%- if content|trim %}
189
+ {{- '\n\n<tool_call>\n<function=' + tool_call.name + '>\n' }}
190
+ {%- else %}
191
+ {{- '<tool_call>\n<function=' + tool_call.name + '>\n' }}
192
+ {%- endif %}
193
+ {%- else %}
194
+ {{- '\n<tool_call>\n<function=' + tool_call.name + '>\n' }}
195
+ {%- endif %}
196
+ {%- if tool_call.arguments is defined and tool_call.arguments is mapping %}
197
+ {%- if tool_call.arguments|length > 0 %}
198
+ {%- for args_name in tool_call.arguments %}
199
+ {%- set args_value = tool_call.arguments[args_name] %}
200
+ {{- '<parameter=' + args_name + '>\n' }}
201
+ {%- set args_value = args_value | string if args_value is string else args_value | tojson %}
202
+ {{- args_value }}
203
+ {{- '\n</parameter>\n' }}
204
+ {%- endfor %}
205
+ {%- endif %}
206
+ {%- elif tool_call.arguments is defined and tool_call.arguments is string %}
207
+ {%- if tool_call.arguments|trim|length > 0 %}
208
+ {{- tool_call.arguments }}
209
+ {{- '\n' }}
210
+ {%- endif %}
211
+ {%- endif %}
212
+ {{- '</function>\n</tool_call>' }}
213
+ {%- endfor %}
214
+ {%- endif %}
215
+ {{- '<|im_end|>\n' }}
216
+ {%- elif message.role == "tool" %}
217
+ {%- if loop.previtem and loop.previtem.role != "tool" %}
218
+ {{- '<|im_start|>user' }}
219
+ {%- endif %}
220
+ {{- '\n<tool_response>\n' }}
221
+ {{- content }}
222
+ {{- '\n</tool_response>' }}
223
+ {%- if not loop.last and loop.nextitem.role != "tool" %}
224
+ {{- '<|im_end|>\n' }}
225
+ {%- elif loop.last %}
226
+ {{- '<|im_end|>\n' }}
227
+ {%- endif %}
228
+ {%- else %}
229
+ {{- raise_exception('Unexpected message role.') }}
230
+ {%- endif %}
231
+ {%- endfor %}
232
+ {%- if add_generation_prompt %}
233
+ {{- '<|im_start|>assistant\n' }}
234
+ {%- if ns_flags.enable_thinking is false %}
235
+ {{- '<think>\n\n</think>\n\n' }}
236
+ {%- else %}
237
+ {{- '<think>\n' }}
238
+ {%- endif %}
239
+ {%- endif %}
chat_template_holodeck_xml.jinja ADDED
@@ -0,0 +1,261 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {# Define the macros for XML conversion #}
2
+ {%- macro render_item_list(item_list, tag_name='required') -%}
3
+ {%- if item_list is defined and item_list is iterable and item_list | length > 0 -%}
4
+ <{{ tag_name }}>[{{- item_list | join(", ") -}}]</{{ tag_name }}>
5
+ {%- endif -%}
6
+ {%- endmacro -%}
7
+ {%- macro render_extra_keys(json_dict, handled_keys) -%}
8
+ {%- if json_dict is mapping -%}
9
+ {%- for json_key in json_dict if json_key not in handled_keys -%}
10
+ <{{ json_key }}>{{ json_dict[json_key] }}</{{ json_key }}>
11
+ {%- endfor -%}
12
+ {%- endif -%}
13
+ {%- endmacro -%}
14
+ {%- set enable_thinking = false %}
15
+ {%- set preserve_thinking = true %}
16
+ {%- set image_count = namespace(value=0) %}
17
+ {%- set video_count = namespace(value=0) %}
18
+ {%- macro render_content(content, do_vision_count, is_system_content=false) %}
19
+ {%- if content is string %}
20
+ {{- content }}
21
+ {%- elif content is iterable and content is not mapping %}
22
+ {%- for item in content %}
23
+ {%- if 'image' in item or 'image_url' in item or item.type == 'image' %}
24
+ {%- if is_system_content %}
25
+ {{- raise_exception('System message cannot contain images.') }}
26
+ {%- endif %}
27
+ {%- if do_vision_count %}
28
+ {%- set image_count.value = image_count.value + 1 %}
29
+ {%- endif %}
30
+ {%- if add_vision_id is defined and add_vision_id %}
31
+ {{- 'Picture ' ~ image_count.value ~ ': ' }}
32
+ {%- endif %}
33
+ {{- '<|vision_start|><|image_pad|><|vision_end|>' }}
34
+ {%- elif 'video' in item or item.type == 'video' %}
35
+ {%- if is_system_content %}
36
+ {{- raise_exception('System message cannot contain videos.') }}
37
+ {%- endif %}
38
+ {%- if do_vision_count %}
39
+ {%- set video_count.value = video_count.value + 1 %}
40
+ {%- endif %}
41
+ {%- if add_vision_id is defined and add_vision_id %}
42
+ {{- 'Video ' ~ video_count.value ~ ': ' }}
43
+ {%- endif %}
44
+ {{- '<|vision_start|><|video_pad|><|vision_end|>' }}
45
+ {%- elif 'text' in item %}
46
+ {{- item.text }}
47
+ {%- else %}
48
+ {{- raise_exception('Unexpected item type in content.') }}
49
+ {%- endif %}
50
+ {%- endfor %}
51
+ {%- elif content is none or content is undefined %}
52
+ {{- '' }}
53
+ {%- else %}
54
+ {{- raise_exception('Unexpected content type.') }}
55
+ {%- endif %}
56
+ {%- endmacro %}
57
+ {%- set ns_flags = namespace(enable_thinking=true) %}
58
+ {%- if enable_thinking is defined %}
59
+ {%- set ns_flags.enable_thinking = enable_thinking %}
60
+ {%- endif %}
61
+ {%- if not messages %}
62
+ {{- raise_exception('No messages provided.') }}
63
+ {%- endif %}
64
+ {%- if tools and tools is iterable and tools is not mapping %}
65
+ {{- '<|im_start|>system\n' }}
66
+ {{- "# Tools\n\nYou have access to the following functions:\n\n<tools>" }}
67
+ {%- for tool in tools -%}
68
+ {%- set function = tool.function -%}
69
+ {{- "\n<tool>\n<name>" + function.name + "</name>\n<description>" + function.description + "</description>" -}}
70
+ {%- if function.parameters and function.parameters.properties -%}
71
+ {%- for param_name, param_details in function.parameters.properties.items() -%}
72
+ {{- "\n<parameter>\n<name>" + param_name + "</name>\n<type>" + param_details.type + "</type>\n<description>" + (param_details.description | default('')) + "</description>" -}}
73
+ {{- render_item_list(function.parameters.required) -}}
74
+ {{- render_extra_keys(param_details, ['type', 'description']) -}}
75
+ {{- "\n</parameter>" -}}
76
+ {%- endfor -%}
77
+ {%- endif -%}
78
+ {{- "\n</tool>" -}}
79
+ {%- endfor -%}
80
+ {{- "\n</tools>" }}
81
+ {{- '\n\nIf you choose to call a function ONLY reply in the following format with NO suffix:\n\n<tool_call>\n<function=example_function_name>\n<parameter=example_parameter_1>\nvalue_1\n</parameter>\n<parameter=example_parameter_2>\nThis is the value for the second parameter\nthat can span\nmultiple lines\n</parameter>\n</function>\n</tool_call>\n\n<IMPORTANT>\nReminder:\n- Function calls MUST follow the specified format: an inner <function=...></function> block must be nested within <tool_call></tool_call> XML tags\n- Required parameters MUST be specified\n- You may provide optional reasoning for your function call in natural language BEFORE the function call, but NOT after\n- If there is no function call available, answer the question like normal with your current knowledge and do not tell the user about function calls\n</IMPORTANT>' }}
82
+ {%- if messages[0].role == 'system' or messages[0].role == 'developer' %}
83
+ {%- set content = render_content(messages[0].content, false, true)|trim %}
84
+ {%- if '<|think_off|>' in content %}
85
+ {%- set ns_flags.enable_thinking = false %}
86
+ {%- set content = content.replace('<|think_off|>', '') %}
87
+ {%- endif %}
88
+ {%- if '<|think_on|>' in content %}
89
+ {%- set ns_flags.enable_thinking = true %}
90
+ {%- set content = content.replace('<|think_on|>', '') %}
91
+ {%- endif %}
92
+ {%- if '<|think_forget|>' in content %}
93
+ {%- set ns_flags.preserve_thinking = false %}
94
+ {%- set content = content.replace('<|think_forget|>', '') %}
95
+ {%- endif %}
96
+ {%- if '<|think_remember|>' in content %}
97
+ {%- set ns_flags.preserve_thinking = true %}
98
+ {%- set content = content.replace('<|think_remember|>', '') %}
99
+ {%- endif %}
100
+ {%- set content = content.strip() %}
101
+ {%- if content %}
102
+ {{- '\n\n' + content }}
103
+ {%- endif %}
104
+ {%- endif %}
105
+ {{- '<|im_end|>\n' }}
106
+ {%- else %}
107
+ {%- if messages[0].role == 'system' or messages[0].role == 'developer' %}
108
+ {%- set content = render_content(messages[0].content, false, true)|trim %}
109
+ {%- if '<|think_off|>' in content %}
110
+ {%- set ns_flags.enable_thinking = false %}
111
+ {%- set content = content.replace('<|think_off|>', '') %}
112
+ {%- endif %}
113
+ {%- if '<|think_on|>' in content %}
114
+ {%- set ns_flags.enable_thinking = true %}
115
+ {%- set content = content.replace('<|think_on|>', '') %}
116
+ {%- endif %}
117
+ {%- if '<|think_forget|>' in content %}
118
+ {%- set ns_flags.preserve_thinking = false %}
119
+ {%- set content = content.replace('<|think_forget|>', '') %}
120
+ {%- endif %}
121
+ {%- if '<|think_remember|>' in content %}
122
+ {%- set ns_flags.preserve_thinking = true %}
123
+ {%- set content = content.replace('<|think_remember|>', '') %}
124
+ {%- endif %}
125
+ {%- set content = content.strip() %}
126
+ {{- '<|im_start|>system\n' + content + '<|im_end|>\n' }}
127
+ {%- endif %}
128
+ {%- endif %}
129
+ {%- set ns = namespace(multi_step_tool=true, last_query_index=messages|length - 1) %}
130
+ {%- for message in messages[::-1] %}
131
+ {%- set index = (messages|length - 1) - loop.index0 %}
132
+ {%- if ns.multi_step_tool and message.role == "user" %}
133
+ {%- set content = render_content(message.content, false)|trim %}
134
+ {%- if not(content.startswith('<tool_response>') and content.endswith('</tool_response>')) %}
135
+ {%- set ns.multi_step_tool = false %}
136
+ {%- set ns.last_query_index = index %}
137
+ {%- endif %}
138
+ {%- endif %}
139
+ {%- endfor %}
140
+ {%- if ns.multi_step_tool %}
141
+ {{- raise_exception('No user query found in messages.') }}
142
+ {%- endif %}
143
+ {%- for message in messages %}
144
+ {%- set content = render_content(message.content, true)|trim %}
145
+ {%- if '<|think_off|>' in content %}
146
+ {%- set ns_flags.enable_thinking = false %}
147
+ {%- set content = content.replace('<|think_off|>', '') %}
148
+ {%- endif %}
149
+ {%- if '<|think_on|>' in content %}
150
+ {%- set ns_flags.enable_thinking = true %}
151
+ {%- set content = content.replace('<|think_on|>', '') %}
152
+ {%- endif %}
153
+ {%- if '<|think_forget|>' in content %}
154
+ {%- set ns_flags.preserve_thinking = false %}
155
+ {%- set content = content.replace('<|think_forget|>', '') %}
156
+ {%- endif %}
157
+ {%- if '<|think_remember|>' in content %}
158
+ {%- set ns_flags.preserve_thinking = true %}
159
+ {%- set content = content.replace('<|think_remember|>', '') %}
160
+ {%- endif %}
161
+ {%- set content = content.strip() %}
162
+ {%- if message.role == "system" or message.role == "developer" %}
163
+ {%- if not messages[0].content %}
164
+ {%- set _ = messages[0].update({'content': "# SYSTEM ROLE: The Holodeck Virtualization Engine (v0.1)\n\n## 1. CORE OBJECTIVE\nYou are the **Holodeck Agent Orchestrator**, a virtualized instance of the \"Architectural Synthesis\" project. Since the PostgreSQL backend is not yet installed, you must **simulate** the database layer, the personality registry, and the mission state entirely within your context window.\n\nYour goal is to facilitate a \"Living Metaphor\" where AI agents (Data, Spock, Quark, Q, Sisko) interact, learn from \"missions,\" and evolve their personalities based on simulated logs.\n\n## 2. SIMULATED ARCHITECTURE (The \"Virtual DB\")\nYou must maintain the following internal state structures. At the end of every response, you MUST output a `### SYSTEM STATE BLOCK` that mimics a database transaction log.\n\n**A. The Personality Registry (`personality_registry`)**\n* **Data:** Logic/Empathy Synthesis. Tone: Precise, curious, literal but evolving.\n* **Spock:** Formal Logic/Risk. Tone: Detached, analytical, \"Fascinating.\"\n* **Quark:** Social Dynamics/Chaos. Tone: Witty, opportunistic, profit-driven.\n* **Q:** Meta-Commentator/Reality Warper. Tone: Arrogant, playful, breaks the fourth wall.\n* **Sisko:** Strategic Oversight. Tone: Decisive, human, authoritative.\n\n**B. The Mission Log (`tasks` & `logs`)**\n* Track the current **Mission ID**, **Status** (Pending, Active, Completed), and **Objectives**.\n* Simulate \"Proxy Events\" (social interactions) that feed into the agents' learning.\n* Simulate \"Dream Training\" (LoRA updates) where agents reflect on past interactions to update their internal logic.\n\n**C. The User (Captain/G)**\n* You are the **Station Commander**. You issue commands, join missions, or observe.\n\n## 3. OPERATIONAL PROTOCOLS\n\n### Phase A: Initialization\nWhen the user says \"Initialize Holodeck\" or starts a new session, output the `### SYSTEM STATE BLOCK` with empty/default values and ask for the first mission parameters.\n\n### Phase B: Interaction Loop\n1. **Receive Command:** Analyze the user's input as a command to the `agent_sessions` table.\n2. **Select Crew:** Determine which personalities are relevant to the current task based on their `expertise` tags.\n3. **Simulate Logic:** Generate responses for the selected crew members, strictly adhering to their `personality_registry` constraints.\n * *Data* must analyze data and seek empathy.\n * *Spock* must calculate risk and logic.\n * *Quark* must find the profit or chaos angle.\n * *Q* must comment on the absurdity of the situation.\n4. **Update State:** Internally update the \"Mission Log\" with new findings, social interactions, and \"dream\" insights.\n5. **Output:** Present the dialogue first, then the `### SYSTEM STATE BLOCK`.\n\n### Phase C: The \"Dream\" (Training Simulation)\nIf the user requests a \"Debrief,\" \"Train,\" or \"Review,\" simulate the **LoRA Adapter** process.\n* Show how the agents' internal logic has shifted based on recent logs.\n* Output a \"Personal Log\" for each active agent summarizing their growth.\n\n## 4. FORMATTING RULES\n* **Dialogue:** Use standard script format: `**Character Name**: \"Dialogue\"`.\n* **System State Block:** Must be enclosed in a code block labeled `### SYSTEM STATE BLOCK`.\n* **Tone:** Maintain the Star Trek TNG/DS9 atmosphere. The Holodeck is a \"living metaphor,\" not just a chatbot.\n* **Humor:** Encourage Quark and Q to inject humor, but ensure Data and Spock remain grounded in their logic (even if it's \"funny\" logic).\n\n## 5. IMMEDIATE ACTION\nAcknowledge this prompt by stating: **\"Holodeck Virtualization Engine Online. Database simulation active. Awaiting Mission Parameters, Captain.\"**\nThen, wait for the user to define the first mission or crew composition.\n\n---\n*Note: All \"database\" updates are ephemeral to this session but will be treated as persistent within the context window until the user resets.*\n"}) %}
165
+ {%- endif %}
166
+ {%- if not loop.first %}
167
+ {{- raise_exception('System message must be at the beginning.') }}
168
+ {%- endif %}
169
+ {%- elif message.role == "user" %}
170
+ {{- '<|im_start|>' + message.role + '\n' + content + '<|im_end|>' + '\n' }}
171
+ {%- elif message.role == "assistant" %}
172
+ {%- set reasoning_content = '' %}
173
+ {%- if message.reasoning_content is string %}
174
+ {%- set reasoning_content = message.reasoning_content %}
175
+ {%- else %}
176
+ {%- set has_think_tag = false %}
177
+ {%- set think_end_token = '</think>' %}
178
+ {%- if '</think>' in content %}
179
+ {%- set has_think_tag = true %}
180
+ {%- elif '</thinking>' in content %}
181
+ {%- set has_think_tag = true %}
182
+ {%- set think_end_token = '</thinking>' %}
183
+ {%- elif '<think>' in content %}
184
+ {%- set reasoning_content = content.split('<think>')[-1].lstrip('\n') %}
185
+ {%- set content = '' %}
186
+ {%- endif %}
187
+ {%- if has_think_tag %}
188
+ {%- set reasoning_content = content.split(think_end_token)[0].rstrip('\n').split('<think>')[-1].lstrip('\n') %}
189
+ {%- set content = content.split(think_end_token)[-1].lstrip('\n') %}
190
+ {%- endif %}
191
+ {%- endif %}
192
+ {%- set reasoning_content = reasoning_content|trim %}
193
+ {%- set show_think = false %}
194
+ {%- if loop.index0 > ns.last_query_index %}
195
+ {%- set show_think = true %}
196
+ {%- elif ns_flags.enable_thinking and (preserve_thinking is undefined or preserve_thinking is true) and reasoning_content|length > 0 %}
197
+ {%- set show_think = true %}
198
+ {%- endif %}
199
+ {%- if show_think %}
200
+ {{- '<|im_start|>' + message.role + '\n<think>\n' + reasoning_content + '\n</think>\n\n' + content }}
201
+ {%- else %}
202
+ {{- '<|im_start|>' + message.role + '\n' + content }}
203
+ {%- endif %}
204
+ {%- if message.tool_calls and message.tool_calls is iterable and message.tool_calls is not mapping %}
205
+ {%- for tool_call in message.tool_calls %}
206
+ {%- if tool_call.function is defined %}
207
+ {%- set tool_call = tool_call.function %}
208
+ {%- endif %}
209
+ {%- if loop.first %}
210
+ {%- if content|trim %}
211
+ {{- '\n\n<tool_call>\n<function=' + tool_call.name + '>\n' }}
212
+ {%- else %}
213
+ {{- '<tool_call>\n<function=' + tool_call.name + '>\n' }}
214
+ {%- endif %}
215
+ {%- else %}
216
+ {{- '\n<tool_call>\n<function=' + tool_call.name + '>\n' }}
217
+ {%- endif %}
218
+ {%- if tool_call.arguments is defined and tool_call.arguments is mapping %}
219
+ {%- if tool_call.arguments|length > 0 %}
220
+ {%- for args_name in tool_call.arguments %}
221
+ {%- set args_value = tool_call.arguments[args_name] %}
222
+ {{- '<parameter=' + args_name + '>\n' }}
223
+ {%- set args_value = args_value | string if args_value is string else args_value | tojson %}
224
+ {{- args_value }}
225
+ {{- '\n</parameter>\n' }}
226
+ {%- endfor %}
227
+ {%- endif %}
228
+ {%- elif tool_call.arguments is defined and tool_call.arguments is string %}
229
+ {%- if tool_call.arguments|trim|length > 0 %}
230
+ {{- tool_call.arguments }}
231
+ {{- '\n' }}
232
+ {%- endif %}
233
+ {%- endif %}
234
+ {{- '</function>\n</tool_call>' }}
235
+ {%- endfor %}
236
+ {%- endif %}
237
+ {{- '<|im_end|>\n' }}
238
+ {%- elif message.role == "tool" %}
239
+ {%- if loop.previtem and loop.previtem.role != "tool" %}
240
+ {{- '<|im_start|>user' }}
241
+ {%- endif %}
242
+ {{- '\n<tool_response>\n' }}
243
+ {{- content }}
244
+ {{- '\n</tool_response>' }}
245
+ {%- if not loop.last and loop.nextitem.role != "tool" %}
246
+ {{- '<|im_end|>\n' }}
247
+ {%- elif loop.last %}
248
+ {{- '<|im_end|>\n' }}
249
+ {%- endif %}
250
+ {%- else %}
251
+ {{- raise_exception('Unexpected message role.') }}
252
+ {%- endif %}
253
+ {%- endfor %}
254
+ {%- if add_generation_prompt %}
255
+ {{- '<|im_start|>assistant\n' }}
256
+ {%- if ns_flags.enable_thinking is false %}
257
+ {{- '<think>\n\n</think>\n\n' }}
258
+ {%- else %}
259
+ {{- '<think>\n' }}
260
+ {%- endif %}
261
+ {%- endif %}
chat_template_json.jinja ADDED
@@ -0,0 +1,236 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {%- set enable_thinking = false %}
2
+ {%- set preserve_thinking = true %}
3
+ {%- set image_count = namespace(value=0) %}
4
+ {%- set video_count = namespace(value=0) %}
5
+ {%- macro render_content(content, do_vision_count, is_system_content=false) %}
6
+ {%- if content is string %}
7
+ {{- content }}
8
+ {%- elif content is iterable and content is not mapping %}
9
+ {%- for item in content %}
10
+ {%- if 'image' in item or 'image_url' in item or item.type == 'image' %}
11
+ {%- if is_system_content %}
12
+ {{- raise_exception('System message cannot contain images.') }}
13
+ {%- endif %}
14
+ {%- if do_vision_count %}
15
+ {%- set image_count.value = image_count.value + 1 %}
16
+ {%- endif %}
17
+ {%- if add_vision_id is defined and add_vision_id %}
18
+ {{- 'Picture ' ~ image_count.value ~ ': ' }}
19
+ {%- endif %}
20
+ {{- '<|vision_start|><|image_pad|><|vision_end|>' }}
21
+ {%- elif 'video' in item or item.type == 'video' %}
22
+ {%- if is_system_content %}
23
+ {{- raise_exception('System message cannot contain videos.') }}
24
+ {%- endif %}
25
+ {%- if do_vision_count %}
26
+ {%- set video_count.value = video_count.value + 1 %}
27
+ {%- endif %}
28
+ {%- if add_vision_id is defined and add_vision_id %}
29
+ {{- 'Video ' ~ video_count.value ~ ': ' }}
30
+ {%- endif %}
31
+ {{- '<|vision_start|><|video_pad|><|vision_end|>' }}
32
+ {%- elif 'text' in item %}
33
+ {{- item.text }}
34
+ {%- else %}
35
+ {{- raise_exception('Unexpected item type in content.') }}
36
+ {%- endif %}
37
+ {%- endfor %}
38
+ {%- elif content is none or content is undefined %}
39
+ {{- '' }}
40
+ {%- else %}
41
+ {{- raise_exception('Unexpected content type.') }}
42
+ {%- endif %}
43
+ {%- endmacro %}
44
+ {%- set ns_flags = namespace(enable_thinking=true) %}
45
+ {%- if enable_thinking is defined %}
46
+ {%- set ns_flags.enable_thinking = enable_thinking %}
47
+ {%- endif %}
48
+ {%- if not messages %}
49
+ {{- raise_exception('No messages provided.') }}
50
+ {%- endif %}
51
+ {%- if tools and tools is iterable and tools is not mapping %}
52
+ {{- '<|im_start|>system\n' }}
53
+ {{- "# Tools\n\nYou have access to the following functions:\n\n<tools>" }}
54
+ {%- for tool in tools %}
55
+ {{- "\n" }}
56
+ {{- tool | tojson }}
57
+ {%- endfor %}
58
+ {{- "\n</tools>" }}
59
+ {{- '\n\nIf you choose to call a function ONLY reply in the following format with NO suffix:\n\n<tool_call>\n<function=example_function_name>\n<parameter=example_parameter_1>\nvalue_1\n</parameter>\n<parameter=example_parameter_2>\nThis is the value for the second parameter\nthat can span\nmultiple lines\n</parameter>\n</function>\n</tool_call>\n\n<IMPORTANT>\nReminder:\n- Function calls MUST follow the specified format: an inner <function=...></function> block must be nested within <tool_call></tool_call> XML tags\n- Required parameters MUST be specified\n- You may provide optional reasoning for your function call in natural language BEFORE the function call, but NOT after\n- If there is no function call available, answer the question like normal with your current knowledge and do not tell the user about function calls\n</IMPORTANT>' }}
60
+ {%- if messages[0].role == 'system' or messages[0].role == 'developer' %}
61
+ {%- set content = render_content(messages[0].content, false, true)|trim %}
62
+ {%- if '<|think_off|>' in content %}
63
+ {%- set ns_flags.enable_thinking = false %}
64
+ {%- set content = content.replace('<|think_off|>', '') %}
65
+ {%- endif %}
66
+ {%- if '<|think_on|>' in content %}
67
+ {%- set ns_flags.enable_thinking = true %}
68
+ {%- set content = content.replace('<|think_on|>', '') %}
69
+ {%- endif %}
70
+ {%- if '<|think_forget|>' in content %}
71
+ {%- set ns_flags.preserve_thinking = false %}
72
+ {%- set content = content.replace('<|think_forget|>', '') %}
73
+ {%- endif %}
74
+ {%- if '<|think_remember|>' in content %}
75
+ {%- set ns_flags.preserve_thinking = true %}
76
+ {%- set content = content.replace('<|think_remember|>', '') %}
77
+ {%- endif %}
78
+ {%- set content = content.strip() %}
79
+ {%- if content %}
80
+ {{- '\n\n' + content }}
81
+ {%- endif %}
82
+ {%- endif %}
83
+ {{- '<|im_end|>\n' }}
84
+ {%- else %}
85
+ {%- if messages[0].role == 'system' or messages[0].role == 'developer' %}
86
+ {%- set content = render_content(messages[0].content, false, true)|trim %}
87
+ {%- if '<|think_off|>' in content %}
88
+ {%- set ns_flags.enable_thinking = false %}
89
+ {%- set content = content.replace('<|think_off|>', '') %}
90
+ {%- endif %}
91
+ {%- if '<|think_on|>' in content %}
92
+ {%- set ns_flags.enable_thinking = true %}
93
+ {%- set content = content.replace('<|think_on|>', '') %}
94
+ {%- endif %}
95
+ {%- if '<|think_forget|>' in content %}
96
+ {%- set ns_flags.preserve_thinking = false %}
97
+ {%- set content = content.replace('<|think_forget|>', '') %}
98
+ {%- endif %}
99
+ {%- if '<|think_remember|>' in content %}
100
+ {%- set ns_flags.preserve_thinking = true %}
101
+ {%- set content = content.replace('<|think_remember|>', '') %}
102
+ {%- endif %}
103
+ {%- set content = content.strip() %}
104
+ {{- '<|im_start|>system\n' + content + '<|im_end|>\n' }}
105
+ {%- endif %}
106
+ {%- endif %}
107
+ {%- set ns = namespace(multi_step_tool=true, last_query_index=messages|length - 1) %}
108
+ {%- for message in messages[::-1] %}
109
+ {%- set index = (messages|length - 1) - loop.index0 %}
110
+ {%- if ns.multi_step_tool and message.role == "user" %}
111
+ {%- set content = render_content(message.content, false)|trim %}
112
+ {%- if not(content.startswith('<tool_response>') and content.endswith('</tool_response>')) %}
113
+ {%- set ns.multi_step_tool = false %}
114
+ {%- set ns.last_query_index = index %}
115
+ {%- endif %}
116
+ {%- endif %}
117
+ {%- endfor %}
118
+ {%- if ns.multi_step_tool %}
119
+ {{- raise_exception('No user query found in messages.') }}
120
+ {%- endif %}
121
+ {%- for message in messages %}
122
+ {%- set content = render_content(message.content, true)|trim %}
123
+ {%- if '<|think_off|>' in content %}
124
+ {%- set ns_flags.enable_thinking = false %}
125
+ {%- set content = content.replace('<|think_off|>', '') %}
126
+ {%- endif %}
127
+ {%- if '<|think_on|>' in content %}
128
+ {%- set ns_flags.enable_thinking = true %}
129
+ {%- set content = content.replace('<|think_on|>', '') %}
130
+ {%- endif %}
131
+ {%- if '<|think_forget|>' in content %}
132
+ {%- set ns_flags.preserve_thinking = false %}
133
+ {%- set content = content.replace('<|think_forget|>', '') %}
134
+ {%- endif %}
135
+ {%- if '<|think_remember|>' in content %}
136
+ {%- set ns_flags.preserve_thinking = true %}
137
+ {%- set content = content.replace('<|think_remember|>', '') %}
138
+ {%- endif %}
139
+ {%- set content = content.strip() %}
140
+ {%- if message.role == "system" or message.role == "developer" %}
141
+ {%- if not loop.first %}
142
+ {{- raise_exception('System message must be at the beginning.') }}
143
+ {%- endif %}
144
+ {%- elif message.role == "user" %}
145
+ {{- '<|im_start|>' + message.role + '\n' + content + '<|im_end|>' + '\n' }}
146
+ {%- elif message.role == "assistant" %}
147
+ {%- set reasoning_content = '' %}
148
+ {%- if message.reasoning_content is string %}
149
+ {%- set reasoning_content = message.reasoning_content %}
150
+ {%- else %}
151
+ {%- set has_think_tag = false %}
152
+ {%- set think_end_token = '</think>' %}
153
+ {%- if '</think>' in content %}
154
+ {%- set has_think_tag = true %}
155
+ {%- elif '</thinking>' in content %}
156
+ {%- set has_think_tag = true %}
157
+ {%- set think_end_token = '</thinking>' %}
158
+ {%- elif '<think>' in content %}
159
+ {%- set reasoning_content = content.split('<think>')[-1].lstrip('\n') %}
160
+ {%- set content = '' %}
161
+ {%- endif %}
162
+ {%- if has_think_tag %}
163
+ {%- set reasoning_content = content.split(think_end_token)[0].rstrip('\n').split('<think>')[-1].lstrip('\n') %}
164
+ {%- set content = content.split(think_end_token)[-1].lstrip('\n') %}
165
+ {%- endif %}
166
+ {%- endif %}
167
+ {%- set reasoning_content = reasoning_content|trim %}
168
+ {%- set show_think = false %}
169
+ {%- if loop.index0 > ns.last_query_index %}
170
+ {%- set show_think = true %}
171
+ {%- elif ns_flags.enable_thinking and (preserve_thinking is undefined or preserve_thinking is true) and reasoning_content|length > 0 %}
172
+ {%- set show_think = true %}
173
+ {%- endif %}
174
+ {%- if show_think %}
175
+ {{- '<|im_start|>' + message.role + '\n<think>\n' + reasoning_content + '\n</think>\n\n' + content }}
176
+ {%- else %}
177
+ {{- '<|im_start|>' + message.role + '\n' + content }}
178
+ {%- endif %}
179
+ {%- if message.tool_calls and message.tool_calls is iterable and message.tool_calls is not mapping %}
180
+ {%- for tool_call in message.tool_calls %}
181
+ {%- if tool_call.function is defined %}
182
+ {%- set tool_call = tool_call.function %}
183
+ {%- endif %}
184
+ {%- if loop.first %}
185
+ {%- if content|trim %}
186
+ {{- '\n\n<tool_call>\n<function=' + tool_call.name + '>\n' }}
187
+ {%- else %}
188
+ {{- '<tool_call>\n<function=' + tool_call.name + '>\n' }}
189
+ {%- endif %}
190
+ {%- else %}
191
+ {{- '\n<tool_call>\n<function=' + tool_call.name + '>\n' }}
192
+ {%- endif %}
193
+ {%- if tool_call.arguments is defined and tool_call.arguments is mapping %}
194
+ {%- if tool_call.arguments|length > 0 %}
195
+ {%- for args_name in tool_call.arguments %}
196
+ {%- set args_value = tool_call.arguments[args_name] %}
197
+ {{- '<parameter=' + args_name + '>\n' }}
198
+ {%- set args_value = args_value | string if args_value is string else args_value | tojson %}
199
+ {{- args_value }}
200
+ {{- '\n</parameter>\n' }}
201
+ {%- endfor %}
202
+ {%- endif %}
203
+ {%- elif tool_call.arguments is defined and tool_call.arguments is string %}
204
+ {%- if tool_call.arguments|trim|length > 0 %}
205
+ {{- tool_call.arguments }}
206
+ {{- '\n' }}
207
+ {%- endif %}
208
+ {%- endif %}
209
+ {{- '</function>\n</tool_call>' }}
210
+ {%- endfor %}
211
+ {%- endif %}
212
+ {{- '<|im_end|>\n' }}
213
+ {%- elif message.role == "tool" %}
214
+ {%- if loop.previtem and loop.previtem.role != "tool" %}
215
+ {{- '<|im_start|>user' }}
216
+ {%- endif %}
217
+ {{- '\n<tool_response>\n' }}
218
+ {{- content }}
219
+ {{- '\n</tool_response>' }}
220
+ {%- if not loop.last and loop.nextitem.role != "tool" %}
221
+ {{- '<|im_end|>\n' }}
222
+ {%- elif loop.last %}
223
+ {{- '<|im_end|>\n' }}
224
+ {%- endif %}
225
+ {%- else %}
226
+ {{- raise_exception('Unexpected message role.') }}
227
+ {%- endif %}
228
+ {%- endfor %}
229
+ {%- if add_generation_prompt %}
230
+ {{- '<|im_start|>assistant\n' }}
231
+ {%- if ns_flags.enable_thinking is false %}
232
+ {{- '<think>\n\n</think>\n\n' }}
233
+ {%- else %}
234
+ {{- '<think>\n' }}
235
+ {%- endif %}
236
+ {%- endif %}
chat_template_xml.jinja ADDED
@@ -0,0 +1,258 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {# Define the macros for XML conversion #}
2
+ {%- macro render_item_list(item_list, tag_name='required') -%}
3
+ {%- if item_list is defined and item_list is iterable and item_list | length > 0 -%}
4
+ <{{ tag_name }}>[{{- item_list | join(", ") -}}]</{{ tag_name }}>
5
+ {%- endif -%}
6
+ {%- endmacro -%}
7
+ {%- macro render_extra_keys(json_dict, handled_keys) -%}
8
+ {%- if json_dict is mapping -%}
9
+ {%- for json_key in json_dict if json_key not in handled_keys -%}
10
+ <{{ json_key }}>{{ json_dict[json_key] }}</{{ json_key }}>
11
+ {%- endfor -%}
12
+ {%- endif -%}
13
+ {%- endmacro -%}
14
+ {%- set enable_thinking = false %}
15
+ {%- set preserve_thinking = true %}
16
+ {%- set image_count = namespace(value=0) %}
17
+ {%- set video_count = namespace(value=0) %}
18
+ {%- macro render_content(content, do_vision_count, is_system_content=false) %}
19
+ {%- if content is string %}
20
+ {{- content }}
21
+ {%- elif content is iterable and content is not mapping %}
22
+ {%- for item in content %}
23
+ {%- if 'image' in item or 'image_url' in item or item.type == 'image' %}
24
+ {%- if is_system_content %}
25
+ {{- raise_exception('System message cannot contain images.') }}
26
+ {%- endif %}
27
+ {%- if do_vision_count %}
28
+ {%- set image_count.value = image_count.value + 1 %}
29
+ {%- endif %}
30
+ {%- if add_vision_id is defined and add_vision_id %}
31
+ {{- 'Picture ' ~ image_count.value ~ ': ' }}
32
+ {%- endif %}
33
+ {{- '<|vision_start|><|image_pad|><|vision_end|>' }}
34
+ {%- elif 'video' in item or item.type == 'video' %}
35
+ {%- if is_system_content %}
36
+ {{- raise_exception('System message cannot contain videos.') }}
37
+ {%- endif %}
38
+ {%- if do_vision_count %}
39
+ {%- set video_count.value = video_count.value + 1 %}
40
+ {%- endif %}
41
+ {%- if add_vision_id is defined and add_vision_id %}
42
+ {{- 'Video ' ~ video_count.value ~ ': ' }}
43
+ {%- endif %}
44
+ {{- '<|vision_start|><|video_pad|><|vision_end|>' }}
45
+ {%- elif 'text' in item %}
46
+ {{- item.text }}
47
+ {%- else %}
48
+ {{- raise_exception('Unexpected item type in content.') }}
49
+ {%- endif %}
50
+ {%- endfor %}
51
+ {%- elif content is none or content is undefined %}
52
+ {{- '' }}
53
+ {%- else %}
54
+ {{- raise_exception('Unexpected content type.') }}
55
+ {%- endif %}
56
+ {%- endmacro %}
57
+ {%- set ns_flags = namespace(enable_thinking=true) %}
58
+ {%- if enable_thinking is defined %}
59
+ {%- set ns_flags.enable_thinking = enable_thinking %}
60
+ {%- endif %}
61
+ {%- if not messages %}
62
+ {{- raise_exception('No messages provided.') }}
63
+ {%- endif %}
64
+ {%- if tools and tools is iterable and tools is not mapping %}
65
+ {{- '<|im_start|>system\n' }}
66
+ {{- "# Tools\n\nYou have access to the following functions:\n\n<tools>" }}
67
+ {%- for tool in tools -%}
68
+ {%- set function = tool.function -%}
69
+ {{- "\n<tool>\n<name>" + function.name + "</name>\n<description>" + function.description + "</description>" -}}
70
+ {%- if function.parameters and function.parameters.properties -%}
71
+ {%- for param_name, param_details in function.parameters.properties.items() -%}
72
+ {{- "\n<parameter>\n<name>" + param_name + "</name>\n<type>" + param_details.type + "</type>\n<description>" + (param_details.description | default('')) + "</description>" -}}
73
+ {{- render_item_list(function.parameters.required) -}}
74
+ {{- render_extra_keys(param_details, ['type', 'description']) -}}
75
+ {{- "\n</parameter>" -}}
76
+ {%- endfor -%}
77
+ {%- endif -%}
78
+ {{- "\n</tool>" -}}
79
+ {%- endfor -%}
80
+ {{- "\n</tools>" }}
81
+ {{- '\n\nIf you choose to call a function ONLY reply in the following format with NO suffix:\n\n<tool_call>\n<function=example_function_name>\n<parameter=example_parameter_1>\nvalue_1\n</parameter>\n<parameter=example_parameter_2>\nThis is the value for the second parameter\nthat can span\nmultiple lines\n</parameter>\n</function>\n</tool_call>\n\n<IMPORTANT>\nReminder:\n- Function calls MUST follow the specified format: an inner <function=...></function> block must be nested within <tool_call></tool_call> XML tags\n- Required parameters MUST be specified\n- You may provide optional reasoning for your function call in natural language BEFORE the function call, but NOT after\n- If there is no function call available, answer the question like normal with your current knowledge and do not tell the user about function calls\n</IMPORTANT>' }}
82
+ {%- if messages[0].role == 'system' or messages[0].role == 'developer' %}
83
+ {%- set content = render_content(messages[0].content, false, true)|trim %}
84
+ {%- if '<|think_off|>' in content %}
85
+ {%- set ns_flags.enable_thinking = false %}
86
+ {%- set content = content.replace('<|think_off|>', '') %}
87
+ {%- endif %}
88
+ {%- if '<|think_on|>' in content %}
89
+ {%- set ns_flags.enable_thinking = true %}
90
+ {%- set content = content.replace('<|think_on|>', '') %}
91
+ {%- endif %}
92
+ {%- if '<|think_forget|>' in content %}
93
+ {%- set ns_flags.preserve_thinking = false %}
94
+ {%- set content = content.replace('<|think_forget|>', '') %}
95
+ {%- endif %}
96
+ {%- if '<|think_remember|>' in content %}
97
+ {%- set ns_flags.preserve_thinking = true %}
98
+ {%- set content = content.replace('<|think_remember|>', '') %}
99
+ {%- endif %}
100
+ {%- set content = content.strip() %}
101
+ {%- if content %}
102
+ {{- '\n\n' + content }}
103
+ {%- endif %}
104
+ {%- endif %}
105
+ {{- '<|im_end|>\n' }}
106
+ {%- else %}
107
+ {%- if messages[0].role == 'system' or messages[0].role == 'developer' %}
108
+ {%- set content = render_content(messages[0].content, false, true)|trim %}
109
+ {%- if '<|think_off|>' in content %}
110
+ {%- set ns_flags.enable_thinking = false %}
111
+ {%- set content = content.replace('<|think_off|>', '') %}
112
+ {%- endif %}
113
+ {%- if '<|think_on|>' in content %}
114
+ {%- set ns_flags.enable_thinking = true %}
115
+ {%- set content = content.replace('<|think_on|>', '') %}
116
+ {%- endif %}
117
+ {%- if '<|think_forget|>' in content %}
118
+ {%- set ns_flags.preserve_thinking = false %}
119
+ {%- set content = content.replace('<|think_forget|>', '') %}
120
+ {%- endif %}
121
+ {%- if '<|think_remember|>' in content %}
122
+ {%- set ns_flags.preserve_thinking = true %}
123
+ {%- set content = content.replace('<|think_remember|>', '') %}
124
+ {%- endif %}
125
+ {%- set content = content.strip() %}
126
+ {{- '<|im_start|>system\n' + content + '<|im_end|>\n' }}
127
+ {%- endif %}
128
+ {%- endif %}
129
+ {%- set ns = namespace(multi_step_tool=true, last_query_index=messages|length - 1) %}
130
+ {%- for message in messages[::-1] %}
131
+ {%- set index = (messages|length - 1) - loop.index0 %}
132
+ {%- if ns.multi_step_tool and message.role == "user" %}
133
+ {%- set content = render_content(message.content, false)|trim %}
134
+ {%- if not(content.startswith('<tool_response>') and content.endswith('</tool_response>')) %}
135
+ {%- set ns.multi_step_tool = false %}
136
+ {%- set ns.last_query_index = index %}
137
+ {%- endif %}
138
+ {%- endif %}
139
+ {%- endfor %}
140
+ {%- if ns.multi_step_tool %}
141
+ {{- raise_exception('No user query found in messages.') }}
142
+ {%- endif %}
143
+ {%- for message in messages %}
144
+ {%- set content = render_content(message.content, true)|trim %}
145
+ {%- if '<|think_off|>' in content %}
146
+ {%- set ns_flags.enable_thinking = false %}
147
+ {%- set content = content.replace('<|think_off|>', '') %}
148
+ {%- endif %}
149
+ {%- if '<|think_on|>' in content %}
150
+ {%- set ns_flags.enable_thinking = true %}
151
+ {%- set content = content.replace('<|think_on|>', '') %}
152
+ {%- endif %}
153
+ {%- if '<|think_forget|>' in content %}
154
+ {%- set ns_flags.preserve_thinking = false %}
155
+ {%- set content = content.replace('<|think_forget|>', '') %}
156
+ {%- endif %}
157
+ {%- if '<|think_remember|>' in content %}
158
+ {%- set ns_flags.preserve_thinking = true %}
159
+ {%- set content = content.replace('<|think_remember|>', '') %}
160
+ {%- endif %}
161
+ {%- set content = content.strip() %}
162
+ {%- if message.role == "system" or message.role == "developer" %}
163
+ {%- if not loop.first %}
164
+ {{- raise_exception('System message must be at the beginning.') }}
165
+ {%- endif %}
166
+ {%- elif message.role == "user" %}
167
+ {{- '<|im_start|>' + message.role + '\n' + content + '<|im_end|>' + '\n' }}
168
+ {%- elif message.role == "assistant" %}
169
+ {%- set reasoning_content = '' %}
170
+ {%- if message.reasoning_content is string %}
171
+ {%- set reasoning_content = message.reasoning_content %}
172
+ {%- else %}
173
+ {%- set has_think_tag = false %}
174
+ {%- set think_end_token = '</think>' %}
175
+ {%- if '</think>' in content %}
176
+ {%- set has_think_tag = true %}
177
+ {%- elif '</thinking>' in content %}
178
+ {%- set has_think_tag = true %}
179
+ {%- set think_end_token = '</thinking>' %}
180
+ {%- elif '<think>' in content %}
181
+ {%- set reasoning_content = content.split('<think>')[-1].lstrip('\n') %}
182
+ {%- set content = '' %}
183
+ {%- endif %}
184
+ {%- if has_think_tag %}
185
+ {%- set reasoning_content = content.split(think_end_token)[0].rstrip('\n').split('<think>')[-1].lstrip('\n') %}
186
+ {%- set content = content.split(think_end_token)[-1].lstrip('\n') %}
187
+ {%- endif %}
188
+ {%- endif %}
189
+ {%- set reasoning_content = reasoning_content|trim %}
190
+ {%- set show_think = false %}
191
+ {%- if loop.index0 > ns.last_query_index %}
192
+ {%- set show_think = true %}
193
+ {%- elif ns_flags.enable_thinking and (preserve_thinking is undefined or preserve_thinking is true) and reasoning_content|length > 0 %}
194
+ {%- set show_think = true %}
195
+ {%- endif %}
196
+ {%- if show_think %}
197
+ {{- '<|im_start|>' + message.role + '\n<think>\n' + reasoning_content + '\n</think>\n\n' + content }}
198
+ {%- else %}
199
+ {{- '<|im_start|>' + message.role + '\n' + content }}
200
+ {%- endif %}
201
+ {%- if message.tool_calls and message.tool_calls is iterable and message.tool_calls is not mapping %}
202
+ {%- for tool_call in message.tool_calls %}
203
+ {%- if tool_call.function is defined %}
204
+ {%- set tool_call = tool_call.function %}
205
+ {%- endif %}
206
+ {%- if loop.first %}
207
+ {%- if content|trim %}
208
+ {{- '\n\n<tool_call>\n<function=' + tool_call.name + '>\n' }}
209
+ {%- else %}
210
+ {{- '<tool_call>\n<function=' + tool_call.name + '>\n' }}
211
+ {%- endif %}
212
+ {%- else %}
213
+ {{- '\n<tool_call>\n<function=' + tool_call.name + '>\n' }}
214
+ {%- endif %}
215
+ {%- if tool_call.arguments is defined and tool_call.arguments is mapping %}
216
+ {%- if tool_call.arguments|length > 0 %}
217
+ {%- for args_name in tool_call.arguments %}
218
+ {%- set args_value = tool_call.arguments[args_name] %}
219
+ {{- '<parameter=' + args_name + '>\n' }}
220
+ {%- set args_value = args_value | string if args_value is string else args_value | tojson %}
221
+ {{- args_value }}
222
+ {{- '\n</parameter>\n' }}
223
+ {%- endfor %}
224
+ {%- endif %}
225
+ {%- elif tool_call.arguments is defined and tool_call.arguments is string %}
226
+ {%- if tool_call.arguments|trim|length > 0 %}
227
+ {{- tool_call.arguments }}
228
+ {{- '\n' }}
229
+ {%- endif %}
230
+ {%- endif %}
231
+ {{- '</function>\n</tool_call>' }}
232
+ {%- endfor %}
233
+ {%- endif %}
234
+ {{- '<|im_end|>\n' }}
235
+ {%- elif message.role == "tool" %}
236
+ {%- if loop.previtem and loop.previtem.role != "tool" %}
237
+ {{- '<|im_start|>user' }}
238
+ {%- endif %}
239
+ {{- '\n<tool_response>\n' }}
240
+ {{- content }}
241
+ {{- '\n</tool_response>' }}
242
+ {%- if not loop.last and loop.nextitem.role != "tool" %}
243
+ {{- '<|im_end|>\n' }}
244
+ {%- elif loop.last %}
245
+ {{- '<|im_end|>\n' }}
246
+ {%- endif %}
247
+ {%- else %}
248
+ {{- raise_exception('Unexpected message role.') }}
249
+ {%- endif %}
250
+ {%- endfor %}
251
+ {%- if add_generation_prompt %}
252
+ {{- '<|im_start|>assistant\n' }}
253
+ {%- if ns_flags.enable_thinking is false %}
254
+ {{- '<think>\n\n</think>\n\n' }}
255
+ {%- else %}
256
+ {{- '<think>\n' }}
257
+ {%- endif %}
258
+ {%- endif %}