| 123 | } |
| 124 | |
| 125 | std::vector<common_chat_msg_diff> common_chat_msg_diff::compute_diffs(const common_chat_msg & msg_prv, const common_chat_msg & msg_new) { |
| 126 | std::vector<common_chat_msg_diff> diffs; |
| 127 | if (msg_new.tool_calls.size() > msg_prv.tool_calls.size()) { |
| 128 | diffs.reserve(msg_new.tool_calls.size() - msg_prv.tool_calls.size() + 3); |
| 129 | } else { |
| 130 | diffs.reserve(3); |
| 131 | } |
| 132 | |
| 133 | // TODO: these can become expensive for long messages - how to optimize? |
| 134 | if (msg_prv.reasoning_content != msg_new.reasoning_content) { |
| 135 | auto & diff = diffs.emplace_back(); |
| 136 | diff.reasoning_content_delta = string_diff(msg_prv.reasoning_content, msg_new.reasoning_content); |
| 137 | } |
| 138 | if (msg_prv.content != msg_new.content) { |
| 139 | auto & diff = diffs.emplace_back(); |
| 140 | diff.content_delta = string_diff(msg_prv.content, msg_new.content); |
| 141 | } |
| 142 | |
| 143 | if (msg_new.tool_calls.size() < msg_prv.tool_calls.size()) { |
| 144 | throw std::runtime_error("Invalid diff: now finding less tool calls!"); |
| 145 | } |
| 146 | |
| 147 | if (!msg_prv.tool_calls.empty()) { |
| 148 | const auto idx = msg_prv.tool_calls.size() - 1; |
| 149 | const auto & pref = msg_prv.tool_calls[idx]; |
| 150 | const auto & newf = msg_new.tool_calls[idx]; |
| 151 | if (pref.name != newf.name) { |
| 152 | throw std::runtime_error("Invalid diff: tool call mismatch!"); |
| 153 | } |
| 154 | const auto args_diff = string_diff(pref.arguments, newf.arguments); |
| 155 | if (!args_diff.empty() || pref.id != newf.id) { |
| 156 | auto & diff = diffs.emplace_back(); |
| 157 | diff.tool_call_index = idx; |
| 158 | if (pref.id != newf.id) { |
| 159 | diff.tool_call_delta.id = newf.id; |
| 160 | diff.tool_call_delta.name = newf.name; |
| 161 | } |
| 162 | diff.tool_call_delta.arguments = args_diff; |
| 163 | } |
| 164 | } |
| 165 | for (size_t idx = msg_prv.tool_calls.size(); idx < msg_new.tool_calls.size(); ++idx) { |
| 166 | auto & diff = diffs.emplace_back(); |
| 167 | diff.tool_call_index = idx; |
| 168 | diff.tool_call_delta = msg_new.tool_calls[idx]; |
| 169 | } |
| 170 | |
| 171 | return diffs; |
| 172 | } |
| 173 | |
| 174 | using chat_template_caps = jinja::caps; |
| 175 |
nothing calls this directly
no test coverage detected