─── Disk-cache identity salt ─────────────────────────────────────────── Compute a 16-byte salt from inputs that affect KV cache validity: model path + stat(size + mtime) [covers rope/yarn — GGUF-derived], max_ctx, and sha1(chat_template_src). Returns all-zeroes if model_path is empty (back-compat / disk disabled).
| 823 | for (size_t i = 0; i < system_parts.size(); i++) { |
| 824 | if (i) merged_system += "\n\n"; |
| 825 | merged_system += system_parts[i]; |
| 826 | } |
| 827 | chat_msgs.insert(chat_msgs.begin(), {"system", merged_system}); |
| 828 | } |
| 829 | |
| 830 | return chat_msgs; |
| 831 | } |
| 832 | |
| 833 | // ─── Disk-cache identity salt ─────────────────────────────────────────── |
| 834 | // Compute a 16-byte salt from inputs that affect KV cache validity: |
| 835 | // model path + stat(size + mtime) [covers rope/yarn — GGUF-derived], |
| 836 | // max_ctx, and sha1(chat_template_src). |
| 837 | // Returns all-zeroes if model_path is empty (back-compat / disk disabled). |
| 838 | static std::array<uint8_t, 16> compute_disk_cache_salt(const ServerConfig & cfg) { |
| 839 | std::array<uint8_t, 16> salt{}; |
| 840 | if (cfg.model_path.empty()) return salt; |
| 841 | |
| 842 | const std::string & path = cfg.model_path; |
| 843 | struct stat st{}; |
| 844 | int64_t file_size = 0; |
| 845 | int64_t file_mtime = 0; |
| 846 | if (::stat(path.c_str(), &st) == 0) { |
| 847 | file_size = (int64_t)st.st_size; |
| 848 | file_mtime = (int64_t)st.st_mtime; |
| 849 | } else { |
| 850 | std::fprintf(stderr, "[disk-cache] salt: stat(%s) failed — path-only fingerprint\n", |
| 851 | path.c_str()); |
| 852 | } |
| 853 | |
| 854 | // Hash chat_template_src separately (can be large; fold as digest). |
| 855 | uint8_t tmpl_digest[20] = {}; |
| 856 | sha1_hash(cfg.chat_template_src.data(), cfg.chat_template_src.size(), tmpl_digest); |
| 857 | |
| 858 | // Serialization: path_len(4) + path + file_size(8) + file_mtime(8) + max_ctx(4) + tmpl_digest(20). |
| 859 | std::vector<uint8_t> buf; |
| 860 | uint32_t plen = (uint32_t)path.size(); |
| 861 | buf.insert(buf.end(), (uint8_t *)&plen, (uint8_t *)&plen + 4); |
| 862 | buf.insert(buf.end(), (uint8_t *)path.data(), (uint8_t *)path.data() + path.size()); |
| 863 | buf.insert(buf.end(), (uint8_t *)&file_size, (uint8_t *)&file_size + 8); |