From 402eac4a6fc8499136a3be20dbccf5e34ba53a73 Mon Sep 17 00:00:00 2001 From: Taylor Ho Date: Wed, 5 Aug 2026 18:17:49 -0700 Subject: [PATCH 1/5] feat(desktop): unify agent creation in the add-agent dialog - Move the new-agent card to the first grid position and use fluid 160px minimum tracks across agent and team galleries. - Replace the add-card action menu with a unified Add agent dialog for creating, importing, and selecting shared agents. - Embed the existing create-agent form with aligned gradient footer actions and consistent Add agent copy. - Add modal-wide snapshot drag-and-drop handling with the existing safe preview and confirmation pipeline. - Prompt before discarding modified create-agent content when switching flows or closing the dialog. Co-authored-by: Taylor Ho Signed-off-by: Taylor Ho --- .../agents/ui/AgentDefinitionDialog.tsx | 582 +++++++++--------- .../agents/ui/AgentDefinitionDialogShell.tsx | 57 ++ .../src/features/agents/ui/AgentDialog.tsx | 16 +- desktop/src/features/agents/ui/AgentsView.tsx | 65 +- .../agents/ui/PersonaCatalogDialog.tsx | 483 +++++++++++---- .../agents/ui/UnifiedAgentsSection.tsx | 159 +---- .../features/agents/ui/personaLibraryCopy.ts | 2 +- 7 files changed, 791 insertions(+), 573 deletions(-) create mode 100644 desktop/src/features/agents/ui/AgentDefinitionDialogShell.tsx diff --git a/desktop/src/features/agents/ui/AgentDefinitionDialog.tsx b/desktop/src/features/agents/ui/AgentDefinitionDialog.tsx index 12702f45ac..bf01c13774 100644 --- a/desktop/src/features/agents/ui/AgentDefinitionDialog.tsx +++ b/desktop/src/features/agents/ui/AgentDefinitionDialog.tsx @@ -8,8 +8,6 @@ import type { UpdatePersonaInput, } from "@/shared/api/types"; import { cn } from "@/shared/lib/cn"; -import { ChooserDialogContent } from "@/shared/ui/chooser-dialog-content"; -import { Dialog } from "@/shared/ui/dialog"; import { Input } from "@/shared/ui/input"; import { Textarea } from "@/shared/ui/textarea"; import { AgentCreationPreview } from "./AgentCreationPreview"; @@ -85,6 +83,7 @@ import { import { useProviderApiKeyFieldState } from "./providerApiKeyFieldState"; import { buildRuntimeModelProviderPayload } from "./agentDefinitionSubmitPayload"; import { AgentDefinitionDialogFooter } from "./AgentDefinitionDialogFooter"; +import { AgentDefinitionDialogShell } from "./AgentDefinitionDialogShell"; import { AddCustomHarnessDialog } from "./AddCustomHarnessDialog"; import { ADD_CUSTOM_HARNESS_OPTION, @@ -94,6 +93,7 @@ import { type AgentDefinitionDialogProps = { open: boolean; + embedded?: boolean; title: string; description: string; submitLabel: string; @@ -102,6 +102,7 @@ type AgentDefinitionDialogProps = { isPending: boolean; runtimes: AcpRuntimeCatalogEntry[]; runtimeCatalogStatus?: "loading" | "ready" | "error"; + onDirtyChange?: (dirty: boolean) => void; onOpenChange: (open: boolean) => void; onSubmit: ( input: CreatePersonaInput | UpdatePersonaInput, @@ -121,6 +122,7 @@ export type AgentDefinitionSubmitOptions = { export function AgentDefinitionDialog({ open, + embedded = false, title, description, submitLabel, @@ -129,6 +131,7 @@ export function AgentDefinitionDialog({ isPending, runtimes, runtimeCatalogStatus = "ready" as const, + onDirtyChange, onOpenChange, onSubmit, publishCatalogUpdatesOnSave = false, @@ -193,6 +196,10 @@ export function AgentDefinitionDialog({ (hasText(initialValues.model) || hasText(initialValues.provider)), ); + React.useEffect(() => { + onDirtyChange?.(hasUserChanges); + }, [hasUserChanges, onDirtyChange]); + React.useEffect(() => { if (!open || !initialValues) { return; @@ -725,316 +732,309 @@ export function AgentDefinitionDialog({ ); } - return ( - { - if (!nextOpen && (isPending || isAvatarUploadPending)) return; - handleOpenChange(nextOpen); - }} - open={open} + const footer = ( + handleOpenChange(false)} + publishesCatalogUpdates={publishCatalogUpdatesOnSave && hasUserChanges} + submitBlockReason={null} + submitLabel={submitLabel} + /> + ); + const form = ( +
setHasUserChanges(true)} + onSubmit={handleSubmitForm} > - handleOpenChange(false)} - publishesCatalogUpdates={ - publishCatalogUpdatesOnSave && hasUserChanges - } - submitBlockReason={null} - submitLabel={submitLabel} - /> - } - > - setHasUserChanges(true)} - onSubmit={handleSubmitForm} - > - { - setHasUserChanges(true); - setAvatarUrl(""); - }} - onUploadPendingChange={setIsAvatarUploadPending} - onSelectAvatar={(nextAvatarUrl) => { - setHasUserChanges(true); - setAvatarUrl(nextAvatarUrl); - }} + { + setHasUserChanges(true); + setAvatarUrl(""); + }} + onUploadPendingChange={setIsAvatarUploadPending} + onSelectAvatar={(nextAvatarUrl) => { + setHasUserChanges(true); + setAvatarUrl(nextAvatarUrl); + }} + /> + +
+
+ +
+ setDisplayName(event.target.value)} + placeholder="Fizz" + value={displayName} + /> +
+
+ +
+ +
+