feat: persist deep compression history and include it in guide messages

This commit is contained in:
JOJO 2026-04-07 11:50:54 +08:00
parent edc7f9b7ea
commit a21df8f7fb
2 changed files with 75 additions and 3 deletions

View File

@ -19,7 +19,7 @@ SUMMARY_PROMPT = (
"请使用中文,结构清晰,尽量具体,不要省略关键上下文。"
)
GUIDE_USER_MESSAGE_TEMPLATE = "当前对话已经被自动压缩请阅读{path}并继续工作"
GUIDE_USER_MESSAGE_TEMPLATE = "当前对话已经被自动压缩(第{count}次)。请阅读{path}并继续工作"
def _emit(sender, event_type: str, payload: Dict[str, Any]):
@ -31,6 +31,54 @@ def _emit(sender, event_type: str, payload: Dict[str, Any]):
pass
def _normalize_deep_compression_records(metadata: Dict[str, Any]) -> List[Dict[str, Any]]:
records = metadata.get("deep_compression_records")
if not isinstance(records, list):
return []
normalized: List[Dict[str, Any]] = []
for item in records:
if not isinstance(item, dict):
continue
try:
count = int(item.get("count", 0) or 0)
except Exception:
count = 0
path = str(item.get("compact_file") or "").strip()
if count <= 0 or not path:
continue
normalized.append({
"count": count,
"compact_file": path,
"created_at": item.get("created_at"),
"source_conversation_id": item.get("source_conversation_id"),
"compressed_conversation_id": item.get("compressed_conversation_id"),
})
normalized.sort(key=lambda x: (int(x.get("count") or 0), str(x.get("created_at") or "")))
deduped: List[Dict[str, Any]] = []
seen = set()
for rec in normalized:
key = (int(rec.get("count") or 0), str(rec.get("compact_file") or ""))
if key in seen:
continue
seen.add(key)
deduped.append(rec)
return deduped
def _build_guide_message(*, compression_index: int, compact_file: str, previous_records: List[Dict[str, Any]]) -> str:
base = GUIDE_USER_MESSAGE_TEMPLATE.format(count=compression_index, path=compact_file)
if not previous_records:
return base
lines = [base, "", "此前压缩摘要文件位置:"]
for rec in previous_records:
count = int(rec.get("count") or 0)
path = str(rec.get("compact_file") or "").strip()
if count <= 0 or not path:
continue
lines.append(f"- 第{count}次:{path}")
return "\n".join(lines).strip()
def _extract_text_only(content: Any) -> str:
if content is None:
return ""
@ -202,7 +250,9 @@ async def run_deep_compression(
old_title = conv_data.get("title") or "未命名"
compression_count = int(metadata.get("compression_count", 0) or 0)
target_count = compression_count + 1
previous_records = _normalize_deep_compression_records(metadata)
previous_max_count = max([int(item.get("count") or 0) for item in previous_records], default=0)
target_count = max(compression_count, previous_max_count) + 1
job_id = f"cmp_{datetime.now().strftime('%Y%m%d_%H%M%S_%f')}"
cm.set_compression_state(
in_progress=True,
@ -271,9 +321,29 @@ async def run_deep_compression(
"skip_auto_title_generation": True,
}
)
current_record = {
"count": target_count,
"compact_file": relative_compact_path,
"created_at": datetime.now().isoformat(),
"source_conversation_id": conversation_id,
"compressed_conversation_id": new_conv_id,
}
all_records = previous_records + [current_record]
cm.conversation_manager.update_conversation_metadata(
new_conv_id,
{
"compression_count": target_count,
"deep_compression_records": all_records,
"last_deep_compression_record": current_record,
},
)
cm.conversation_manager.update_conversation_title(new_conv_id, f"{old_title}对话 压缩后")
web_terminal.load_conversation(new_conv_id)
guide_message = GUIDE_USER_MESSAGE_TEMPLATE.format(path=relative_compact_path)
guide_message = _build_guide_message(
compression_index=target_count,
compact_file=relative_compact_path,
previous_records=previous_records,
)
# 清理旧对话压缩状态
cm.conversation_manager.update_conversation_metadata(

View File

@ -395,6 +395,8 @@ class ConversationManager:
"compression_job_id": None,
"compression_error": None,
"compression_resume_payload": None,
"deep_compression_records": [],
"last_deep_compression_record": None,
"skip_auto_title_generation": False,
}
if isinstance(metadata_overrides, dict):