修复: 协议层与体验缺陷六件
- temperature 按模型适配,仅收 1 的模型不再 400 - 流式 error 帧不再被 choices 必填整帧丢弃 - 只读缓存写后失效 - git diff 中文截断撞 UTF-8 边界 panic - 非视觉模型纯图片直接拒绝 - 全局快捷键补输入焦点守卫
This commit is contained in:
@@ -841,12 +841,12 @@ fn phase1_push_only_keeps_clean_no_dirty_flag() {
|
||||
|
||||
#[test]
|
||||
fn phase1_advance_persisted_count_sets_baseline_and_clears_dirty() {
|
||||
// advance_persisted_count(new_count):推进基线 + 清 needs_full_rewrite(DB 已与内存一致)
|
||||
// advance_persisted_count(new_count, full):推进基线;全量重写才清 needs_full_rewrite
|
||||
let mut mgr = ContextManager::new(cfg(100_000));
|
||||
mgr.push(ChatMessage::user("x"));
|
||||
mgr.push(ChatMessage::user("y"));
|
||||
// 模拟 save 成功后推进
|
||||
mgr.advance_persisted_count(2);
|
||||
// 模拟 save(全量重写)成功后推进
|
||||
mgr.advance_persisted_count(2, true);
|
||||
assert_eq!(mgr.persisted_msg_count(), 2);
|
||||
assert!(!mgr.needs_full_rewrite());
|
||||
}
|
||||
@@ -855,11 +855,26 @@ fn phase1_advance_persisted_count_sets_baseline_and_clears_dirty() {
|
||||
fn phase1_advance_persisted_count_max_no_regression() {
|
||||
// 防回退:advance 传更小值不回退基线(防误传 / 并发致基线丢失 → 下次增量漏写)
|
||||
let mut mgr = ContextManager::new(cfg(100_000));
|
||||
mgr.advance_persisted_count(5);
|
||||
mgr.advance_persisted_count(3); // 误传更小
|
||||
mgr.advance_persisted_count(5, true);
|
||||
mgr.advance_persisted_count(3, true); // 误传更小
|
||||
assert_eq!(mgr.persisted_msg_count(), 5, "基线不可回退");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn phase1_advance_incremental_keeps_dirty() {
|
||||
// 增量/无变化路径(full=false)不得清 dirty:写库期间新置的 dirty(如压缩链 mark)
|
||||
// 与本次 append 写库无关,误清会致改动滞留内存永不落库
|
||||
let mut mgr = ContextManager::new(cfg(100_000));
|
||||
mgr.push(ChatMessage::user("a"));
|
||||
mgr.advance_persisted_count(1, false); // 增量 save 成功
|
||||
assert!(!mgr.needs_full_rewrite());
|
||||
mgr.mark_needs_full_rewrite(); // 模拟写库期间压缩 mark
|
||||
mgr.advance_persisted_count(1, false); // 又一次增量 save
|
||||
assert!(mgr.needs_full_rewrite(), "增量路径 advance 不得清 dirty");
|
||||
mgr.advance_persisted_count(1, true); // 直到全量重写才清
|
||||
assert!(!mgr.needs_full_rewrite());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn phase1_compress_old_messages_sets_dirty() {
|
||||
// compress 改既有消息 status(active→compressed) → 必须全量重写收敛
|
||||
@@ -881,7 +896,7 @@ fn phase1_compress_no_op_does_not_set_dirty() {
|
||||
mgr.push(ChatMessage::user("a"));
|
||||
let _ = mgr.compress_old_messages(1);
|
||||
assert!(mgr.needs_full_rewrite(), "首次压缩应置 dirty");
|
||||
mgr.advance_persisted_count(1); // 模拟 save 后清 dirty
|
||||
mgr.advance_persisted_count(1, true); // 模拟 save(全量)后清 dirty
|
||||
// 二次压缩同范围:全已 compressed,无新标 → 不应再置 dirty
|
||||
let compressed = mgr.compress_old_messages(1);
|
||||
assert!(compressed.is_empty());
|
||||
@@ -974,7 +989,7 @@ fn phase1_clear_resets_baseline_and_sets_dirty() {
|
||||
// clear:基线重置 0 + 置 dirty(下次 save 全量重写空列表清 DB)
|
||||
let mut mgr = ContextManager::new(cfg(100_000));
|
||||
mgr.push(ChatMessage::user("a"));
|
||||
mgr.advance_persisted_count(1);
|
||||
mgr.advance_persisted_count(1, true);
|
||||
assert_eq!(mgr.persisted_msg_count(), 1);
|
||||
mgr.clear();
|
||||
assert_eq!(mgr.persisted_msg_count(), 0, "clear 应重置基线到 0");
|
||||
@@ -1021,7 +1036,7 @@ fn phase1_append_after_dirty_stays_dirty_until_save() {
|
||||
mgr.push(ChatMessage::user("b")); // 追加
|
||||
assert!(mgr.needs_full_rewrite(), "dirty 后 push 不应清 dirty");
|
||||
// 模拟 save(全量重写)成功后推进 + 清
|
||||
mgr.advance_persisted_count(2);
|
||||
mgr.advance_persisted_count(2, true);
|
||||
assert!(!mgr.needs_full_rewrite());
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user