diff --git a/desktop/src/features/channels/ui/AddChannelBotDialog.tsx b/desktop/src/features/channels/ui/AddChannelBotDialog.tsx
index 231e0973b3..45c33d59ef 100644
--- a/desktop/src/features/channels/ui/AddChannelBotDialog.tsx
+++ b/desktop/src/features/channels/ui/AddChannelBotDialog.tsx
@@ -1,4 +1,4 @@
-import { AlertTriangle, ChevronDown, ChevronRight } from "lucide-react";
+import { AlertTriangle, ChevronDown } from "lucide-react";
import * as React from "react";
import {
@@ -43,7 +43,6 @@ import { getActivePersonas } from "@/features/agents/lib/catalog";
import { getUsableTeams } from "@/features/agents/lib/teamPersonas";
import { useLastRuntimeProvider } from "@/features/agents/lib/useLastRuntimeProvider";
import { CreateAgentRespondToField } from "@/features/agents/ui/RespondToField";
-import { cn } from "@/shared/lib/cn";
type AddChannelBotDialogProps = {
backendProviders?: BackendProviderCandidate[];
@@ -93,43 +92,6 @@ function formatBatchFailureSummary(
.join("; ");
}
-// ── Collapsible section ─────────────────────────────────────────────────────
-
-function DisclosureSection({
- children,
- defaultOpen = false,
- label,
- testId,
-}: {
- children: React.ReactNode;
- defaultOpen?: boolean;
- label: string;
- testId?: string;
-}) {
- const [isOpen, setIsOpen] = React.useState(defaultOpen);
-
- return (
-
-
setIsOpen((prev) => !prev)}
- type="button"
- >
-
- {label}
-
- {isOpen ?
{children}
: null}
-
- );
-}
-
-// ── Main dialog ─────────────────────────────────────────────────────────────
-
export function AddChannelBotDialog({
backendProviders,
backendProvidersLoading,
@@ -456,6 +418,9 @@ export function AddChannelBotDialog({
}
}
+ // Allowlist mode requires at least one entry, mirroring the harness's own
+ // validation. If we let it through empty, the agent crash-loops at startup
+ // with a config error.
const respondToValid =
respondTo !== "allowlist" || respondToAllowlist.length > 0;
@@ -488,7 +453,7 @@ export function AddChannelBotDialog({
- {/* ─── Primary: Who ─────────────────────────────────────────────── */}
-
- {teams.length > 0 ? (
-
+ {resolvedBackendProviders.length > 0 ? (
+
+
Run on
+
handleRunOnChange(e.target.value)}
+ value={runOn}
+ >
+ This computer
+ {resolvedBackendProviders.map((p) => (
+
+ {p.id}
+
+ ))}
+
+
) : null}
- {
- setIncludeGeneric((current) => !current);
- setSubmissionNotice(null);
- setSubmissionError(null);
- }}
- onTogglePersona={(personaId) => {
- setSelectedPersonaIds((current) => toggleValue(current, personaId));
- setSubmissionNotice(null);
- setSubmissionError(null);
- }}
- personas={personas}
- selectedPersonaIds={selectedPersonaIds}
- />
+ {isProviderMode && selectedBackendProvider ? (
+
+
+
+ This provider at{" "}
+
+ {selectedBackendProvider.binaryPath}
+ {" "}
+ will receive your agent's private key. Only use providers
+ from trusted sources.
+
+
+ ) : null}
- {/* ─── Primary: Runtime ─────────────────────────────────────────── */}
+ {probeError ? (
+
+ Could not probe provider: {probeError}
+
+ ) : null}
+
+ {isProviderMode && probedProvider?.config_schema ? (
+
+ ) : null}
Runtime
@@ -588,6 +565,50 @@ export function AddChannelBotDialog({
+ {teams.length > 0 ? (
+
+ ) : null}
+
+ {
+ setIncludeGeneric((current) => !current);
+ setSubmissionNotice(null);
+ setSubmissionError(null);
+ }}
+ onTogglePersona={(personaId) => {
+ setSelectedPersonaIds((current) => toggleValue(current, personaId));
+ setSubmissionNotice(null);
+ setSubmissionError(null);
+ }}
+ personas={personas}
+ selectedPersonaIds={selectedPersonaIds}
+ />
+
+ {includeGeneric ? (
+ {
+ setHasEditedCustomName(true);
+ setCustomName(value);
+ }}
+ onPromptChange={setCustomPrompt}
+ prompt={customPrompt}
+ />
+ ) : null}
+
{reusableAgent ? (
) : null}
+ {selectedCount > 0 ? (
+
+ ) : null}
+
{selectedCount === 0 ? (
Pick one or more personas, or enable Generic to add a custom agent.
) : null}
- {/* ─── Customize (collapsed by default) ─────────────────────────── */}
-
-
- {includeGeneric ? (
- {
- setHasEditedCustomName(true);
- setCustomName(value);
- }}
- onPromptChange={setCustomPrompt}
- prompt={customPrompt}
- />
- ) : (
-
- Enable Generic above to set a custom name and system prompt.
-
- )}
-
- {selectedCount > 0 ? (
-
- ) : null}
-
-
- {/* ─── Advanced (collapsed by default) ──────────────────────────── */}
-
-
- {resolvedBackendProviders.length > 0 ? (
-
-
Run on
-
handleRunOnChange(e.target.value)}
- value={runOn}
- >
- This computer
- {resolvedBackendProviders.map((p) => (
-
- {p.id}
-
- ))}
-
-
- ) : null}
-
- {isProviderMode && selectedBackendProvider ? (
-
-
-
- This provider at{" "}
-
- {selectedBackendProvider.binaryPath}
- {" "}
- will receive your agent's private key. Only use providers
- from trusted sources.
-
-
- ) : null}
-
- {probeError ? (
-
- Could not probe provider: {probeError}
-
- ) : null}
-
- {isProviderMode && probedProvider?.config_schema ? (
-
- ) : null}
-
-
- {/* ─── Warnings & errors ────────────────────────────────────────── */}
-
{providersErrorMessage ? (
{providersErrorMessage}