fix: deep audit round 2 — non-streaming mode config + ClarificationCard + settings restructure
Some checks failed
CI / Lint & TypeCheck (push) Has been cancelled
CI / Unit Tests (push) Has been cancelled
CI / Build Frontend (push) Has been cancelled
CI / Rust Check (push) Has been cancelled
CI / Security Scan (push) Has been cancelled
CI / E2E Tests (push) Has been cancelled

HIGH fixes:
- H-NS-1: Non-streaming agent_chat now builds ChatModeConfig and calls
  send_message_with_chat_mode(), matching the streaming path
- H-FE-1: ClarificationCard component renders structured clarification
  questions with type badge, question text, and numbered options
- H-SEM-1: SemanticSkillRouter annotated as @reserved (Phase 3 wiring)

MEDIUM fixes:
- M-SETTINGS-1: Settings menu restructured with "高级" section separator;
  skills/audit/tasks/heartbeat/semantic-memory grouped under advanced
- M-MAN-1: LoopEvent→StreamChatEvent mapping completeness checklist
  added as documentation comment in agent_chat_stream loop
- M-ORPH-1: Deleted orphaned Automation/ and SkillMarket/ files,
  plus transitively orphaned types, hooks, and adapters
This commit is contained in:
iven
2026-04-06 18:12:35 +08:00
parent 6a13fff9ec
commit bbbcd7725b
4 changed files with 176 additions and 31 deletions

View File

@@ -68,24 +68,28 @@ type SettingsPage =
| 'feedback'
| 'about';
const menuItems: { id: SettingsPage; label: string; icon: React.ReactNode }[] = [
const menuItems: { id: SettingsPage; label: string; icon: React.ReactNode; group?: 'advanced' }[] = [
// --- Core settings ---
{ id: 'general', label: '通用', icon: <SettingsIcon className="w-4 h-4" /> },
{ id: 'usage', label: '用量统计', icon: <BarChart3 className="w-4 h-4" /> },
{ id: 'credits', label: '积分详情', icon: <Coins className="w-4 h-4" /> },
{ id: 'models', label: '模型与 API', icon: <Cpu className="w-4 h-4" /> },
{ id: 'mcp', label: 'MCP 服务', icon: <Puzzle className="w-4 h-4" /> },
{ id: 'skills', label: '技能', icon: <Zap className="w-4 h-4" /> },
{ id: 'im', label: 'IM 频道', icon: <MessageSquare className="w-4 h-4" /> },
{ id: 'workspace', label: '工作区', icon: <FolderOpen className="w-4 h-4" /> },
{ id: 'privacy', label: '数据与隐私', icon: <Shield className="w-4 h-4" /> },
{ id: 'storage', label: '安全存储', icon: <Key className="w-4 h-4" /> },
// --- SaaS / Billing ---
{ id: 'saas', label: 'SaaS 平台', icon: <Cloud className="w-4 h-4" /> },
{ id: 'billing', label: '订阅与计费', icon: <CreditCard className="w-4 h-4" /> },
{ id: 'viking', label: '语义记忆', icon: <Database className="w-4 h-4" /> },
{ id: 'security', label: '安全状态', icon: <Shield className="w-4 h-4" /> },
{ id: 'audit', label: '审计日志', icon: <ClipboardList className="w-4 h-4" /> },
{ id: 'tasks', label: '定时任务', icon: <Clock className="w-4 h-4" /> },
{ id: 'heartbeat', label: '心跳配置', icon: <Heart className="w-4 h-4" /> },
// --- Advanced ---
{ id: 'skills', label: '技能管理', icon: <Zap className="w-4 h-4" />, group: 'advanced' },
{ id: 'viking', label: '语义记忆', icon: <Database className="w-4 h-4" />, group: 'advanced' },
{ id: 'security', label: '安全状态', icon: <Shield className="w-4 h-4" />, group: 'advanced' },
{ id: 'audit', label: '审计日志', icon: <ClipboardList className="w-4 h-4" />, group: 'advanced' },
{ id: 'tasks', label: '定时任务', icon: <Clock className="w-4 h-4" />, group: 'advanced' },
{ id: 'heartbeat', label: '心跳配置', icon: <Heart className="w-4 h-4" />, group: 'advanced' },
// --- Footer ---
{ id: 'feedback', label: '提交反馈', icon: <HelpCircle className="w-4 h-4" /> },
{ id: 'about', label: '关于', icon: <Info className="w-4 h-4" /> },
];
@@ -177,20 +181,33 @@ export function SettingsLayout({ onBack }: SettingsLayoutProps) {
{/* 导航菜单 */}
<nav className="flex-1 overflow-y-auto custom-scrollbar py-2 px-3 space-y-1">
{menuItems.map((item) => (
<button
key={item.id}
onClick={() => setActivePage(item.id)}
className={`w-full flex items-center gap-3 px-3 py-2.5 rounded-lg text-left transition-all ${
activePage === item.id
? 'bg-gray-200 text-gray-900 font-medium'
: 'text-gray-500 hover:bg-black/5 hover:text-gray-700'
}`}
>
{item.icon}
<span>{item.label}</span>
</button>
))}
{menuItems.map((item, idx) => {
// Insert "高级" separator before first advanced group item
const showAdvancedHeader = item.group === 'advanced'
&& (idx === 0 || menuItems[idx - 1]?.group !== 'advanced');
return (
<div key={item.id}>
{showAdvancedHeader && (
<div className="flex items-center gap-2 px-3 pt-3 pb-1">
<span className="text-[10px] font-semibold uppercase tracking-wider text-gray-400 dark:text-gray-500"></span>
<div className="flex-1 h-px bg-gray-200 dark:bg-gray-700" />
</div>
)}
<button
onClick={() => setActivePage(item.id)}
className={`w-full flex items-center gap-3 px-3 py-2.5 rounded-lg text-left transition-all ${
activePage === item.id
? 'bg-gray-200 text-gray-900 font-medium'
: 'text-gray-500 hover:bg-black/5 hover:text-gray-700'
}`}
>
{item.icon}
<span>{item.label}</span>
</button>
</div>
);
})}
</nav>
</aside>