Safetensors
GGUF
Turkish
llama
Llama-3
instruct
finetune
chatml
gpt4
synthetic data
distillation
function calling
json mode
axolotl
roleplaying
chat
Instructions to use tda45/TdAI with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- llama-cpp-python
How to use tda45/TdAI with llama-cpp-python:
# !pip install llama-cpp-python from llama_cpp import Llama llm = Llama.from_pretrained( repo_id="tda45/TdAI", filename="llama.cpp/models/ggml-vocab-aquila.gguf", )
output = llm( "Once upon a time,", max_tokens=512, echo=True ) print(output)
- Notebooks
- Google Colab
- Kaggle
- Local Apps Settings
- llama.cpp
How to use tda45/TdAI with llama.cpp:
Install (macOS, Linux)
curl -LsSf https://llama.app/install.sh | sh # Start a local OpenAI-compatible server with a web UI: llama serve -hf tda45/TdAI # Run inference directly in the terminal: llama cli -hf tda45/TdAI
Install from WinGet (Windows)
winget install llama.cpp # Start a local OpenAI-compatible server with a web UI: llama serve -hf tda45/TdAI # Run inference directly in the terminal: llama cli -hf tda45/TdAI
Use pre-built binary
# Download pre-built binary from: # https://github.com/ggerganov/llama.cpp/releases # Start a local OpenAI-compatible server with a web UI: ./llama-server -hf tda45/TdAI # Run inference directly in the terminal: ./llama-cli -hf tda45/TdAI
Build from source code
git clone https://github.com/ggerganov/llama.cpp.git cd llama.cpp cmake -B build cmake --build build -j --target llama-server llama-cli # Start a local OpenAI-compatible server with a web UI: ./build/bin/llama-server -hf tda45/TdAI # Run inference directly in the terminal: ./build/bin/llama-cli -hf tda45/TdAI
Use Docker
docker model run hf.co/tda45/TdAI
- LM Studio
- Jan
- Ollama
How to use tda45/TdAI with Ollama:
ollama run hf.co/tda45/TdAI
- Unsloth Studio
How to use tda45/TdAI with Unsloth Studio:
Install Unsloth Studio (macOS, Linux, WSL)
curl -fsSL https://unsloth.ai/install.sh | sh # Run unsloth studio unsloth studio -H 0.0.0.0 -p 8888 # Then open http://localhost:8888 in your browser # Search for tda45/TdAI to start chatting
Install Unsloth Studio (Windows)
irm https://unsloth.ai/install.ps1 | iex # Run unsloth studio unsloth studio -H 0.0.0.0 -p 8888 # Then open http://localhost:8888 in your browser # Search for tda45/TdAI to start chatting
Using HuggingFace Spaces for Unsloth
# No setup required # Open https://huggingface.co/spaces/unsloth/studio in your browser # Search for tda45/TdAI to start chatting
- Atomic Chat new
- Docker Model Runner
How to use tda45/TdAI with Docker Model Runner:
docker model run hf.co/tda45/TdAI
- Lemonade
How to use tda45/TdAI with Lemonade:
Pull the model
# Download Lemonade from https://lemonade-server.ai/ lemonade pull tda45/TdAI
Run and chat with the model
lemonade run user.TdAI-{{QUANT_TAG}}List all available models
lemonade list
| using json = nlohmann::ordered_json; | |
| // ANSI color codes - using 256-color palette for brighter colors (all bold) | |
| // All template paths extracted from tests/test-chat.cpp | |
| static const std::vector<std::string> ALL_TEMPLATE_PATHS = { | |
| "models/templates/Apertus-8B-Instruct.jinja", | |
| "models/templates/Apriel-1.6-15b-Thinker-fixed.jinja", | |
| "models/templates/ByteDance-Seed-OSS.jinja", | |
| "models/templates/CohereForAI-c4ai-command-r-plus-tool_use.jinja", | |
| "models/templates/CohereForAI-c4ai-command-r7b-12-2024-tool_use.jinja", | |
| "models/templates/GLM-4.6.jinja", | |
| "models/templates/GLM-4.7-Flash.jinja", | |
| "models/templates/Kimi-K2-Instruct.jinja", | |
| "models/templates/Kimi-K2-Thinking.jinja", | |
| "models/templates/MiMo-VL.jinja", | |
| "models/templates/MiniMax-M2.jinja", | |
| "models/templates/Mistral-Small-3.2-24B-Instruct-2506.jinja", | |
| "models/templates/NVIDIA-Nemotron-3-Nano-30B-A3B-BF16.jinja", | |
| "models/templates/NVIDIA-Nemotron-Nano-v2.jinja", | |
| "models/templates/NousResearch-Hermes-2-Pro-Llama-3-8B-tool_use.jinja", | |
| "models/templates/NousResearch-Hermes-3-Llama-3.1-8B-tool_use.jinja", | |
| "models/templates/Qwen-QwQ-32B.jinja", | |
| "models/templates/Qwen-Qwen2.5-7B-Instruct.jinja", | |
| "models/templates/Qwen3-Coder.jinja", | |
| "models/templates/deepseek-ai-DeepSeek-R1-Distill-Llama-8B.jinja", | |
| "models/templates/deepseek-ai-DeepSeek-R1-Distill-Qwen-32B.jinja", | |
| "models/templates/deepseek-ai-DeepSeek-V3.1.jinja", | |
| "models/templates/fireworks-ai-llama-3-firefunction-v2.jinja", | |
| "models/templates/google-gemma-2-2b-it.jinja", | |
| "models/templates/ibm-granite-granite-3.3-2B-Instruct.jinja", | |
| "models/templates/llama-cpp-deepseek-r1.jinja", | |
| "models/templates/meetkai-functionary-medium-v3.1.jinja", | |
| "models/templates/meetkai-functionary-medium-v3.2.jinja", | |
| "models/templates/meta-llama-Llama-3.1-8B-Instruct.jinja", | |
| "models/templates/meta-llama-Llama-3.2-3B-Instruct.jinja", | |
| "models/templates/meta-llama-Llama-3.3-70B-Instruct.jinja", | |
| "models/templates/mistralai-Ministral-3-14B-Reasoning-2512.jinja", | |
| "models/templates/mistralai-Mistral-Nemo-Instruct-2407.jinja", | |
| "models/templates/moonshotai-Kimi-K2.jinja", | |
| "models/templates/openai-gpt-oss-120b.jinja", | |
| "models/templates/unsloth-Apriel-1.5.jinja", | |
| "models/templates/unsloth-mistral-Devstral-Small-2507.jinja", | |
| }; | |
| struct analysis_options { | |
| std::vector<std::string> template_paths; | |
| bool analyze_all = false; | |
| }; | |
| static std::string read_file(const std::string & path) { | |
| std::ifstream fin(path, std::ios::binary); | |
| if (!fin.is_open()) { | |
| throw std::runtime_error("Could not open file: " + path); | |
| } | |
| std::ostringstream buf; | |
| buf << fin.rdbuf(); | |
| return buf.str(); | |
| } | |
| static void print_usage(const char * program_name) { | |
| LOG_ERR("Usage: %s [options]\n", program_name); | |
| LOG_ERR("\nOptions:\n"); | |
| LOG_ERR(" --template <name> Analyze specific template from test suite (e.g., 'deepseek' or 'DeepSeek-V3.1')\n"); | |
| LOG_ERR(" --template-file <path> Analyze custom template file\n"); | |
| LOG_ERR(" --all Analyze all templates from test suite\n"); | |
| LOG_ERR("\nExamples:\n"); | |
| LOG_ERR(" %s --all\n", program_name); | |
| LOG_ERR(" %s --template deepseek\n", program_name); | |
| LOG_ERR(" %s --template-file my-template.jinja\n", program_name); | |
| } | |
| static bool parse_options(int argc, char ** argv, analysis_options & opts) { | |
| if (argc < 2) { | |
| print_usage(argv[0]); | |
| return false; | |
| } | |
| for (int i = 1; i < argc; ++i) { | |
| std::string arg = argv[i]; | |
| if (arg == "--all") { | |
| opts.analyze_all = true; | |
| } else if (arg == "--template") { | |
| if (i + 1 >= argc) { | |
| LOG_ERR("--template requires an argument\n"); | |
| return false; | |
| } | |
| std::string pattern = argv[++i]; | |
| std::transform(pattern.begin(), pattern.end(), pattern.begin(), ::tolower); | |
| // Find matching templates | |
| bool found = false; | |
| for (const auto & path : ALL_TEMPLATE_PATHS) { | |
| std::string path_lower = path; | |
| std::transform(path_lower.begin(), path_lower.end(), path_lower.begin(), ::tolower); | |
| if (path_lower.find(pattern) != std::string::npos) { | |
| opts.template_paths.push_back(path); | |
| found = true; | |
| } | |
| } | |
| if (!found) { | |
| LOG_ERR("No templates found matching: %s\n", pattern.c_str()); | |
| return false; | |
| } | |
| } else if (arg == "--template-file") { | |
| if (i + 1 >= argc) { | |
| LOG_ERR("--template-file requires an argument\n"); | |
| return false; | |
| } | |
| opts.template_paths.push_back(argv[++i]); | |
| } else { | |
| LOG_ERR("Unknown option: %s\n", arg.c_str()); | |
| print_usage(argv[0]); | |
| return false; | |
| } | |
| } | |
| if (opts.analyze_all) { | |
| opts.template_paths = ALL_TEMPLATE_PATHS; | |
| } | |
| if (opts.template_paths.empty()) { | |
| LOG_ERR("No templates specified\n"); | |
| print_usage(argv[0]); | |
| return false; | |
| } | |
| return true; | |
| } | |
| static json build_tools_definition() { | |
| json parameters_schema = json::object(); | |
| parameters_schema["type"] = "object"; | |
| parameters_schema["properties"] = json::object(); | |
| parameters_schema["properties"]["param1"] = json::object({ | |
| { "type", "string" }, | |
| { "description", "First parameter" } | |
| }); | |
| parameters_schema["properties"]["param2"] = json::object({ | |
| { "type", "string" }, | |
| { "description", "Second parameter" } | |
| }); | |
| parameters_schema["required"] = json::array({ "param1", "param2" }); | |
| return json::array({ | |
| json{ { "type", "function" }, | |
| { "function", json{ { "name", "test_function_name" }, | |
| { "description", "A test function for debugging" }, | |
| { "parameters", parameters_schema } } } } | |
| }); | |
| } | |
| // Helper to create a tool call with arguments as JSON object | |
| static json build_tool_call(const std::string & name, const json & args_object, const std::string & id = "call_001") { | |
| return json{ | |
| {"id", id}, | |
| {"type", "function"}, | |
| {"function", json{ | |
| {"name", name}, | |
| {"arguments", args_object} // Pass as JSON object, not serialized string | |
| }} | |
| }; | |
| } | |
| // Helper functions to create repeating message definitions | |
| static json make_user_msg() { | |
| return json{ | |
| {"role", "user"}, | |
| {"content", "Hello, please help me."} | |
| }; | |
| } | |
| static json make_user_msg2() { | |
| return json{ | |
| {"role", "user"}, | |
| {"content", "Thank you."} | |
| }; | |
| } | |
| static json make_user_msg2_continue() { | |
| return json{ | |
| {"role", "user"}, | |
| {"content", "Continue."} | |
| }; | |
| } | |
| static json make_assistant_no_tool() { | |
| return json{ | |
| {"role", "assistant"}, | |
| {"content", "Let me help you."} | |
| }; | |
| } | |
| static json make_assistant_one_tool() { | |
| return json{ | |
| {"role", "assistant"}, | |
| {"content", nullptr}, | |
| {"tool_calls", json::array({ | |
| build_tool_call("test_function_name", json::object({{"param1", "value1"}, {"param2", "value2"}})) | |
| })} | |
| }; | |
| } | |
| static json make_assistant_two_tools() { | |
| return json{ | |
| {"role", "assistant"}, | |
| {"content", nullptr}, | |
| {"tool_calls", json::array({ | |
| build_tool_call("test_function_name", json::object({{"param1", "value1"}, {"param2", "value2"}})), | |
| build_tool_call("test_function_name", json::object({{"param1", "value3"}, {"param2", "value4"}}), "call_002") | |
| })} | |
| }; | |
| } | |
| static json make_assistant_no_reasoning() { | |
| return json{ | |
| {"role", "assistant"}, | |
| {"content", "I can help you with that."} | |
| }; | |
| } | |
| static json make_assistant_with_reasoning() { | |
| return json{ | |
| {"role", "assistant"}, | |
| {"content", "I can help you with that."}, | |
| {"reasoning_content", "The user is asking for help. I should respond positively."} | |
| }; | |
| } | |
| static json make_assistant_one_tool_with_reasoning() { | |
| return json{ | |
| {"role", "assistant"}, | |
| {"content", nullptr}, | |
| {"tool_calls", json::array({ | |
| build_tool_call("test_function_name", json::object({{"param1", "value1"}, {"param2", "value2"}})) | |
| })}, | |
| {"reasoning_content", "I need to call the tool first."} | |
| }; | |
| } | |
| static void print_diff_split(const std::string & title, const diff_split & diff) { | |
| LOG_ERR("\n%s=== %s ===%s\n", ANSI_CYAN, title.c_str(), ANSI_RESET); | |
| LOG_ERR("%sCommon Prefix:%s '%s'\n", ANSI_PREFIX, ANSI_RESET, diff.prefix.c_str()); | |
| LOG_ERR("%sCommon Suffix:%s '%s'\n", ANSI_SUFFIX, ANSI_RESET, diff.suffix.c_str()); | |
| LOG_ERR("%sLeft (difference):%s '%s'\n", ANSI_GREEN, ANSI_RESET, diff.left.c_str()); | |
| LOG_ERR("%sRight (difference):%s '%s'\n", ANSI_ORANGE, ANSI_RESET, diff.right.c_str()); | |
| } | |
| static void check_reasoning_variables(const common_chat_template & tmpl) { | |
| LOG_ERR("\n%s=== Checking Reasoning Variables ===%s\n", ANSI_CYAN, ANSI_RESET); | |
| try { | |
| // Create a list of candidate reasoning/thinking variable names to probe | |
| std::vector<std::string> candidate_vars = { | |
| "enable_reasoning", | |
| "use_reasoning", | |
| "reasoning_enabled", | |
| "has_reasoning", | |
| "reasoning_mode", | |
| "reasoning_format", | |
| "reasoning_active", | |
| "with_reasoning", | |
| "use_thinking", | |
| "thinking_enabled", | |
| "has_thinking", | |
| "thinking_mode", | |
| "thinking_format", | |
| "thinking_active", | |
| "with_thinking", | |
| "enable_reason", | |
| "reason_enabled", | |
| "enable_think", | |
| "think_enabled", | |
| }; | |
| jinja::context ctx; | |
| ctx.is_get_stats = true; | |
| json messages = json::array({ | |
| json{ | |
| {"role", "user"}, | |
| {"content", "Test message"} | |
| }, | |
| json{ | |
| {"role", "assistant"}, | |
| {"content", "Response"}, | |
| {"reasoning_content", "Some reasoning"} | |
| } | |
| }); | |
| // Set up base context | |
| jinja::global_from_json(ctx, json{ | |
| {"messages", messages}, | |
| {"tools", json::array()}, | |
| {"bos_token", ""}, | |
| {"eos_token", ""}, | |
| {"add_generation_prompt", false}, | |
| {"enable_thinking", true} // Already passed, so we'll exclude this from results | |
| }, true); | |
| // Add candidate variables as undefined to probe which ones are accessed | |
| for (const auto & var_name : candidate_vars) { | |
| ctx.set_val(var_name, jinja::mk_val<jinja::value_undefined_t>(var_name)); | |
| } | |
| try { | |
| jinja::runtime runtime(ctx); | |
| runtime.execute(tmpl.prog); | |
| } catch (const std::exception & e) { | |
| // Execution may fail, that's okay - we just want to see what variables were accessed | |
| } | |
| // Check which candidate variables were accessed (stats.used = true) | |
| std::vector<std::string> accessed_vars; | |
| for (const auto & var_name : candidate_vars) { | |
| auto val = ctx.get_val(var_name); | |
| if (!val->is_undefined()) { | |
| // Variable was overwritten, skip it | |
| continue; | |
| } | |
| if (val->stats.used) { | |
| accessed_vars.push_back(var_name); | |
| } | |
| } | |
| if (accessed_vars.empty()) { | |
| LOG_ERR("%sNo reasoning/thinking-related variables were queried by the template%s\n", ANSI_GRAY, ANSI_RESET); | |
| } else { | |
| LOG_ERR("Template queries the following reasoning/thinking-related variables:\n"); | |
| for (const auto & var : accessed_vars) { | |
| LOG_ERR(" %s- %s%s\n", ANSI_ORANGE, var.c_str(), ANSI_RESET); | |
| } | |
| } | |
| } catch (const std::exception & e) { | |
| LOG_ERR("Error checking reasoning variables: %s\n", e.what()); | |
| } | |
| } | |
| static void analyze_template(const std::string & template_path) { | |
| LOG_ERR("\n"); | |
| LOG_ERR("%s", ANSI_PURPLE); | |
| LOG_ERR("================================================================================\n"); | |
| LOG_ERR(" ANALYZING TEMPLATE: %s\n", template_path.c_str()); | |
| LOG_ERR("================================================================================\n"); | |
| LOG_ERR("%s", ANSI_RESET); | |
| std::string template_source; | |
| try { | |
| template_source = read_file(template_path); | |
| } catch (const std::exception & e) { | |
| LOG_ERR("Error reading template: %s\n", e.what()); | |
| return; | |
| } | |
| try { | |
| common_chat_template chat_template(template_source, "", ""); | |
| json tools = build_tools_definition(); | |
| // ===== CAPABILITIES ANALYSIS ===== | |
| LOG_ERR("\n%s=== Template Capabilities (from jinja::caps) ===%s\n", ANSI_CYAN, ANSI_RESET); | |
| auto caps = chat_template.original_caps(); | |
| LOG_ERR("%ssupports_tools:%s %s\n", ANSI_BLUE, ANSI_RESET, caps.supports_tools ? "true" : "false"); | |
| LOG_ERR("%ssupports_tool_calls:%s %s\n", ANSI_BLUE, ANSI_RESET, caps.supports_tool_calls ? "true" : "false"); | |
| LOG_ERR("%ssupports_system_role:%s %s\n", ANSI_BLUE, ANSI_RESET, caps.supports_system_role ? "true" : "false"); | |
| LOG_ERR("%ssupports_parallel_tool_calls:%s %s\n", ANSI_BLUE, ANSI_RESET, caps.supports_parallel_tool_calls ? "true" : "false"); | |
| LOG_ERR("%ssupports_typed_content:%s %s\n", ANSI_BLUE, ANSI_RESET, caps.supports_typed_content ? "true" : "false"); | |
| LOG_ERR("%ssupports_string_content:%s %s\n", ANSI_BLUE, ANSI_RESET, caps.supports_string_content ? "true" : "false"); | |
| // ===== DIFFERENTIAL ANALYSIS ===== | |
| // Test 1: With and without tools (single user message) | |
| { | |
| json user_msg = make_user_msg(); | |
| autoparser::generation_params params_no_tools; | |
| params_no_tools.messages = json::array({ user_msg }); | |
| params_no_tools.add_generation_prompt = false; | |
| params_no_tools.tools = json::array(); | |
| autoparser::generation_params params_with_tools = params_no_tools; | |
| params_with_tools.tools = tools; | |
| std::string output_no_tools = common_chat_template_direct_apply(chat_template, params_no_tools); | |
| std::string output_with_tools = common_chat_template_direct_apply(chat_template, params_with_tools); | |
| auto diff = calculate_diff_split(output_no_tools, output_with_tools); | |
| print_diff_split("Diff: With vs Without Tools (single user message)", diff); | |
| } | |
| // Test 2: With and without add_generation_prompt (single user message) | |
| { | |
| json user_msg = make_user_msg(); | |
| autoparser::generation_params params_no_prompt; | |
| params_no_prompt.messages = json::array({ user_msg }); | |
| params_no_prompt.add_generation_prompt = false; | |
| params_no_prompt.tools = json::array(); | |
| autoparser::generation_params params_with_prompt = params_no_prompt; | |
| params_with_prompt.add_generation_prompt = true; | |
| std::string output_no_prompt = common_chat_template_direct_apply(chat_template, params_no_prompt); | |
| std::string output_with_prompt = common_chat_template_direct_apply(chat_template, params_with_prompt); | |
| auto diff = calculate_diff_split(output_no_prompt, output_with_prompt); | |
| print_diff_split("Diff: With vs Without add_generation_prompt (single user message)", diff); | |
| } | |
| // Test 3: Assistant with reasoning_content (user, assistant) | |
| { | |
| json user_msg = make_user_msg(); | |
| autoparser::generation_params params_no_reasoning; | |
| params_no_reasoning.messages = json::array({ user_msg, make_assistant_no_reasoning() }); | |
| params_no_reasoning.add_generation_prompt = false; | |
| params_no_reasoning.enable_thinking = true; | |
| autoparser::generation_params params_with_reasoning = params_no_reasoning; | |
| params_with_reasoning.messages = json::array({ user_msg, make_assistant_with_reasoning() }); | |
| std::string output_no_reasoning = common_chat_template_direct_apply(chat_template, params_no_reasoning); | |
| std::string output_with_reasoning = common_chat_template_direct_apply(chat_template, params_with_reasoning); | |
| auto diff = calculate_diff_split(output_no_reasoning, output_with_reasoning); | |
| print_diff_split("Diff: With vs Without reasoning_content (user, assistant)", diff); | |
| } | |
| // Test 4: Assistant with reasoning_content (user, assistant, user) | |
| { | |
| json user_msg = make_user_msg(); | |
| json user_msg2 = make_user_msg2(); | |
| autoparser::generation_params params_no_reasoning; | |
| params_no_reasoning.messages = json::array({ user_msg, make_assistant_no_reasoning(), user_msg2 }); | |
| params_no_reasoning.add_generation_prompt = false; | |
| params_no_reasoning.enable_thinking = true; | |
| autoparser::generation_params params_with_reasoning = params_no_reasoning; | |
| params_with_reasoning.messages = json::array({ user_msg, make_assistant_with_reasoning(), user_msg2 }); | |
| std::string output_no_reasoning = common_chat_template_direct_apply(chat_template, params_no_reasoning); | |
| std::string output_with_reasoning = common_chat_template_direct_apply(chat_template, params_with_reasoning); | |
| auto diff = calculate_diff_split(output_no_reasoning, output_with_reasoning); | |
| print_diff_split("Diff: With vs Without reasoning_content (user, assistant, user)", diff); | |
| } | |
| // Test 5: Tool call in last assistant message (user, assistant) | |
| { | |
| json user_msg = make_user_msg(); | |
| autoparser::generation_params params_no_tool; | |
| params_no_tool.messages = json::array({ user_msg, make_assistant_no_tool() }); | |
| params_no_tool.add_generation_prompt = false; | |
| params_no_tool.tools = tools; | |
| autoparser::generation_params params_with_tool = params_no_tool; | |
| params_with_tool.messages = json::array({ user_msg, make_assistant_one_tool() }); | |
| std::string output_no_tool = common_chat_template_direct_apply(chat_template, params_no_tool); | |
| std::string output_with_tool = common_chat_template_direct_apply(chat_template, params_with_tool); | |
| auto diff = calculate_diff_split(output_no_tool, output_with_tool); | |
| print_diff_split("Diff: With vs Without tool call (user, assistant)", diff); | |
| } | |
| // Test 6: Tool call in last assistant message (user, assistant, user) | |
| { | |
| json user_msg = make_user_msg(); | |
| json user_msg2 = make_user_msg2_continue(); | |
| autoparser::generation_params params_no_tool; | |
| params_no_tool.messages = json::array({ user_msg, make_assistant_no_tool(), user_msg2 }); | |
| params_no_tool.add_generation_prompt = false; | |
| params_no_tool.tools = tools; | |
| autoparser::generation_params params_with_tool = params_no_tool; | |
| params_with_tool.messages = json::array({ user_msg, make_assistant_one_tool(), user_msg2 }); | |
| std::string output_no_tool = common_chat_template_direct_apply(chat_template, params_no_tool); | |
| std::string output_with_tool = common_chat_template_direct_apply(chat_template, params_with_tool); | |
| auto diff = calculate_diff_split(output_no_tool, output_with_tool); | |
| print_diff_split("Diff: With vs Without tool call (user, assistant, user)", diff); | |
| } | |
| // Test 7: One vs two tool calls (user, assistant) | |
| { | |
| json user_msg = make_user_msg(); | |
| autoparser::generation_params params_one_tool; | |
| params_one_tool.messages = json::array({ user_msg, make_assistant_one_tool() }); | |
| params_one_tool.add_generation_prompt = false; | |
| params_one_tool.tools = tools; | |
| autoparser::generation_params params_two_tools = params_one_tool; | |
| params_two_tools.messages = json::array({ user_msg, make_assistant_two_tools() }); | |
| std::string output_one_tool = common_chat_template_direct_apply(chat_template, params_one_tool); | |
| std::string output_two_tools = common_chat_template_direct_apply(chat_template, params_two_tools); | |
| auto diff = calculate_diff_split(output_one_tool, output_two_tools); | |
| print_diff_split("Diff: One vs Two tool calls (user, assistant)", diff); | |
| } | |
| // Test 8: One vs two tool calls (user, assistant, user) | |
| { | |
| json user_msg = make_user_msg(); | |
| json user_msg2 = make_user_msg2_continue(); | |
| autoparser::generation_params params_one_tool; | |
| params_one_tool.messages = json::array({ user_msg, make_assistant_one_tool(), user_msg2 }); | |
| params_one_tool.add_generation_prompt = false; | |
| params_one_tool.tools = tools; | |
| autoparser::generation_params params_two_tools = params_one_tool; | |
| params_two_tools.messages = json::array({ user_msg, make_assistant_two_tools(), user_msg2 }); | |
| std::string output_one_tool = common_chat_template_direct_apply(chat_template, params_one_tool); | |
| std::string output_two_tools = common_chat_template_direct_apply(chat_template, params_two_tools); | |
| auto diff = calculate_diff_split(output_one_tool, output_two_tools); | |
| print_diff_split("Diff: One vs Two tool calls (user, assistant, user)", diff); | |
| } | |
| // Test 9: Tool call with vs without reasoning_content (user, assistant) | |
| { | |
| json user_msg = make_user_msg(); | |
| autoparser::generation_params params_no_reasoning; | |
| params_no_reasoning.messages = json::array({ user_msg, make_assistant_one_tool() }); | |
| params_no_reasoning.add_generation_prompt = false; | |
| params_no_reasoning.tools = tools; | |
| params_no_reasoning.enable_thinking = true; | |
| autoparser::generation_params params_with_reasoning = params_no_reasoning; | |
| params_with_reasoning.messages = json::array({ user_msg, make_assistant_one_tool_with_reasoning() }); | |
| std::string output_no_reasoning = common_chat_template_direct_apply(chat_template, params_no_reasoning); | |
| std::string output_with_reasoning = common_chat_template_direct_apply(chat_template, params_with_reasoning); | |
| auto diff = calculate_diff_split(output_no_reasoning, output_with_reasoning); | |
| print_diff_split("Diff: Tool call with vs without reasoning_content (user, assistant)", diff); | |
| } | |
| // Check reasoning variables | |
| check_reasoning_variables(chat_template); | |
| } catch (const std::exception & e) { | |
| LOG_ERR("Analysis failed: %s\n", e.what()); | |
| } | |
| } | |
| int main(int argc, char ** argv) { | |
| // Set log level to capture all output | |
| common_log_set_verbosity_thold(99); | |
| analysis_options opts; | |
| if (!parse_options(argc, argv, opts)) { | |
| return 1; | |
| } | |
| LOG_ERR("\n"); | |
| LOG_ERR("%s", ANSI_PURPLE); | |
| LOG_ERR("================================================================================\n"); | |
| LOG_ERR(" TEMPLATE ANALYSIS TOOL\n"); | |
| LOG_ERR("================================================================================\n"); | |
| LOG_ERR("%s", ANSI_RESET); | |
| LOG_ERR("Analyzing %s%zu%s template(s)\n", ANSI_CYAN, opts.template_paths.size(), ANSI_RESET); | |
| for (const auto & path : opts.template_paths) { | |
| analyze_template(path); | |
| } | |
| LOG_ERR("\n"); | |
| LOG_ERR("%s", ANSI_GREEN); | |
| LOG_ERR("================================================================================\n"); | |
| LOG_ERR(" ANALYSIS COMPLETE\n"); | |
| LOG_ERR("================================================================================\n"); | |
| LOG_ERR("%s", ANSI_RESET); | |
| return 0; | |
| } | |