新增: aichat前端体验四件与队列残留收口
- R4 代码块语言角标:MessageList decorateCodeHtml 捕获 language-xxx 输出 data-lang+CSS ::before 左上角标,hover 显,无语言裸块不渲染 - R6 工具结果路径可复制:ToolResultBody 五处 file-bar 的 path span→button(read_file/list_directory/search_files/grep/patch_file),点击复制完整路径+✓/✕ 1.2s 反馈+execCommand 降级链 - I6 重新生成 UI 入口:MessageItem user 气泡 hover 补重新生成按钮(canRegenerate=isLastUser&&非流式),复用 handleRetry→store.regenerate 链路 - V4 浮窗审批 High 风险二次确认:useToolApproval 导出 isHighRiskTool/highRiskConfirmText,ApprovalPopup.onApprove 前置 ConfirmDialog,数字键守卫不绕确认 - 9-28#5 两处全局清队列残留:useAiEvents/useAiLifecycleEvents 无 convId 的 AiError 分支改保留队列+console.warn(防误伤其他会话排队消息) - i18n zh/en 补 clickToCopy 键;裸 @ 改 @ 转义(vue-i18n linked-message 前缀吞噬)
This commit is contained in:
@@ -151,7 +151,7 @@ import { useI18n } from 'vue-i18n'
|
||||
import { listen, type UnlistenFn } from '@tauri-apps/api/event'
|
||||
import { getCurrentWebviewWindow } from '@tauri-apps/api/webviewWindow'
|
||||
import { toolDisplayName } from '@/composables/ai/useToolCardHeader'
|
||||
import { dispatchApprovalIPC } from '@/composables/ai/useToolApproval'
|
||||
import { dispatchApprovalIPC, isHighRiskTool, highRiskConfirmText } from '@/composables/ai/useToolApproval'
|
||||
import { ApprovalPopupEvents } from '@/composables/ai/useApprovalPopup'
|
||||
import { formatWaitTime, waitLevelOf } from '@/utils/time'
|
||||
import ConfirmDialog from '@/components/ConfirmDialog.vue'
|
||||
@@ -170,20 +170,24 @@ const { toast, showToast } = useToast()
|
||||
/** 拖动态(样式反馈) */
|
||||
const isDragging = ref(false)
|
||||
|
||||
// ── M5:path 类 deny 二次确认(独立窗口本地 confirm;拒绝不可逆——工具返 Err、loop 续跑不再重试)──
|
||||
// 浮窗是独立 WebviewWindow,与主窗口 JS 上下文隔离,不复用 useConfirm 跨窗口 reactive。
|
||||
// pendingDenyTc 持有「待确认拒绝」的 tc;answerConfirm 据 result 决定续跑 runApproval 或放弃。
|
||||
const confirmState = reactive<{ visible: boolean; msg: string; tc: AiToolCallInfo | null }>({
|
||||
// ── M5/V4:浮窗本地二次确认(独立窗口本地 confirm;与主窗口 JS 上下文隔离,不复用 useConfirm)──
|
||||
// M5:path 类 deny(拒绝不可逆——工具返 Err、loop 续跑不再重试)。
|
||||
// V4:High 风险工具 risk 批准前置确认(对齐 ToolCard 安全语义:注意力分散场景数字键「1」
|
||||
// 单键放行 run_command/delete_file 太危险)。action 记录「待确认动作」供 answerConfirm 分派。
|
||||
const confirmState = reactive<{ visible: boolean; msg: string; tc: AiToolCallInfo | null; action: 'deny' | 'approve' }>({
|
||||
visible: false,
|
||||
msg: '',
|
||||
tc: null,
|
||||
action: 'deny',
|
||||
})
|
||||
function answerConfirm(ok: boolean) {
|
||||
const tc = confirmState.tc
|
||||
const action = confirmState.action
|
||||
confirmState.visible = false
|
||||
confirmState.tc = null
|
||||
if (ok && tc) {
|
||||
void runApproval(tc, false, 'deny')
|
||||
if (action === 'approve') void runApproval(tc, true)
|
||||
else void runApproval(tc, false, 'deny')
|
||||
}
|
||||
}
|
||||
|
||||
@@ -406,8 +410,16 @@ async function onApproveSession(tc: AiToolCallInfo) {
|
||||
async function onApproveAlways(tc: AiToolCallInfo) {
|
||||
await runApproval(tc, false, 'always')
|
||||
}
|
||||
/** risk 类:批准(approved=true) */
|
||||
/** risk 类:批准(approved=true)。V4:High 风险工具先二次确认(按钮与数字键 1 同走本入口,
|
||||
* 确认框打开时数字键守卫生效,不绕确认;拒绝仍按 M5 原逻辑)。 */
|
||||
async function onApprove(tc: AiToolCallInfo) {
|
||||
if (isHighRiskTool(tc.name)) {
|
||||
confirmState.msg = highRiskConfirmText(tc.name)
|
||||
confirmState.tc = tc
|
||||
confirmState.action = 'approve'
|
||||
confirmState.visible = true
|
||||
return
|
||||
}
|
||||
await runApproval(tc, true)
|
||||
}
|
||||
/** path 类 deny / risk 类 reject(统一入口,kind 由 dispatchApprovalIPC 据 tc.kind 分派)。
|
||||
|
||||
Reference in New Issue
Block a user