修复: checkpoint 参数化 + 压缩 permit 死锁降级 + 密钥归一化 + SSE CRLF/多字节
This commit is contained in:
@@ -343,21 +343,17 @@ async fn save_conversation_inner(
|
||||
Err(e) => tracing::warn!("读取对话 {conv_id} 失败: {e}"),
|
||||
}
|
||||
|
||||
// T6: 自动 checkpoint(每 20 轮或总 token > 150k 时创建)
|
||||
// 自动 checkpoint(每 20 轮或总 token > 150k 时创建)
|
||||
{
|
||||
let total_tokens: i64 = persist_msgs.len() as i64;
|
||||
if total_tokens > 0 && total_tokens % 20 == 0 {
|
||||
let snapshot = serde_json::to_string(&persist_msgs).unwrap_or_default();
|
||||
if !snapshot.is_empty() && snapshot.len() < 1_000_000 {
|
||||
let ck_id = format!("ck_{}_{}", conv_id.replace('-', ""), total_tokens);
|
||||
let escaped_snapshot = snapshot.replace("'", "''");
|
||||
let ck_now = now_millis();
|
||||
let sql = format!("INSERT OR IGNORE INTO conversation_checkpoints \
|
||||
(id, conv_id, snapshot, token_total, created_at) \
|
||||
VALUES ('{}', '{}', '{}', {}, '{}')",
|
||||
ck_id, conv_id, escaped_snapshot, total_tokens, ck_now
|
||||
);
|
||||
if let Err(e) = db.conn().lock().await.execute_batch(&sql) {
|
||||
let ck_now = now_millis().to_string();
|
||||
// 参数化绑定(走 AiConversationRepo::insert_checkpoint),替代原 format! 拼 SQL,
|
||||
// 防 snapshot 含引号/特殊字符致注入或损坏。
|
||||
if let Err(e) = conv_repo.insert_checkpoint(&ck_id, conv_id, &snapshot, total_tokens, &ck_now).await {
|
||||
tracing::warn!("checkpoint 写入失败 {conv_id}: {e}");
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user