diff --git a/desktop/src/features/agents/ui/AgentIdentityCard.tsx b/desktop/src/features/agents/ui/AgentIdentityCard.tsx
index a66fb9cd7..8dea118cb 100644
--- a/desktop/src/features/agents/ui/AgentIdentityCard.tsx
+++ b/desktop/src/features/agents/ui/AgentIdentityCard.tsx
@@ -12,6 +12,7 @@ type AgentIdentityCardProps = {
label: string;
modelLabel: string;
onClick: () => void;
+ status?: ReactNode;
};
export function AgentIdentityCard({
@@ -22,6 +23,7 @@ export function AgentIdentityCard({
label,
modelLabel,
onClick,
+ status,
}: AgentIdentityCardProps) {
const trimmedAvatarUrl = avatarUrl?.trim() || null;
@@ -56,6 +58,12 @@ export function AgentIdentityCard({
{actions}
) : null}
+ {status ? (
+
+ {status}
+
+ ) : null}
+
{label}
diff --git a/desktop/src/features/agents/ui/TeamIdentityCard.tsx b/desktop/src/features/agents/ui/TeamIdentityCard.tsx
index 17d129e6f..9255f9282 100644
--- a/desktop/src/features/agents/ui/TeamIdentityCard.tsx
+++ b/desktop/src/features/agents/ui/TeamIdentityCard.tsx
@@ -1,5 +1,5 @@
import type { ReactNode } from "react";
-import { Link, Users } from "lucide-react";
+import { Info, Link, Users } from "lucide-react";
import { ProfileAvatar } from "@/features/profile/ui/ProfileAvatar";
import type { AgentPersona } from "@/shared/api/types";
@@ -28,6 +28,7 @@ export function TeamIdentityCard({
actions,
children,
dataTestId,
+ description,
isSymlink = false,
memberCount,
personas,
@@ -37,6 +38,7 @@ export function TeamIdentityCard({
version,
}: TeamIdentityCardProps) {
const footerModelLabel = getTeamFooterModelLabel(personas);
+ const trimmedDescription = description?.trim();
return (
) : null}
+ {trimmedDescription ? (
+
+
+
+
+
+ {trimmedDescription}
+
+
+ ) : null}
{actions}
diff --git a/desktop/src/features/agents/ui/UnifiedAgentsSection.tsx b/desktop/src/features/agents/ui/UnifiedAgentsSection.tsx
index a63018443..93ab5509d 100644
--- a/desktop/src/features/agents/ui/UnifiedAgentsSection.tsx
+++ b/desktop/src/features/agents/ui/UnifiedAgentsSection.tsx
@@ -15,7 +15,9 @@ import {
} from "lucide-react";
import { toast } from "sonner";
+import { useActiveAgentTurns } from "@/features/agents/activeAgentTurnsStore";
import { isManagedAgentActive } from "@/features/agents/lib/managedAgentControlActions";
+import { AgentStatusBadge } from "@/features/agents/ui/AgentStatusBadge";
import { useUserProfileQuery } from "@/features/profile/hooks";
import type {
AgentPersona,
@@ -24,6 +26,7 @@ import type {
} from "@/shared/api/types";
import { useFeedbackToasts } from "@/shared/hooks/useToastEffect";
import { useFileImportZone } from "@/shared/hooks/useFileImportZone";
+import { normalizePubkey } from "@/shared/lib/pubkey";
import { Button } from "@/shared/ui/button";
import {
DropdownMenu,
@@ -36,6 +39,7 @@ import { IdentityCardSkeleton } from "@/shared/ui/identity-card-skeleton";
import { AgentIdentityCard } from "./AgentIdentityCard";
import { CreateIdentityCard } from "./CreateIdentityCard";
import { EditAgentDialog } from "./EditAgentDialog";
+import { ManagedAgentLogPanel } from "./ManagedAgentLogPanel";
type UnifiedAgentsSectionProps = {
actionErrorMessage: string | null;
@@ -121,6 +125,12 @@ export function UnifiedAgentsSection(props: UnifiedAgentsSectionProps) {
agentsError,
isActionPending,
isAgentsLoading,
+ logContent,
+ logError,
+ logLoading,
+ presenceLoaded,
+ presenceLookup,
+ selectedLogAgentPubkey,
onAddToChannel,
onBulkRemoveStopped,
onBulkStopRunning,
@@ -170,6 +180,14 @@ export function UnifiedAgentsSection(props: UnifiedAgentsSectionProps) {
}
return additional;
}, [groups]);
+ const selectedLogAgent = React.useMemo(
+ () =>
+ selectedLogAgentPubkey
+ ? (agents.find((agent) => agent.pubkey === selectedLogAgentPubkey) ??
+ null)
+ : null,
+ [agents, selectedLogAgentPubkey],
+ );
const [collapsed, setCollapsed] = React.useState>(new Set());
const {
fileInputRef,
@@ -249,6 +267,8 @@ export function UnifiedAgentsSection(props: UnifiedAgentsSectionProps) {
key={group.persona.id}
persona={group.persona}
personaMenuProps={personaMenuProps}
+ presenceLoaded={presenceLoaded}
+ presenceLookup={presenceLookup}
onOpenAgentProfile={onOpenAgentProfile}
/>
);
@@ -270,6 +290,8 @@ export function UnifiedAgentsSection(props: UnifiedAgentsSectionProps) {
collapsed={collapsed}
groupKey="__additional_persona_agents__"
label="Additional agent instances"
+ presenceLoaded={presenceLoaded}
+ presenceLookup={presenceLookup}
onToggle={toggle}
onOpenAgentProfile={onOpenAgentProfile}
/>
@@ -281,6 +303,8 @@ export function UnifiedAgentsSection(props: UnifiedAgentsSectionProps) {
collapsed={collapsed}
groupKey="__unknown__"
label="Unknown Persona"
+ presenceLoaded={presenceLoaded}
+ presenceLookup={presenceLookup}
onToggle={toggle}
onOpenAgentProfile={onOpenAgentProfile}
/>
@@ -292,10 +316,25 @@ export function UnifiedAgentsSection(props: UnifiedAgentsSectionProps) {
collapsed={collapsed}
groupKey="__ungrouped__"
label="Custom Agents"
+ presenceLoaded={presenceLoaded}
+ presenceLookup={presenceLookup}
onToggle={toggle}
onOpenAgentProfile={onOpenAgentProfile}
/>
) : null}
+ {selectedLogAgent ? (
+
+
+
+ ) : null}
) : null}
@@ -371,12 +410,16 @@ function AgentPersonaCard({
agentMenuProps,
persona,
personaMenuProps,
+ presenceLoaded,
+ presenceLookup,
onOpenAgentProfile,
}: {
agent: ManagedAgent | undefined;
agentMenuProps: AgentMenuProps;
persona: AgentPersona;
personaMenuProps: PersonaMenuProps;
+ presenceLoaded: boolean;
+ presenceLookup: PresenceLookup;
onOpenAgentProfile?: (pubkey: string) => void;
}) {
const title = persona.displayName;
@@ -408,6 +451,15 @@ function AgentPersonaCard({
}
personaMenuProps.onEditPersona(persona);
}}
+ status={
+ agent ? (
+
+ ) : null
+ }
/>
);
}
@@ -415,10 +467,14 @@ function AgentPersonaCard({
function StandaloneAgentCard({
agent,
agentMenuProps,
+ presenceLoaded,
+ presenceLookup,
onOpenAgentProfile,
}: {
agent: ManagedAgent;
agentMenuProps: AgentMenuProps;
+ presenceLoaded: boolean;
+ presenceLookup: PresenceLookup;
onOpenAgentProfile?: (pubkey: string) => void;
}) {
const title = agent.name;
@@ -439,6 +495,35 @@ function StandaloneAgentCard({
agentMenuProps.onOpenLogs(agent.pubkey);
}
}}
+ status={
+
+ }
+ />
+ );
+}
+
+function AgentCardStatus({
+ agent,
+ presenceLoaded,
+ presenceLookup,
+}: {
+ agent: ManagedAgent;
+ presenceLoaded: boolean;
+ presenceLookup: PresenceLookup;
+}) {
+ const activeTurns = useActiveAgentTurns(agent.pubkey);
+ const presenceStatus = presenceLookup[normalizePubkey(agent.pubkey)];
+
+ return (
+ 0}
+ presenceLoaded={presenceLoaded}
+ presenceStatus={presenceStatus}
+ status={agent.status}
/>
);
}
@@ -465,6 +550,9 @@ function AgentPersonaActionsMenu({