Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 12 additions & 5 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -54,10 +54,13 @@ endif()

include(FetchContent)

# Fetch nlohmann/json
FetchContent_Declare(json URL https://github.com/nlohmann/json/archive/refs/heads/develop.zip)
FetchContent_MakeAvailable(json)
target_link_libraries(minja INTERFACE nlohmann_json::nlohmann_json)
# Fetch rapidjson
FetchContent_Declare(RapidJSON_repo
GIT_REPOSITORY https://github.com/Tencent/rapidjson.git
GIT_TAG master # Or a specific release tag
)
FetchContent_MakeAvailable(RapidJSON_repo)
target_include_directories(minja INTERFACE ${rapidjson_SOURCE_DIR}/include)

if(MINJA_TEST_ENABLED)
if (MINJA_FUZZTEST_ENABLED)
Expand Down Expand Up @@ -110,7 +113,11 @@ endif()

find_program(CPPCHECK cppcheck)
if(CPPCHECK)
set(CMAKE_CXX_CPPCHECK "${CPPCHECK}" -i ${json_SOURCE_DIR}/include/nlohmann/json.hpp)
# Update the cppcheck exclusion if rapidjson headers cause issues.
# For now, let's remove the exclusion for nlohmann/json.
# If rapidjson needs an exclusion, it can be added here.
# Example: set(CMAKE_CXX_CPPCHECK "${CPPCHECK}" -i ${rapidjson_SOURCE_DIR}/include/rapidjson/...)
set(CMAKE_CXX_CPPCHECK "${CPPCHECK}")
message(STATUS "cppcheck found: ${CPPCHECK}")
endif()

Expand Down
51 changes: 46 additions & 5 deletions examples/chat-template.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,14 @@
#include <minja/chat-template.hpp>
#include <iostream>

using json = nlohmann::ordered_json;
#include "rapidjson/document.h"
#include "rapidjson/stringbuffer.h"
#include "rapidjson/writer.h" // For debugging if needed
#include "rapidjson/error/en.h"


// using json = nlohmann::ordered_json; // Replaced
// No top-level using Document = rapidjson::Document; needed if interaction is via minja types

int main() {
minja::chat_template tmpl(
Expand All @@ -21,14 +28,48 @@ int main() {
);

minja::chat_template_inputs inputs;
inputs.messages = json::parse(R"([

// For messages
rapidjson::Document messages_doc;
const char* messages_json_str = R"([
{"role": "user", "content": "Hello"},
{"role": "assistant", "content": "Hi there"}
])");
])";
if (messages_doc.Parse(messages_json_str).HasParseError()) {
fprintf(stderr, "JSON parse error for messages: %s (offset %u)\n",
rapidjson::GetParseError_En(messages_doc.GetParseError()),
static_cast<unsigned>(messages_doc.GetErrorOffset()));
return 1;
}
// Assuming inputs.messages is a rapidjson::Value and needs an allocator,
// or chat_template_inputs constructor/assignment handles it.
// If inputs.messages needs to be self-contained or modified by `apply`,
// it might need its own allocator or copy from messages_doc using an allocator.
// Let's assume chat_template_inputs is designed to take ownership or copy.
// The `chat_template_inputs` struct was defined with its own allocator member `allocator_for_inputs`
// and its members `messages`, `tools`, `extra_context` are `rapidjson::Value`.
// We need to ensure an allocator is available for these members.
// Simplest for an example: create a main Document that owns all data for inputs.
rapidjson::Document input_data_owner_doc;
inputs.allocator_for_inputs = &input_data_owner_doc.GetAllocator();

inputs.messages.CopyFrom(messages_doc, *inputs.allocator_for_inputs);

inputs.add_generation_prompt = true;
inputs.tools = json::parse(R"([

// For tools
rapidjson::Document tools_doc;
const char* tools_json_str = R"([
{"type": "function", "function": {"name": "google_search", "arguments": {"query": "2+2"}}}
])");
])";
if (tools_doc.Parse(tools_json_str).HasParseError()) {
fprintf(stderr, "JSON parse error for tools: %s (offset %u)\n",
rapidjson::GetParseError_En(tools_doc.GetParseError()),
static_cast<unsigned>(tools_doc.GetErrorOffset()));
return 1;
}
inputs.tools.CopyFrom(tools_doc, *inputs.allocator_for_inputs);
// inputs.extra_context is already kNullType by default in chat_template_inputs constructor.

std::cout << tmpl.apply(inputs) << std::endl;
}
48 changes: 44 additions & 4 deletions examples/raw.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,53 @@
#include <minja/minja.hpp>
#include <iostream>

using json = nlohmann::ordered_json;
// rapidjson includes
#include "rapidjson/document.h"
#include "rapidjson/writer.h"
#include "rapidjson/stringbuffer.h"
#include "rapidjson/error/en.h"

// using json = nlohmann::ordered_json; // Replaced
// No top-level using Document = rapidjson::Document; needed if interaction is via minja types

int main() {
auto tmpl = minja::Parser::parse("Hello, {{ location }}!", /* options= */ {});
auto context = minja::Context::make(minja::Value(json {
{"location", "World"},
}));

// Create data for the context using rapidjson
// The minja::Value constructor that takes nlohmann::json is temporary.
// Ideally, minja::Value would be constructed directly with rapidjson values or
// have a more direct way to build its internal structure.
// For this example, we'll bridge via the nlohmann-accepting constructor,
// assuming it's been updated internally as per the minja.hpp refactoring.
// This implies minja::Value(nlohmann::json) converts to its new rapidjson backend.

// If minja::Value is to be constructed directly with rapidjson:
// 1. Create a rapidjson::Document to own the memory
// 2. Create the object within that document
// 3. Pass the rapidjson::Value (referencing the object in the doc) to a
// minja::Value constructor designed for this (e.g., Value(const rapidjson::Value&, rapidjson::Document::AllocatorType*))
// or, if minja::Value itself manages an owned_document_ for such cases.

// Given the current state of minja.hpp (with the nlohmann bridge constructor):
nlohmann::json context_data_nl = {
{"location", "World"}
};
minja::Value context_value(context_data_nl); // This uses the bridge constructor

// If the bridge was removed, it would look something like this:
// rapidjson::Document context_doc_owner;
// rapidjson::Value context_rvalue(rapidjson::kObjectType);
// rapidjson::Value location_key("location", context_doc_owner.GetAllocator());
// rapidjson::Value location_val("World", context_doc_owner.GetAllocator());
// context_rvalue.AddMember(location_key, location_val, context_doc_owner.GetAllocator());
// minja::Value context_value; // Needs a way to be initialized with context_rvalue
// and potentially take ownership or reference context_doc_owner.
// This part is complex and depends on the final design of minja::Value's rapidjson integration.
// The current minja.hpp overwrite created an owned_document_ in string/primitive constructors
// and in the nlohmann::json constructor.
// A minja::Value representing an object directly built with rapidjson would need careful handling.

auto context = minja::Context::make(std::move(context_value));
auto result = tmpl->render(context);
std::cout << result << std::endl;
}
Loading