| 761 | } |
| 762 | |
| 763 | static std::string apply( |
| 764 | const common_chat_template & tmpl, |
| 765 | const struct templates_params & inputs, |
| 766 | const std::optional<json> & messages_override = std::nullopt, |
| 767 | const std::optional<json> & tools_override = std::nullopt, |
| 768 | const std::optional<json> & additional_context = std::nullopt) |
| 769 | { |
| 770 | jinja::context ctx(tmpl.source()); |
| 771 | |
| 772 | nlohmann::ordered_json inp = nlohmann::ordered_json{ |
| 773 | {"messages", messages_override.has_value() ? *messages_override : inputs.messages}, |
| 774 | {"bos_token", tmpl.bos_token()}, |
| 775 | {"eos_token", tmpl.eos_token()}, |
| 776 | }; |
| 777 | if (tools_override.has_value() || !inputs.tools.empty()) { |
| 778 | inp["tools"] = tools_override.has_value() ? *tools_override : inputs.tools; |
| 779 | } |
| 780 | if (inputs.extra_context.is_object()) { |
| 781 | // TODO: do we need to merge, or replacing is fine? |
| 782 | for (const auto & [k, v] : inputs.extra_context.items()) { |
| 783 | inp[k] = v; |
| 784 | } |
| 785 | } |
| 786 | if (additional_context.has_value()) { |
| 787 | // TODO: merge properly instead of overwriting (matching old behavior) |
| 788 | for (const auto & [k, v] : additional_context->items()) { |
| 789 | inp[k] = v; |
| 790 | } |
| 791 | } |
| 792 | if (inputs.add_generation_prompt) { |
| 793 | inp["add_generation_prompt"] = true; |
| 794 | } |
| 795 | |
| 796 | jinja::global_from_json(ctx, inp, inputs.mark_input); |
| 797 | |
| 798 | // render |
| 799 | jinja::runtime runtime(ctx); |
| 800 | const jinja::value results = runtime.execute(tmpl.prog); |
| 801 | auto parts = runtime.gather_string_parts(results); |
| 802 | |
| 803 | std::string result = parts->as_string().str(); |
| 804 | |
| 805 | // TODO: improve this later |
| 806 | if (inputs.add_bos && string_starts_with(result, tmpl.bos_token())) { |
| 807 | result = result.substr(tmpl.bos_token().size()); |
| 808 | } |
| 809 | if (inputs.add_eos && string_ends_with(result, tmpl.eos_token())) { |
| 810 | result = result.substr(0, result.size() - tmpl.eos_token().size()); |
| 811 | } |
| 812 | return result; |
| 813 | } |
| 814 | |
| 815 | static common_chat_params common_chat_params_init_generic(const common_chat_template & tmpl, const struct templates_params & inputs) { |
| 816 | common_chat_params data; |
no test coverage detected