修复: aichat P0 三项(AR-2 新建对话守卫 + AR-3 审批卡片可读化 + AR-4 create_project 双审)
- AR-2 ai_conversation_create 加 generating 守卫(clear 前,防审批态新建清空 session 致 generating 永不复位卡死) - AR-3 audit.rs build_approval_reason 按 9 工具特化拼对象名(id/field/path/title/name)+ ToolCard resultSummary 补 restore/purge case + ARG_LABEL_MAP id 加友好标签 + i18n 双语补 4 key - AR-4 create_project schema 加 path/stack + handler 有 path 时合并绑定(spawn_blocking 探测栈,复用 bind_directory 逻辑,消除双审双 API) - cargo check / vue-tsc 0 error - 审查 boundary 全误判(并行同工作区 git diff 污染),主代理独立核查三任务全正确
This commit is contained in:
@@ -31,7 +31,7 @@
|
||||
<div v-if="tc.status === 'pending_approval'" class="ai-tool-approval">
|
||||
<div v-if="toolArgsEntries(tc.args).length" class="ai-tool-approval-args">
|
||||
<div v-for="arg in toolArgsEntries(tc.args)" :key="arg.key" class="ai-tool-arg">
|
||||
<span class="ai-tool-arg-key">{{ arg.key }}</span>
|
||||
<span class="ai-tool-arg-key">{{ arg.label }}</span>
|
||||
<span class="ai-tool-arg-val">{{ formatArgValue(arg.val) }}</span>
|
||||
</div>
|
||||
</div>
|
||||
@@ -119,6 +119,8 @@ interface ToolResult {
|
||||
title?: string
|
||||
field?: string
|
||||
deleted?: boolean
|
||||
restored?: boolean
|
||||
purged?: boolean
|
||||
}
|
||||
|
||||
/** 内联 SVG 图标字符串(经 v-html 注入,常量安全;图标库改造见决策记录) */
|
||||
@@ -145,10 +147,29 @@ function formatJson(data: unknown): string {
|
||||
}
|
||||
}
|
||||
|
||||
/** 审批参数 key → 友好标签映射(静态,不查 store);未命中回退原 key */
|
||||
const ARG_LABEL_MAP: Record<string, string> = {
|
||||
id: 'ID',
|
||||
project_id: '项目 ID',
|
||||
name: '名称',
|
||||
title: '标题',
|
||||
description: '描述',
|
||||
field: '字段',
|
||||
value: '新值',
|
||||
path: '路径',
|
||||
priority: '优先级',
|
||||
tags: '标签',
|
||||
source: '来源',
|
||||
}
|
||||
|
||||
/** 审批参数转键值对数组(非对象/空时返回空数组,防 args 非 object 时 v-for 报错) */
|
||||
function toolArgsEntries(args: unknown): Array<{ key: string; val: unknown }> {
|
||||
function toolArgsEntries(args: unknown): Array<{ key: string; label: string; val: unknown }> {
|
||||
if (args && typeof args === 'object' && !Array.isArray(args)) {
|
||||
return Object.entries(args as Record<string, unknown>).map(([key, val]) => ({ key, val }))
|
||||
return Object.entries(args as Record<string, unknown>).map(([key, val]) => ({
|
||||
key,
|
||||
label: ARG_LABEL_MAP[key] || key,
|
||||
val,
|
||||
}))
|
||||
}
|
||||
return []
|
||||
}
|
||||
@@ -282,6 +303,8 @@ function toolResultSummary(tc: AiToolCallInfo): string {
|
||||
case 'create_task': return r.title ? t('aiTool.createdWithName', { name: r.title }) : t('aiTool.created')
|
||||
case 'update_project': return r.field ? t('aiTool.updatedField', { field: r.field }) : t('aiTool.updated')
|
||||
case 'delete_project': return r.deleted ? t('aiTool.deleted') : t('aiTool.deleteIneffective')
|
||||
case 'restore_project': return r.restored ? t('aiTool.restored') : t('aiTool.restoreIneffective')
|
||||
case 'purge_project': return r.purged ? t('aiTool.purged') : t('aiTool.purgeIneffective')
|
||||
case 'run_workflow': return t('aiTool.workflowHint')
|
||||
default: return ''
|
||||
}
|
||||
|
||||
@@ -26,6 +26,10 @@ export default {
|
||||
updated: 'Updated',
|
||||
deleted: 'Deleted',
|
||||
deleteIneffective: 'Delete ineffective',
|
||||
restored: 'Restored',
|
||||
restoreIneffective: 'Restore ineffective (not in trash)',
|
||||
purged: 'Purged',
|
||||
purgeIneffective: 'Purge ineffective',
|
||||
workflowHint: 'Run it on the workflow page',
|
||||
},
|
||||
}
|
||||
|
||||
@@ -28,6 +28,10 @@ export default {
|
||||
updated: '已更新',
|
||||
deleted: '已删除',
|
||||
deleteIneffective: '删除未生效',
|
||||
restored: '已恢复',
|
||||
restoreIneffective: '恢复未生效(项目不在回收站)',
|
||||
purged: '已彻底删除',
|
||||
purgeIneffective: '清除未生效',
|
||||
workflowHint: '请到工作流页面运行',
|
||||
},
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user