/** * AutonomyConfig - Configuration UI for L4 self-evolution authorization * * Allows users to configure: * - Autonomy level (supervised/assisted/autonomous) * - Individual action permissions * - Approval thresholds * - Audit log viewing * * Part of ZCLAW L4 Self-Evolution capability. */ import { useState, useCallback, useEffect } from 'react'; import { motion, AnimatePresence } from 'framer-motion'; import { Shield, ShieldAlert, ShieldCheck, ShieldQuestion, Settings, AlertTriangle, CheckCircle, Clock, RotateCcw, Info, ChevronDown, ChevronRight, Trash2, } from 'lucide-react'; import { getAutonomyManager, DEFAULT_AUTONOMY_CONFIGS, type AutonomyConfig, type AutonomyLevel, type AuditLogEntry, type ActionType, } from '../lib/autonomy-manager'; // === Types === interface AutonomyConfigProps { className?: string; onConfigChange?: (config: AutonomyConfig) => void; } // === Autonomy Level Config === const LEVEL_CONFIG: Record = { supervised: { label: '监督模式', description: '所有操作都需要用户确认', icon: ShieldQuestion, color: 'text-yellow-500', }, assisted: { label: '辅助模式', description: '低风险操作自动执行,高风险需确认', icon: ShieldAlert, color: 'text-blue-500', }, autonomous: { label: '自主模式', description: 'Agent 自主决策,仅高影响操作通知', icon: ShieldCheck, color: 'text-green-500', }, }; const ACTION_LABELS: Record = { memory_save: '自动保存记忆', memory_delete: '删除记忆', identity_update: '更新身份文件', identity_rollback: '回滚身份', skill_install: '安装技能', skill_uninstall: '卸载技能', config_change: '修改配置', workflow_trigger: '触发工作流', hand_trigger: '触发 Hand', llm_call: '调用 LLM', reflection_run: '运行反思', compaction_run: '运行压缩', }; // === Components === function LevelSelector({ value, onChange, }: { value: AutonomyLevel; onChange: (level: AutonomyLevel) => void; }) { return (
{(Object.keys(LEVEL_CONFIG) as AutonomyLevel[]).map((level) => { const config = LEVEL_CONFIG[level]; const Icon = config.icon; const isSelected = value === level; return ( ); })}
); } function ActionToggle({ label, enabled, onChange, disabled, }: { label: string; enabled: boolean; onChange: (enabled: boolean) => void; disabled?: boolean; }) { return (
{label}
); } function AuditLogEntryItem({ entry, onRollback, }: { entry: AuditLogEntry; onRollback?: (id: string) => void; }) { const [expanded, setExpanded] = useState(false); const outcomeColors = { success: 'text-green-500', failed: 'text-red-500', rolled_back: 'text-yellow-500', }; const outcomeLabels = { success: '成功', failed: '失败', rolled_back: '已回滚', }; const time = new Date(entry.timestamp).toLocaleString('zh-CN', { hour: '2-digit', minute: '2-digit', second: '2-digit', }); return (
{expanded && (
风险: {entry.decision.riskLevel} · 重要性: {entry.decision.importance}
原因: {entry.decision.reason}
{entry.outcome !== 'rolled_back' && entry.decision.riskLevel !== 'low' && ( )}
)}
); } // === Main Component === export function AutonomyConfig({ className = '', onConfigChange }: AutonomyConfigProps) { const [manager] = useState(() => getAutonomyManager()); const [config, setConfig] = useState(manager.getConfig()); const [auditLog, setAuditLog] = useState([]); const [hasChanges, setHasChanges] = useState(false); // Load audit log useEffect(() => { setAuditLog(manager.getAuditLog(50)); }, [manager]); const updateConfig = useCallback( (updates: Partial) => { setConfig((prev) => { const next = { ...prev, ...updates }; setHasChanges(true); onConfigChange?.(next); return next; }); }, [onConfigChange] ); const handleLevelChange = useCallback((level: AutonomyLevel) => { const newConfig = DEFAULT_AUTONOMY_CONFIGS[level]; setConfig(newConfig); setHasChanges(true); onConfigChange?.(newConfig); }, [onConfigChange]); const handleSave = useCallback(() => { manager.updateConfig(config); setHasChanges(false); }, [manager, config]); const handleRollback = useCallback((auditId: string) => { if (manager.rollback(auditId)) { setAuditLog(manager.getAuditLog(50)); } }, [manager]); const handleClearLog = useCallback(() => { manager.clearAuditLog(); setAuditLog([]); }, [manager]); return (
{/* Header */}

自主授权

{/* Content */}
{/* Autonomy Level */}
自主级别
{/* Allowed Actions */}
允许的操作
updateConfig({ allowedActions: { ...config.allowedActions, memoryAutoSave: enabled }, }) } /> updateConfig({ allowedActions: { ...config.allowedActions, identityAutoUpdate: enabled }, }) } /> updateConfig({ allowedActions: { ...config.allowedActions, skillAutoInstall: enabled }, }) } /> updateConfig({ allowedActions: { ...config.allowedActions, selfModification: enabled }, }) } /> updateConfig({ allowedActions: { ...config.allowedActions, autoCompaction: enabled }, }) } /> updateConfig({ allowedActions: { ...config.allowedActions, autoReflection: enabled }, }) } />
{/* Approval Thresholds */}
审批阈值
重要性上限 updateConfig({ approvalThreshold: { ...config.approvalThreshold, importanceMax: parseInt(e.target.value), }, }) } className="w-24 h-2 bg-gray-200 dark:bg-gray-700 rounded-lg appearance-none cursor-pointer accent-purple-500" /> {config.approvalThreshold.importanceMax}
风险等级上限
{/* Audit Log */}
审计日志 ({auditLog.length} 条)
{auditLog.length > 0 ? (
{auditLog .slice() .reverse() .map((entry) => ( ))}
) : (
暂无审计日志
)}
{/* Info */}

高风险操作(删除记忆、修改身份文件)始终需要用户确认,无论自主级别如何设置。 所有自主操作都会记录在审计日志中,支持一键回滚。

); } export default AutonomyConfig;