909 lines · 34.4 KB · TypeScript
RawDownload
import { useAtomValue } from "@effect/atom-react";import { connectionStatusText } from "@t3tools/client-runtime/connection";import { safeErrorLogAttributes } from "@t3tools/client-runtime/errors";import {  isAtomCommandInterrupted,  squashAtomCommandFailure,} from "@t3tools/client-runtime/state/runtime";import {  defaultInstanceIdForDriver,  type EnvironmentId,  PROVIDER_DISPLAY_NAMES,  ProviderDriverKind,  type ProviderInstanceConfig,  type ProviderInstanceId,  resolveProviderInstanceEnabled,} from "@t3tools/contracts";import { DEFAULT_UNIFIED_SETTINGS } from "@t3tools/contracts/settings";import {  getBackgroundActivityPresetSettings,  resolveServerBackgroundActivitySettings,} from "@t3tools/shared/backgroundActivitySettings";import * as Arr from "effect/Array";import * as Duration from "effect/Duration";import * as Equal from "effect/Equal";import * as Result from "effect/Result";import {  CloudIcon,  LaptopIcon,  LoaderIcon,  MonitorIcon,  PlusIcon,  RefreshCwIcon,  TerminalIcon,} from "lucide-react";import { useCallback, useMemo, useRef, useState } from "react"; import { isDesktopLocalConnectionTarget } from "../../connection/desktopLocal";import { isElectron } from "../../env";import { usePrimarySessionState } from "../../environments/primary";import { useEnvironmentSettings, useUpdateEnvironmentSettings } from "../../hooks/useSettings";import { cn } from "../../lib/utils";import { resolveAppModelSelectionState } from "../../modelSelection";import {  useEnvironments,  usePrimaryEnvironmentId,  type EnvironmentPresentation,} from "../../state/environments";import { EMPTY_SERVER_PROVIDERS, serverEnvironment } from "../../state/server";import { useEnvironmentSessionState } from "../../state/session";import { useAtomCommand } from "../../state/use-atom-command";import { getRelativeTimeState } from "../../timestampFormat";import {  ConnectionStatusDot,  connectionPhaseDotClassName,  connectionPhasePingClassName,} from "../ConnectionStatusDot";import {  canOneClickUpdateProviderCandidate,  collectProviderUpdateCandidates,  hasOneClickUpdateProviderCandidate,  isProviderUpdateActive,  type ProviderUpdateCandidate,} from "../ProviderUpdateLaunchNotification.logic";import { Button } from "../ui/button";import {  NumberField,  NumberFieldDecrement,  NumberFieldGroup,  NumberFieldIncrement,  NumberFieldInput,} from "../ui/number-field";import { stackedThreadToast, toastManager } from "../ui/toast";import { Tooltip, TooltipPopup, TooltipTrigger } from "../ui/tooltip";import { AddProviderInstanceDialog } from "./AddProviderInstanceDialog";import { ProviderInstanceCard } from "./ProviderInstanceCard";import { DRIVER_OPTIONS, getDriverOption } from "./providerDriverMeta";import { searchableSetting } from "./settingsSearch";import {  backgroundActivityOverrideSettings,  buildProviderInstanceUpdatePatch,  durationToSeconds,  normalizeIntervalSeconds,  PROVIDER_HEALTH_INTERVAL_STEP_SECONDS,} from "./SettingsPanels.logic";import {  PolicyTooltip,  SettingResetButton,  SettingsPageContainer,  SettingsRow,  SettingsSection,  useRelativeTimeTick,} from "./settingsLayout";import {  buildProviderEnvironmentOptions,  classifyProviderEnvironmentAccess,  type ProviderEnvironmentAccess,  type ProviderOperateAccess,  resolvePrimaryOperateAccess,  resolveRemoteOperateAccess,  resolveSelectedProviderEnvironmentId,} from "./ProviderSettingsPanel.logic"; function withoutProviderInstanceKey<V>(  record: Readonly<Record<ProviderInstanceId, V>> | undefined,  key: ProviderInstanceId,): Record<ProviderInstanceId, V> {  const next = { ...record } as Record<ProviderInstanceId, V>;  delete next[key];  return next;} function withoutProviderInstanceFavorites(  favorites: ReadonlyArray<{ readonly provider: ProviderInstanceId; readonly model: string }>,  instanceId: ProviderInstanceId,) {  return favorites.filter((favorite) => favorite.provider !== instanceId);} const PROVIDER_SETTINGS = DRIVER_OPTIONS.map((definition) => ({  provider: definition.value,})); function ProviderLastChecked({ lastCheckedAt }: { lastCheckedAt: string | null }) {  useRelativeTimeTick();  const lastCheckedRelative = getRelativeTimeState(lastCheckedAt);   if (lastCheckedRelative.status === "missing") {    return null;  }   if (lastCheckedRelative.status === "invalid") {    return <span className="text-[11px] text-muted-foreground/50">Checked unavailable</span>;  }   return (    <span className="text-[11px] text-muted-foreground/60">      {lastCheckedRelative.suffix ? (        <>          Checked <span className="font-mono tabular-nums">{lastCheckedRelative.value}</span>{" "}          {lastCheckedRelative.suffix}        </>      ) : (        <>Checked {lastCheckedRelative.value}</>      )}    </span>  );} function providerEnvironmentIcon(environment: EnvironmentPresentation) {  if (environment.entry.target._tag === "PrimaryConnectionTarget") return MonitorIcon;  if (environment.entry.target._tag === "RelayConnectionTarget") return CloudIcon;  if (environment.entry.target._tag === "SshConnectionTarget") return TerminalIcon;  if (isDesktopLocalConnectionTarget(environment.entry.target)) return LaptopIcon;  return CloudIcon;} function providerEnvironmentDetail(environment: EnvironmentPresentation): string {  if (environment.entry.target._tag === "PrimaryConnectionTarget") return "Primary device";  if (environment.relayManaged) return "T3 Connect";  if (environment.entry.target._tag === "SshConnectionTarget") return "SSH";  if (isDesktopLocalConnectionTarget(environment.entry.target)) return "Local device";  return environment.displayUrl ?? "Remote device";} function EnvironmentUnavailableRow({  environment,  access,}: {  readonly environment: EnvironmentPresentation;  readonly access: Exclude<ProviderEnvironmentAccess, { kind: "editable" | "read-only" }>;}) {  const isLoading = access.kind === "loading";  const title = isLoading    ? "Loading provider settings"    : access.kind === "error"      ? "Could not connect to this device"      : "Provider settings are unavailable";  const description = isLoading    ? access.reason === "permissions"      ? "Checking what this session is allowed to change."      : `Waiting for ${environment.label}'s configuration.`    : connectionStatusText(environment.connection);  // No spinner: this state can persist indefinitely for a wedged device, and a  // continuously repainting animation would run the whole time.  return (    <SettingsSection title="Providers">      <SettingsRow title={title} description={description} />    </SettingsSection>  );} export function ProviderSettingsPanel() {  const { environments, isReady } = useEnvironments();  const primaryEnvironmentId = usePrimaryEnvironmentId();  const options = useMemo(    () => buildProviderEnvironmentOptions(environments, primaryEnvironmentId),    [environments, primaryEnvironmentId],  );  // Raw user intent; the effective selection is re-derived every render so a  // device that drops out of the catalog falls back without erasing the pick —  // if it reappears (e.g. after a reconnect) the selection is restored.  const [selectedEnvironmentId, setSelectedEnvironmentId] = useState<EnvironmentId | null>(    primaryEnvironmentId,  );  const effectiveEnvironmentId = resolveSelectedProviderEnvironmentId(    options,    selectedEnvironmentId,    primaryEnvironmentId,  );  const selectedEnvironment =    options.find((environment) => environment.environmentId === effectiveEnvironmentId) ?? null;  const onlyPrimaryDevice =    options.length === 1 && options[0]?.entry.target._tag === "PrimaryConnectionTarget";   return (    <SettingsPageContainer>      {!onlyPrimaryDevice ? (        <SettingsSection title="Devices">          {options.length === 0 ? (            // The catalog hydrates asynchronously, so an empty list before it is            // ready means "not loaded yet", not "nothing is connected".            <SettingsRow              title={isReady ? "No connected devices" : "Loading devices"}              description={                isReady                  ? "Connect an execution environment before configuring providers."                  : "Reading connected execution environments."              }            />          ) : (            <div className="grid gap-1 sm:grid-cols-2">              {options.map((environment) => {                const Icon = providerEnvironmentIcon(environment);                const selected = environment.environmentId === effectiveEnvironmentId;                const statusText = connectionStatusText(environment.connection);                return (                  <button                    key={environment.environmentId}                    type="button"                    aria-pressed={selected}                    className={cn(                      "flex min-w-0 items-center gap-3 rounded-xl px-3 py-2.5 text-left transition-colors sm:px-4",                      selected                        ? "bg-primary/8 ring-1 ring-primary/25 dark:bg-primary/12"                        : "hover:bg-muted/40",                    )}                    onClick={() => setSelectedEnvironmentId(environment.environmentId)}                  >                    <span className="flex size-8 shrink-0 items-center justify-center rounded-lg border border-border/60 bg-background text-muted-foreground">                      <Icon className="size-4" aria-hidden />                    </span>                    <span className="min-w-0 flex-1">                      <span className="flex items-center gap-1.5">                        <ConnectionStatusDot                          tooltipText={statusText}                          dotClassName={connectionPhaseDotClassName(environment.connection.phase)}                          pingClassName={connectionPhasePingClassName(environment.connection.phase)}                        />                        <span className="truncate text-sm font-medium text-foreground">                          {environment.label}                        </span>                      </span>                      <span className="block truncate pl-[18px] text-xs text-muted-foreground">                        {providerEnvironmentDetail(environment)} · {statusText}                      </span>                    </span>                  </button>                );              })}            </div>          )}        </SettingsSection>      ) : null}       {selectedEnvironment ? (        <SelectedEnvironmentProviderSettings          key={selectedEnvironment.environmentId}          environment={selectedEnvironment}        />      ) : null}    </SettingsPageContainer>  );} function SelectedEnvironmentProviderSettings({  environment,}: {  readonly environment: EnvironmentPresentation;}) {  const isPrimary = environment.entry.target._tag === "PrimaryConnectionTarget";  if (isPrimary) {    // The desktop app owns its primary server outright; a browser session    // checks the scopes its cookie session was granted.    if (isElectron) {      return <AccessGatedProviderSettings environment={environment} operateAccess="granted" />;    }    return <PrimarySessionGatedProviderSettings environment={environment} />;  }  return <RemoteSessionGatedProviderSettings environment={environment} />;} function PrimarySessionGatedProviderSettings({  environment,}: {  readonly environment: EnvironmentPresentation;}) {  const primarySessionState = usePrimarySessionState();  const operateAccess = resolvePrimaryOperateAccess({    isPrimary: true,    hasDesktopBridge: false,    session: primarySessionState.data,    isPending: primarySessionState.isPending,    hasError: primarySessionState.error !== null,  });  return <AccessGatedProviderSettings environment={environment} operateAccess={operateAccess} />;} function RemoteSessionGatedProviderSettings({  environment,}: {  readonly environment: EnvironmentPresentation;}) {  const sessionState = useEnvironmentSessionState(environment.environmentId);  const operateAccess = resolveRemoteOperateAccess({    session: sessionState.data,    isPending: sessionState.isPending,    hasError: sessionState.hasError,  });  return <AccessGatedProviderSettings environment={environment} operateAccess={operateAccess} />;} function AccessGatedProviderSettings({  environment,  operateAccess,}: {  readonly environment: EnvironmentPresentation;  readonly operateAccess: ProviderOperateAccess;}) {  const access = classifyProviderEnvironmentAccess({    connectionPhase: environment.connection.phase,    hasServerConfig: environment.serverConfig !== null,    operateAccess,  });  if (access.kind !== "editable" && access.kind !== "read-only") {    return <EnvironmentUnavailableRow environment={environment} access={access} />;  }  return (    <EnvironmentProviderSettings      environmentId={environment.environmentId}      environmentLabel={environment.label}      readOnly={access.kind === "read-only"}    />  );} export function EnvironmentProviderSettings({  environmentId,  environmentLabel,  readOnly = false,}: {  readonly environmentId: EnvironmentId;  readonly environmentLabel: string;  /**   * Render the full provider layout, greyed out and inert, when this session's   * credential lacks `orchestration:operate` on the environment. Showing the   * real configuration keeps the view honest; disabling interaction keeps   * every one of its writes from being offered and then rejected.   */  readonly readOnly?: boolean;}) {  const settings = useEnvironmentSettings(environmentId);  const updateSettings = useUpdateEnvironmentSettings(environmentId);  const serverProviders =    useAtomValue(serverEnvironment.providersValueAtom(environmentId)) ?? EMPTY_SERVER_PROVIDERS;  const refreshServerProviders = useAtomCommand(serverEnvironment.refreshProviders, {    reportFailure: false,  });  const updateProvider = useAtomCommand(serverEnvironment.updateProvider, {    reportFailure: false,  });  const [isRefreshingProviders, setIsRefreshingProviders] = useState(false);  const [isAddInstanceDialogOpen, setIsAddInstanceDialogOpen] = useState(false);  const [updatingProviderDrivers, setUpdatingProviderDrivers] = useState<    ReadonlySet<ProviderDriverKind>  >(() => new Set());  const [openInstanceDetails, setOpenInstanceDetails] = useState<Record<string, boolean>>({});  const refreshingRef = useRef(false);  const updatingDriversRef = useRef<Set<ProviderDriverKind>>(new Set());   const providerUpdateCandidates = useMemo(    () => collectProviderUpdateCandidates(serverProviders),    [serverProviders],  );  const providerUpdateCandidateByInstanceId = useMemo(    () => new Map(providerUpdateCandidates.map((candidate) => [candidate.instanceId, candidate])),    [providerUpdateCandidates],  );  const visibleProviderSettings = PROVIDER_SETTINGS.filter(    (providerSettings) =>      providerSettings.provider !== "cursor" ||      serverProviders.some(        (provider) =>          provider.instanceId === defaultInstanceIdForDriver(ProviderDriverKind.make("cursor")),      ),  );  const textGenerationModelSelection = resolveAppModelSelectionState(settings, serverProviders);  const textGenInstanceId = textGenerationModelSelection.instanceId;  const resolvedBackgroundActivity = resolveServerBackgroundActivitySettings(settings);  const providerHealthPreset = getBackgroundActivityPresetSettings(    resolvedBackgroundActivity.profile,  ).providerHealthRefreshInterval;  const providerHealthRefreshIntervalSeconds = durationToSeconds(    resolvedBackgroundActivity.providerHealthRefreshInterval,  );  const defaultProviderHealthRefreshIntervalSeconds = durationToSeconds(providerHealthPreset);  const lastCheckedAt =    serverProviders.length > 0      ? serverProviders.reduce(          (latest, provider) => (provider.checkedAt > latest ? provider.checkedAt : latest),          serverProviders[0]!.checkedAt,        )      : null;   const refreshProviders = useCallback(() => {    if (refreshingRef.current) return;    refreshingRef.current = true;    setIsRefreshingProviders(true);    void (async () => {      const result = await refreshServerProviders({        environmentId,        input: {},      });      refreshingRef.current = false;      setIsRefreshingProviders(false);      if (result._tag === "Failure" && !isAtomCommandInterrupted(result)) {        console.warn("Failed to refresh providers", {          operation: "refresh-providers",          environmentId,          ...safeErrorLogAttributes(squashAtomCommandFailure(result)),        });      }    })();  }, [environmentId, refreshServerProviders]);   const runProviderUpdate = useCallback(    async (candidate: ProviderUpdateCandidate) => {      // Ref-based re-entry guard, mirroring refreshProviders: a state updater      // may run after this function returns, so it cannot gate the dispatch.      if (updatingDriversRef.current.has(candidate.driver)) {        return;      }      updatingDriversRef.current.add(candidate.driver);      setUpdatingProviderDrivers((previous) => new Set(previous).add(candidate.driver));       const result = await updateProvider({        environmentId,        input: {          provider: candidate.driver,          instanceId: candidate.instanceId,        },      });      if (result._tag === "Failure" && !isAtomCommandInterrupted(result)) {        const error = squashAtomCommandFailure(result);        toastManager.add(          stackedThreadToast({            type: "error",            title: `Could not update ${PROVIDER_DISPLAY_NAMES[candidate.driver] ?? candidate.driver}`,            description:              error instanceof Error                ? error.message                : "The provider update command could not be started.",          }),        );      }      updatingDriversRef.current.delete(candidate.driver);      setUpdatingProviderDrivers((previous) => {        if (!previous.has(candidate.driver)) {          return previous;        }        const next = new Set(previous);        next.delete(candidate.driver);        return next;      });    },    [environmentId, updateProvider],  );   interface InstanceRow {    readonly instanceId: ProviderInstanceId;    readonly instance: ProviderInstanceConfig;    readonly driver: ProviderDriverKind;    readonly isDefault: boolean;    readonly isDirty?: boolean;  }   const instancesByDriver = new Map<    ProviderDriverKind,    Array<[ProviderInstanceId, ProviderInstanceConfig]>  >();  for (const [rawId, instance] of Object.entries(settings.providerInstances ?? {})) {

Lines 1–500 of 909.