From 0af8d394575e77cb1c0cf650dc3d1ab7116e33cb Mon Sep 17 00:00:00 2001 From: npub1223z34hd7vtwc6qj4s7flsxkj644nlre2nthu7lrrmkumhu3xddsrx9r6w <52a228d6edf316ec6812ac3c9fc0d696ab59fc7954d77e7be31eedcddf91335b@sprout-oss.stage.blox.sqprod.co> Date: Tue, 7 Jul 2026 01:12:49 -0700 Subject: [PATCH] refactor(desktop): unify New Agent selectors on the persona dropdown pattern MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Agent runtime, "Who can talk to this agent", and "Run on" fields used raw handleRunOnChange(e.target.value)} + onValueChange={handleRunOnChange} + options={[ + { label: "This computer", value: "local" }, + ...backendProviders.map((p) => ({ + label: p.id, + value: p.id, + })), + ]} + placeholder="Choose where this agent runs" value={runOn} - > - - {backendProviders.map((p) => ( - - ))} - + /> ) : null} diff --git a/desktop/src/features/agents/ui/CreateAgentDialogSections.tsx b/desktop/src/features/agents/ui/CreateAgentDialogSections.tsx index eb5c7812b..adc3207f9 100644 --- a/desktop/src/features/agents/ui/CreateAgentDialogSections.tsx +++ b/desktop/src/features/agents/ui/CreateAgentDialogSections.tsx @@ -2,6 +2,7 @@ import type { AcpRuntime, ManagedAgentPrereqs } from "@/shared/api/types"; import { cn } from "@/shared/lib/cn"; import { Input } from "@/shared/ui/input"; import { describeResolvedCommand } from "./agentUi"; +import { PersonaDropdownField } from "./PersonaDropdownField"; export function CreateAgentBasicsFields({ name, @@ -55,19 +56,19 @@ export function CreateAgentRuntimeField({ - + /> {selectedRuntime ? (

Detected via{" "} diff --git a/desktop/src/features/agents/ui/PersonaDropdownField.tsx b/desktop/src/features/agents/ui/PersonaDropdownField.tsx index 90aa3fc06..df7522ba4 100644 --- a/desktop/src/features/agents/ui/PersonaDropdownField.tsx +++ b/desktop/src/features/agents/ui/PersonaDropdownField.tsx @@ -34,6 +34,7 @@ export function PersonaDropdownField({ }) { const [open, setOpen] = React.useState(false); const selectedOption = options.find((option) => option.value === value); + const showAsPlaceholder = !selectedOption || selectedOption.isPlaceholder; return (

@@ -52,7 +53,7 @@ export function PersonaDropdownField({ {selectedOption?.label ?? placeholder} diff --git a/desktop/src/features/agents/ui/RespondToField.tsx b/desktop/src/features/agents/ui/RespondToField.tsx index dd36c52c6..8e0b180cc 100644 --- a/desktop/src/features/agents/ui/RespondToField.tsx +++ b/desktop/src/features/agents/ui/RespondToField.tsx @@ -12,6 +12,7 @@ import { cn } from "@/shared/lib/cn"; import { Input } from "@/shared/ui/input"; import { Textarea } from "@/shared/ui/textarea"; import { UserAvatar } from "@/shared/ui/UserAvatar"; +import { PersonaDropdownField } from "./PersonaDropdownField"; /** * Inbound author gate UI for create/edit agent dialogs. @@ -30,6 +31,12 @@ import { UserAvatar } from "@/shared/ui/UserAvatar"; * `desktop/src-tauri/src/managed_agents/types.rs`. */ +const RESPOND_TO_OPTIONS = [ + { label: "Owner only (default)", value: "owner-only" }, + { label: "Anyone", value: "anyone" }, + { label: "Allowlist", value: "allowlist" }, +] as const; + function formatSearchUserName(user: UserSearchResult) { return ( user.displayName?.trim() || @@ -118,18 +125,14 @@ export function CreateAgentRespondToField({ - + />

Controls which Nostr authors the agent listens to (@mentions, DMs, thread replies). The agent's owner can always shut it down with diff --git a/desktop/src/features/agents/ui/personaDialogPickers.tsx b/desktop/src/features/agents/ui/personaDialogPickers.tsx index e3b51cfcb..03f68b593 100644 --- a/desktop/src/features/agents/ui/personaDialogPickers.tsx +++ b/desktop/src/features/agents/ui/personaDialogPickers.tsx @@ -30,6 +30,12 @@ export type PersonaModelOption = { export type PersonaDropdownOption = { disabled?: boolean; + /** + * Marks an "auto"/default option that stands in for "no explicit choice". + * The trigger renders it faded, like placeholder text, so it reads as + * helper copy rather than an actively selected value. + */ + isPlaceholder?: boolean; label: string; value: string; }; diff --git a/desktop/tests/e2e/persona-env-vars.spec.ts b/desktop/tests/e2e/persona-env-vars.spec.ts index 7098a7f0e..dd90ab946 100644 --- a/desktop/tests/e2e/persona-env-vars.spec.ts +++ b/desktop/tests/e2e/persona-env-vars.spec.ts @@ -320,7 +320,7 @@ test("agent model options follow the selected LLM provider", async ({ const runtime = page.locator("#agent-runtime"); const llmProvider = page.locator("#agent-llm-provider"); const model = page.locator("#persona-model"); - await expect(runtime).toHaveValue("buzz-agent"); + await expect(runtime).toContainText("Buzz Agent"); await expect(llmProvider).toBeVisible(); await expect(model).toBeVisible(); // Without live discovery, the only static option is "Default model".