修复: namespace 占位符发 LLM 前未展开 + key 含斜杠丢原文
This commit is contained in:
@@ -157,11 +157,18 @@ impl NamespaceStore {
|
||||
}
|
||||
}
|
||||
|
||||
/// 简单的基于长度的哈希(唯一性由 content 长度 + 前 16 字符保证)
|
||||
/// 用于构建引用路径中的 key 段,不需要密码学强度
|
||||
/// 内容 → 引用 key 段(确定性,不含 `/` 等会破坏 `parse_namespace_key` 的字符)。
|
||||
///
|
||||
/// 历史 bug:旧实现用 `"{len}_{前16字符}"`,前 16 字符原样进 key;内容前缀含 `/`(目录列表、
|
||||
/// 带路径的 grep 结果、文件头是路径)时,`namespace://tool/{key}` 被 `parse_namespace_key`
|
||||
/// 的 `split('/').nth(1)` 从首个 `/` 截断 → read/read_only 拿回 None → 原文彻底丢失。
|
||||
/// 现改用 SipHash u64 → 16 位 hex:确定性 + 极低碰撞 + 不含特殊字符。
|
||||
fn simple_hash(content: &str) -> String {
|
||||
let prefix: String = content.chars().take(16).collect();
|
||||
format!("{}_{}", content.len(), prefix)
|
||||
use std::collections::hash_map::DefaultHasher;
|
||||
use std::hash::{Hash, Hasher};
|
||||
let mut hasher = DefaultHasher::new();
|
||||
content.hash(&mut hasher);
|
||||
format!("{:016x}", hasher.finish())
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
@@ -226,6 +233,18 @@ mod tests {
|
||||
assert_eq!(r1, r2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn store_content_with_slash_in_prefix_reads_back() {
|
||||
// 回归:旧 simple_hash 把内容前 16 字符原样进 key,前缀含 '/' 时(目录列表/带路径 grep
|
||||
// 结果/文件头是路径)namespace://tool/{key} 被 parse_namespace_key 的 split('/') 截断
|
||||
// → read None,原文丢失。hex hash 修复后 store→read 正确取回。
|
||||
let mut ns = NamespaceStore::new(100_000);
|
||||
let content = "foo/bar/baz/qux\nline2\nline3";
|
||||
let path = ns.store("list_directory", content);
|
||||
assert!(is_namespace_ref(&path));
|
||||
assert_eq!(ns.read(&path).map(str::to_owned), Some(content.to_string()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn eviction_oldest_removed_when_over_limit() {
|
||||
let mut ns = NamespaceStore::new(100); // 极小容量
|
||||
|
||||
Reference in New Issue
Block a user