| 14 | using json = nlohmann::ordered_json; |
| 15 | |
| 16 | class PromptCache { |
| 17 | private: |
| 18 | uint64_t checksum_; |
| 19 | std::vector<uint64_t> tool_checksums_; |
| 20 | |
| 21 | uint64_t _calculate_message_checksum(const json& messages, size_t end) { |
| 22 | uint64_t checksum = 0; |
| 23 | const size_t message_count = std::min(end, messages.size()); |
| 24 | for (size_t i = 0; i < message_count; ++i) { |
| 25 | const std::string message_string = messages[i].dump(); |
| 26 | checksum = _calculate_checksum(message_string.data(), message_string.size(), checksum); |
| 27 | } |
| 28 | return checksum; |
| 29 | } |
| 30 | |
| 31 | std::vector<uint64_t> _calculate_tool_checksums(const json& tools) { |
| 32 | std::vector<uint64_t> tool_checksums; |
| 33 | tool_checksums.reserve(tools.size()); |
| 34 | for (const auto& tool : tools) { |
| 35 | const std::string tool_string = tool.dump(); |
| 36 | tool_checksums.push_back(_calculate_checksum(tool_string.data(), tool_string.size())); |
| 37 | } |
| 38 | return tool_checksums; |
| 39 | } |
| 40 | |
| 41 | uint64_t _calculate_checksum(const void* p, size_t len, uint64_t sum = 0) { |
| 42 | const uint8_t* data = reinterpret_cast<const uint8_t*>(p); |
| 43 | uint64_t _sum = sum; |
| 44 | |
| 45 | const uint64_t* p64 = reinterpret_cast<const uint64_t*>(data); |
| 46 | size_t blocks = len / sizeof(uint64_t); |
| 47 | for (size_t i = 0; i < blocks; ++i) { |
| 48 | _sum += p64[i]; |
| 49 | } |
| 50 | |
| 51 | const uint8_t* p8 = data + blocks * sizeof(uint64_t); |
| 52 | size_t remain = len % sizeof(uint64_t); |
| 53 | for (size_t i = 0; i < remain; ++i) { |
| 54 | _sum += p8[i]; |
| 55 | } |
| 56 | |
| 57 | return _sum; |
| 58 | } |
| 59 | |
| 60 | public: |
| 61 | PromptCache() : checksum_(0), tool_checksums_() {} |
| 62 | |
| 63 | bool can_use_tool_cache(json& tools) { |
| 64 | std::vector<uint64_t> new_tool_checksums = _calculate_tool_checksums(tools); |
| 65 | |
| 66 | if (tool_checksums_.size() == new_tool_checksums.size()){ |
| 67 | for (size_t i = 0; i < tool_checksums_.size(); ++i) { |
| 68 | if (tool_checksums_[i] != new_tool_checksums[i]) { |
| 69 | tool_checksums_ = std::move(new_tool_checksums); |
| 70 | return false; |
| 71 | } |
| 72 | } |
| 73 | return true; |