diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index 54691da3f4..36f1e0cd50 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -81,6 +81,8 @@ add_library(${TARGET} imatrix-loader.cpp imatrix-loader.h json-schema-to-grammar.cpp + json.cpp + json.h llguidance.cpp log.cpp log.h diff --git a/common/arg.cpp b/common/arg.cpp index 0a479c6aaa..4a36ff9b0c 100644 --- a/common/arg.cpp +++ b/common/arg.cpp @@ -5,6 +5,7 @@ #include "common.h" #include "download.h" #include "json-schema-to-grammar.h" +#include "json.h" #include "llama.h" #include "log.h" #include "sampling.h" @@ -21,9 +22,6 @@ #include #endif -#define JSON_ASSERT GGML_ASSERT -#include - #include #include #include @@ -32,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -55,7 +54,6 @@ #define LLAMA_MAX_URL_LENGTH 2084 // Maximum URL Length in Chrome: 2083 -using json = nlohmann::ordered_json; using namespace common_arg_utils; static std::initializer_list mmproj_examples = { @@ -2272,7 +2270,7 @@ common_params_context common_params_parser_init(common_params & params, llama_ex {"-j", "--json-schema"}, "SCHEMA", "JSON schema to constrain generations (https://json-schema.org/), e.g. `{}` for any JSON object\nFor schemas w/ external $refs, use --grammar + example/json_schema_to_grammar.py instead", [](common_params & params, const std::string & value) { - params.sampling.grammar = {COMMON_GRAMMAR_TYPE_OUTPUT_FORMAT, json_schema_to_grammar(json::parse(value))}; + params.sampling.grammar = {COMMON_GRAMMAR_TYPE_OUTPUT_FORMAT, json_schema_to_grammar(common_json::parse(value))}; } ).set_sampling()); add_opt(common_arg( @@ -2289,7 +2287,7 @@ common_params_context common_params_parser_init(common_params & params, llama_ex std::istreambuf_iterator(), std::back_inserter(schema) ); - params.sampling.grammar = {COMMON_GRAMMAR_TYPE_OUTPUT_FORMAT, json_schema_to_grammar(json::parse(schema))}; + params.sampling.grammar = {COMMON_GRAMMAR_TYPE_OUTPUT_FORMAT, json_schema_to_grammar(common_json::parse(schema))}; } ).set_sampling()); add_opt(common_arg( @@ -3500,13 +3498,13 @@ common_params_context common_params_parser_init(common_params & params, llama_ex {"--chat-template-kwargs"}, "STRING", "sets additional params for the json template parser, must be a valid json object string, e.g. '{\"key1\":\"value1\",\"key2\":\"value2\"}'", [](common_params & params, const std::string & value) { - auto parsed = json::parse(value); - for (const auto & item : parsed.items()) { - if (item.key() == "enable_thinking") { + auto parsed = common_json::parse(value); + for (const auto & [key, val] : parsed.items()) { + if (key == "enable_thinking") { LOG_WRN("Setting 'enable_thinking' via --chat-template-kwargs is deprecated. " "Use --reasoning on / --reasoning off instead.\n"); } - params.default_template_kwargs[item.key()] = item.value().dump(); + params.default_template_kwargs[key] = val.dump(); } } ).set_examples({LLAMA_EXAMPLE_SERVER, LLAMA_EXAMPLE_CLI}).set_env("LLAMA_ARG_CHAT_TEMPLATE_KWARGS")); @@ -3674,7 +3672,7 @@ common_params_context common_params_parser_init(common_params & params, llama_ex if (value == "default") { params.default_template_kwargs.erase("reasoning_effort"); } else { - params.default_template_kwargs["reasoning_effort"] = json(value).dump(); + params.default_template_kwargs["reasoning_effort"] = common_json::make(value).dump(); } } ).set_examples({LLAMA_EXAMPLE_SERVER, LLAMA_EXAMPLE_COMPLETION, LLAMA_EXAMPLE_CLI}).set_env("LLAMA_ARG_REASONING_EFFORT")); diff --git a/common/chat-auto-parser-helpers.cpp b/common/chat-auto-parser-helpers.cpp index 81b17e5e1d..b37906bdf8 100644 --- a/common/chat-auto-parser-helpers.cpp +++ b/common/chat-auto-parser-helpers.cpp @@ -4,14 +4,11 @@ #include "chat-peg-parser.h" #include "chat.h" #include "log.h" -#include "nlohmann/json.hpp" #include "peg-parser.h" #include #include -using json = nlohmann::ordered_json; - std::string trim_whitespace(const std::string & str) { size_t start = 0; while (start < str.length() && std::isspace(static_cast(str[start]))) { diff --git a/common/chat.cpp b/common/chat.cpp index 39761f12ac..ee2e777af2 100644 --- a/common/chat.cpp +++ b/common/chat.cpp @@ -3799,7 +3799,7 @@ static common_chat_params common_chat_templates_apply_legacy(const struct common common_chat_params params; params.prompt = std::string(buf.data(), res); if (!inputs.json_schema.empty()) { - params.grammar = json_schema_to_grammar(json::parse(inputs.json_schema)); + params.grammar = json_schema_to_grammar(common_json::parse(inputs.json_schema)); } else { params.grammar = inputs.grammar; } diff --git a/common/download.cpp b/common/download.cpp index 2509f75ab9..4b28a708c8 100644 --- a/common/download.cpp +++ b/common/download.cpp @@ -5,9 +5,7 @@ #include "log.h" #include "download.h" #include "hf-cache.h" - -#define JSON_ASSERT GGML_ASSERT -#include +#include "json.h" #include #include @@ -44,8 +42,6 @@ #include #endif -using json = nlohmann::ordered_json; - // // downloader // @@ -856,8 +852,8 @@ static std::string common_docker_get_token(const std::string & repo) { throw std::runtime_error("Failed to get Docker registry token, HTTP code: " + std::to_string(res.first)); } - std::string response_str(res.second.begin(), res.second.end()); - nlohmann::ordered_json response = nlohmann::ordered_json::parse(response_str); + std::string response_str(res.second.begin(), res.second.end()); + common_json response = common_json::parse(response_str); if (!response.contains("token")) { throw std::runtime_error("Docker registry token response missing 'token' field"); @@ -919,9 +915,9 @@ std::string common_docker_resolve_model(const std::string & docker) { throw std::runtime_error("Failed to get Docker manifest, HTTP code: " + std::to_string(manifest_res.first)); } - std::string manifest_str(manifest_res.second.begin(), manifest_res.second.end()); - nlohmann::ordered_json manifest = nlohmann::ordered_json::parse(manifest_str); - std::string gguf_digest; // Find the GGUF layer + std::string manifest_str(manifest_res.second.begin(), manifest_res.second.end()); + common_json manifest = common_json::parse(manifest_str); + std::string gguf_digest; // Find the GGUF layer if (manifest.contains("layers")) { for (const auto & layer : manifest["layers"]) { if (layer.contains("mediaType")) { diff --git a/common/hf-cache.cpp b/common/hf-cache.cpp index f1dacaa477..50d6dd6105 100644 --- a/common/hf-cache.cpp +++ b/common/hf-cache.cpp @@ -4,9 +4,7 @@ #include "common.h" #include "log.h" #include "http.h" - -#define JSON_ASSERT GGML_ASSERT -#include +#include "json.h" #include #include @@ -15,8 +13,6 @@ #include #include -namespace nl = nlohmann; - #if defined(_WIN32) #define WIN32_LEAN_AND_MEAN #ifndef NOMINMAX @@ -195,8 +191,8 @@ static void safe_write_file(const fs::path & path, const std::string & data) { } } -static nl::json api_get(const std::string & url, - const std::string & token) { +static common_json api_get(const std::string & url, + const std::string & token) { auto [cli, parts] = common_http_client(url); httplib::Headers headers = { @@ -214,10 +210,10 @@ static nl::json api_get(const std::string & url, auto body = res->body; if (res->status == 200) { - return nl::json::parse(res->body); + return common_json::parse(res->body); } try { - body = nl::json::parse(res->body)["error"].get(); + body = common_json::parse(res->body)["error"].get(); } catch (...) { } throw std::runtime_error("GET failed (" + std::to_string(res->status) + "): " + body); @@ -280,7 +276,7 @@ static std::string get_repo_commit(const std::string & repo_id, safe_write_file(refs_path / name, commit); return commit; - } catch (const nl::json::exception & e) { + } catch (const common_json_error & e) { LOG_ERR("%s: JSON error: %s\n", __func__, e.what()); } catch (const std::exception & e) { LOG_ERR("%s: error: %s\n", __func__, e.what()); @@ -358,7 +354,7 @@ hf_files get_repo_files(const std::string & repo_id, files.push_back(file); } - } catch (const nl::json::exception & e) { + } catch (const common_json_error & e) { LOG_ERR("%s: JSON error: %s\n", __func__, e.what()); } catch (const std::exception & e) { LOG_ERR("%s: error: %s\n", __func__, e.what()); diff --git a/common/json-schema-to-grammar.cpp b/common/json-schema-to-grammar.cpp index 955b4e014b..e7b12aed8a 100644 --- a/common/json-schema-to-grammar.cpp +++ b/common/json-schema-to-grammar.cpp @@ -1227,7 +1227,7 @@ bool common_schema_info::resolves_to_string(const nlohmann::ordered_json & schem return check(schema); } -std::string json_schema_to_grammar(const json & schema, bool force_gbnf) { +std::string json_schema_to_grammar(const common_json & schema, bool force_gbnf) { #ifdef LLAMA_USE_LLGUIDANCE if (!force_gbnf) { return "%llguidance {}\nstart: %json " + schema.dump(); @@ -1236,7 +1236,7 @@ std::string json_schema_to_grammar(const json & schema, bool force_gbnf) { (void)force_gbnf; #endif // LLAMA_USE_LLGUIDANCE return build_grammar([&](const common_grammar_builder & callbacks) { - auto copy = schema; + auto copy = common_json_raw(schema); callbacks.resolve_refs(copy); callbacks.add_schema("", copy); }); diff --git a/common/json-schema-to-grammar.h b/common/json-schema-to-grammar.h index 240d642311..bab5591eff 100644 --- a/common/json-schema-to-grammar.h +++ b/common/json-schema-to-grammar.h @@ -1,12 +1,14 @@ #pragma once +#include "json.h" + #include #include #include #include -std::string json_schema_to_grammar(const nlohmann::ordered_json & schema, +std::string json_schema_to_grammar(const common_json & schema, bool force_gbnf = false); class common_schema_converter; diff --git a/tools/server/server-schema.cpp b/tools/server/server-schema.cpp index 5d7fa6ae6e..33c4ecd46e 100644 --- a/tools/server/server-schema.cpp +++ b/tools/server/server-schema.cpp @@ -258,7 +258,7 @@ std::vector> make_llama_cmpl_schema(const common_params & try { auto schema = json_value(data, "json_schema", json::object()); SRV_DBG("JSON schema: %s\n", schema.dump(2).c_str()); - std::string grammar_str = json_schema_to_grammar(schema); + std::string grammar_str = json_schema_to_grammar(common_json_from_raw(schema)); SRV_DBG("Converted grammar: %s\n", grammar_str.c_str()); params.sampling.grammar = {COMMON_GRAMMAR_TYPE_OUTPUT_FORMAT, std::move(grammar_str)}; } catch (const std::exception & e) {