优化: aichat效率剩余(压缩后台化防阻塞/审计批量事务/只读缓存轮内去重/流式增量渲染/AiCommandOutput合批/双渲染合并) + 跨端加固(df-project路径保留大小写/tunnel文档更正supervisor重连/relay固定时间比较与帧上限/启动校验) + 销账
This commit is contained in:
@@ -243,6 +243,56 @@ impl_repo!(
|
||||
// 通用 query 宏硬编码 ORDER BY created_at 会触发 "no such column" → 调用方 unwrap_or_default 吞错。
|
||||
// 故为此表提供专用查询,绕过通用 query。详见 ai.rs audit_finalize。
|
||||
impl AiToolExecutionRepo {
|
||||
/// 批量插入审计记录(单事务多行 INSERT,砍 N 次串行 INSERT 尾巴)。
|
||||
///
|
||||
/// 对比 [`insert`](`impl_repo!` 生成,每次 spawn_blocking + 单行 execute):
|
||||
/// 本方法单次 `spawn_blocking` + 单事务,`prepare` 一次 INSERT stmt 循环 bind N 行,
|
||||
/// 一次 `COMMIT`(原子性:全插或全不插,审计留痕可追溯)。空 `records` 直接返回(无操作)。
|
||||
///
|
||||
/// **用途**:audit/mod.rs `process_tool_calls` 低风险工具 join_all 并行执行后的回填循环
|
||||
/// (每工具一条审计),把 N 次串行 INSERT 合并为一次事务批量(治 aichat 效率 AC-EFF-T1-1)。
|
||||
///
|
||||
/// 安全:全部值走参数绑定(同 `insert` 宏体),无 SQL 拼接注入面;单连接 Mutex 持锁整段,
|
||||
/// 与单行 insert 的锁粒度相同(一次持锁换 N 次持锁)。
|
||||
pub async fn insert_batch(&self, records: Vec<AiToolExecutionRecord>) -> Result<()> {
|
||||
if records.is_empty() {
|
||||
return Ok(());
|
||||
}
|
||||
let conn = self.conn.clone();
|
||||
tokio::task::spawn_blocking(move || {
|
||||
let guard = conn.blocking_lock();
|
||||
guard.execute_batch("BEGIN").map_err(storage_err)?;
|
||||
let result = (|| -> std::result::Result<(), rusqlite::Error> {
|
||||
let mut stmt = guard.prepare(
|
||||
"INSERT INTO ai_tool_executions (id, conversation_id, message_id, tool_call_id, tool_name, arguments, result, status, risk_level, requested_at, executed_at, decided_by)
|
||||
VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11, ?12)",
|
||||
)?;
|
||||
for rec in &records {
|
||||
stmt.execute(params![
|
||||
rec.id, rec.conversation_id, rec.message_id, rec.tool_call_id, rec.tool_name,
|
||||
rec.arguments, rec.result, rec.status, rec.risk_level,
|
||||
rec.requested_at, rec.executed_at, rec.decided_by
|
||||
])?;
|
||||
}
|
||||
Ok(())
|
||||
})();
|
||||
match result {
|
||||
Ok(()) => {
|
||||
guard.execute_batch("COMMIT").map_err(storage_err)?;
|
||||
}
|
||||
Err(e) => {
|
||||
// 回滚失败静默(尽量保一致性;rollback 失败通常是连接已坏,交给上层)
|
||||
let _ = guard.execute_batch("ROLLBACK");
|
||||
return Err(storage_err(e));
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
})
|
||||
.await
|
||||
.map_err(storage_err)??;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// 按 tool_call_id 查最新一条审计记录(审批回填定位用)。
|
||||
pub async fn find_by_tool_call_id(
|
||||
&self,
|
||||
|
||||
Reference in New Issue
Block a user