优化: df-ai/df-storage/df-nodes 底层加固: 上下文/模型/节点/仓储
df-ai: - context/mod.rs + manager_tests.rs: 上下文管理调整 + 测试同步(48 行) - openai_compat.rs: OpenAI 兼容层增强(+51) - presets/models.json: 模型预设 +18 df-storage: - crud/conversation_repo.rs: 会话仓储(loop_state 相关) - crud/task_repo.rs: 任务仓储 - crud/mod.rs: 导出调整 df-nodes: - task_advance_node.rs: 任务推进节点 验收: cargo check -p devflow EXIT 0。
This commit is contained in:
@@ -1045,9 +1045,12 @@ fn phase1_append_after_dirty_stays_dirty_until_save() {
|
||||
// ============================================================
|
||||
|
||||
#[test]
|
||||
fn eviction_inserts_summary_message_at_view_head() {
|
||||
// 触发淘汰 → 视图头部应有一条 "[早期对话概要]" user 摘要(补偿无声丢弃的早期主题),
|
||||
fn eviction_inserts_summary_message_at_view_tail() {
|
||||
// 触发淘汰 → 视图尾部应有一条 "[早期对话概要]" user 摘要(补偿无声丢弃的早期主题),
|
||||
// 概要 ≤ EVICTION_SUMMARY_MAX_CHARS,保护消息完好,且纯视图(不污染内存全量/不落库)。
|
||||
// 缓存友好(2026-10):摘要改尾部追加(push)而非头部插入(insert(0))——头部插入位移
|
||||
// 整条前缀字节,使 DeepSeek 等自动前缀缓存 provider 全部缓存失效(命中率掉到个位数)。
|
||||
// 尾部追加让稳定前缀(system + 早期 history)逐轮不变,命中率最大化。
|
||||
let mut mgr = ContextManager::new(cfg(200));
|
||||
for i in 0..20 {
|
||||
if i % 2 == 0 {
|
||||
@@ -1063,46 +1066,47 @@ fn eviction_inserts_summary_message_at_view_head() {
|
||||
let (msgs, trimmed) = mgr.build_for_request(0);
|
||||
assert!(trimmed, "超预算应触发裁剪");
|
||||
|
||||
// 视图头部 = 补偿摘要(role=user,"[早期对话概要]" 前缀 + 高频主题)
|
||||
let head = msgs.first().expect("视图不应为空");
|
||||
// 视图尾部 = 补偿摘要(role=user,"[早期对话概要]" 前缀 + 高频主题)
|
||||
let tail = msgs.last().expect("视图不应为空");
|
||||
assert!(
|
||||
matches!(head.role, MessageRole::User),
|
||||
"视图头部应为 user 摘要, 实际 {:?}",
|
||||
head.role
|
||||
matches!(tail.role, MessageRole::User),
|
||||
"视图尾部应为 user 摘要, 实际 {:?}",
|
||||
tail.role
|
||||
);
|
||||
assert!(
|
||||
head.content.starts_with("[早期对话概要] 高频主题: "),
|
||||
tail.content.starts_with("[早期对话概要] 高频主题: "),
|
||||
"摘要格式不符, 实际 {}",
|
||||
head.content
|
||||
tail.content
|
||||
);
|
||||
assert!(
|
||||
head.content.contains("审批"),
|
||||
tail.content.contains("审批"),
|
||||
"摘要应含被淘汰区高频主题词'审批', 实际 {}",
|
||||
head.content
|
||||
tail.content
|
||||
);
|
||||
assert!(
|
||||
head.content.chars().count() <= EVICTION_SUMMARY_MAX_CHARS,
|
||||
tail.content.chars().count() <= EVICTION_SUMMARY_MAX_CHARS,
|
||||
"摘要应 ≤ {} 字符, 实际 {}",
|
||||
EVICTION_SUMMARY_MAX_CHARS,
|
||||
head.content.chars().count()
|
||||
tail.content.chars().count()
|
||||
);
|
||||
|
||||
// 保护消息完好:末条(i=19 assistant)保留;摘要 user 与首轮真实 user 相邻,由
|
||||
// sanitize 的 ensure_sequence_legal 合并(摘要在前,换行接原文),故 msgs[1] 为 i=1 的 assistant
|
||||
// 保护消息完好:末条(i=19 assistant)保留;摘要 user 追加在尾部,与末尾 assistant
|
||||
// 不同 role 不合并,故 msgs[倒数第2] 仍为 i=19 的 assistant
|
||||
assert_eq!(
|
||||
msgs.last().unwrap().content,
|
||||
msgs[msgs.len() - 2].content,
|
||||
"第19条回复内容同样较长用于撑爆上下文预算触发视图裁剪逻辑",
|
||||
"保护区最新消息被误裁"
|
||||
);
|
||||
assert!(
|
||||
matches!(msgs[1].role, MessageRole::Assistant),
|
||||
"摘要与首轮 user 合并后,第二条应为 assistant, 实际 {:?}",
|
||||
msgs[1].role
|
||||
matches!(msgs[msgs.len() - 2].role, MessageRole::Assistant),
|
||||
"摘要前一条应为 assistant(i=19), 实际 {:?}",
|
||||
msgs[msgs.len() - 2].role
|
||||
);
|
||||
// 首条仍是保留区真实首条 user(摘要不再抢占头部,不位移前缀)
|
||||
assert!(
|
||||
msgs[0].content.contains("审批流程与审批门禁需要适配"),
|
||||
"合并不应丢失被保留的首轮真实 user 文本, 实际 {}",
|
||||
msgs[0].content
|
||||
matches!(msgs[0].role, MessageRole::User),
|
||||
"视图头部应为真实首条 user(摘要已移尾部), 实际 {:?}",
|
||||
msgs[0].role
|
||||
);
|
||||
|
||||
// 纯视图:摘要不进内存全量,被淘汰原文存储态不变
|
||||
|
||||
Reference in New Issue
Block a user