char-fork/llama.cpp
git clone https://git.t4t.associates/char-fork/llama.cpp
ad1de39e0
char/aliceai-t5-moe
1{%- macro escape_attr ( value ) - %} 2{{ - value | string | replace ( '&' , '&' )| replace ( '"', ' & quot ; ') -}} 3{%- endmacro -%} 4 5{%- macro open_tag(tag, attrs=[]) -%} 6{{- ' <| open |> ' + tag -}} 7{%- for attr in attrs -%} 8{{- ' ' + attr[0] + ' = "' - }}{{ - escape_attr ( attr [ 1 ]) - }}{{ - '"' -}} 9{%- endfor -%} 10{{- ' <| sep |> ' -}} 11{%- endmacro -%} 12 13{%- macro close_tag(tag) -%} 14{{- ' <| close |> ' + tag + ' <| sep |> ' -}} 15{%- endmacro -%} 16 17{%- macro next_image(state) -%} 18{%- if image_prompts is defined and image_prompts is not none -%} 19{%- if state.image_index >= image_prompts|length -%} 20{{- raise_exception(' More image placeholders than image prompts . ') -}} 21{%- endif -%} 22{{- image_prompts[state.image_index] -}} 23{%- set state.image_index = state.image_index + 1 -%} 24{%- else -%} 25{{- ' <| kimi_image_placeholder |> ' -}} 26{%- endif -%} 27{%- endmacro -%} 28 29{%- macro render_text(text, state) -%} 30{%- set text = text|string -%} 31{%- if image_prompts is defined and image_prompts is not none and ' <| kimi_image_placeholder |> ' in text -%} 32{%- set parts = text.split(' <| kimi_image_placeholder |> ') -%} 33{%- for part in parts -%} 34{{- part -}} 35{%- if not loop.last -%}{{- next_image(state) -}}{%- endif -%} 36{%- endfor -%} 37{%- else -%} 38{{- text -}} 39{%- endif -%} 40{%- endmacro -%} 41 42{%- macro render_content(content, state) -%} 43{%- if content is string -%} 44{{- render_text(content, state) -}} 45{%- elif content is not none and content is defined -%} 46{%- for part in content -%} 47{%- if part.type in [' image ', ' image_url '] -%} 48{{- next_image(state) -}} 49{%- else -%} 50{{- render_text(part.text, state) -}} 51{%- endif -%} 52{%- endfor -%} 53{%- endif -%} 54{%- endmacro -%} 55 56{%- macro internal_system_message(message_type, body) -%} 57{{- open_tag(' message ', [(' role ', ' system '), (' type ', message_type)]) -}} 58{{- body|trim -}} 59{{- close_tag(' message ') -}} 60{{- ' <| end_of_msg |> ' -}} 61{%- endmacro -%} 62 63{%- macro json_sorted(value) -%} 64{#- tojson has no sort_keys, so sort each mapping level with dictsort to match the 65reference implementation. Array order is kept as-is. -#} 66{%- if value is mapping -%} 67{{- '{' -}} 68{%- for key, item in value|dictsort -%} 69{%- if not loop.first -%}{{- ' , ' -}}{%- endif -%} 70{{- key|tojson(ensure_ascii=false) -}}{{- ' : ' -}}{{- json_sorted(item) -}} 71{%- endfor -%} 72{{- '}' -}} 73{%- elif value is string or value is number or value is boolean or value is none -%} 74{{- value|tojson(ensure_ascii=false) -}} 75{%- else -%} 76{{- ' [ ' -}} 77{%- for item in value -%} 78{%- if not loop.first -%}{{- ' , ' -}}{%- endif -%} 79{{- json_sorted(item) -}} 80{%- endfor -%} 81{{- ' ] ' -}} 82{%- endif -%} 83{%- endmacro -%} 84 85{%- macro render_tool_declare(tool_list, dynamic=false) -%} 86{{- open_tag(' message ', [(' role ', ' system '), (' type ', ' tool - declare ')]) -}} 87{%- if dynamic -%} 88{{- '## New Tools Available \ nThe system dynamically extends the toolset via lazy - loading .\ nYou have access to all existing and extended tools .\ nHere are the specs for the extended tools .\ n \ n ``` json \ n ' -}} 89{%- else -%} 90{{- '# Tools \ nHere are the available tools , described in JSONSchema .\ n \ n ``` json \ n ' -}} 91{%- endif -%} 92{{- json_sorted(tool_list) -}} 93{{- ' \ n ``` ' -}} 94{{- close_tag(' message ') -}} 95{{- ' <| end_of_msg |> ' -}} 96{%- endmacro -%} 97 98{%- macro xtml_type(value) -%} 99{%- if value is boolean -%}boolean 100{%- elif value is none -%}null 101{%- elif value is number -%}number 102{%- elif value is string -%}string 103{%- elif value is mapping -%}object 104{%- else -%}array 105{%- endif -%} 106{%- endmacro -%} 107 108{%- macro xtml_value(value) -%} 109{%- if value is string -%} 110{{- value -}} 111{%- else -%} 112{{- value|tojson(ensure_ascii=false) -}} 113{%- endif -%} 114{%- endmacro -%} 115 116{%- macro render_assistant(message, state) -%} 117{%- if thinking -%} 118{%- set reasoning_content = message.get(' reasoning_content ') or message.get(' reasoning ') -%} 119{{- open_tag(' think ') -}} 120{%- if reasoning_content is not none and reasoning_content|string|trim -%} 121{{- render_text(reasoning_content, state) -}} 122{%- endif -%} 123{{- close_tag(' think ') -}} 124{%- endif -%} 125{{- open_tag(' response ') -}} 126{{- render_content(message.get(' content '), state) -}} 127{{- close_tag(' response ') -}} 128{%- set tool_calls = message.get(' tool_calls ') -%} 129{%- if tool_calls -%} 130{{- open_tag(' tools ') -}} 131{%- for tool_call in tool_calls -%} 132{%- if tool_call is not mapping -%} 133{{- raise_exception(' Kimi K3 tool calls must be mappings . ') -}} 134{%- endif -%} 135{%- set fn = tool_call.function if tool_call.function is defined and tool_call.function is mapping else tool_call -%} 136{%- if fn.get(' name ') is none -%} 137{{- raise_exception(' Kimi K3 tool calls require a function name . ') -}} 138{%- endif -%} 139{{- open_tag(' call ', [(' tool ', fn.name), (' index ', loop.index)]) -}} 140{%- set arguments = fn.get(' arguments ', {}) -%} 141{%- set json_block = fn.get(' _xtml_json_block ') -%} 142{%- if json_block is not none -%} 143{{- open_tag(' json ', [(' type ', ' object ')]) -}} 144{{- render_text(json_block, state) -}} 145{{- close_tag(' json ') -}} 146{%- elif arguments is mapping -%} 147{%- for key, value in arguments.items() -%} 148{{- open_tag(' argument ', [(' key ', key), (' type ', xtml_type(value))]) -}} 149{{- render_text(xtml_value(value), state) -}} 150{{- close_tag(' argument ') -}} 151{%- endfor -%} 152{%- elif arguments is string and arguments|trim -%} 153{{- open_tag(' json ', [(' type ', ' object ')]) -}} 154{{- render_text(arguments, state) -}} 155{{- close_tag(' json ') -}} 156{%- elif arguments is not none and arguments is not string -%} 157{{- raise_exception(' Kimi K3 tool call arguments must be a mapping or a JSON object string . ') -}} 158{%- endif -%} 159{{- close_tag(' call ') -}} 160{%- endfor -%} 161{{- close_tag(' tools ') -}} 162{%- endif -%} 163{%- endmacro -%} 164 165{%- macro render_tool_message(message, state, resolved_name=none) -%} 166{%- set state.tool_index = state.tool_index + 1 -%} 167{%- if resolved_name is not none -%} 168{%- set tool_name = resolved_name -%} 169{%- elif ' tool ' in message -%} 170{%- set tool_name = message.get(' tool ') -%} 171{%- else -%} 172{%- set tool_name = message.get(' name ') -%} 173{%- endif -%} 174{%- if tool_name is none and state.tool_calls is not none and state.tool_index <= state.tool_calls|length -%} 175{%- set fallback_call = state.tool_calls[state.tool_index - 1] -%} 176{%- set fallback_fn = fallback_call.function if fallback_call.function is defined and fallback_call.function is mapping else fallback_call -%} 177{%- set tool_name = fallback_fn.name -%} 178{%- endif -%} 179{%- if tool_name is none -%} 180{{- raise_exception(' Kimi K3 tool messages need a resolvable tool name : carry ` tool `/` name `, or match a preceding assistant tool_call by order . ') -}} 181{%- endif -%} 182{{- open_tag(' message ', [(' role ', ' tool '), (' tool ', tool_name), (' index ', state.tool_index)]) -}} 183{{- render_content(message.get(' content '), state) -}} 184{{- close_tag(' message ') -}} 185{{- ' <| end_of_msg |> ' -}} 186{%- endmacro -%} 187 188{%- if thinking is undefined -%} 189{%- set thinking = true -%} 190{%- endif -%} 191{%- if thinking_effort is undefined -%} 192{%- set thinking_effort = ' max ' -%} 193{%- endif -%} 194{%- if thinking and thinking_effort is not none and thinking_effort not in [' low ', ' high ', ' max '] -%} 195{{- raise_exception(' Unsupported thinking_effort = ' + thinking_effort|string + ' ; supported values are low , high , and max . ') -}} 196{%- endif -%} 197 198{%- set state = namespace(image_index=0, tool_calls=none, tool_index=0, response_schema=none) -%} 199 200{%- if tools is defined and tools -%} 201{{- render_tool_declare(tools) -}} 202{%- endif -%} 203 204{%- if thinking and thinking_effort in [' low ', ' high ', ' max '] -%} 205{{- internal_system_message( 206' thinking - effort ', 207' ` thinking_effort ` guides on how much to think in your thinking channel ( not including the response channel ), supported values include ` low `, ` medium `, ` high `, and ` max `.\ nNow the system is invoked with ` thinking_effort = ' + thinking_effort|string + ' `. ' 208) -}} 209{%- endif -%} 210 211{%- for message in messages -%} 212{%- if message is mapping -%} 213{%- if ' role ' not in message -%} 214{{- raise_exception(' Kimi K3 messages require a role . ') -}} 215{%- elif message.role == ' user ' -%} 216{%- set attrs = [(' role ', ' user ')] -%} 217{%- if message.get(' name ') -%}{%- set attrs = attrs + [(' name ', message.name)] -%}{%- endif -%} 218{{- open_tag(' message ', attrs) -}} 219{{- render_content(message.get(' content '), state) -}} 220{{- close_tag(' message ') -}} 221{{- ' <| end_of_msg |> ' -}} 222{%- elif message.role == ' system ' and message.get(' tools ') -%} 223{{- render_tool_declare(message.tools, dynamic=true) -}} 224{%- elif message.role == ' system ' -%} 225{%- set attrs = [(' role ', ' system ')] -%} 226{%- if message.get(' name ') -%}{%- set attrs = attrs + [(' name ', message.name)] -%}{%- endif -%} 227{{- open_tag(' message ', attrs) -}} 228{{- render_content(message.get(' content '), state) -}} 229{{- close_tag(' message ') -}} 230{{- ' <| end_of_msg |> ' -}} 231{%- elif message.role == ' assistant ' -%} 232{%- set state.tool_calls = message.get(' tool_calls ') -%} 233{%- set state.tool_index = 0 -%} 234{%- set attrs = [(' role ', ' assistant ')] -%} 235{%- if message.get(' name ') -%}{%- set attrs = attrs + [(' name ', message.name)] -%}{%- endif -%} 236{{- open_tag(' message ', attrs) -}} 237{{- render_assistant(message, state) -}} 238{{- close_tag(' message ') -}} 239{{- ' <| end_of_msg |> ' -}} 240{%- elif message.role == ' tool ' and (loop.first or messages[loop.index0 - 1].role != ' tool ') -%} 241{%- set run = namespace(tool_messages=[], resolved_count=0) -%} 242{%- for candidate in messages[loop.index0:] -%} 243{%- if candidate is not mapping or candidate.role != ' tool ' -%}{%- break -%}{%- endif -%} 244{%- set run.tool_messages = run.tool_messages + [candidate] -%} 245{%- set call_id = candidate.get(' tool_call_id ', candidate.get(' id ')) -%} 246{%- set match = namespace(found=false) -%} 247{%- if call_id is not none and state.tool_calls is not none -%} 248{%- for tool_call in state.tool_calls -%} 249{%- if not match.found and tool_call is mapping and tool_call.get(' id ') is not none and tool_call.get(' id ')|string == call_id|string -%} 250{%- set match.found = true -%} 251{%- endif -%} 252{%- endfor -%} 253{%- endif -%} 254{%- if match.found -%}{%- set run.resolved_count = run.resolved_count + 1 -%}{%- endif -%} 255{%- endfor -%} 256{%- if run.tool_messages|length > 0 and run.resolved_count == run.tool_messages|length -%} 257{%- set emitted = namespace(ids=[]) -%} 258{%- for tool_call in state.tool_calls -%} 259{%- if tool_call is mapping and tool_call.get(' id ') is not none and tool_call.get(' id ')|string not in emitted.ids -%} 260{%- set emitted.ids = emitted.ids + [tool_call.get(' id ')|string] -%} 261{%- set fn = tool_call.function if tool_call.function is defined and tool_call.function is mapping else tool_call -%} 262{%- for tool_message in run.tool_messages -%} 263{%- set result_id = tool_message.get(' tool_call_id ', tool_message.get(' id ')) -%} 264{%- if result_id is not none and result_id|string == tool_call.get(' id ')|string -%} 265{{- render_tool_message(tool_message, state, fn.get(' name ')) -}} 266{%- endif -%} 267{%- endfor -%} 268{%- endif -%} 269{%- endfor -%} 270{%- else -%} 271{%- for tool_message in run.tool_messages -%} 272{{- render_tool_message(tool_message, state) -}} 273{%- endfor -%} 274{%- endif -%} 275{%- endif -%} 276{%- endif -%} 277{%- endfor -%} 278 279{%- if tool_choice is defined and tool_choice == ' required ' -%} 280{{- internal_system_message(' tool - choice ', ' The system is invoked with ` tool_choice = required `.\ nYou MUST call tools in the next message . ') -}} 281{%- elif tool_choice is defined and tool_choice == ' none ' -%} 282{{- internal_system_message(' tool - choice ', ' The system is invoked with ` tool_choice = none `.\ nYou MUST NOT call any tools in the next message . ') -}} 283{%- endif -%} 284 285{%- if response_schema is defined -%} 286{%- set state.response_schema = response_schema -%} 287{%- elif response_format is defined and response_format is mapping and response_format.get(' json_schema ') is not none -%} 288{%- set schema_wrapper = response_format.get(' json_schema ') -%} 289{%- if schema_wrapper is mapping and ' schema ' in schema_wrapper -%} 290{%- set state.response_schema = schema_wrapper.get(' schema ') -%} 291{%- elif schema_wrapper is mapping and ' json_schema ' in schema_wrapper -%} 292{%- set state.response_schema = schema_wrapper.get(' json_schema ') -%} 293{%- else -%} 294{%- set state.response_schema = schema_wrapper -%} 295{%- endif -%} 296{%- endif -%} 297 298{%- set response_format_type = none -%} 299{%- if response_format is defined and response_format is mapping -%} 300{%- set response_format_type = response_format.get(' type ') -%} 301{%- elif response_format is defined -%} 302{%- set response_format_type = response_format -%} 303{%- endif -%} 304{%- if response_format_type == ' json_object ' -%} 305{{- internal_system_message( 306' response - format ', 307' The system is invoked with ` response_format = json_object `.\ nYour response must be raw JSON data without markdown code blocks (``` json ) or any additional formatting . ' 308) -}} 309{%- elif response_format_type == ' json_schema ' -%} 310{{- internal_system_message( 311' response - format ', 312' The system is invoked with ` response_format = json_schema `.\ nYour response must be raw JSON data without markdown code blocks (``` json ) or any additional formatting .\ nThe JSON data must match the following schema :\ n ``` json \ n ' + json_sorted(state.response_schema) + ' \ n ``` ' 313) -}} 314{%- endif -%} 315 316{%- if add_generation_prompt -%} 317{{- open_tag(' message ', [(' role ', ' assistant ')]) -}} 318{{- open_tag(' think ' if thinking else ' response ') -}} 319{%- endif -%} 320 321{%- if image_prompts is defined and image_prompts is not none and state.image_index != image_prompts|length -%} 322{{- raise_exception(' image prompt count ' + image_prompts|length|string + ' != consumed placeholder count ' + state . image_index | string ) - }} 323{%- endif -%} 324