Files
buzz/desktop/src/features/agents/ui/agentConfigControls.tsx
Mic Neale 16d4ec335e feat(desktop): use collective mesh routing for Auto (#2825)
Uses MeshLLM built-in `mesh` collective intelligence / Mixture of Agents
when Buzz Auto sees two or more distinct physical models. With zero or
one model, Auto remains ordinary `auto`. This is an alternative way to
improve tool responses, accuracy, and resistance to hallucination when a
high-latency distributed mesh contains diverse models.

Models and members may come and go: collective routing enables only
after stable capacity, drops on confirmed contraction, and can recover
later. Mesh-specific failures retry once through ordinary Auto.

This update also pins MeshLLM to a v0.73.1-compatible backport of
[MeshLLM #1074](https://github.com/Mesh-LLM/mesh-llm/pull/1074), so
client-only Buzz nodes cannot enter model election or download a remote
provider model. Buzz preserves the selected local sharing model and
switches an existing client to sharing across a controlled app restart,
retaining one runtime and one `:9337` / `:3131` pair per machine.

Validation:
- Full local `just ci` passes on the cleaned branch.
- MeshLLM host-runtime suite: 1,568 passed, 0 failed; strict Clippy
passes.
- Buzz desktop Tauri suite with `mesh-llm`: 1,721 passed, 0 failed;
strict feature Clippy passes.
- Playwright covers client-to-share using the saved local model and no
destructive stop.
- Packaged two-machine testing proved single-model routing, dual-model
collective routing, tool-markup fallback, and runtime reuse.
- Packaged client-only recheck routed a real Mini Buzz turn through M5
while Mini stayed `is_client=true`, `is_host=false`, hosted no models,
and created no Gemma cache.

Builds on the recovery work merged in #2823; this PR does not duplicate
it.

---------

Signed-off-by: Michael Neale <michael.neale@gmail.com>
Signed-off-by: Tyler Longwell <tlongwell@block.xyz>
Co-authored-by: Michael Neale <michael.neale@gmail.com>
Co-authored-by: npub1qyvc0c5kl4gqv2fd97fsk46tu378sqgy35vc83rvgfwne90sel7s0ed67d <011987e296fd5006292d2f930b574be47c7801048d1983c46c425d3c95f0cffd@buzz.block.builderlab.xyz>
Co-authored-by: Tyler Longwell <tlongwell@block.xyz>
2026-07-26 19:46:13 -04:00

685 lines
22 KiB
TypeScript

/**
* Shared provider and model field components for agent dialogs.
*
* Both CreateAgentDialog (local mode) and AgentInstanceEditDialog import these
* instead of duplicating the picker logic.
*/
import * as React from "react";
import { Check, ChevronDown, Search } from "lucide-react";
import type { AcpRuntimeCatalogEntry } from "@/shared/api/types";
import { cn } from "@/shared/lib/cn";
import { Input } from "@/shared/ui/input";
import { Popover, PopoverContent, PopoverTrigger } from "@/shared/ui/popover";
import {
AUTO_MODEL_DROPDOWN_VALUE,
AUTO_PROVIDER_DROPDOWN_VALUE,
CUSTOM_MODEL_DROPDOWN_VALUE,
CUSTOM_PROVIDER_DROPDOWN_VALUE,
getDefaultLlmModelLabel,
getModelSelectValue,
getPersonaProviderOptions,
hasPersonaModelOption,
PERSONA_FIELD_CONTROL_CLASS,
PERSONA_FIELD_SHELL_CLASS,
providerDisplayLabel,
type PersonaModelOption,
} from "./agentConfigOptions";
import { MODEL_DISCOVERY_LOADING_VALUE } from "./usePersonaModelDiscovery";
import type { PersonaModelDiscoveryStatus } from "./personaModelDiscoveryStatus";
export const MODEL_NO_MODELS_VALUE = "__no_models__";
export type AgentDropdownOption = {
disabled?: boolean;
label: React.ReactNode;
value: string;
};
/**
* Ensures an opened model dropdown never renders as a blank white bar.
* When `options` is empty and discovery has finished, appends a single
* disabled "No models found" sentinel row in place. Returns `options`
* for convenient chaining in tests.
*/
export function appendNoModelsSentinel(
options: AgentDropdownOption[],
loading: boolean,
): AgentDropdownOption[] {
if (options.length === 0 && !loading) {
options.push({
disabled: true,
label: "No models found",
value: MODEL_NO_MODELS_VALUE,
});
}
return options;
}
export function resolveModelFieldStatusMessage({
discoveredModelOptions,
loading,
status,
}: {
discoveredModelOptions: readonly PersonaModelOption[] | null;
loading: boolean;
status: PersonaModelDiscoveryStatus | null;
}): string | null {
if (loading) return "Loading models...";
if (status !== null) return status.message;
return discoveredModelOptions !== null
? "Saved changes take effect on the next start."
: null;
}
function optionTestId(testId: string | undefined, value: string) {
if (!testId) return undefined;
return `${testId}-option-${value || "empty"}`;
}
export function AgentConfigTextInput({
className,
usePersonaInputStyle = false,
...props
}: React.ComponentProps<typeof Input> & {
usePersonaInputStyle?: boolean;
}) {
const input = (
<Input
{...props}
className={cn(
usePersonaInputStyle && "h-8 px-0 py-0 leading-6",
usePersonaInputStyle && PERSONA_FIELD_CONTROL_CLASS,
className,
)}
/>
);
return usePersonaInputStyle ? (
<div
className={cn(
"mt-2 flex min-h-11 items-center px-3",
PERSONA_FIELD_SHELL_CLASS,
)}
>
{input}
</div>
) : (
input
);
}
export function AgentDropdownSelect({
ariaRequired,
className,
disabled = false,
emptyOptionsLabel = "No options available",
id,
onValueChange,
options,
placeholder = "Select",
placeholderClassName,
placeholderValue,
searchable = false,
selectedLabel,
testId,
value,
}: {
ariaRequired?: boolean;
className?: string;
disabled?: boolean;
/** Shown when the option list is empty (not a search filter miss). */
emptyOptionsLabel?: string;
id: string;
onValueChange: (value: string) => void;
options: readonly AgentDropdownOption[];
placeholder?: string;
placeholderClassName?: string;
placeholderValue?: string;
/** Show a filter input above the options when the list is long. */
searchable?: boolean;
selectedLabel?: React.ReactNode;
testId?: string;
value: string;
}) {
const [open, setOpen] = React.useState(false);
const [query, setQuery] = React.useState("");
const selectedOption = options.find((option) => option.value === value);
const isPlaceholderSelection =
selectedLabel === undefined &&
(selectedOption === undefined ||
(placeholderValue !== undefined &&
selectedOption.value === placeholderValue));
const showSearch = searchable && options.length > 1;
const filteredOptions = React.useMemo(() => {
const trimmed = query.trim().toLowerCase();
if (!showSearch || trimmed === "") return options;
return options.filter((option) =>
(typeof option.label === "string" ? option.label : option.value)
.toLowerCase()
.includes(trimmed),
);
}, [options, query, showSearch]);
function handleOpenChange(next: boolean) {
setOpen(next);
if (!next) setQuery("");
}
return (
<Popover open={open} onOpenChange={handleOpenChange}>
<PopoverTrigger asChild>
<button
aria-controls={`${id}-listbox`}
aria-expanded={open}
aria-haspopup="listbox"
aria-required={ariaRequired}
className={cn(
"flex h-9 w-full items-center justify-between rounded-md border border-input bg-background px-3 py-2 text-left text-sm font-normal shadow-xs transition-colors hover:bg-background/90 focus-visible:outline-hidden focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-60",
className,
)}
data-testid={testId}
data-value={value}
disabled={disabled}
id={id}
role="combobox"
type="button"
>
<span
className={cn(
"min-w-0 truncate",
isPlaceholderSelection &&
(placeholderClassName ?? "text-foreground/45"),
)}
>
{selectedLabel ?? selectedOption?.label ?? placeholder}
</span>
<ChevronDown
aria-hidden="true"
className={cn(
"ml-3 h-4 w-4 shrink-0 transition-transform duration-150",
disabled ? "text-foreground/30" : "text-foreground",
open && "rotate-180",
)}
/>
</button>
</PopoverTrigger>
<PopoverContent
align="start"
className="z-[100] max-h-72 overflow-y-auto rounded-2xl border-foreground/10 bg-white p-1.5 text-foreground opacity-100 data-[state=closed]:animate-none data-[state=open]:animate-none"
sideOffset={8}
style={{
boxShadow: "0 16px 36px rgb(0 0 0 / 0.12)",
width: "var(--radix-popover-trigger-width)",
}}
>
<div
aria-labelledby={id}
className="space-y-1"
id={`${id}-listbox`}
role="listbox"
>
{showSearch ? (
<div className="relative">
<Search
aria-hidden="true"
className="pointer-events-none absolute left-3 top-1/2 h-3.5 w-3.5 -translate-y-1/2 text-foreground/45"
/>
<Input
aria-label="Search models"
autoFocus
className="h-9 rounded-xl border-foreground/10 bg-white pl-9 text-sm"
data-testid={testId ? `${testId}-search` : undefined}
onChange={(event) => setQuery(event.target.value)}
placeholder="Search models…"
value={query}
/>
</div>
) : null}
{filteredOptions.length === 0 ? (
<p
className="px-3 py-2 text-sm text-foreground/55"
data-testid={testId ? `${testId}-empty` : undefined}
>
{showSearch && query.trim().length > 0
? "No matches"
: emptyOptionsLabel}
</p>
) : null}
{filteredOptions.map((option) => {
const selected = option.value === value;
return (
<button
aria-disabled={option.disabled || undefined}
aria-selected={selected}
className={cn(
"flex w-full items-center justify-between gap-3 rounded-xl px-3 py-2 text-left text-sm leading-5 text-black opacity-100 transition-colors hover:bg-black/5 focus-visible:outline-hidden focus-visible:ring-1 focus-visible:ring-black/30",
selected && "bg-[var(--buzz-welcome-chartreuse)]/35",
option.disabled && "cursor-not-allowed text-black/35",
)}
data-testid={optionTestId(testId, option.value)}
data-value={option.value}
disabled={option.disabled}
key={option.value}
onClick={() => {
if (option.disabled) return;
onValueChange(option.value);
setOpen(false);
}}
role="option"
type="button"
>
<span className="min-w-0 truncate">{option.label}</span>
<Check
aria-hidden="true"
className={cn(
"h-4 w-4 shrink-0 text-black transition-opacity",
option.disabled && "text-black/35",
selected ? "opacity-100" : "opacity-0",
)}
strokeWidth={2.5}
/>
</button>
);
})}
</div>
</PopoverContent>
</Popover>
);
}
export function RequiredFieldLabel({
className,
children,
htmlFor,
isRequired,
}: {
className?: string;
children: React.ReactNode;
htmlFor: string;
isRequired: boolean;
}) {
return (
<label className={cn("text-sm font-medium", className)} htmlFor={htmlFor}>
{children}
{isRequired ? (
<span className="ml-1 text-destructive" aria-hidden="true">
*
</span>
) : null}
</label>
);
}
export function resolveDefaultModelLabel({
defaultModelLabel,
discoveredModelOptions,
globalModel,
isSharedCompute,
}: {
defaultModelLabel?: string;
discoveredModelOptions: readonly PersonaModelOption[] | null;
globalModel?: string;
isSharedCompute: boolean;
}) {
return (
defaultModelLabel ??
discoveredModelOptions?.find((option) => option.id.trim() === "")?.label ??
(isSharedCompute
? "Auto (collective when available)"
: getDefaultLlmModelLabel(globalModel))
);
}
export function AgentModelField({
disabled,
discoveredModelOptions,
globalModel,
allowDefaultModel = true,
defaultModelLabel,
disableSelectDuringDiscovery = true,
keepSelectedModelValueLabel = false,
id = "agent-model",
isCustomModelEditing,
isRequired,
model,
modelDiscoveryLoading,
modelDiscoveryStatus,
onIsCustomModelEditingChange,
onModelChange,
placeholder = "Select model",
placeholderClassName,
provider,
fieldClassName,
labelClassName,
selectClassName,
testId,
useCustomSelect = false,
showStatusMessage = true,
showCustomModelOption = true,
useChevronIcon = false,
usePersonaInputStyle = false,
}: {
disabled: boolean;
discoveredModelOptions: readonly PersonaModelOption[] | null;
/** Known lower-precedence model used when this field is left empty. */
globalModel?: string;
/** Hide the empty/default option when no valid lower-precedence model exists. */
allowDefaultModel?: boolean;
/** Source-aware label for the empty/default option. */
defaultModelLabel?: string;
/** Disable the trigger while live model discovery refreshes the option list. */
disableSelectDuringDiscovery?: boolean;
/** Keep the closed trigger from swapping to discovered display labels. */
keepSelectedModelValueLabel?: boolean;
/** DOM id for the model select. Defaults to `"agent-model"`. Override in
* contexts where multiple instances coexist on the same page (e.g. the
* global-config settings card) to avoid duplicate DOM ids. */
id?: string;
isCustomModelEditing: boolean;
isRequired: boolean;
model: string;
modelDiscoveryLoading: boolean;
modelDiscoveryStatus: PersonaModelDiscoveryStatus | null;
onIsCustomModelEditingChange: (value: boolean) => void;
onModelChange: (value: string) => void;
/** Trigger placeholder shown when there is no selected model option. */
placeholder?: string;
/** Optional class override for placeholder text. */
placeholderClassName?: string;
provider?: string;
/** Optional class override for the field wrapper. */
fieldClassName?: string;
/** Optional class override for the label. */
labelClassName?: string;
/** Optional class override for contexts with custom visual treatments. */
selectClassName?: string;
/** Optional test id for custom dropdown trigger/options. */
testId?: string;
/** Render the polished app dropdown instead of the native select. */
useCustomSelect?: boolean;
/** Hide the helper/status line in compact presentations. */
showStatusMessage?: boolean;
/** Hide the explicit custom-model escape hatch in compact presentations. */
showCustomModelOption?: boolean;
/** Render a controlled chevron instead of the native select indicator. */
useChevronIcon?: boolean;
/** Match custom agent text inputs when this field is shown in that flow. */
usePersonaInputStyle?: boolean;
}) {
const trimmedModel = model.trim();
const isSharedCompute = provider?.trim() === "relay-mesh";
const discoveredDefaultOption = discoveredModelOptions?.find(
(option) => option.id.trim() === "",
);
// Model discovery can report the harness's current/default model while the
// persisted value remains empty ("let the harness choose"). Treat that as a
// real, displayable option instead of a blank select state. Explicit labels
// from a lower-precedence/baked default still win when present.
const defaultOption: PersonaModelOption = {
id: "",
label: resolveDefaultModelLabel({
defaultModelLabel,
discoveredModelOptions,
globalModel,
isSharedCompute,
}),
};
const discoveredWithoutDefault = (discoveredModelOptions ?? []).filter(
(option) => option.id.trim() !== "",
);
const baseModelOptions = isSharedCompute
? [defaultOption, ...discoveredWithoutDefault]
: [
...(allowDefaultModel || discoveredDefaultOption
? [defaultOption]
: []),
...discoveredWithoutDefault,
];
const shouldShowPendingModelOption =
!isSharedCompute &&
!isCustomModelEditing &&
modelDiscoveryLoading &&
discoveredModelOptions === null &&
trimmedModel.length > 0;
const effectiveModelOptions =
shouldShowPendingModelOption &&
!baseModelOptions.some((option) => option.id === trimmedModel)
? [...baseModelOptions, { id: trimmedModel, label: trimmedModel }]
: baseModelOptions;
// isModelCustom: true when the current model isn't in any known option set.
// We check discovered options (when available) or runtime-static options so
// a previously-saved custom model stays in custom mode even before discovery.
const isModelCustom =
!isSharedCompute &&
!hasPersonaModelOption(effectiveModelOptions, trimmedModel);
const modelSelectValue =
isSharedCompute && (trimmedModel === "" || trimmedModel === "auto")
? AUTO_MODEL_DROPDOWN_VALUE
: getModelSelectValue({
isCustomModelEditing,
isModelCustom,
model,
});
// The select is only disabled for mutation pending — never for missing discovery.
// Default/custom options remain usable regardless of discovery state.
const selectDisabled =
disabled || (disableSelectDuringDiscovery && modelDiscoveryLoading);
// Show the custom model input whenever custom mode is active or the current
// model is already custom — not gated on discovery having returned.
const showCustomModelInput =
!isSharedCompute && (isCustomModelEditing || isModelCustom);
const handleModelSelectChange = (nextValue: string) => {
if (nextValue === AUTO_MODEL_DROPDOWN_VALUE) {
onIsCustomModelEditingChange(false);
onModelChange(isSharedCompute ? "auto" : "");
return;
}
if (nextValue === CUSTOM_MODEL_DROPDOWN_VALUE) {
onIsCustomModelEditingChange(true);
return;
}
onIsCustomModelEditingChange(false);
onModelChange(nextValue);
};
const modelOptions: AgentDropdownOption[] = [
...effectiveModelOptions.map((option) => ({
label: option.label,
value: option.id || AUTO_MODEL_DROPDOWN_VALUE,
})),
...(modelDiscoveryLoading && discoveredModelOptions === null
? [
{
disabled: true,
label: "Loading models...",
value: MODEL_DISCOVERY_LOADING_VALUE,
},
]
: []),
...(!isSharedCompute &&
(showCustomModelOption || modelSelectValue === CUSTOM_MODEL_DROPDOWN_VALUE)
? [{ label: "Custom model...", value: CUSTOM_MODEL_DROPDOWN_VALUE }]
: []),
];
// An opened dropdown must never show a blank popover. When all the above
// yields an empty list and discovery has finished, add a disabled sentinel
// row so the user sees "No models found" instead of a bare white bar.
appendNoModelsSentinel(modelOptions, modelDiscoveryLoading);
const stableSelectedModelLabel =
keepSelectedModelValueLabel &&
modelSelectValue === trimmedModel &&
trimmedModel.length > 0
? trimmedModel
: undefined;
// While discovery is in flight with nothing selected, the closed field
// reads "Loading models…" instead of a select-prompt — the field isn't
// waiting on the user, it's waiting on the harness.
const restingPlaceholder =
modelDiscoveryLoading &&
discoveredModelOptions === null &&
trimmedModel.length === 0 &&
!isCustomModelEditing
? "Loading models..."
: placeholder;
const statusMessage = resolveModelFieldStatusMessage({
discoveredModelOptions,
loading: modelDiscoveryLoading,
status: modelDiscoveryStatus,
});
const modelSelect = useCustomSelect ? (
<AgentDropdownSelect
ariaRequired={isRequired}
className={selectClassName}
disabled={selectDisabled}
emptyOptionsLabel="Couldn't load models"
id={id}
onValueChange={handleModelSelectChange}
options={modelOptions}
placeholder={restingPlaceholder}
placeholderClassName={placeholderClassName}
searchable
selectedLabel={stableSelectedModelLabel}
testId={testId ?? id}
value={modelSelectValue}
/>
) : (
<select
aria-required={isRequired}
className={cn(
"flex h-9 w-full rounded-md border border-input bg-background px-3 py-2 text-sm shadow-xs disabled:cursor-not-allowed disabled:opacity-60",
useChevronIcon && "appearance-none pr-10",
selectClassName,
)}
disabled={selectDisabled}
id={id}
onChange={(event) => handleModelSelectChange(event.target.value)}
value={modelSelectValue}
>
{modelOptions.map((option) => (
<option
disabled={option.disabled}
key={option.value}
value={option.value}
>
{option.label}
</option>
))}
</select>
);
return (
<div className={cn("space-y-1.5", fieldClassName)}>
<RequiredFieldLabel
className={labelClassName}
htmlFor={id}
isRequired={isRequired}
>
Model
</RequiredFieldLabel>
{!useCustomSelect && useChevronIcon ? (
<div className="relative">
{modelSelect}
<ChevronDown
aria-hidden="true"
className="pointer-events-none absolute right-4 top-1/2 h-4 w-4 -translate-y-1/2 text-foreground"
/>
</div>
) : (
modelSelect
)}
{showCustomModelInput ? (
<AgentConfigTextInput
aria-label="Custom model ID"
autoCorrect="off"
disabled={disabled}
onChange={(event) => onModelChange(event.target.value)}
placeholder="Custom model ID"
usePersonaInputStyle={usePersonaInputStyle}
value={model}
/>
) : null}
{showStatusMessage && statusMessage ? (
<p className="text-xs text-muted-foreground">{statusMessage}</p>
) : null}
</div>
);
}
export function AgentProviderField({
disabled,
globalProvider,
isCustomProviderEditing,
isRequired,
onProviderChange,
provider,
selectedRuntime,
}: {
disabled: boolean;
globalProvider?: string;
isCustomProviderEditing: boolean;
isRequired: boolean;
onProviderChange: (value: string) => void;
provider: string;
selectedRuntime: AcpRuntimeCatalogEntry | undefined;
}) {
const trimmedProvider = provider.trim();
const providerOptions = getPersonaProviderOptions(
trimmedProvider,
selectedRuntime?.id ?? "",
globalProvider,
);
const providerSelectValue = isCustomProviderEditing
? CUSTOM_PROVIDER_DROPDOWN_VALUE
: trimmedProvider || AUTO_PROVIDER_DROPDOWN_VALUE;
return (
<div className="space-y-1.5">
<RequiredFieldLabel htmlFor="agent-provider" isRequired={isRequired}>
LLM provider
</RequiredFieldLabel>
<select
aria-required={isRequired}
className="flex h-9 w-full rounded-md border border-input bg-background px-3 py-2 text-sm shadow-xs disabled:cursor-not-allowed disabled:opacity-60"
disabled={disabled}
id="agent-provider"
onChange={(event) => onProviderChange(event.target.value)}
value={providerSelectValue}
>
{providerOptions.map((option) => (
<option
key={option.id}
value={option.id || AUTO_PROVIDER_DROPDOWN_VALUE}
>
{option.id ? providerDisplayLabel(option.label) : option.label}
</option>
))}
<option value={CUSTOM_PROVIDER_DROPDOWN_VALUE}>
Custom provider...
</option>
</select>
{isCustomProviderEditing ? (
<Input
aria-label="Custom provider ID"
autoCorrect="off"
disabled={disabled}
onChange={(event) => onProviderChange(event.target.value)}
placeholder="Custom provider ID"
value={provider}
/>
) : null}
<p className="text-xs text-muted-foreground">
Changing the provider updates the available model list immediately.
</p>
</div>
);
}