feat: persist deep compression history and include it in guide messages
This commit is contained in:
parent
edc7f9b7ea
commit
a21df8f7fb
@ -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]):
|
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
|
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:
|
def _extract_text_only(content: Any) -> str:
|
||||||
if content is None:
|
if content is None:
|
||||||
return ""
|
return ""
|
||||||
@ -202,7 +250,9 @@ async def run_deep_compression(
|
|||||||
|
|
||||||
old_title = conv_data.get("title") or "未命名"
|
old_title = conv_data.get("title") or "未命名"
|
||||||
compression_count = int(metadata.get("compression_count", 0) or 0)
|
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')}"
|
job_id = f"cmp_{datetime.now().strftime('%Y%m%d_%H%M%S_%f')}"
|
||||||
cm.set_compression_state(
|
cm.set_compression_state(
|
||||||
in_progress=True,
|
in_progress=True,
|
||||||
@ -271,9 +321,29 @@ async def run_deep_compression(
|
|||||||
"skip_auto_title_generation": True,
|
"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}对话 压缩后")
|
cm.conversation_manager.update_conversation_title(new_conv_id, f"{old_title}对话 压缩后")
|
||||||
web_terminal.load_conversation(new_conv_id)
|
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(
|
cm.conversation_manager.update_conversation_metadata(
|
||||||
|
|||||||
@ -395,6 +395,8 @@ class ConversationManager:
|
|||||||
"compression_job_id": None,
|
"compression_job_id": None,
|
||||||
"compression_error": None,
|
"compression_error": None,
|
||||||
"compression_resume_payload": None,
|
"compression_resume_payload": None,
|
||||||
|
"deep_compression_records": [],
|
||||||
|
"last_deep_compression_record": None,
|
||||||
"skip_auto_title_generation": False,
|
"skip_auto_title_generation": False,
|
||||||
}
|
}
|
||||||
if isinstance(metadata_overrides, dict):
|
if isinstance(metadata_overrides, dict):
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user