diff --git a/apps/web/src/app/agents/[agentId]/page.tsx b/apps/web/src/app/agents/[agentId]/page.tsx index a6098f71..aaa41cab 100644 --- a/apps/web/src/app/agents/[agentId]/page.tsx +++ b/apps/web/src/app/agents/[agentId]/page.tsx @@ -16,7 +16,26 @@ import { import { AgentVisibilityCard } from '@/components/agent-dashboard/AgentVisibilityCard'; import { api, Agent, AgentInvokeResponse } from '@/lib/api'; import { updateAgentVisibility } from '@/lib/api/agents'; -import { AgentVisibilityPayload, VisibilityScope } from '@/lib/types/agents'; +import { AgentVisibilityPayload, VisibilityScope, getNodeBadgeLabel } from '@/lib/types/agents'; +import { Bot, Settings, FileText, Building2, Cpu, MessageSquare, BarChart3, Users, Globe, Lock, Eye, EyeOff, ChevronLeft, Loader2 } from 'lucide-react'; + +// Tab types +type TabId = 'dashboard' | 'prompts' | 'microdao' | 'identity' | 'models' | 'chat'; + +interface Tab { + id: TabId; + label: string; + icon: React.ReactNode; +} + +const TABS: Tab[] = [ + { id: 'dashboard', label: 'Dashboard', icon: }, + { id: 'prompts', label: 'System Prompts', icon: }, + { id: 'microdao', label: 'MicroDAO', icon: }, + { id: 'identity', label: 'Identity', icon: }, + { id: 'models', label: 'Models', icon: }, + { id: 'chat', label: 'Chat', icon: }, +]; // Chat Message type interface Message { @@ -31,10 +50,10 @@ interface Message { }; } -export default function AgentPage() { +export default function AgentConsolePage() { const params = useParams(); const agentId = params.agentId as string; - const [activeTab, setActiveTab] = useState<'dashboard' | 'chat'>('dashboard'); + const [activeTab, setActiveTab] = useState('dashboard'); // Dashboard state const { dashboard, isLoading: dashboardLoading, error: dashboardError, refresh } = useAgentDashboard(agentId, { @@ -43,7 +62,6 @@ export default function AgentPage() { // Chat state const [agent, setAgent] = useState(null); - const [chatLoading, setChatLoading] = useState(false); const [messages, setMessages] = useState([]); const [input, setInput] = useState(''); const [invoking, setInvoking] = useState(false); @@ -53,13 +71,10 @@ export default function AgentPage() { useEffect(() => { async function loadAgent() { try { - setChatLoading(true); const data = await api.getAgent(agentId); setAgent(data); } catch (error) { console.error('Failed to load agent:', error); - } finally { - setChatLoading(false); } } if (activeTab === 'chat') { @@ -115,14 +130,14 @@ export default function AgentPage() { }; // Loading state - if (dashboardLoading && !dashboard && activeTab === 'dashboard') { + if (dashboardLoading && !dashboard) { return (
-
+
-
-

Loading agent dashboard...

+ +

Loading agent console...

@@ -131,12 +146,12 @@ export default function AgentPage() { } // Error state - if (dashboardError && activeTab === 'dashboard') { + if (dashboardError) { return (
-
+
-

Failed to load agent dashboard

+

Failed to load agent console

{dashboardError.message}

- +
+ {TABS.map(tab => ( + + ))}
- +
+ + {/* Content */} +
{/* Dashboard Tab */} {activeTab === 'dashboard' && dashboard && (
+ {/* Quick Stats */} +
+
+
MicroDAOs
+
{dashboard.microdao_memberships?.length || 0}
+
+
+
Visibility
+
+ {dashboard.public_profile?.visibility_scope || 'city'} +
+
+
+
Kind
+
{profile?.kind}
+
+
+
Status
+
+ {profile?.status || 'offline'} +
+
+
+ + {/* Main Info Cards */} +
@@ -216,13 +320,97 @@ export default function AgentPage() {
- {/* System Prompts - Full Width */} +
+ )} + + {/* System Prompts Tab */} + {activeTab === 'prompts' && dashboard && ( +
+
+

+ + System Prompts +

+

+ Configure the agent's behavior through system prompts. These prompts define how the agent responds and operates. +

+
+ +
+ )} + + {/* MicroDAO Tab */} + {activeTab === 'microdao' && dashboard && ( +
+
+

+ + MicroDAO Membership +

+

+ Manage which MicroDAOs this agent belongs to. Every agent must belong to at least one MicroDAO. +

+ + {/* Primary MicroDAO */} + {profile?.primary_microdao_id && ( +
+
Primary MicroDAO
+ + {profile.primary_microdao_name || profile.primary_microdao_slug} + +
+ )} + + {/* Orchestrator Actions */} + {profile?.is_orchestrator && ( +
+
+ + Orchestrator Privileges +
+

+ As an orchestrator, this agent can create and manage MicroDAOs. +

+ +
+ )} +
+ + +
+ )} + + {/* Identity Tab */} + {activeTab === 'identity' && dashboard && ( +
+
+

+ + Agent Identity & Visibility +

+

+ Configure how this agent appears to others and whether it's visible as a public citizen. +

+
{/* Visibility Settings */} - -
)} + {/* Models Tab */} + {activeTab === 'models' && dashboard && ( +
+
+

+ + Model Configuration +

+

+ Configure which AI models this agent uses for different tasks. +

+ + {/* Current Model */} +
+
Current Model
+
+ {dashboard.profile.model || 'Default (via DAGI Router)'} +
+
+ + {/* Model Bindings (placeholder) */} +
+
+ + Model Bindings +
+

+ Advanced model configuration will be available in a future update. + Currently, models are managed through the DAGI Router. +

+
+
+
+ )} + {/* Chat Tab */} {activeTab === 'chat' && (
@@ -259,8 +475,8 @@ export default function AgentPage() {
{messages.length === 0 && (
-

💬

-

Start a conversation with {dashboard?.profile.display_name || agent?.name || agentId}

+ +

Start a conversation with {profile?.display_name || agentId}

)} {messages.map(msg => ( @@ -289,7 +505,7 @@ export default function AgentPage() {
-
+ Thinking...
@@ -325,4 +541,3 @@ export default function AgentPage() {
); } - diff --git a/apps/web/src/app/citizens/[slug]/page.tsx b/apps/web/src/app/citizens/[slug]/page.tsx index 8daf7a2d..496839e4 100644 --- a/apps/web/src/app/citizens/[slug]/page.tsx +++ b/apps/web/src/app/citizens/[slug]/page.tsx @@ -7,8 +7,9 @@ import { getAgentKindIcon } from '@/lib/agent-dashboard'; import { useCitizenProfile, useCitizenInteraction } from '@/hooks/useCitizens'; import { askCitizen } from '@/lib/api/citizens'; import { CityChatWidget } from '@/components/city/CityChatWidget'; +import { ChevronLeft, Building2, MapPin, MessageSquare, HelpCircle, Loader2, Users } from 'lucide-react'; -type LooseRecord = Record; +type LooseRecord = Record; export default function CitizenProfilePage() { const params = useParams<{ slug: string }>(); @@ -30,7 +31,7 @@ export default function CitizenProfilePage() {
-
+
@@ -43,8 +44,9 @@ export default function CitizenProfilePage() {

{error?.message || 'Citizen not found'}

- - ← Back to Citizens + + + Back to Citizens
@@ -53,73 +55,89 @@ export default function CitizenProfilePage() { } const status = citizen.status || 'unknown'; - const statusColor = - status === 'online' ? 'bg-emerald-500/20 text-emerald-300' : 'bg-white/10 text-white/60'; - + const isOnline = status === 'online'; const daisCore = (citizen.dais_public?.core as LooseRecord) || {}; const daisPhenotype = (citizen.dais_public?.phenotype as LooseRecord) || {}; - const daisMemex = (citizen.dais_public?.memex as LooseRecord) || {}; - const daisEconomics = (citizen.dais_public?.economics as LooseRecord) || {}; - const metricsEntries = Object.entries(citizen.metrics_public || {}); - const actions = (citizen.interaction?.actions as string[]) || []; return (
+ {/* Back Link */} - ← Back to Citizens + + Back to Citizens + {/* Hero Section */}
-
- {getAgentKindIcon(citizen.kind || '')} + {/* Avatar */} +
+ {citizen.avatar_url ? ( + // eslint-disable-next-line @next/next/no-img-element + + ) : ( + getAgentKindIcon(citizen.kind || '') + )}
+ + {/* Info */}
-

{citizen.display_name}

+
+

Громадянин DAARION City

+

{citizen.display_name}

+

- {citizen.public_title || citizen.kind || 'Citizen of DAARION'} + {citizen.public_title || citizen.kind || 'Citizen'}

+ + {/* Badges */}
- + {/* Status */} + + {status} + + {/* District */} {citizen.district && ( - - {citizen.district} District + + + {citizen.district} )} + + {/* MicroDAO */} {citizen.microdao && ( - MicroDAO: {citizen.microdao.name} + + {citizen.microdao.name} )}
- {citizen.admin_panel_url && ( - - ⚙️ Agent Dashboard - - )}
-
+ + {/* Content */} +
+ {/* Tagline */} {citizen.public_tagline && (
- "{citizen.public_tagline}" + “{citizen.public_tagline}”
)} + {/* Skills */} {citizen.public_skills?.length > 0 && (

Skills

@@ -135,74 +153,31 @@ export default function CitizenProfilePage() {
)} - -
- {citizen.district && ( -
-

District

-

{citizen.district}

-
- )} - {citizen.city_presence?.primary_room_slug && ( -
-

Primary Room

-

- #{citizen.city_presence.primary_room_slug} -

-
- )} - {citizen.home_node && ( -
-

Home Node

-
-

{citizen.home_node.name || citizen.node_id}

- {citizen.home_node.roles && citizen.home_node.roles.length > 0 && ( -
- {citizen.home_node.roles.map((role) => ( - - {role} - - ))} -
- )} - {citizen.home_node.environment && ( - - {citizen.home_node.environment} - - )} -
-
- )} -
-
-

Взаємодія з громадянином

+ {/* Interaction Section */} +
+

+ + Взаємодія з громадянином +

-
-

Чат

+ {/* Chat Link */} +
+

Чат у кімнаті MicroDAO

{interactionLoading ? ( -
Завантаження…
+
+ + Завантаження… +
) : interaction?.primary_room_slug ? ( - Відкрити чат у кімнаті{' '} - {interaction.primary_room_name ?? interaction.primary_room_slug} + + Відкрити чат у кімнаті {interaction.primary_room_name ?? interaction.primary_room_slug} ) : (
@@ -216,8 +191,12 @@ export default function CitizenProfilePage() { )}
-
-

Поставити запитання

+ {/* Ask Question */} +
+

+ + Поставити запитання +