Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 3 additions & 18 deletions desktop/src/features/agents/ui/AgentGroupRows.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,40 +6,30 @@ export type AgentGroupRowsProps = {
agents: ManagedAgent[];
channelIdToName: Record<string, string>;
channelsByPubkey: Record<string, { id: string; name: string }[]>;
isActionPending: boolean;
logContent: string | null;
logError: Error | null;
logLoading: boolean;
personaLabelsById: Record<string, string>;
presenceLoaded: boolean;
presenceLookup: PresenceLookup;
selectedLogAgentPubkey: string | null;
onAddToChannel: (agent: ManagedAgent) => void;
onDelete: (pubkey: string) => void;
onOpenProfile: (pubkey: string) => void;
onSelectLogAgent: (pubkey: string | null) => void;
onStart: (pubkey: string) => void;
onStop: (pubkey: string) => void;
onToggleStartOnAppLaunch: (pubkey: string, startOnAppLaunch: boolean) => void;
};

export function AgentGroupRows({
agents,
channelIdToName,
channelsByPubkey,
isActionPending,
logContent,
logError,
logLoading,
personaLabelsById,
presenceLoaded,
presenceLookup,
selectedLogAgentPubkey,
onAddToChannel,
onDelete,
onOpenProfile,
onSelectLogAgent,
onStart,
onStop,
onToggleStartOnAppLaunch,
}: AgentGroupRowsProps) {
return (
<div className="divide-y divide-border/50 border-t border-border/50">
Expand All @@ -48,7 +38,6 @@ export function AgentGroupRows({
agent={agent}
channelIdToName={channelIdToName}
channelNames={channelsByPubkey[normalizePubkey(agent.pubkey)] ?? []}
isActionPending={isActionPending}
isLogSelected={selectedLogAgentPubkey === agent.pubkey}
key={agent.pubkey}
logContent={
Expand All @@ -59,12 +48,8 @@ export function AgentGroupRows({
personaLabelsById={personaLabelsById}
presenceLoaded={presenceLoaded}
presenceLookup={presenceLookup}
onAddToChannel={onAddToChannel}
onDelete={onDelete}
onOpenProfile={onOpenProfile}
onSelectLogAgent={onSelectLogAgent}
onStart={onStart}
onStop={onStop}
onToggleStartOnAppLaunch={onToggleStartOnAppLaunch}
/>
))}
</div>
Expand Down
68 changes: 63 additions & 5 deletions desktop/src/features/agents/ui/AgentsScreen.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,76 @@
import * as React from "react";

import { useAppNavigation } from "@/app/navigation/useAppNavigation";
import { useOpenDmMutation } from "@/features/channels/hooks";
import { UserProfilePanel } from "@/features/profile/ui/UserProfilePanel";
import { useIdentityQuery } from "@/shared/api/hooks";
import type { AgentPersona } from "@/shared/api/types";
import { ProfilePanelProvider } from "@/shared/context/ProfilePanelContext";
import { useThreadPanelWidth } from "@/shared/hooks/useThreadPanelWidth";
import { ViewLoadingFallback } from "@/shared/ui/ViewLoadingFallback";

const AgentsView = React.lazy(async () => {
const module = await import("@/features/agents/ui/AgentsView");
return { default: module.AgentsView };
});

type ProfilePanelTarget =
| { kind: "pubkey"; pubkey: string }
| { kind: "persona"; persona: AgentPersona };

export function AgentsScreen() {
const identityQuery = useIdentityQuery();
const [profilePanelTarget, setProfilePanelTarget] =
React.useState<ProfilePanelTarget | null>(null);
const threadPanelWidth = useThreadPanelWidth();
const openDmMutation = useOpenDmMutation();
const { goChannel } = useAppNavigation();

const handleOpenDm = React.useCallback(
async (pubkeys: string[]) => {
const dm = await openDmMutation.mutateAsync({ pubkeys });
await goChannel(dm.id);
},
[goChannel, openDmMutation],
);

return (
<div className="relative flex min-h-0 min-w-0 flex-1 flex-col overflow-hidden">
<React.Suspense fallback={<ViewLoadingFallback kind="agents" />}>
<AgentsView />
</React.Suspense>
</div>
<ProfilePanelProvider
onOpenPersonaProfilePanel={(persona) =>
setProfilePanelTarget({ kind: "persona", persona })
}
onOpenProfilePanel={(pubkey) =>
setProfilePanelTarget({ kind: "pubkey", pubkey })
}
>
<div className="relative flex min-h-0 min-w-0 flex-1 flex-col overflow-hidden">
<div className="flex min-h-0 min-w-0 flex-1 flex-row overflow-hidden">
<React.Suspense fallback={<ViewLoadingFallback kind="agents" />}>
<AgentsView />
</React.Suspense>
{profilePanelTarget ? (
<UserProfilePanel
canResetWidth={threadPanelWidth.canReset}
currentPubkey={identityQuery.data?.pubkey}
onClose={() => setProfilePanelTarget(null)}
onOpenDm={handleOpenDm}
onResetWidth={threadPanelWidth.onResetWidth}
onResizeStart={threadPanelWidth.onResizeStart}
persona={
profilePanelTarget.kind === "persona"
? profilePanelTarget.persona
: undefined
}
pubkey={
profilePanelTarget.kind === "pubkey"
? profilePanelTarget.pubkey
: undefined
}
widthPx={threadPanelWidth.widthPx}
/>
) : null}
</div>
</div>
</ProfilePanelProvider>
);
}
33 changes: 7 additions & 26 deletions desktop/src/features/agents/ui/AgentsView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,10 @@ import { UnifiedAgentsSection } from "./UnifiedAgentsSection";
import { useManagedAgentActions } from "./useManagedAgentActions";
import { usePersonaActions } from "./usePersonaActions";
import { useTeamActions } from "./useTeamActions";
import { useProfilePanel } from "@/shared/context/ProfilePanelContext";

export function AgentsView() {
const { openPersonaProfilePanel, openProfilePanel } = useProfilePanel();
const agents = useManagedAgentActions();
const personas = usePersonaActions();
const teamActions = useTeamActions(
Expand Down Expand Up @@ -75,11 +77,6 @@ export function AgentsView() {
personaLabelsById={personas.personaLabelsById}
presenceLoaded={agents.managedPresenceQuery.isSuccess}
presenceLookup={agents.managedPresenceQuery.data ?? {}}
onAddToChannel={(agent) => {
agents.setActionNoticeMessage(null);
agents.setActionErrorMessage(null);
agents.setAgentToAddToChannel(agent);
}}
onBulkRemoveStopped={() => {
void agents.handleBulkRemoveStopped();
}}
Expand All @@ -89,22 +86,13 @@ export function AgentsView() {
onCreateAgent={() => {
agents.setIsCreateOpen(true);
}}
onDeleteAgent={(pubkey) => {
void agents.handleDelete(pubkey);
}}
onSelectLogAgent={agents.setLogAgentPubkey}
onStartAgent={(pubkey) => {
void agents.handleStart(pubkey);
}}
onStopAgent={(pubkey) => {
void agents.handleStop(pubkey);
onOpenAgentProfile={(pubkey) => {
openProfilePanel?.(pubkey);
}}
onToggleStartOnAppLaunch={(pubkey, startOnAppLaunch) => {
void agents.handleToggleStartOnAppLaunch(
pubkey,
startOnAppLaunch,
);
onOpenPersonaProfile={(persona) => {
openPersonaProfilePanel?.(persona);
}}
onSelectLogAgent={agents.setLogAgentPubkey}
selectedLogAgentPubkey={agents.logAgentPubkey}
// Persona props
canChooseCatalog={personas.catalogPersonas.length > 0}
Expand All @@ -128,13 +116,6 @@ export function AgentsView() {
isPersonasPending={personas.isPending}
onCreatePersona={personas.openCreate}
onChooseCatalog={personas.openCatalog}
onDuplicatePersona={personas.openDuplicate}
onEditPersona={personas.openEdit}
onExportPersona={personas.handleExport}
onDeactivatePersona={(persona) => {
void personas.handleSetActive(persona, false, "library");
}}
onDeletePersona={personas.openDelete}
onImportPersonaFile={(fileBytes, fileName) => {
void personas.handleImportFile(fileBytes, fileName);
}}
Expand Down
Loading