新增: 批次工作落地(推进链/评估闭环/事件总线/并发/加固) + 技术债清理 + 文档整理
后端: - 工作流推进链(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:
@@ -44,7 +44,33 @@
|
||||
<div v-if="tc.diff" class="ai-tool-approval-diff">
|
||||
<pre class="ai-tool-diff-pre"><code><span v-for="(ln, idx) in diffLines" :key="idx" class="ai-tool-diff-line" :class="'ai-tool-diff-line--' + ln.kind">{{ ln.text }}{{ '\n' }}</span></code></pre>
|
||||
</div>
|
||||
<div class="ai-tool-actions">
|
||||
<!-- path_auth 审批链阶段3b:按 tc.kind 分两组按钮。
|
||||
- kind='path'(路径授权挂起):once/always/deny 三选项,调 authorizeDir。
|
||||
- 其余(risk/缺省,普通 RiskLevel 审批):approve/reject 两选项,调 approve。 -->
|
||||
<div v-if="tc.kind === 'path'" class="ai-tool-actions ai-tool-actions--path">
|
||||
<button class="ai-tool-btn ai-tool-btn--approve"
|
||||
:disabled="approving"
|
||||
@click="onAuthorize('once')">
|
||||
<span v-if="approving" class="ai-tool-btn-spinner" />
|
||||
<svg v-else width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><polyline points="20 6 9 17 4 12"/></svg>
|
||||
{{ $t('aiChat.dirAuthOnce') }}
|
||||
</button>
|
||||
<button class="ai-tool-btn ai-tool-btn--always"
|
||||
:disabled="approving"
|
||||
@click="onAuthorize('always')">
|
||||
<span v-if="approving" class="ai-tool-btn-spinner" />
|
||||
<svg v-else width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><polyline points="20 6 9 17 4 12"/></svg>
|
||||
{{ $t('aiChat.dirAuthAlways') }}
|
||||
</button>
|
||||
<button class="ai-tool-btn ai-tool-btn--reject"
|
||||
:disabled="approving"
|
||||
@click="onAuthorize('deny')">
|
||||
<span v-if="approving" class="ai-tool-btn-spinner" />
|
||||
<svg v-else width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg>
|
||||
{{ $t('aiChat.dirAuthDeny') }}
|
||||
</button>
|
||||
</div>
|
||||
<div v-else class="ai-tool-actions">
|
||||
<button class="ai-tool-btn ai-tool-btn--approve"
|
||||
:disabled="approving"
|
||||
@click="onApprove(true)">
|
||||
@@ -127,8 +153,12 @@ const emit = defineEmits<{
|
||||
toggle: [id: string]
|
||||
/** read_file "展开全部/收起" → 内容级展开 */
|
||||
'expand-content': [id: string]
|
||||
/** 审批按钮 → 父级转发 store.approveToolCall */
|
||||
approve: [{ id: string; approved: boolean }]
|
||||
/**
|
||||
* 审批按钮 → 父级转发 store.approveToolCall。
|
||||
* path_auth 审批链阶段3b:risk 类带 approved boolean;path 类带 decision('once'|'always'|'deny')。
|
||||
* 调用方(store.approveToolCall)按是否有 decision 分派 approve / authorizeDir。
|
||||
*/
|
||||
approve: [{ id: string; approved: boolean; decision?: 'once' | 'always' | 'deny' }]
|
||||
}>()
|
||||
|
||||
// AE-2025-05:本卡自治二次确认状态机(每张 ToolCard 各持一份 confirmState,与 AiChat 父级隔离)。
|
||||
@@ -189,6 +219,27 @@ async function onApprove(approved: boolean) {
|
||||
emit('approve', { id: props.tc.id, approved })
|
||||
}
|
||||
|
||||
/**
|
||||
* path_auth 审批链阶段3b:path 类(路径授权挂起)三选项处理。
|
||||
* once=仅本次会话授权 / always=写持久白名单 / deny=拒绝。
|
||||
* 与 onApprove 同款 loading + 超时兜底,但 emit 带 decision(approved=false 仅占位,
|
||||
* 实际语义由 decision 决定;调用方 store.approveToolCall 按 decision 走 authorizeDir)。
|
||||
* path 类不做 High 风险二次确认(路径授权是显式白名单写入,非破坏性操作,once/always/deny 三选项
|
||||
* 本身就是用户明示决策,二次确认反增摩擦)。
|
||||
*/
|
||||
async function onAuthorize(decision: 'once' | 'always' | 'deny') {
|
||||
if (approving.value) return // 防重入
|
||||
approving.value = true
|
||||
approvingTimer = setTimeout(() => {
|
||||
approving.value = false
|
||||
approvingTimer = null
|
||||
console.warn('[AI] 路径授权 loading 超时,后端可能未回执,已复位允许重试:', props.tc.id)
|
||||
showApproveTimeoutToast()
|
||||
}, APPROVE_LOADING_TIMEOUT_MS)
|
||||
// approved=false 仅占位:store.approveToolCall 据 decision 走 authorizeDir,approved 入参被忽略。
|
||||
emit('approve', { id: props.tc.id, approved: false, decision })
|
||||
}
|
||||
|
||||
// status 离开 pending_approval → 复位 approving(后端回执/转态时)。原 cmdOutputExpanded/
|
||||
// httpBodyExpanded 初始化逻辑已随结果区迁入 ToolResultBody,此处仅留 approving 复位。
|
||||
watch(() => props.tc.status, (s) => {
|
||||
@@ -350,6 +401,9 @@ const diffLines = computed(() => parseDiffLines(props.tc.diff))
|
||||
}
|
||||
.ai-tool-btn--approve { background: var(--df-success-bg); color: var(--df-success); }
|
||||
.ai-tool-btn--approve:hover { background: var(--df-success); color: #fff; border-color: var(--df-success); }
|
||||
/* path_auth 审批链阶段3b:always 按钮(warning 色调,与 DirAuthDialog.vue 同款语义) */
|
||||
.ai-tool-btn--always { background: var(--df-warning-bg); color: var(--df-warning); }
|
||||
.ai-tool-btn--always:hover { background: var(--df-warning); color: #000; border-color: var(--df-warning); }
|
||||
.ai-tool-btn--reject { background: var(--df-danger-bg); color: var(--df-danger); }
|
||||
.ai-tool-btn--reject:hover { background: var(--df-danger); color: #fff; border-color: var(--df-danger); }
|
||||
/* 审批 loading(B-260616-08):禁用两按钮防重复点击,spinner 转在原位 */
|
||||
|
||||
Reference in New Issue
Block a user