package renderers

import (
	"os"
	"testing"

	"github.com/google/go-cmp/cmp"

	"github.com/ollama/ollama/api"
)

// Expectations captured from testdata/nemotron35_chat_template.jinja2, so they
// are the template's output and not the renderer's. The default run compares
// the v35 renderer against them; VERIFY_JINJA2=1 re-checks them against the
// template itself.
const nemotron35Template = "testdata/nemotron35_chat_template.jinja2"

var nemotron35Expected = map[string]string{
	"medium effort":                                      "<|im_start|>system\n<|im_end|>\n<|im_start|>user\nHello\n\n{reasoning effort: efficient}<|im_end|>\n<|im_start|>assistant\n<think>\n",
	"no system default thinking on":                      "<|im_start|>system\n<|im_end|>\n<|im_start|>user\nHello<|im_end|>\n<|im_start|>assistant\n<think>\n",
	"no system explicit thinking off":                    "<|im_start|>system\n<|im_end|>\n<|im_start|>user\nHello<|im_end|>\n<|im_start|>assistant\n<think></think>",
	"literal endthink does not enable thinking":          "<|im_start|>system\n<|im_end|>\n<|im_start|>user\nliteral </think> only<|im_end|>\n<|im_start|>assistant\n<think></think>",
	"user no think toggle":                               "<|im_start|>system\n<|im_end|>\n<|im_start|>user\nHello /no_think<|im_end|>\n<|im_start|>assistant\n<think>\n",
	"system think toggle overrides false":                "<|im_start|>system\nPolicy /think<|im_end|>\n<|im_start|>user\nHello<|im_end|>\n<|im_start|>assistant\n<think></think>",
	"later toggle wins":                                  "<|im_start|>system\nPolicy /no_think<|im_end|>\n<|im_start|>user\nActually /think<|im_end|>\n<|im_start|>assistant\n<think></think>",
	"system sanitizes toggles but preserves closing tag": "<|im_start|>system\nA /think B /no_think C </think><|im_end|>\n<|im_start|>user\nHello<|im_end|>\n<|im_start|>assistant\n<think></think>",
	"assistant plain content adds empty think block":     "<|im_start|>system\n<|im_end|>\n<|im_start|>user\nHi<|im_end|>\n<|im_start|>assistant\n<think></think>Hello there<|im_end|>\n<|im_start|>assistant\n<think>\n",
	"assistant reasoning content":                        "<|im_start|>system\n<|im_end|>\n<|im_start|>user\nHi<|im_end|>\n<|im_start|>assistant\n<think>\nNeed to think</think>Answer<|im_end|>\n<|im_start|>assistant\n<think>\n",
	"assistant preserves existing think tags":            "<|im_start|>system\n<|im_end|>\n<|im_start|>user\nHi<|im_end|>\n<|im_start|>assistant\n<think>kept</think>Answer<|im_end|>\n<|im_start|>assistant\n<think>\n",
	"tools without system":                               "<|im_start|>system\n# Tools\n\nYou have access to the following functions:\n\n<tools>\n<function>\n<name>search_docs</name>\n<description>Search docs</description>\n<parameters>\n<parameter>\n<name>query</name>\n<type>string</type>\n<description>Search query</description>\n<enum>[\"api\", \"cli\"]</enum>\n</parameter>\n<parameter>\n<name>mode</name>\n<type>['string', 'null']</type>\n<description>Mode</description>\n<anyOf>[{\"type\": \"string\"}, {\"type\": \"number\"}]</anyOf>\n</parameter>\n<parameter>\n<name>payload</name>\n<type>object</type>\n<description>Payload</description>\n<properties>{\"enabled\": {\"type\": \"boolean\"}}</properties>\n<required>[\"enabled\"]</required>\n</parameter>\n<parameter>\n<name>tags</name>\n<type>array</type>\n<description>Tags</description>\n<items>{\"type\": \"string\"}</items>\n</parameter>\n<$defs>{\"shared\": {\"type\": \"string\"}}</$defs>\n<required>[\"query\"]</required>\n</parameters>\n</function>\n</tools>\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><|im_end|>\n<|im_start|>user\nUse a tool<|im_end|>\n<|im_start|>assistant\n<think>\n",
	"system with tools":                                  "<|im_start|>system\nFollow policy.\n\n# Tools\n\nYou have access to the following functions:\n\n<tools>\n<function>\n<name>search_docs</name>\n<description>Search docs</description>\n<parameters>\n<parameter>\n<name>query</name>\n<type>string</type>\n<description>Search query</description>\n<enum>[\"api\", \"cli\"]</enum>\n</parameter>\n<parameter>\n<name>mode</name>\n<type>['string', 'null']</type>\n<description>Mode</description>\n<anyOf>[{\"type\": \"string\"}, {\"type\": \"number\"}]</anyOf>\n</parameter>\n<parameter>\n<name>payload</name>\n<type>object</type>\n<description>Payload</description>\n<properties>{\"enabled\": {\"type\": \"boolean\"}}</properties>\n<required>[\"enabled\"]</required>\n</parameter>\n<parameter>\n<name>tags</name>\n<type>array</type>\n<description>Tags</description>\n<items>{\"type\": \"string\"}</items>\n</parameter>\n<$defs>{\"shared\": {\"type\": \"string\"}}</$defs>\n<required>[\"query\"]</required>\n</parameters>\n</function>\n</tools>\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><|im_end|>\n<|im_start|>user\nUse a tool<|im_end|>\n<|im_start|>assistant\n<think>\n",
	"assistant tool call with content":                   "<|im_start|>system\n<|im_end|>\n<|im_start|>user\nWeather?<|im_end|>\n<|im_start|>assistant\n<think></think>Checking now.\n<tool_call>\n<function=get_weather>\n<parameter=city>\nParis\n</parameter>\n</function>\n</tool_call>\n<|im_end|>\n<|im_start|>assistant\n<think>\n",
	"assistant tool call with structured arguments":      "<|im_start|>system\n<|im_end|>\n<|im_start|>user\nCreate data<|im_end|>\n<|im_start|>assistant\n<think></think>\n<tool_call>\n<function=create>\n<parameter=payload>\n{\"count\": 42, \"nested\": {\"value\": \"ok\"}}\n</parameter>\n<parameter=tags>\n[\"a\", \"b\"]\n</parameter>\n</function>\n</tool_call>\n<|im_end|>\n<|im_start|>assistant\n<think>\n",
	"assistant tool call truncated with reasoning":       "<|im_start|>system\n<|im_end|>\n<|im_start|>user\nWeather?<|im_end|>\n<|im_start|>assistant\n<think></think>Checking now.\n<tool_call>\n<function=get_weather>\n<parameter=city>\nParis\n</parameter>\n</function>\n</tool_call>\n<|im_end|>\n<|im_start|>user\nAnd tomorrow?<|im_end|>\n<|im_start|>assistant\n<think>\n",
	"assistant tool call truncated open think only":      "<|im_start|>system\n<|im_end|>\n<|im_start|>user\nWeather?<|im_end|>\n<|im_start|>assistant\n<think></think>\n<tool_call>\n<function=get_weather>\n<parameter=city>\nParis\n</parameter>\n</function>\n</tool_call>\n<|im_end|>\n<|im_start|>user\nAnd tomorrow?<|im_end|>\n<|im_start|>assistant\n<think>\n",
	"assistant tool call empty content":                  "<|im_start|>system\n<|im_end|>\n<|im_start|>user\nWeather?<|im_end|>\n<|im_start|>assistant\n<think></think>\n<tool_call>\n<function=get_weather>\n<parameter=city>\nParis\n</parameter>\n</function>\n</tool_call>\n<|im_end|>\n<|im_start|>assistant\n<think>\n",
	"assistant truncated with think pair":                "<|im_start|>system\n<|im_end|>\n<|im_start|>user\nHi<|im_end|>\n<|im_start|>assistant\n<think></think>Visible<|im_end|>\n<|im_start|>user\nNext<|im_end|>\n<|im_start|>assistant\n<think>\n",
	"assistant truncated reasoning content":              "<|im_start|>system\n<|im_end|>\n<|im_start|>user\nHi<|im_end|>\n<|im_start|>assistant\n<think></think>Visible<|im_end|>\n<|im_start|>user\nNext<|im_end|>\n<|im_start|>assistant\n<think>\n",
	"assistant truncated plain content":                  "<|im_start|>system\n<|im_end|>\n<|im_start|>user\nHi<|im_end|>\n<|im_start|>assistant\n<think></think>Visible<|im_end|>\n<|im_start|>user\nNext<|im_end|>\n<|im_start|>assistant\n<think>\n",
	"assistant truncated empty content":                  "<|im_start|>system\n<|im_end|>\n<|im_start|>user\nHi<|im_end|>\n<|im_start|>assistant\n<think></think><|im_end|>\n<|im_start|>user\nNext<|im_end|>\n<|im_start|>assistant\n<think>\n",
	"consecutive tool messages grouped":                  "<|im_start|>system\n<|im_end|>\n<|im_start|>user\nDo work<|im_end|>\n<|im_start|>assistant\n<think></think>\n<tool_call>\n<function=step>\n<parameter=value>\n1\n</parameter>\n</function>\n</tool_call>\n<|im_end|>\n<|im_start|>user\n<tool_response>\none\n</tool_response>\n<tool_response>\ntwo\n</tool_response>\n<|im_end|>\n<|im_start|>assistant\n<think>\n",
	"fallback role":                                      "<|im_start|>system\n<|im_end|>\n<|im_start|>developer\nCustom role content<|im_end|>\n<|im_start|>assistant\n<think>\n",
	"tool without description":                           "<|im_start|>system\n# Tools\n\nYou have access to the following functions:\n\n<tools>\n<function>\n<name>ping</name>\n<parameters>\n<parameter>\n<name>host</name>\n<type>string</type>\n<description>Host</description>\n</parameter>\n<required>[\"host\"]</required>\n</parameters>\n</function>\n</tools>\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><|im_end|>\n<|im_start|>user\ngo<|im_end|>\n<|im_start|>assistant\n<think>\n",
	"tool without parameters":                            "<|im_start|>system\n# Tools\n\nYou have access to the following functions:\n\n<tools>\n<function>\n<name>now</name>\n<description>Current time</description>\n<parameters>\n</parameters>\n</function>\n</tools>\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><|im_end|>\n<|im_start|>user\ngo<|im_end|>\n<|im_start|>assistant\n<think>\n",
	"tool param without type":                            "<|im_start|>system\n# Tools\n\nYou have access to the following functions:\n\n<tools>\n<function>\n<name>q</name>\n<description>Query</description>\n<parameters>\n<parameter>\n<name>x</name>\n<description>no type</description>\n</parameter>\n</parameters>\n</function>\n</tools>\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><|im_end|>\n<|im_start|>user\ngo<|im_end|>\n<|im_start|>assistant\n<think>\n",
	"tool param with unhandled keys":                     "<|im_start|>system\n# Tools\n\nYou have access to the following functions:\n\n<tools>\n<function>\n<name>q</name>\n<description>Query</description>\n<parameters>\n<parameter>\n<name>x</name>\n<type>string</type>\n<description>X</description>\n<items>[\"a\", \"b\"]</items>\n</parameter>\n</parameters>\n</function>\n</tools>\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><|im_end|>\n<|im_start|>user\ngo<|im_end|>\n<|im_start|>assistant\n<think>\n",
	"tool without required list":                         "<|im_start|>system\n# Tools\n\nYou have access to the following functions:\n\n<tools>\n<function>\n<name>q</name>\n<description>Query</description>\n<parameters>\n<parameter>\n<name>x</name>\n<type>string</type>\n</parameter>\n</parameters>\n</function>\n</tools>\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><|im_end|>\n<|im_start|>user\ngo<|im_end|>\n<|im_start|>assistant\n<think>\n",
	"system message after first turn":                    "<|im_start|>system\nFirst system<|im_end|>\n<|im_start|>user\nHi<|im_end|>\n<|im_start|>system\nSecond system<|im_end|>\n<|im_start|>user\nAgain<|im_end|>\n<|im_start|>assistant\n<think>\n",
	"tool message last":                                  "<|im_start|>system\n<|im_end|>\n<|im_start|>user\ngo<|im_end|>\n<|im_start|>assistant\n<think></think>\n<tool_call>\n<function=f>\n</function>\n</tool_call>\n<|im_end|>\n<|im_start|>user\n<tool_response>\nresult\n</tool_response>\n<|im_end|>\n<|im_start|>assistant\n<think>\n",
	"tool run then assistant":                            "<|im_start|>system\n<|im_end|>\n<|im_start|>user\ngo<|im_end|>\n<|im_start|>assistant\n<think></think>\n<tool_call>\n<function=f>\n</function>\n</tool_call>\n<|im_end|>\n<|im_start|>user\n<tool_response>\none\n</tool_response>\n<tool_response>\ntwo\n</tool_response>\n<|im_end|>\n<|im_start|>assistant\n<think></think>done<|im_end|>\n<|im_start|>user\nnext<|im_end|>\n<|im_start|>assistant\n<think>\n",
	"two user turns truncates earlier thinking":          "<|im_start|>system\n<|im_end|>\n<|im_start|>user\nfirst<|im_end|>\n<|im_start|>assistant\n<think></think>answer one<|im_end|>\n<|im_start|>user\nsecond<|im_end|>\n<|im_start|>assistant\n<think>\nlate reasoning</think>answer two<|im_end|>\n<|im_start|>assistant\n<think>\n",
	"assistant reasoning with tool call":                 "<|im_start|>system\n<|im_end|>\n<|im_start|>user\ngo<|im_end|>\n<|im_start|>assistant\n<think>\ndecide</think>calling\n<tool_call>\n<function=f>\n</function>\n</tool_call>\n<|im_end|>\n<|im_start|>assistant\n<think>\n",
	"system only no user":                                "<|im_start|>system\nOnly system<|im_end|>\n<|im_start|>assistant\n<think>\n",
	"assistant first no user":                            "<|im_start|>system\n<|im_end|>\n<|im_start|>assistant\n<think></think>unprompted<|im_end|>\n<|im_start|>user\nnow ask<|im_end|>\n<|im_start|>assistant\n<think>\n",
	"tool message first":                                 "<|im_start|>system\n<|im_end|>\n<tool_response>\norphan result\n</tool_response>\n<|im_end|>\n<|im_start|>assistant\n<think>\n",
	"multiple tools":                                     "<|im_start|>system\n# Tools\n\nYou have access to the following functions:\n\n<tools>\n<function>\n<name>alpha</name>\n<description>First</description>\n<parameters>\n<parameter>\n<name>a</name>\n<type>string</type>\n</parameter>\n</parameters>\n</function>\n<function>\n<name>beta</name>\n<description>Second</description>\n<parameters>\n</parameters>\n</function>\n</tools>\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><|im_end|>\n<|im_start|>user\ngo<|im_end|>\n<|im_start|>assistant\n<think>\n",
	"tool call multiple arguments":                       "<|im_start|>system\n<|im_end|>\n<|im_start|>user\ngo<|im_end|>\n<|im_start|>assistant\n<think></think>\n<tool_call>\n<function=f>\n<parameter=one>\n1\n</parameter>\n<parameter=two>\n2\n</parameter>\n<parameter=three>\nTrue\n</parameter>\n</function>\n</tool_call>\n<|im_end|>\n<|im_start|>assistant\n<think>\n",
	"assistant fully empty":                              "<|im_start|>system\n<|im_end|>\n<|im_start|>user\ngo<|im_end|>\n<|im_start|>assistant\n<think></think><|im_end|>\n<|im_start|>user\nagain<|im_end|>\n<|im_start|>assistant\n<think>\n",
	"deep multi turn truncation":                         "<|im_start|>system\n<|im_end|>\n<|im_start|>user\nu1<|im_end|>\n<|im_start|>assistant\n<think></think>a1<|im_end|>\n<|im_start|>user\nu2<|im_end|>\n<|im_start|>assistant\n<think></think>a2<|im_end|>\n<|im_start|>user\nu3<|im_end|>\n<|im_start|>assistant\n<think>\nt3</think>a3<|im_end|>\n<|im_start|>assistant\n<think>\n",
	"content think tags with tool call":                  "<|im_start|>system\n<|im_end|>\n<|im_start|>user\ngo<|im_end|>\n<|im_start|>assistant\n<think>inline</think>after\n<tool_call>\n<function=f>\n</function>\n</tool_call>\n<|im_end|>\n<|im_start|>assistant\n<think>\n",
	"tool response json":                                 "<|im_start|>system\n<|im_end|>\n<|im_start|>user\ngo<|im_end|>\n<|im_start|>assistant\n<think></think>\n<tool_call>\n<function=f>\n</function>\n</tool_call>\n<|im_end|>\n<|im_start|>user\n<tool_response>\n{\"temp\": 14, \"unit\": \"c\"}\n</tool_response>\n<|im_end|>\n<|im_start|>user\nand?<|im_end|>\n<|im_start|>assistant\n<think>\n",
	"assistant closing tag only":                         "<|im_start|>system\n<|im_end|>\n<|im_start|>user\ngo<|im_end|>\n<|im_start|>assistant\nstray </think> tail<|im_end|>\n<|im_start|>user\nagain<|im_end|>\n<|im_start|>assistant\n<think>\n",
	"tool call scalar arg types":                         "<|im_start|>system\n<|im_end|>\n<|im_start|>user\ngo<|im_end|>\n<|im_start|>assistant\n<think></think>\n<tool_call>\n<function=f>\n<parameter=int>\n7\n</parameter>\n<parameter=float>\n2.5\n</parameter>\n<parameter=wholefloat>\n2\n</parameter>\n<parameter=boolfalse>\nFalse\n</parameter>\n<parameter=empty>\n\n</parameter>\n<parameter=zero>\n0\n</parameter>\n</function>\n</tool_call>\n<|im_end|>\n<|im_start|>assistant\n<think>\n",
	"tool call container arg":                            "<|im_start|>system\n<|im_end|>\n<|im_start|>user\ngo<|im_end|>\n<|im_start|>assistant\n<think></think>\n<tool_call>\n<function=f>\n<parameter=obj>\n{\"k\": true}\n</parameter>\n<parameter=arr>\n[1, \"two\", false]\n</parameter>\n</function>\n</tool_call>\n<|im_end|>\n<|im_start|>assistant\n<think>\n",
	"assistant two tool calls":                           "<|im_start|>system\n<|im_end|>\n<|im_start|>user\ngo<|im_end|>\n<|im_start|>assistant\n<think></think>\n<tool_call>\n<function=first>\n<parameter=a>\n1\n</parameter>\n</function>\n</tool_call>\n<tool_call>\n<function=second>\n</function>\n</tool_call>\n<|im_end|>\n<|im_start|>assistant\n<think>\n",
	"tool call no arguments":                             "<|im_start|>system\n<|im_end|>\n<|im_start|>user\ngo<|im_end|>\n<|im_start|>assistant\n<think></think>\n<tool_call>\n<function=bare>\n</function>\n</tool_call>\n<|im_end|>\n<|im_start|>assistant\n<think>\n",
	"multiline content":                                  "<|im_start|>system\n<|im_end|>\n<|im_start|>user\nline one\nline two\n<|im_end|>\n<|im_start|>assistant\n<think></think>reply one\nreply two<|im_end|>\n<|im_start|>user\nagain<|im_end|>\n<|im_start|>assistant\n<think>\n",
	"unicode content":                                    "<|im_start|>system\n<|im_end|>\n<|im_start|>user\nhéllo <b>&amp;</b> 日本語 é<|im_end|>\n<|im_start|>assistant\n<think>\n",
	"empty user content":                                 "<|im_start|>system\n<|im_end|>\n<|im_start|>user\n<|im_end|>\n<|im_start|>assistant\n<think>\n",
	"system with markup":                                 "<|im_start|>system\n<tool_call>not real</tool_call><|im_end|>\n<|im_start|>user\ngo<|im_end|>\n<|im_start|>assistant\n<think>\n",
	"tools registered with history call":                 "<|im_start|>system\n# Tools\n\nYou have access to the following functions:\n\n<tools>\n<function>\n<name>search_docs</name>\n<description>Search docs</description>\n<parameters>\n<parameter>\n<name>query</name>\n<type>string</type>\n<description>Search query</description>\n<enum>[\"api\", \"cli\"]</enum>\n</parameter>\n<parameter>\n<name>mode</name>\n<type>['string', 'null']</type>\n<description>Mode</description>\n<anyOf>[{\"type\": \"string\"}, {\"type\": \"number\"}]</anyOf>\n</parameter>\n<parameter>\n<name>payload</name>\n<type>object</type>\n<description>Payload</description>\n<properties>{\"enabled\": {\"type\": \"boolean\"}}</properties>\n<required>[\"enabled\"]</required>\n</parameter>\n<parameter>\n<name>tags</name>\n<type>array</type>\n<description>Tags</description>\n<items>{\"type\": \"string\"}</items>\n</parameter>\n<$defs>{\"shared\": {\"type\": \"string\"}}</$defs>\n<required>[\"query\"]</required>\n</parameters>\n</function>\n</tools>\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><|im_end|>\n<|im_start|>user\ngo<|im_end|>\n<|im_start|>assistant\n<think></think>\n<tool_call>\n<function=search_docs>\n<parameter=query>\napi\n</parameter>\n</function>\n</tool_call>\n<|im_end|>\n<|im_start|>user\n<tool_response>\nfound\n</tool_response>\n<|im_end|>\n<|im_start|>user\nthanks<|im_end|>\n<|im_start|>assistant\n<think>\n",
	"think unset with history":                           "<|im_start|>system\n<|im_end|>\n<|im_start|>user\nu1<|im_end|>\n<|im_start|>assistant\n<think></think>a1<|im_end|>\n<|im_start|>user\nu2<|im_end|>\n<|im_start|>assistant\n<think>\n",
	"consecutive assistant messages":                     "<|im_start|>system\n<|im_end|>\n<|im_start|>user\ngo<|im_end|>\n<|im_start|>assistant\n<think></think>first<|im_end|>\n<|im_start|>assistant\n<think></think>second<|im_end|>\n<|im_start|>user\nagain<|im_end|>\n<|im_start|>assistant\n<think>\n",
	"user directly after tool":                           "<|im_start|>system\n<|im_end|>\n<|im_start|>user\ngo<|im_end|>\n<|im_start|>assistant\n<think></think>\n<tool_call>\n<function=f>\n</function>\n</tool_call>\n<|im_end|>\n<|im_start|>user\n<tool_response>\nres\n</tool_response>\n<|im_end|>\n<|im_start|>user\nnext<|im_end|>\n<|im_start|>assistant\n<think>\n",
	"assistant thinking empty content":                   "<|im_start|>system\n<|im_end|>\n<|im_start|>user\ngo<|im_end|>\n<|im_start|>assistant\n<think></think><|im_end|>\n<|im_start|>user\nagain<|im_end|>\n<|im_start|>assistant\n<think>\n",
	"tool response empty":                                "<|im_start|>system\n<|im_end|>\n<|im_start|>user\ngo<|im_end|>\n<|im_start|>assistant\n<think></think>\n<tool_call>\n<function=f>\n</function>\n</tool_call>\n<|im_end|>\n<|im_start|>user\n<tool_response>\n\n</tool_response>\n<|im_end|>\n<|im_start|>assistant\n<think>\n",
	"assistant whitespace content":                       "<|im_start|>system\n<|im_end|>\n<|im_start|>user\ngo<|im_end|>\n<|im_start|>assistant\n<think></think><|im_end|>\n<|im_start|>user\nagain<|im_end|>\n<|im_start|>assistant\n<think>\n",
	"empty system message":                               "<|im_start|>system\n<|im_end|>\n<|im_start|>user\ngo<|im_end|>\n<|im_start|>assistant\n<think>\n",
	"agentic multi round tool loop":                      "<|im_start|>system\n# Tools\n\nYou have access to the following functions:\n\n<tools>\n<function>\n<name>search_docs</name>\n<description>Search docs</description>\n<parameters>\n<parameter>\n<name>query</name>\n<type>string</type>\n<description>Search query</description>\n<enum>[\"api\", \"cli\"]</enum>\n</parameter>\n<parameter>\n<name>mode</name>\n<type>['string', 'null']</type>\n<description>Mode</description>\n<anyOf>[{\"type\": \"string\"}, {\"type\": \"number\"}]</anyOf>\n</parameter>\n<parameter>\n<name>payload</name>\n<type>object</type>\n<description>Payload</description>\n<properties>{\"enabled\": {\"type\": \"boolean\"}}</properties>\n<required>[\"enabled\"]</required>\n</parameter>\n<parameter>\n<name>tags</name>\n<type>array</type>\n<description>Tags</description>\n<items>{\"type\": \"string\"}</items>\n</parameter>\n<$defs>{\"shared\": {\"type\": \"string\"}}</$defs>\n<required>[\"query\"]</required>\n</parameters>\n</function>\n</tools>\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><|im_end|>\n<|im_start|>user\nplan it<|im_end|>\n<|im_start|>assistant\n<think></think>checking\n<tool_call>\n<function=lookup>\n<parameter=q>\na\n</parameter>\n</function>\n</tool_call>\n<|im_end|>\n<|im_start|>user\n<tool_response>\nres one\n</tool_response>\n<|im_end|>\n<|im_start|>assistant\n<think></think>again\n<tool_call>\n<function=lookup>\n<parameter=q>\nb\n</parameter>\n</function>\n</tool_call>\n<|im_end|>\n<|im_start|>user\n<tool_response>\nres two\n</tool_response>\n<|im_end|>\n<|im_start|>assistant\n<think></think>final answer<|im_end|>\n<|im_start|>user\nthanks<|im_end|>\n<|im_start|>assistant\n<think>\n",
	"tool call punctuated name":                          "<|im_start|>system\n<|im_end|>\n<|im_start|>user\ngo<|im_end|>\n<|im_start|>assistant\n<think></think>\n<tool_call>\n<function=ns.sub_tool-v2>\n</function>\n</tool_call>\n<|im_end|>\n<|im_start|>assistant\n<think>\n",
	"tool call empty containers":                         "<|im_start|>system\n<|im_end|>\n<|im_start|>user\ngo<|im_end|>\n<|im_start|>assistant\n<think></think>\n<tool_call>\n<function=f>\n<parameter=obj>\n{}\n</parameter>\n<parameter=arr>\n[]\n</parameter>\n</function>\n</tool_call>\n<|im_end|>\n<|im_start|>assistant\n<think>\n",
	"explicit think true with tools":                     "<|im_start|>system\n# Tools\n\nYou have access to the following functions:\n\n<tools>\n<function>\n<name>search_docs</name>\n<description>Search docs</description>\n<parameters>\n<parameter>\n<name>query</name>\n<type>string</type>\n<description>Search query</description>\n<enum>[\"api\", \"cli\"]</enum>\n</parameter>\n<parameter>\n<name>mode</name>\n<type>['string', 'null']</type>\n<description>Mode</description>\n<anyOf>[{\"type\": \"string\"}, {\"type\": \"number\"}]</anyOf>\n</parameter>\n<parameter>\n<name>payload</name>\n<type>object</type>\n<description>Payload</description>\n<properties>{\"enabled\": {\"type\": \"boolean\"}}</properties>\n<required>[\"enabled\"]</required>\n</parameter>\n<parameter>\n<name>tags</name>\n<type>array</type>\n<description>Tags</description>\n<items>{\"type\": \"string\"}</items>\n</parameter>\n<$defs>{\"shared\": {\"type\": \"string\"}}</$defs>\n<required>[\"query\"]</required>\n</parameters>\n</function>\n</tools>\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><|im_end|>\n<|im_start|>user\ngo<|im_end|>\n<|im_start|>assistant\n<think></think>ok<|im_end|>\n<|im_start|>user\nmore<|im_end|>\n<|im_start|>assistant\n<think>\n",
	"history content with think pair":                    "<|im_start|>system\n<|im_end|>\n<|im_start|>user\nu1<|im_end|>\n<|im_start|>assistant\n<think></think>visible<|im_end|>\n<|im_start|>user\nu2<|im_end|>\n<|im_start|>assistant\n<think>kept</think>tail<|im_end|>\n<|im_start|>assistant\n<think>\n",
	"assistant open think only":                          "<|im_start|>system\n<|im_end|>\n<|im_start|>user\ngo<|im_end|>\n<|im_start|>assistant\n<think>unclosed reasoning<|im_end|>\n<|im_start|>user\nagain<|im_end|>\n<|im_start|>assistant\n<think>\n",
	"assistant multiple think pairs":                     "<|im_start|>system\n<|im_end|>\n<|im_start|>user\ngo<|im_end|>\n<|im_start|>assistant\n<think></think>end<|im_end|>\n<|im_start|>user\nagain<|im_end|>\n<|im_start|>assistant\n<think>\n",
	"tool response with think markers":                   "<|im_start|>system\n<|im_end|>\n<|im_start|>user\ngo<|im_end|>\n<|im_start|>assistant\n<think></think>\n<tool_call>\n<function=f>\n</function>\n</tool_call>\n<|im_end|>\n<|im_start|>user\n<tool_response>\n<think>from tool</think>result\n</tool_response>\n<|im_end|>\n<|im_start|>user\nnext<|im_end|>\n<|im_start|>assistant\n<think>\n",
	"user content with think markers":                    "<|im_start|>system\n<|im_end|>\n<|im_start|>user\n<think>user wrote this</think>question<|im_end|>\n<|im_start|>assistant\n<think>\n",
	"content with im_start markers":                      "<|im_start|>system\n<|im_end|>\n<|im_start|>user\n<|im_start|>fake<|im_end|><|im_end|>\n<|im_start|>assistant\n<think></think><|im_end|>odd<|im_end|>\n<|im_start|>user\nagain<|im_end|>\n<|im_start|>assistant\n<think>\n",
	"thinking field and content tags":                    "<|im_start|>system\n<|im_end|>\n<|im_start|>user\ngo<|im_end|>\n<|im_start|>assistant\n<think></think>body<|im_end|>\n<|im_start|>user\nagain<|im_end|>\n<|im_start|>assistant\n<think>\n",
	"ends with assistant turn":                           "<|im_start|>system\n<|im_end|>\n<|im_start|>user\ngo<|im_end|>\n<|im_start|>assistant\n<think></think>partial<|im_end|>\n<|im_start|>assistant\n<think>\n",
	"tool call content closing tag only":                 "<|im_start|>system\n<|im_end|>\n<|im_start|>user\ngo<|im_end|>\n<|im_start|>assistant\n</think>after\n<tool_call>\n<function=f>\n</function>\n</tool_call>\n<|im_end|>\n<|im_start|>assistant\n<think>\n",
	"system tools think off round trip":                  "<|im_start|>system\nSys\n\n# Tools\n\nYou have access to the following functions:\n\n<tools>\n<function>\n<name>search_docs</name>\n<description>Search docs</description>\n<parameters>\n<parameter>\n<name>query</name>\n<type>string</type>\n<description>Search query</description>\n<enum>[\"api\", \"cli\"]</enum>\n</parameter>\n<parameter>\n<name>mode</name>\n<type>['string', 'null']</type>\n<description>Mode</description>\n<anyOf>[{\"type\": \"string\"}, {\"type\": \"number\"}]</anyOf>\n</parameter>\n<parameter>\n<name>payload</name>\n<type>object</type>\n<description>Payload</description>\n<properties>{\"enabled\": {\"type\": \"boolean\"}}</properties>\n<required>[\"enabled\"]</required>\n</parameter>\n<parameter>\n<name>tags</name>\n<type>array</type>\n<description>Tags</description>\n<items>{\"type\": \"string\"}</items>\n</parameter>\n<$defs>{\"shared\": {\"type\": \"string\"}}</$defs>\n<required>[\"query\"]</required>\n</parameters>\n</function>\n</tools>\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><|im_end|>\n<|im_start|>user\ngo<|im_end|>\n<|im_start|>assistant\n<think></think>\n<tool_call>\n<function=search_docs>\n<parameter=query>\ncli\n</parameter>\n</function>\n</tool_call>\n<|im_end|>\n<|im_start|>user\n<tool_response>\nhit\n</tool_response>\n<|im_end|>\n<|im_start|>user\nsummarize<|im_end|>\n<|im_start|>assistant\n<think></think>",
	"tool call null and numeric args":                    "<|im_start|>system\n<|im_end|>\n<|im_start|>user\ngo<|im_end|>\n<|im_start|>assistant\n<think></think>\n<tool_call>\n<function=f>\n<parameter=nothing>\nNone\n</parameter>\n<parameter=negative>\n-12\n</parameter>\n<parameter=big>\n9007199254740993\n</parameter>\n<parameter=fraction>\n0.125\n</parameter>\n</function>\n</tool_call>\n<|im_end|>\n<|im_start|>assistant\n<think>\n",
	"tool call nested mixed container":                   "<|im_start|>system\n<|im_end|>\n<|im_start|>user\ngo<|im_end|>\n<|im_start|>assistant\n<think></think>\n<tool_call>\n<function=f>\n<parameter=deep>\n{\"b\": false, \"f\": 1.5, \"i\": 3, \"inner\": [1, {\"z\": true}], \"n\": null, \"s\": \"q\\\"uote\"}\n</parameter>\n</function>\n</tool_call>\n<|im_end|>\n<|im_start|>assistant\n<think>\n",
	"tool param many unhandled keys":                     "<|im_start|>system\n# Tools\n\nYou have access to the following functions:\n\n<tools>\n<function>\n<name>q</name>\n<description>Query</description>\n<parameters>\n<parameter>\n<name>x</name>\n<type>string</type>\n<description>X</description>\n<anyOf>[{\"type\": \"null\"}]</anyOf>\n<items>{\"minimum\": 0, \"type\": \"number\"}</items>\n</parameter>\n</parameters>\n</function>\n</tools>\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><|im_end|>\n<|im_start|>user\ngo<|im_end|>\n<|im_start|>assistant\n<think>\n",
	"tool call content think pair only":                  "<|im_start|>system\n<|im_end|>\n<|im_start|>user\nu1<|im_end|>\n<|im_start|>assistant\n<think></think>\n<tool_call>\n<function=f>\n</function>\n</tool_call>\n<|im_end|>\n<|im_start|>user\nu2<|im_end|>\n<|im_start|>assistant\n<think>y</think>z\n<tool_call>\n<function=g>\n</function>\n</tool_call>\n<|im_end|>\n<|im_start|>assistant\n<think>\n",
	"tool call quoted string arg":                        "<|im_start|>system\n<|im_end|>\n<|im_start|>user\ngo<|im_end|>\n<|im_start|>assistant\n<think></think>\n<tool_call>\n<function=f>\n<parameter=s>\nline\nbreak \"quoted\"\n</parameter>\n</function>\n</tool_call>\n<|im_end|>\n<|im_start|>assistant\n<think>\n",
	"tool schema nested and items":                       "<|im_start|>system\n# Tools\n\nYou have access to the following functions:\n\n<tools>\n<function>\n<name>deep</name>\n<description>Nested schema</description>\n<parameters>\n<parameter>\n<name>outer</name>\n<type>object</type>\n<description>Outer object</description>\n<enum>[\"a\", \"b\"]</enum>\n<items>{\"type\": \"integer\"}</items>\n<properties>{\"inner\": {\"type\": \"string\", \"description\": \"Inner\"}, \"flag\": {\"type\": [\"boolean\", \"null\"]}}</properties>\n<required>[\"inner\"]</required>\n</parameter>\n<items>{\"type\": \"string\"}</items>\n<required>[\"outer\"]</required>\n</parameters>\n</function>\n</tools>\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><|im_end|>\n<|im_start|>user\ngo<|im_end|>\n<|im_start|>assistant\n<think>\n",
	"tool call unsigned numeric container":               "<|im_start|>system\n<|im_end|>\n<|im_start|>user\ngo<|im_end|>\n<|im_start|>assistant\n<think></think>\n<tool_call>\n<function=f>\n<parameter=nums>\n{\"f32\": 1.5, \"i64\": -9, \"u\": 7, \"u8\": 255}\n</parameter>\n</function>\n</tool_call>\n<|im_end|>\n<|im_start|>assistant\n<think>\n",
	"tool call whitespace content":                       "<|im_start|>system\n<|im_end|>\n<|im_start|>user\ngo<|im_end|>\n<|im_start|>assistant\n<think></think>\n<tool_call>\n<function=f>\n</function>\n</tool_call>\n<|im_end|>\n<|im_start|>assistant\n<think>\n",
	"tool schema defs property map":                      "<|im_start|>system\n# Tools\n\nYou have access to the following functions:\n\n<tools>\n<function>\n<name>defs</name>\n<parameters>\n<parameter>\n<name>x</name>\n<type>string</type>\n</parameter>\n<$defs>{\"shared\": {\"type\": \"string\", \"description\": \"Shared\"}}</$defs>\n</parameters>\n</function>\n</tools>\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><|im_end|>\n<|im_start|>user\ngo<|im_end|>\n<|im_start|>assistant\n<think>\n",
	"tool schema defs rich property":                     "<|im_start|>system\n# Tools\n\nYou have access to the following functions:\n\n<tools>\n<function>\n<name>rich</name>\n<parameters>\n<parameter>\n<name>p</name>\n<type>string</type>\n</parameter>\n<$defs>{\"node\": {\"anyOf\": [{\"type\": \"string\"}, {\"type\": \"null\"}], \"type\": \"object\", \"items\": {\"type\": \"integer\"}, \"description\": \"Node\", \"enum\": [\"x\", \"y\"], \"properties\": {\"child\": {\"type\": \"string\"}}, \"required\": [\"child\"]}}</$defs>\n</parameters>\n</function>\n</tools>\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><|im_end|>\n<|im_start|>user\ngo<|im_end|>\n<|im_start|>assistant\n<think>\n",
	"tool schema items property type":                    "<|im_start|>system\n# Tools\n\nYou have access to the following functions:\n\n<tools>\n<function>\n<name>pt</name>\n<parameters>\n<parameter>\n<name>p</name>\n<type>string</type>\n</parameter>\n<items>[\"string\", \"null\"]</items>\n</parameters>\n</function>\n</tools>\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><|im_end|>\n<|im_start|>user\ngo<|im_end|>\n<|im_start|>assistant\n<think>\n",
	"tool schema nil defs map":                           "<|im_start|>system\n# Tools\n\nYou have access to the following functions:\n\n<tools>\n<function>\n<name>niltest</name>\n<parameters>\n<parameter>\n<name>p</name>\n<type>string</type>\n</parameter>\n<$defs>None</$defs>\n</parameters>\n</function>\n</tools>\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><|im_end|>\n<|im_start|>user\ngo<|im_end|>\n<|im_start|>assistant\n<think>\n",
	"tool call struct argument":                          "<|im_start|>system\n<|im_end|>\n<|im_start|>user\ngo<|im_end|>\n<|im_start|>assistant\n<think></think>\n<tool_call>\n<function=f>\n<parameter=custom>\n{\"a\": \"x\", \"b\": 2}\n</parameter>\n<parameter=list>\n[1, 2, 3]\n</parameter>\n</function>\n</tool_call>\n<|im_end|>\n<|im_start|>assistant\n<think>\n",
	"tool schema nested nil properties":                  "<|im_start|>system\n# Tools\n\nYou have access to the following functions:\n\n<tools>\n<function>\n<name>nested</name>\n<parameters>\n<parameter>\n<name>p</name>\n<type>string</type>\n</parameter>\n<$defs>{\"node\": {\"type\": \"object\", \"required\": [\"q\"]}}</$defs>\n</parameters>\n</function>\n</tools>\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><|im_end|>\n<|im_start|>user\ngo<|im_end|>\n<|im_start|>assistant\n<think>\n",
}

func TestNemotron35RendererMatchesReference(t *testing.T) {
	verifyJinja2 := os.Getenv("VERIFY_JINJA2") != ""

	cases := append(nemotronReferenceCases(), nemotronExtraCases()...)
	cases = append(cases, nemotronReferenceCase{
		name:     "medium effort",
		messages: []api.Message{{Role: "user", Content: "Hello"}},
		think:    &api.ThinkValue{Value: "medium"},
	})
	for _, tc := range cases {
		t.Run(tc.name, func(t *testing.T) {
			want, ok := nemotron35Expected[tc.name]
			if !ok {
				t.Fatalf("no 3.5 expectation for %q: every reference case must cover both flavors", tc.name)
			}

			got, err := RenderWithRenderer("nemotron-3.5-nano", tc.messages, tc.tools, tc.think)
			if err != nil {
				t.Fatalf("Render() error = %v", err)
			}
			if diff := cmp.Diff(want, got); diff != "" {
				t.Fatalf("v35 renderer mismatch (-want +got):\n%s", diff)
			}

			if verifyJinja2 {
				jinja2Output := renderNemotronWithJinja2(t, nemotron35Template, tc.messages, tc.tools, tc.think)
				if diff := cmp.Diff(want, jinja2Output); diff != "" {
					t.Fatalf("3.5 template mismatch (-want +got):\n%s", diff)
				}
			}
		})
	}
}
