清理: 移除代码注释中的走查编号前缀(UX/B/SW/CR/ID/P0-P2-26xxxx,共102处)
This commit is contained in:
@@ -365,7 +365,7 @@ pub(super) async fn handle_approval_tool(
|
||||
conversation_id: Some(conv_id.to_string()),
|
||||
};
|
||||
emit_ai_chat_event(&app_handle, ev);
|
||||
// 审计:去重命中记一条(status 透传缓存来源 completed/rejected/failed,SW-260618-16;decided_by=auto_dedup),不进 pending
|
||||
// 审计:去重命中记一条(status 透传缓存来源 completed/rejected/failed,;decided_by=auto_dedup),不进 pending
|
||||
audit_tool_call(audit_repo, conv_id, &draft.id, &draft.name, &draft.args, &status, risk_level, Some(warned_content), Some("auto_dedup"), current_message_id).await;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1078,7 +1078,7 @@ pub async fn ai_approve(
|
||||
log_slow_lock(__lock_t534, "ai_approve:534");
|
||||
drop(session); // 释放锁后再执行
|
||||
|
||||
// B-260617-01 决策 a(方案 a2 后端分支):run_workflow 特殊处理。
|
||||
// 决策 a(方案 a2 后端分支):run_workflow 特殊处理。
|
||||
// run_workflow handler(tool_registry.rs:544)仅持 db:Arc<Database>,无 AppHandle/State
|
||||
// (registry/event_bus/workflows Repo),经 ai_tools.execute 调用必然 Err。原行为:审批通过 →
|
||||
// handler Err → tool_result=错误提示 → LLM 重试 → 又进审批 → 死循环(工具未标 no_retry)。
|
||||
@@ -1144,7 +1144,7 @@ pub async fn ai_approve(
|
||||
// 前端 store listen 刷新列表(仅命中映射的工具 emit,见 emit_data_changed)。
|
||||
if exec_result.is_ok() {
|
||||
emit_data_changed(&app, &approval.tool_name);
|
||||
// MED-1(CR-260620-01 审查): path 绑定工具(Medium)审批执行后 reload 白名单。
|
||||
// MED-1(审查): path 绑定工具(Medium)审批执行后 reload 白名单。
|
||||
// bind_dir_to_project / repo.update_field 直写 DB 绕过 project.rs IPC reload,
|
||||
// 此处单点补全 → AI 绑定目录即时进白名单,防后续文件工具误弹窗。
|
||||
if matches!(approval.tool_name.as_str(), "bind_directory" | "create_project" | "update_project") {
|
||||
@@ -1486,7 +1486,7 @@ pub async fn ai_authorize_dir(
|
||||
audit_finalize(&state, &tool_call_id, audit_status, Some(result_val.to_string())).await;
|
||||
if exec_result.is_ok() {
|
||||
emit_data_changed(&app, &approval.tool_name);
|
||||
// MED-1(CR-260620-01 审查): path 绑定工具(Medium)审批执行后 reload 白名单。
|
||||
// MED-1(审查): path 绑定工具(Medium)审批执行后 reload 白名单。
|
||||
// bind_dir_to_project / repo.update_field 直写 DB 绕过 project.rs IPC reload,
|
||||
// 此处单点补全 → AI 绑定目录即时进白名单,防后续文件工具误弹窗。
|
||||
if matches!(approval.tool_name.as_str(), "bind_directory" | "create_project" | "update_project") {
|
||||
@@ -2320,7 +2320,7 @@ pub async fn ai_chat_stop(
|
||||
log_slow_lock(__lock_t1611, "ai_chat_stop:1611");
|
||||
drop(session);
|
||||
|
||||
// B-260615-13 兜底任务(F2 加固,2026-08-05):loop 若 panic/异常退出漏发收尾,stop_flag 无人读,
|
||||
// 兜底任务(F2 加固,2026-08-05):loop 若 panic/异常退出漏发收尾,stop_flag 无人读,
|
||||
// 用户点 stop 无反应、generating 卡 true。
|
||||
// 原实现 sleep 3s 后仍 active 就强制复位 + emit AiCompleted——但用户点停时 loop 可能在长工具执行
|
||||
// (>3s),原兜底误触发 → conv 假完成但旧 loop 仍活 → 双完成 + 用户可再发消息(竞态 F2)。
|
||||
|
||||
@@ -180,7 +180,7 @@ pub async fn ai_conversation_create(
|
||||
// 后台跑着的 conv。决策 e:旧 conv 的 per_conv 完整保留(后台 loop 继续跑自己的 conv),
|
||||
// 仅切换 active_conversation_id 到新会话 + 为新会话建独立 per_conv。
|
||||
//
|
||||
// B-260618-06 保留:切换 active 前先持久化旧 active conv(防其内存 messages 因后续操作丢失)。
|
||||
// 保留:切换 active 前先持久化旧 active conv(防其内存 messages 因后续操作丢失)。
|
||||
// 注意:旧 conv 若有后台 loop 在跑,loop 自身的 save_conversation 也会持久化,此处 save 幂等。
|
||||
let old_conv = {
|
||||
let session = state.ai_session.lock().await;
|
||||
@@ -317,7 +317,7 @@ pub async fn ai_conversation_switch(
|
||||
None
|
||||
};
|
||||
let title = record.title.clone();
|
||||
// B-260617-17 续:历史会话 title 空(显"新对话")→ 切入后触发重新生成(用户诉求)。
|
||||
// 续:历史会话 title 空(显"新对话")→ 切入后触发重新生成(用户诉求)。
|
||||
// 含 "新对话" 占位(Some 但未生成):title.rs ensure :40 同步排除"新对话"占位不跳过,
|
||||
// 否则 title 落"新对话"(LLM 返空兜底/默认)后 is_some()=true 永远跳过 → 标题卡死。
|
||||
let need_title_regen = record.title.is_none() || record.title.as_deref() == Some("新对话");
|
||||
|
||||
@@ -497,7 +497,7 @@ pub struct ConvSummary {
|
||||
///
|
||||
/// 优先级:`pending_approvals` 非空(有挂起审批优先报 AwaitingApproval,
|
||||
/// 即使同时在流式)> `generating`(Streaming)> 都不满足(Idle)。
|
||||
// SW-260618-21 b:原预留读视图(0 消费者)。path_auth 审批链阶段1 接入后有消费者
|
||||
// b:原预留读视图(0 消费者)。path_auth 审批链阶段1 接入后有消费者
|
||||
// (try_continue_agent_loop / ai_chat_stop 经 session_state 替代手写 has_pending),不再 dead_code。
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub enum SessionState {
|
||||
@@ -1142,7 +1142,7 @@ pub enum ApprovalKind {
|
||||
Path(PathAuthRequest),
|
||||
/// 普通 RiskLevel 审批(Med/High 风险工具)。
|
||||
/// diff 仅 write_file 挂起审批前预读注入;其余工具 / recovered 审批为 None。
|
||||
#[allow(dead_code)] // IPC 活跃(useAiEvents:252+ToolCard·UX-260618-06)·cargo Rust never-read 误报
|
||||
#[allow(dead_code)] // IPC 活跃(useAiEvents:252+ToolCard·)·cargo Rust never-read 误报
|
||||
Risk { diff: Option<String> },
|
||||
}
|
||||
|
||||
@@ -1166,7 +1166,7 @@ pub(crate) struct ToolCallDraft {
|
||||
}
|
||||
|
||||
// ============================================================
|
||||
// B-260617-01 决策 a(方案 a2):run_workflow 工具经审批后的真实执行入口
|
||||
// 决策 a(方案 a2):run_workflow 工具经审批后的真实执行入口
|
||||
//
|
||||
// 背景:run_workflow handler(tool_registry.rs)仅持 db:Arc<Database>,无 AppHandle/State
|
||||
// (registry/event_bus/workflows Repo),经 ai_tools.execute 必然 Err。ai_approve 识别 run_workflow
|
||||
|
||||
@@ -167,7 +167,7 @@ fn flush_delta(app_handle: &AppHandle, conv_id: &str, pending_delta: &mut String
|
||||
/// 流式接收 LLM 响应。
|
||||
///
|
||||
/// 三类异常处理(返回 StreamResult 显式区分出口):
|
||||
/// - Init 失败(provider.stream() Err):UX-260618-15 **不 emit AiError**,返回
|
||||
/// - Init 失败(provider.stream() Err):**不 emit AiError**,返回
|
||||
/// InitFailed{retryable, error}。retryable 据状态码分类(retry::is_status_retryable 镜像):
|
||||
/// 5xx/429/timeout/connect=true,4xx(非429)/鉴权/参数错=false Fatal。调用方走流前重试(仅
|
||||
/// retryable=true,≤max_retries 次, 复用 retry::backoff_delay 退避 + 30s 总预算),重试耗尽或
|
||||
@@ -177,7 +177,7 @@ fn flush_delta(app_handle: &AppHandle, conv_id: &str, pending_delta: &mut String
|
||||
/// + 系统提示网络中断。空文本仍返回 InitFailed{retryable=true}(无文可保,交重试,emit 权归调用方)。
|
||||
/// - 用户停止(stop_flag):返回 Complete(incomplete 语义非异常中断)。
|
||||
///
|
||||
/// 心跳与停止响应(B-260615-02 / B-260615-04):单 `tokio::select!` 三分支
|
||||
/// 心跳与停止响应(/ ):单 `tokio::select!` 三分支
|
||||
/// - `stream.next()`:正常 chunk 处理
|
||||
/// - `heartbeat.tick()`(30s):静默期(如工具执行后等下一轮首 chunk)emit `AiHeartbeat`,
|
||||
/// 前端 watchdog 据此 reset,区分「LLM 在跑」与「真断」(避免空气泡误报中断)
|
||||
|
||||
@@ -88,7 +88,7 @@ pub(crate) async fn ensure_conversation_title(
|
||||
// 在传给 LLM 前合并连续同 role(拼接 content),不影响其他逻辑(本函数 summary 派生数据)。
|
||||
let summary_msgs = merge_consecutive_roles(summary_msgs);
|
||||
|
||||
// B-260617-17 修复:先用 extract 兜底 emit 让侧栏即时更新(不落库),
|
||||
// 修复:先用 extract 兜底 emit 让侧栏即时更新(不落库),
|
||||
// 下方 LLM 生成成功后覆盖。这样 LLM 失败时有重试机会,
|
||||
// 不会永久锁定一个机械截取的差标题。
|
||||
let _fallback_title = extract_title(&all_msgs).unwrap_or_else(|| "新对话".to_string());
|
||||
|
||||
@@ -73,7 +73,7 @@ pub async fn create_idea(
|
||||
state: State<'_, AppState>,
|
||||
input: CreateIdeaInput,
|
||||
) -> Result<IdeaRecord, String> {
|
||||
// priority 值域校验 ∈ 0..=3 (对标 tasks B-260615-15)。
|
||||
// priority 值域校验 ∈ 0..=3 (对标 tasks )。
|
||||
// priority_from_i32 对越界值兜底归并(>=3→Critical),但 IPC 入口应显式拒非法值,
|
||||
// 防 LLM/前端传 99 等被静默吞为 Critical。
|
||||
if !(0..=3).contains(&input.priority) {
|
||||
|
||||
@@ -338,7 +338,7 @@ pub async fn get_project(
|
||||
|
||||
/// 更新项目单个字段(字段名走 df-storage 白名单校验)
|
||||
///
|
||||
/// B-260801-010 行(id 不存在 / 已软删)→ 返 Err 而非假成功。原实现无视
|
||||
/// 行(id 不存在 / 已软删)→ 返 Err 而非假成功。原实现无视
|
||||
/// update_field 返回值恒返 Ok(true),前端误以为成功但库无变更(UI/DB 不一致)。
|
||||
///
|
||||
/// 返回值保持 bool(成功恒 true):前端 api 包装 `Promise<boolean>` 契约不变零破坏,
|
||||
|
||||
@@ -365,7 +365,7 @@ pub async fn create_task(
|
||||
|
||||
/// 更新任务单个字段(字段名走 df-storage 白名单校验;status 值走枚举校验)。
|
||||
///
|
||||
/// B-260801-010 行(id 不存在 / 已软删)→ 返 Err 而非 false,杜绝「假成功」
|
||||
/// 行(id 不存在 / 已软删)→ 返 Err 而非 false,杜绝「假成功」
|
||||
/// (前端 updateTask 仅 await 不读 bool,但 store.runWithCatch 把 Err 转 toast,用户能感知;
|
||||
/// 若返 false 则 store 静默忽略,本地状态前端手动改但库无变更,造成 UI 与 DB 不一致)。
|
||||
///
|
||||
@@ -406,7 +406,7 @@ pub async fn update_task(
|
||||
}
|
||||
}
|
||||
}
|
||||
// project_id 跨表存在性校验(B-260616-16 收尾)。
|
||||
// project_id 跨表存在性校验(收尾)。
|
||||
// crud.rs tasks 白名单保留 project_id(支持跨项目移动),跨表约束由本命令层兜底。
|
||||
// 拦截移动到不存在的项目(手输脏 id / 已物理删除的项目),避免 tasks.project_id 悬空。
|
||||
if field == "project_id" {
|
||||
|
||||
@@ -109,7 +109,7 @@ pub async fn run_workflow(
|
||||
run_workflow_inner(&app, &state, name, dag, config, task_id, target_status, "manual", None).await
|
||||
}
|
||||
|
||||
/// 工作流执行核心逻辑(B-260617-01 抽取,命令层瘦转发)。
|
||||
/// 工作流执行核心逻辑(抽取,命令层瘦转发)。
|
||||
///
|
||||
/// 原 `run_workflow` 命令体拆出,使 ai_approve 经 execute_run_workflow_for_tool 直接调用
|
||||
/// (持 &AppState 而非 tauri::State,绕开 tauri::State 在非命令上下文不可构造的限制)。
|
||||
@@ -249,7 +249,7 @@ pub async fn run_workflow_inner(
|
||||
// broadcast 不暴露被丢事件的具体类型,无法在此精确判断是否为关键终态事件。
|
||||
// 风险:若关键终态事件(WorkflowCompleted/WorkflowFailed)被丢,finished 判定不触发,
|
||||
// 循环不会 break,前端永久收不到工作流结束信号。
|
||||
// B-260615-35 兜底:收到 Lagged 时,累计次数或单次 n 达阈值则查 DB 终态,
|
||||
// 兜底:收到 Lagged 时,累计次数或单次 n 达阈值则查 DB 终态,
|
||||
// 若工作流已终态则补发对应 workflow-event 并 break 退出 forward。
|
||||
// 避免依赖实时性差的 DB 轮询兜底导致前端审批/完成弹窗卡死。
|
||||
Err(RecvError::Lagged(n)) => {
|
||||
|
||||
@@ -156,12 +156,12 @@ pub struct AppState {
|
||||
pub project_modules: ProjectModuleRepo,
|
||||
/// 工程依赖关系 Repo(V35 module_dependencies,依赖图边数据)。
|
||||
pub module_dependencies: ModuleDependencyRepo,
|
||||
/// 发布表 Repo(预留:ReleaseRepo 持久化已就位·IPC/逻辑未接入·SW-260618-21 b 保留)
|
||||
/// 发布表 Repo(预留:ReleaseRepo 持久化已就位·IPC/逻辑未接入·b 保留)
|
||||
#[allow(dead_code)]
|
||||
pub releases: ReleaseRepo,
|
||||
/// 工作流执行表 Repo
|
||||
pub workflows: WorkflowRepo,
|
||||
/// 节点执行表 Repo(预留:NodeExecutionRepo 持久化已就位·IPC/逻辑未接入·SW-260618-21 b 保留)
|
||||
/// 节点执行表 Repo(预留:NodeExecutionRepo 持久化已就位·IPC/逻辑未接入·b 保留)
|
||||
#[allow(dead_code)]
|
||||
pub node_executions: NodeExecutionRepo,
|
||||
/// 工作流事件总线(tokio broadcast)
|
||||
|
||||
Reference in New Issue
Block a user