新增: 批次工作落地(推进链/评估闭环/事件总线/并发/加固) + 技术债清理 + 文档整理
后端: - 工作流推进链(D-03):advance_task/状态机/闸门走 df-nodes Node trait,conditions 条件引擎扩展 - 想法评估闭环:启发式评分+对抗评估,df-ideas/scoring + df-storage/idea_eval_repo + idea 前端打通 - 全局事件数据总线:df-ai/context+context_helpers+augmentation 跨模块解耦 - AI planner/plan_hint/intent:aichat B 路线并行多轮基础 - patch_file 加固(TD-03/04):读改写整体锁防 lost update,expected_hash 合约闭环 - 压缩超时兜底(F-15 卡死根治) - F-09 多会话并发:LlmConcurrency per-conv + streamingGuard 前端守护 + verify 脚本 - 知识注入 DRY/skills/audit 扩展 清理: - aichat 技术债(误报 allow/死导入/过时注释 30 项) - URGENT.md 删除(11 项加急全解决/迁 todo) - 文档整理(todo/待决策/待审查/ARCHITECTURE/INDEX + 总线/技术债审查新文档)
This commit is contained in:
@@ -135,6 +135,7 @@ pub async fn knowledge_create(
|
||||
source_project: input.source_project,
|
||||
source_ref: input.source_ref,
|
||||
reasoning: None,
|
||||
embedding_status: None,
|
||||
created_at: now.clone(),
|
||||
updated_at: now,
|
||||
};
|
||||
@@ -281,6 +282,21 @@ pub async fn knowledge_archive(
|
||||
knowledge_update_status(state, id, "archived".to_string()).await
|
||||
}
|
||||
|
||||
/// 重新生成向量嵌入(补偿重试)— P1 修复(嵌入失败无标记)的补偿入口
|
||||
///
|
||||
/// 触发条件:embedding_status='failed' 的已发布知识(provider 临时不可用导致永久无向量索引)。
|
||||
/// 行为:fire-and-forget,后台逐条重跑嵌入生成(成功置 done,失败仍 failed 可再次触发)。
|
||||
/// 返回值:本次触发重试的条数(0 表示无 failed 条目或 vector_enabled 关闭)。
|
||||
#[tauri::command]
|
||||
pub async fn knowledge_retry_embedding(
|
||||
state: State<'_, AppState>,
|
||||
) -> Result<usize, String> {
|
||||
let count = crate::commands::ai::retry_failed_embeddings(&state)
|
||||
.await
|
||||
.map_err(err_str)?;
|
||||
Ok(count)
|
||||
}
|
||||
|
||||
// ============================================================
|
||||
// 配置 + 手动提炼
|
||||
// ============================================================
|
||||
@@ -300,8 +316,18 @@ pub async fn knowledge_save_config(
|
||||
state: State<'_, AppState>,
|
||||
config: KnowledgeConfig,
|
||||
) -> Result<bool, String> {
|
||||
let mut cfg = state.knowledge_config.lock().await;
|
||||
*cfg = config;
|
||||
// P0(设置走查-2026-06-21):落 Settings KV 持久化,reload_knowledge_config 启动恢复
|
||||
// (原纯内存 Arc<Mutex> 启动 default 覆盖致 8 项配置重启全丢)。
|
||||
let json = serde_json::to_string(&config).map_err(|e| e.to_string())?;
|
||||
{
|
||||
let mut cfg = state.knowledge_config.lock().await;
|
||||
*cfg = config;
|
||||
}
|
||||
state
|
||||
.settings
|
||||
.set(crate::state::KNOWLEDGE_CONFIG_KEY, &json)
|
||||
.await
|
||||
.map_err(|e| e.to_string())?;
|
||||
Ok(true)
|
||||
}
|
||||
|
||||
@@ -375,21 +401,41 @@ pub async fn knowledge_update(
|
||||
.await
|
||||
.map_err(err_str)?
|
||||
.ok_or_else(|| format!("知识不存在: {id}"))?;
|
||||
// P1 修复(KP-5 审计断档):记录本次实际改动的字段,供 updated 生命线事件审计展示。
|
||||
// 只在值确实变化时计入 changed_fields(避免无改动也产生 updated 噪音事件)。
|
||||
let mut changed_fields: Vec<&'static str> = Vec::new();
|
||||
if let Some(v) = input.title {
|
||||
if record.title != v {
|
||||
changed_fields.push("title");
|
||||
}
|
||||
record.title = v;
|
||||
}
|
||||
if let Some(v) = input.content {
|
||||
if record.content != v {
|
||||
changed_fields.push("content");
|
||||
}
|
||||
record.content = v;
|
||||
}
|
||||
if let Some(v) = input.tags {
|
||||
if record.tags.as_deref() != Some(v.as_str()) {
|
||||
changed_fields.push("tags");
|
||||
}
|
||||
record.tags = Some(v);
|
||||
}
|
||||
// 空串 = 清空(前端编辑器清空 confidence/reasoning 输入框时传 "")
|
||||
if let Some(v) = input.confidence {
|
||||
record.confidence = if v.is_empty() { None } else { Some(v) };
|
||||
let new_conf = if v.is_empty() { None } else { Some(v) };
|
||||
if record.confidence != new_conf {
|
||||
changed_fields.push("confidence");
|
||||
}
|
||||
record.confidence = new_conf;
|
||||
}
|
||||
if let Some(v) = input.reasoning {
|
||||
record.reasoning = if v.is_empty() { None } else { Some(v) };
|
||||
let new_reason = if v.is_empty() { None } else { Some(v) };
|
||||
if record.reasoning != new_reason {
|
||||
changed_fields.push("reasoning");
|
||||
}
|
||||
record.reasoning = new_reason;
|
||||
}
|
||||
record.updated_at = now_millis();
|
||||
state
|
||||
@@ -397,6 +443,14 @@ pub async fn knowledge_update(
|
||||
.update_full(&record)
|
||||
.await
|
||||
.map_err(err_str)?;
|
||||
// 生命线:编辑产生(fire-and-forget)。
|
||||
// 仅在确有字段改动时记录,无改动不产噪音事件(对齐 create/update_status 的语义粒度)。
|
||||
// source_ref="ui" 标识编辑来自前端 UI(未来可细分 detail/inbox,当前统一 ui)。
|
||||
if !changed_fields.is_empty() {
|
||||
KnowledgeTimeline::new(&state.db)
|
||||
.record_updated(&id, &changed_fields, "ui")
|
||||
.await;
|
||||
}
|
||||
Ok(record)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user