feat(ui): add ButlerPanel — pain points, proposals, memory insights
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

- Add Butler types (PainPoint, Proposal, DelegationResult) to viking-client.ts
- Add butler API functions: getButlerInsights, getButlerProposals,
  recordButlerPainPoint, generateButlerSolution, updateButlerProposalStatus,
  butlerDelegateTask
- Create ButlerPanel with three sections:
  - InsightsSection: pain point cards with evidence chain, severity, confidence
  - ProposalsSection: solution cards with accept/reject actions
  - MemorySection: Viking memory entries per agent
- Create useButlerInsights hook for data fetching
- Add "管家" tab to RightPanel with ConciergeBell icon

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
iven
2026-04-07 09:30:28 +08:00
parent e1f3a9719e
commit 80cadd1158
7 changed files with 567 additions and 3 deletions

View File

@@ -12,7 +12,9 @@ import {
MessageSquare, Cpu, FileText, User, Activity, Brain,
Shield, Sparkles, List, Network, Dna, History,
ChevronDown, ChevronUp, RotateCcw, AlertCircle, Loader2,
ConciergeBell,
} from 'lucide-react';
import { ButlerPanel } from './ButlerPanel';
// === Helper to extract code blocks from markdown content ===
function extractCodeBlocksFromContent(content: string): CodeBlock[] {
@@ -106,7 +108,7 @@ export function RightPanel() {
const { messages, setCurrentAgent } = useChatStore();
const currentModel = useConversationStore((s) => s.currentModel);
const currentAgent = useConversationStore((s) => s.currentAgent);
const [activeTab, setActiveTab] = useState<'status' | 'files' | 'agent' | 'memory' | 'reflection' | 'autonomy' | 'evolution'>('status');
const [activeTab, setActiveTab] = useState<'status' | 'files' | 'agent' | 'memory' | 'reflection' | 'autonomy' | 'evolution' | 'butler'>('status');
const [memoryViewMode, setMemoryViewMode] = useState<'list' | 'graph'>('list');
const [isEditingAgent, setIsEditingAgent] = useState(false);
const [agentDraft, setAgentDraft] = useState<AgentDraft | null>(null);
@@ -316,6 +318,12 @@ export function RightPanel() {
icon={<Dna className="w-4 h-4" />}
label="演化"
/>
<TabButton
active={activeTab === 'butler'}
onClick={() => setActiveTab('butler')}
icon={<ConciergeBell className="w-4 h-4" />}
label="管家"
/>
</div>
</div>
@@ -377,7 +385,9 @@ export function RightPanel() {
<AutonomyConfig />
) : activeTab === 'evolution' ? (
<IdentityChangeProposalPanel />
) : activeTab === 'agent' ? (
) : activeTab === 'butler' ? (
<ButlerPanel agentId={currentAgent?.id} />
) : activeTab === 'agent'? (
<div className="space-y-4">
<motion.div
whileHover={cardHover}