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
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:
71
desktop/src/components/ButlerPanel/MemorySection.tsx
Normal file
71
desktop/src/components/ButlerPanel/MemorySection.tsx
Normal file
@@ -0,0 +1,71 @@
|
||||
import { useState, useEffect } from 'react';
|
||||
import { Brain, Loader2 } from 'lucide-react';
|
||||
import { listVikingResources } from '../../lib/viking-client';
|
||||
|
||||
interface MemorySectionProps {
|
||||
agentId: string;
|
||||
}
|
||||
|
||||
interface MemoryEntry {
|
||||
uri: string;
|
||||
name: string;
|
||||
resourceType: string;
|
||||
}
|
||||
|
||||
export function MemorySection({ agentId }: MemorySectionProps) {
|
||||
const [memories, setMemories] = useState<MemoryEntry[]>([]);
|
||||
const [loading, setLoading] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
if (!agentId) return;
|
||||
|
||||
setLoading(true);
|
||||
listVikingResources(`viking://agents/${agentId}/memories/`)
|
||||
.then((entries) => {
|
||||
setMemories(entries as MemoryEntry[]);
|
||||
})
|
||||
.catch(() => {
|
||||
// Memory path may not exist yet — show empty state
|
||||
setMemories([]);
|
||||
})
|
||||
.finally(() => setLoading(false));
|
||||
}, [agentId]);
|
||||
|
||||
if (loading) {
|
||||
return (
|
||||
<div className="flex items-center justify-center py-8">
|
||||
<Loader2 className="w-5 h-5 text-gray-400 animate-spin" />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
if (memories.length === 0) {
|
||||
return (
|
||||
<div className="text-center py-8">
|
||||
<Brain className="w-8 h-8 mx-auto mb-2 text-gray-300 dark:text-gray-600" />
|
||||
<p className="text-sm text-gray-500 dark:text-gray-400">暂无记忆</p>
|
||||
<p className="text-xs text-gray-400 dark:text-gray-500 mt-1">
|
||||
管家会在对话中自动积累对您的了解
|
||||
</p>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="space-y-2">
|
||||
{memories.map((memory) => (
|
||||
<div
|
||||
key={memory.uri}
|
||||
className="rounded-lg border border-gray-200 dark:border-gray-700 bg-white dark:bg-gray-800 px-3 py-2"
|
||||
>
|
||||
<div className="text-sm text-gray-900 dark:text-gray-100 truncate">
|
||||
{memory.name}
|
||||
</div>
|
||||
<div className="text-xs text-gray-400 dark:text-gray-500 truncate mt-0.5">
|
||||
{memory.uri}
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user