feat(intelligence): add self-evolution UI for identity change proposals

P1.1: Identity Change Proposal UI
- Create IdentityChangeProposal.tsx with diff view for SOUL.md changes
- Add approve/reject buttons with visual feedback
- Show evolution history timeline with restore capability

P1.2: Connect Reflection Engine to Identity Proposals
- Update ReflectionLog.tsx to convert reflection proposals to identity proposals
- Add ReflectionIdentityProposal type for non-persisted proposals
- Auto-create identity proposals when reflection detects personality changes

P1.3: Evolution History and Rollback
- Display identity snapshots with timestamps
- One-click restore to previous personality versions
- Visual diff between current and proposed content

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
iven
2026-03-24 00:51:03 +08:00
parent 6c64d704d7
commit bfad61c3da
5 changed files with 526 additions and 6 deletions

View File

@@ -8,7 +8,7 @@ import { toChatAgent, useChatStore, type CodeBlock } from '../store/chatStore';
import {
Wifi, WifiOff, Bot, BarChart3, Plug, RefreshCw,
MessageSquare, Cpu, FileText, User, Activity, Brain,
Shield, Sparkles, GraduationCap, List, Network
Shield, Sparkles, GraduationCap, List, Network, Dna
} from 'lucide-react';
// === Helper to extract code blocks from markdown content ===
@@ -74,6 +74,7 @@ import { MemoryGraph } from './MemoryGraph';
import { ReflectionLog } from './ReflectionLog';
import { AutonomyConfig } from './AutonomyConfig';
import { ActiveLearningPanel } from './ActiveLearningPanel';
import { IdentityChangeProposalPanel } from './IdentityChangeProposal';
import { CodeSnippetPanel, type CodeSnippet } from './CodeSnippetPanel';
import { cardHover, defaultTransition } from '../lib/animations';
import { Button, Badge } from './ui';
@@ -101,7 +102,7 @@ export function RightPanel() {
const quickConfig = useConfigStore((s) => s.quickConfig);
const { messages, currentModel, currentAgent, setCurrentAgent } = useChatStore();
const [activeTab, setActiveTab] = useState<'status' | 'files' | 'agent' | 'memory' | 'reflection' | 'autonomy' | 'learning'>('status');
const [activeTab, setActiveTab] = useState<'status' | 'files' | 'agent' | 'memory' | 'reflection' | 'autonomy' | 'learning' | 'evolution'>('status');
const [memoryViewMode, setMemoryViewMode] = useState<'list' | 'graph'>('list');
const [isEditingAgent, setIsEditingAgent] = useState(false);
const [agentDraft, setAgentDraft] = useState<AgentDraft | null>(null);
@@ -263,6 +264,12 @@ export function RightPanel() {
icon={<GraduationCap className="w-4 h-4" />}
label="学习"
/>
<TabButton
active={activeTab === 'evolution'}
onClick={() => setActiveTab('evolution')}
icon={<Dna className="w-4 h-4" />}
label="演化"
/>
</div>
</div>
@@ -324,6 +331,8 @@ export function RightPanel() {
<AutonomyConfig />
) : activeTab === 'learning' ? (
<ActiveLearningPanel />
) : activeTab === 'evolution' ? (
<IdentityChangeProposalPanel />
) : activeTab === 'agent' ? (
<div className="space-y-4">
<motion.div