TASK_PHASE_MVP_DAGI_INTEGRATION_FIX_20251201 A) Agents Layer: - A1: Added gov_level to API and UI (list + profile) - A2: Added dais_identity_id to API and UI - A3: Added home_microdao_id/name/slug for ownership display B) MicroDAO Layer: - B1/B2: Already implemented (agents, rooms, citizens, district badge) C) Nodes Layer: - C1: Node Dashboard already implemented - C2: Created nodes table migration with owner_microdao_id - C3: INSERT NODE1/NODE2 with dao_daarion ownership D) Backend Fixes: - D1: Extended /api/agents/* with DAIS/governance fields - D2/D3: Already implemented Files changed: - services/city-service/repo_city.py - services/city-service/models_city.py - services/city-service/routes_city.py - services/city-service/migrations.py - apps/web/src/lib/types/agents.ts - apps/web/src/lib/agent-dashboard.ts - apps/web/src/app/agents/page.tsx - apps/web/src/components/agent-dashboard/AgentSummaryCard.tsx Reports: - docs/debug/mvp_dagi_integration_fix_report_20251201.md - docs/tasks/TASK_PHASE_MVP_DAGI_INTEGRATION_FIX_20251201.md
131 lines
4.8 KiB
TypeScript
131 lines
4.8 KiB
TypeScript
'use client';
|
|
|
|
import Link from 'next/link';
|
|
import { AgentProfile, AgentRuntime, getAgentKindIcon, getAgentStatusColor } from '@/lib/agent-dashboard';
|
|
import { StatusBadge } from '@/components/node-dashboard';
|
|
import { getGovLevelBadge } from '@/lib/types/agents';
|
|
import { Shield, Fingerprint, Building2 } from 'lucide-react';
|
|
|
|
interface AgentSummaryCardProps {
|
|
profile: AgentProfile;
|
|
runtime?: AgentRuntime;
|
|
}
|
|
|
|
export function AgentSummaryCard({ profile, runtime }: AgentSummaryCardProps) {
|
|
const kindIcon = getAgentKindIcon(profile.kind);
|
|
const govBadge = getGovLevelBadge(profile.gov_level);
|
|
|
|
return (
|
|
<div className="bg-white/5 backdrop-blur-md rounded-2xl border border-white/10 p-6">
|
|
<div className="flex items-start gap-4">
|
|
{/* Avatar */}
|
|
<div className="relative">
|
|
{profile.dais.vis?.avatar_url ? (
|
|
<img
|
|
src={profile.dais.vis.avatar_url}
|
|
alt={profile.display_name}
|
|
className="w-20 h-20 rounded-xl object-cover"
|
|
/>
|
|
) : (
|
|
<div
|
|
className="w-20 h-20 rounded-xl flex items-center justify-center text-4xl"
|
|
style={{ backgroundColor: profile.dais.vis?.color_primary || '#22D3EE' + '30' }}
|
|
>
|
|
{kindIcon}
|
|
</div>
|
|
)}
|
|
<div className={`absolute -bottom-1 -right-1 w-4 h-4 rounded-full border-2 border-slate-900 ${
|
|
profile.status === 'online' ? 'bg-green-500' :
|
|
profile.status === 'training' ? 'bg-yellow-500' : 'bg-gray-500'
|
|
}`} />
|
|
</div>
|
|
|
|
{/* Info */}
|
|
<div className="flex-1">
|
|
<div className="flex items-center gap-2 mb-1">
|
|
<h2 className="text-xl font-bold text-white">{profile.display_name}</h2>
|
|
<StatusBadge status={profile.status} size="sm" />
|
|
</div>
|
|
|
|
<p className="text-white/50 text-sm mb-2">{profile.agent_id}</p>
|
|
|
|
{profile.dais.core.bio && (
|
|
<p className="text-white/70 text-sm mb-3">{profile.dais.core.bio}</p>
|
|
)}
|
|
|
|
{/* Tags */}
|
|
<div className="flex flex-wrap gap-2">
|
|
<span
|
|
className="px-2 py-1 rounded-md text-sm font-medium"
|
|
style={{
|
|
backgroundColor: (profile.dais.vis?.color_primary || '#22D3EE') + '30',
|
|
color: profile.dais.vis?.color_primary || '#22D3EE'
|
|
}}
|
|
>
|
|
{kindIcon} {profile.kind}
|
|
</span>
|
|
{/* Gov Level Badge (A1) */}
|
|
{profile.gov_level && (
|
|
<span className={`px-2 py-1 rounded-md text-sm font-medium flex items-center gap-1 ${govBadge.color}`}>
|
|
<Shield className="w-3 h-3" />
|
|
{govBadge.label}
|
|
</span>
|
|
)}
|
|
{/* DAIS Identity (A2) */}
|
|
{profile.dais_identity_id && (
|
|
<span className="px-2 py-1 bg-violet-500/20 text-violet-400 rounded-md text-sm flex items-center gap-1">
|
|
<Fingerprint className="w-3 h-3" />
|
|
{profile.dais_identity_id}
|
|
</span>
|
|
)}
|
|
{profile.roles.map(role => (
|
|
<span
|
|
key={role}
|
|
className="px-2 py-1 bg-white/10 text-white/70 rounded-md text-sm"
|
|
>
|
|
{role}
|
|
</span>
|
|
))}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Home MicroDAO (A3) */}
|
|
{(profile.home_microdao_id || profile.primary_microdao_id) && (
|
|
<div className="mt-4 pt-4 border-t border-white/10">
|
|
<div className="flex items-center gap-2 text-sm">
|
|
<Building2 className="w-4 h-4 text-cyan-400" />
|
|
<span className="text-white/50">Belongs to:</span>
|
|
<Link
|
|
href={`/microdao/${profile.home_microdao_slug || profile.primary_microdao_slug}`}
|
|
className="text-cyan-400 hover:text-cyan-300 font-medium"
|
|
>
|
|
{profile.home_microdao_name || profile.primary_microdao_name}
|
|
</Link>
|
|
</div>
|
|
</div>
|
|
)}
|
|
|
|
{/* Runtime info */}
|
|
{runtime && (
|
|
<div className="mt-4 pt-4 border-t border-white/10 flex items-center gap-4">
|
|
<div className="flex items-center gap-2">
|
|
<span className={`w-2 h-2 rounded-full ${
|
|
runtime.health === 'healthy' ? 'bg-green-500' : 'bg-yellow-500'
|
|
}`} />
|
|
<span className="text-white/50 text-sm">
|
|
{runtime.health === 'healthy' ? 'Healthy' : 'Degraded'}
|
|
</span>
|
|
</div>
|
|
{profile.node_id && (
|
|
<span className="text-white/30 text-sm">
|
|
📍 {profile.node_id}
|
|
</span>
|
|
)}
|
|
</div>
|
|
)}
|
|
</div>
|
|
);
|
|
}
|
|
|