- 超阈值工具结果正文落盘+句柄可读回(治 read_file 29.6% 体量裸奔) - read_file 改小文件豁免(8KB), 超阈值压缩+落盘句柄, 无损可找回 - 空轮判据自愈: 连续空轮先 nudge 续轮, 达阈值停靠止损(开关可回退) - 零 token 收敛信号透传(非截断语义分离) - 上下文清单描述按字符截断, 防清单体量无限膨胀
84 lines
3.2 KiB
Rust
84 lines
3.2 KiB
Rust
//! P1 工具结果瘦身 — 端到端集成验证。
|
|
//!
|
|
//! 独立测试二进制(独立进程):`tool_offload::init_base` 的 OnceLock 全局态不外泄,
|
|
//! 不污染 lib 单测(反之亦然)。这是验证「超阈值 → 落盘句柄 → 可无损读回」全链的唯一安全方式。
|
|
|
|
use df_ai::context_helpers::{extract_key_info, READ_FILE_OFFLOAD_BYTES};
|
|
use df_ai::tool_offload;
|
|
|
|
fn tmp_base(tag: &str) -> std::path::PathBuf {
|
|
std::env::temp_dir().join(format!("df-ai-ctx-offload-{tag}-{}", std::process::id()))
|
|
}
|
|
|
|
/// 从句柄行里粗取落盘路径(格式:`[...已外置: <path> —— ...]`)。
|
|
fn path_of(handle_line: &str) -> String {
|
|
handle_line
|
|
.split("已外置: ")
|
|
.nth(1)
|
|
.and_then(|s| s.split(" ——").next())
|
|
.expect("句柄行应含路径")
|
|
.trim()
|
|
.to_string()
|
|
}
|
|
|
|
#[test]
|
|
fn large_read_file_summarized_with_lossless_handle() {
|
|
let base = tmp_base("large");
|
|
let _ = std::fs::remove_dir_all(&base);
|
|
tool_offload::init_base(base.clone());
|
|
|
|
// 造一个超阈值的 read_file 结果(代码风格多行文本)
|
|
let body: String = (1..=800)
|
|
.map(|i| format!("line {i}: fn sample_{i}() {{ let x = {i}; }}\n"))
|
|
.collect();
|
|
assert!(body.len() > READ_FILE_OFFLOAD_BYTES, "夹具须超阈值");
|
|
|
|
let out = extract_key_info(&body, "read_file");
|
|
assert!(out.len() < body.len(), "超阈值 read_file 应被压缩");
|
|
assert!(out.contains("已外置"), "应追加落盘句柄:\n{out}");
|
|
assert!(out.contains("read_file 读该路径"), "句柄应指引读回方式");
|
|
|
|
// 无损性:按句柄路径读回 = 原文逐字节一致
|
|
let line = out.lines().find(|l| l.contains("已外置")).expect("应有句柄行");
|
|
let back = tool_offload::read_offloaded(&path_of(line)).expect("句柄路径应可读回");
|
|
assert_eq!(back, body, "落盘原文须与输入逐字节一致(无损)");
|
|
|
|
// 摘要确实变小(瘦身生效)
|
|
let ratio = out.len() as f64 / body.len() as f64;
|
|
assert!(ratio < 0.2, "压缩比应显著(<0.2),实际 {ratio:.3}");
|
|
|
|
let _ = std::fs::remove_dir_all(&base);
|
|
}
|
|
|
|
#[test]
|
|
fn small_read_file_still_exempt() {
|
|
let base = tmp_base("small");
|
|
tool_offload::init_base(base);
|
|
let small = "line1: fn a() {}\nline2: fn b() {}\n";
|
|
assert_eq!(
|
|
extract_key_info(small, "read_file"),
|
|
small,
|
|
"阈值内 read_file 应原样返回(保 AI 定向读代码语义)"
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn non_read_file_large_result_also_gets_handle() {
|
|
let base = tmp_base("other");
|
|
let _ = std::fs::remove_dir_all(&base);
|
|
tool_offload::init_base(base.clone());
|
|
|
|
let body: String = (1..=1200).map(|i| format!("match {i}: src/foo.rs:{i}\n")).collect();
|
|
assert!(body.len() >= 8 * 1024, "夹具须 ≥8KB(句柄追加下限)");
|
|
let out = extract_key_info(&body, "grep");
|
|
assert!(out.len() < body.len(), "应被压缩");
|
|
assert!(out.contains("已外置"), "≥8KB 结果应带落盘句柄");
|
|
|
|
let line = out.lines().find(|l| l.contains("已外置")).expect("应有句柄行");
|
|
assert_eq!(
|
|
tool_offload::read_offloaded(&path_of(line)).expect("应可读回"),
|
|
body
|
|
);
|
|
let _ = std::fs::remove_dir_all(&base);
|
|
}
|