新增: AI 工具意图识别层 + 文件访问权限模型 Phase B+C
会话意图识别层(intent.rs / df-ai crate):
- Intent 枚举 11 态 + recognize 规则识别(关键词+权重+优先级)+ tool_subset_for 工具子集映射
- 模态接口预留 None,独立模块待接入 loop,36 单测
文件访问权限模型 Phase B+C(F-260619-03):
- Phase B 会话临时白名单 + 循环挂起 + DirAuthDialog 弹窗(仅本次/未来都允许/拒绝)
- Phase C 系统目录黑名单(Win System32/Program Files;Unix /etc /usr...)分段匹配 + 写操作约束
- 已审 CR-260619-09 ✅ PASS
This commit is contained in:
@@ -43,7 +43,8 @@ const appSettings = useAppSettingsStore()
|
||||
// B-260616-17: 看门狗不重置的事件集合(审批等待/完成/错误由各自 case 内 clear)。
|
||||
// 模块级 Set 复用,避免 handleEvent 每事件(delta/token 高频)新建数组字面量做 includes。
|
||||
// F-260616-03: AiMaxRoundsReached 加入——达 max 暂停态等用户决定继续/停止,不计整流超时。
|
||||
const NO_RESET_WATCHDOG = new Set<AiChatEvent['type']>(['AiApprovalRequired', 'AiCompleted', 'AiError', 'AiMaxRoundsReached'])
|
||||
// F-260619-03 Phase B: AiDirAuthRequired 加入——路径授权挂起等用户决定,不计整流超时。
|
||||
const NO_RESET_WATCHDOG = new Set<AiChatEvent['type']>(['AiApprovalRequired', 'AiCompleted', 'AiError', 'AiMaxRoundsReached', 'AiDirAuthRequired'])
|
||||
|
||||
// B-260616-12: 工具执行超时提示(纯前端降级,后端无工具级取消 IPC)。
|
||||
// 每个 running 工具一个独立 setTimeout;到时若仍未收到 Completed/Approval,
|
||||
@@ -97,6 +98,20 @@ function clearAllToolSlowTimers(): void {
|
||||
// 故用 boolean ref 而非数组,语义更精确。
|
||||
export const pendingMaxRounds = ref(false)
|
||||
|
||||
// F-260619-03 Phase B: 路径授权弹窗挂起态(后端 AiDirAuthRequired 事件置,用户决策后清)。
|
||||
//
|
||||
// 同 pendingMaxRounds 模式:模块级 ref(不进 store.state),AiChat.vue 的 DirAuthDialog 组件
|
||||
// 直接 import 读。一次只追踪一个挂起询问(后端单 tool_call_id 挂起,用户决策后 try_continue),
|
||||
// 故用对象 ref 而非数组,语义更精确。null = 无挂起。
|
||||
export interface PendingDirAuth {
|
||||
id: string
|
||||
tool: string
|
||||
path: string
|
||||
dir: string
|
||||
conversationId?: string
|
||||
}
|
||||
export const pendingDirAuth = ref<PendingDirAuth | null>(null)
|
||||
|
||||
/** 通知会话列表发生变化(供 newConversation/deleteConversation/rename/archive 等触发刷新侧栏) */
|
||||
export function notifyConversationChanged() {
|
||||
emit('ai-conversation-changed', {})
|
||||
@@ -198,6 +213,31 @@ function handleStreamingEvent(event: AiChatEvent): boolean {
|
||||
pendingMaxRounds.value = true
|
||||
return true
|
||||
|
||||
case 'AiDirAuthRequired': {
|
||||
// F-260619-03 Phase B: 路径授权挂起(后端 generating 保持 true,等用户决策)。
|
||||
// 置 pendingDirAuth 驱动 DirAuthDialog 弹窗;看门狗已由 NO_RESET_WATCHDOG 跳过 reset。
|
||||
// 同时把工具卡置 pending_approval 态(与 AiApprovalRequired 一致,复用 ToolCard 渲染)。
|
||||
clearStreamWatchdog()
|
||||
const info: AiToolCallInfo = {
|
||||
id: event.id,
|
||||
name: event.tool,
|
||||
args: { path: event.path },
|
||||
status: 'pending_approval',
|
||||
}
|
||||
state.pendingApprovals.push(info)
|
||||
const tc = findToolCall(event.id)
|
||||
if (tc) tc.status = 'pending_approval'
|
||||
clearToolSlowTimer(event.id)
|
||||
pendingDirAuth.value = {
|
||||
id: event.id,
|
||||
tool: event.tool,
|
||||
path: event.path,
|
||||
dir: event.dir,
|
||||
conversationId: event.conversation_id,
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
default:
|
||||
return false
|
||||
}
|
||||
@@ -289,6 +329,11 @@ function handleToolEvent(event: AiChatEvent): boolean {
|
||||
// B-260616-12: 审批通过→工具重新进入执行态,重启慢执行计时器
|
||||
startToolSlowTimer(event.id, findToolCall(event.id)?.name || '')
|
||||
}
|
||||
// F-260619-03 Phase B: 路径授权挂起的工具收到 ApprovalResult(once/always 通过 / deny 拒绝)
|
||||
// → 清弹窗(后端 ai_authorize_dir 已 try_continue 续 loop)。
|
||||
if (pendingDirAuth.value && pendingDirAuth.value.id === event.id) {
|
||||
pendingDirAuth.value = null
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -309,6 +354,7 @@ function handleLifecycleEvent(event: AiChatEvent): boolean {
|
||||
state.generatingConvId = null
|
||||
state.agentRound = 0 // AE-2025-07: agentic 结束,复位轮次(隐藏进度条)
|
||||
pendingMaxRounds.value = false // F-260616-03: 收尾(停止/续跑后新一轮达 max 才会再 set),清操作卡
|
||||
pendingDirAuth.value = null // F-260619-03 Phase B: 收尾清路径授权弹窗(防残留)
|
||||
// UX-2025-04 / CR-30-2 / 决策 a1: 流中途失败保文——后端 emit AiCompleted(incomplete=true),
|
||||
// 前端追加系统提示气泡(镜像后端 session.messages 的 system 提示)。
|
||||
// 注:此系统提示仅前端展示,后端已独立 push 到 session.messages 落库。
|
||||
@@ -358,6 +404,7 @@ function handleLifecycleEvent(event: AiChatEvent): boolean {
|
||||
// 残留可点击审批按钮会让用户误以为还能批(实际后端已终止),残留审批卡误导操作。
|
||||
state.pendingApprovals = []
|
||||
pendingMaxRounds.value = false // F-260616-03: 异常中断,清操作卡
|
||||
pendingDirAuth.value = null // F-260619-03 Phase B: 异常中断清路径授权弹窗
|
||||
localStorage.removeItem('df-ai-gen')
|
||||
localStorage.removeItem('df-ai-text')
|
||||
// UX-03: 错误消息携带 error_type(供错误气泡差异化显隐「去设置」按钮)。
|
||||
|
||||
Reference in New Issue
Block a user