#include <nlohmann/json.hpp>
-using json = nlohmann::ordered_json;
+using ordered_json = nlohmann::ordered_json;
static std::string_view trim_trailing_space(std::string_view sv, int max = -1) {
int count = 0;
// JSON-escape a string and return the inner content (without surrounding quotes).
static std::string escape_json_string_inner(const std::string & s) {
- std::string escaped = json(s).dump();
+ std::string escaped = ordered_json(s).dump();
if (escaped.size() >= 2 && escaped.front() == '"' && escaped.back() == '"') {
return escaped.substr(1, escaped.size() - 2);
}
if (arg_count > 0) {
arg_entry = ",";
}
- arg_entry += json(trim(node.text)).dump() + ":";
+ arg_entry += ordered_json(trim(node.text)).dump() + ":";
++arg_count;
auto & target = args_target();
// Try to parse as JSON value (number, bool, null, object, array)
try {
- json parsed = json::parse(value_content);
+ ordered_json parsed = ordered_json::parse(value_content);
if (parsed.is_string()) {
// Don't add closing quote yet (added by arg_close) for monotonic streaming
std::string escaped = parsed.dump();
common_peg_parser common_chat_peg_builder::standard_constructed_tools(
const std::map<std::string, std::string> & markers,
- const nlohmann::json & tools,
+ const ordered_json & tools,
bool parallel_tool_calls,
bool force_tool_calls) {
if (!tools.is_array() || tools.empty()) {
}
const auto & function = tool_def.at("function");
std::string name = function.at("name");
- nlohmann::json params = function.contains("parameters") ? function.at("parameters") : nlohmann::json::object();
+ ordered_json params = function.contains("parameters") ? function.at("parameters") : ordered_json::object();
// Build argument parsers
auto args = eps();
// Python-style tool calls: name(arg1="value1", arg2=123)
// Used only by LFM2 for now, so we don't merge it into autoparser
common_peg_parser common_chat_peg_builder::python_style_tool_calls(
- const nlohmann::json & tools,
- bool parallel_tool_calls) {
+ const ordered_json & tools,
+ bool parallel_tool_calls) {
if (!tools.is_array() || tools.empty()) {
return eps();
}
}
const auto & function = tool_def.at("function");
std::string name = function.at("name");
- nlohmann::json params = function.contains("parameters") ? function.at("parameters") : nlohmann::json::object();
+ ordered_json params = function.contains("parameters") ? function.at("parameters") : ordered_json::object();
auto args = eps();
if (params.contains("properties") && !params["properties"].empty()) {
// Mode 1: function_is_key — parse {"function_name": {...}}
common_peg_parser common_chat_peg_builder::build_json_tools_function_is_key(
- const nlohmann::json & tools,
- const std::string & args_key,
- const std::string & effective_args_key,
- const std::string & call_id_key,
- const std::string & gen_call_id_key) {
+ const ordered_json & tools,
+ const std::string & args_key,
+ const std::string & effective_args_key,
+ const std::string & call_id_key,
+ const std::string & gen_call_id_key) {
auto tool_choices = choice();
}
const auto & function = tool_def.at("function");
std::string name = function.at("name");
- nlohmann::json params = function.contains("parameters") ? function.at("parameters") : nlohmann::json::object();
+ ordered_json params = function.contains("parameters") ? function.at("parameters") : ordered_json::object();
// Build inner object fields
std::vector<common_peg_parser> inner_fields;
// Mode 2: Nested keys (dot notation like "function.name")
common_peg_parser common_chat_peg_builder::build_json_tools_nested_keys(
- const nlohmann::json & tools,
- const std::string & effective_name_key,
- const std::string & effective_args_key,
- const std::string & call_id_key,
- const std::string & gen_call_id_key) {
+ const ordered_json & tools,
+ const std::string & effective_name_key,
+ const std::string & effective_args_key,
+ const std::string & call_id_key,
+ const std::string & gen_call_id_key) {
auto tool_choices = choice();
}
const auto & function = tool_def.at("function");
std::string name = function.at("name");
- nlohmann::json params = function.contains("parameters") ? function.at("parameters") : nlohmann::json::object();
+ ordered_json params = function.contains("parameters") ? function.at("parameters") : ordered_json::object();
auto nested_name = literal("\"" + nested_name_field + "\"") + space() + literal(":") + space() +
literal("\"") + tool_name(literal(name)) + literal("\"");
// Mode 3: Flat keys with optional ID fields and parameter ordering
common_peg_parser common_chat_peg_builder::build_json_tools_flat_keys(
- const nlohmann::json & tools,
+ const ordered_json & tools,
const std::string & effective_name_key,
const std::string & effective_args_key,
const std::string & call_id_key,
}
const auto & function = tool_def.at("function");
std::string name = function.at("name");
- nlohmann::json params = function.contains("parameters") ? function.at("parameters") : nlohmann::json::object();
+ ordered_json params = function.contains("parameters") ? function.at("parameters") : ordered_json::object();
auto tool_name_ = name_key_parser + space() + literal(":") + space() +
literal("\"") + tool_name(literal(name)) + literal("\"");
common_peg_parser common_chat_peg_builder::standard_json_tools(
const std::string & section_start,
const std::string & section_end,
- const nlohmann::json & tools,
+ const ordered_json & tools,
bool parallel_tool_calls,
bool force_tool_calls,
const std::string & name_key,
// parameters_order: order in which JSON fields should be parsed
common_peg_parser standard_json_tools(const std::string & section_start,
const std::string & section_end,
- const nlohmann::json & tools,
+ const nlohmann::ordered_json & tools,
bool parallel_tool_calls,
bool force_tool_calls,
const std::string & name_key = "",
// Legacy-compatible helper for building XML/tagged style tool calls
// Used by tests and manual parsers
common_peg_parser standard_constructed_tools(const std::map<std::string, std::string> & markers,
- const nlohmann::json & tools,
+ const nlohmann::ordered_json & tools,
bool parallel_tool_calls,
bool force_tool_calls);
// Helper for Python-style function call format: name(arg1="value1", arg2=123)
// Used by LFM2 and similar templates
- common_peg_parser python_style_tool_calls(const nlohmann::json & tools,
- bool parallel_tool_calls);
+ common_peg_parser python_style_tool_calls(const nlohmann::ordered_json & tools,
+ bool parallel_tool_calls);
private:
// Implementation helpers for standard_json_tools — one per JSON tool call layout mode
- common_peg_parser build_json_tools_function_is_key(const nlohmann::json & tools,
- const std::string & args_key,
- const std::string & effective_args_key,
- const std::string & call_id_key,
- const std::string & gen_call_id_key);
-
- common_peg_parser build_json_tools_nested_keys(const nlohmann::json & tools,
- const std::string & effective_name_key,
- const std::string & effective_args_key,
- const std::string & call_id_key,
- const std::string & gen_call_id_key);
-
- common_peg_parser build_json_tools_flat_keys(const nlohmann::json & tools,
+ common_peg_parser build_json_tools_function_is_key(const nlohmann::ordered_json & tools,
+ const std::string & args_key,
+ const std::string & effective_args_key,
+ const std::string & call_id_key,
+ const std::string & gen_call_id_key);
+
+ common_peg_parser build_json_tools_nested_keys(const nlohmann::ordered_json & tools,
+ const std::string & effective_name_key,
+ const std::string & effective_args_key,
+ const std::string & call_id_key,
+ const std::string & gen_call_id_key);
+
+ common_peg_parser build_json_tools_flat_keys(const nlohmann::ordered_json & tools,
const std::string & effective_name_key,
const std::string & effective_args_key,
const std::string & call_id_key,