Jump to content

Connect SuperML | Leeroopedia MCP: Equip your AI agents with best practices, code verification, and debugging knowledge. Powered by Leeroo — building Organizational Superintelligence. Contact us at founders@leeroo.com.

Implementation:Microsoft Autogen Studio UI Settings

From Leeroopedia
Sources https://github.com/microsoft/autogen/blob/main/python/packages/autogen-studio/frontend/src/components/views/settings/view/ui.tsx
Domains React Component, Settings Management, UI Preferences, Toggle Controls
Last Updated 2026-02-11

Overview

The UISettingsPanel component provides a form interface for configuring AutoGen Studio's UI behavior preferences including message display, agent flow visualization, and timeout settings.

Description

The UISettingsPanel is a settings configuration component that manages four key UI preferences for the AutoGen Studio chat interface. It implements a clean, accessible settings form with custom toggle switches and number inputs.

Key architectural features:

  • Local state management: Maintains a local copy of UI settings that syncs with the global store
  • Dirty state tracking: Visual indicators (red dot on Save button) show unsaved changes
  • Reset functionality: One-click reset to default settings with server persistence
  • Responsive controls: Custom SettingToggle and SettingNumberInput components with hover effects
  • Validation: Number input constrains values to valid ranges (1-30 minutes for timeout)
  • Optimistic updates: Immediate UI feedback before server confirmation

The component uses two custom sub-components:

  1. SettingToggle: A custom switch component with label, description, and accessibility features
  2. SettingNumberInput: A bounded numeric input with optional suffix display

Settings managed:

  • show_llm_call_events: Display detailed LLM call logs in message threads
  • expanded_messages_by_default: Auto-expand message threads on load
  • show_agent_flow_by_default: Display agent flow diagram automatically
  • human_input_timeout_minutes: Timeout duration for waiting on user input (1-30 minutes)

Data flow: Store settings → Local state → User changes → Dirty flag → Save/Reset → API call → Server update → Store refresh → Local state update

Usage

The component is rendered within a settings page, typically in a tab alongside environment variables and other configuration panels. It requires:

  • userId: The authenticated user ID for API operations

The component self-manages its connection to the settings store via the useSettingsStore hook, pulling serverSettings and uiSettings from global state.

Code Reference

Source Location: python/packages/autogen-studio/frontend/src/components/views/settings/view/ui.tsx

Signature:

interface UISettingsPanelProps {
  userId: string;
}

export const UISettingsPanel: React.FC<UISettingsPanelProps> = ({ userId }) => {
  const {
    serverSettings,
    uiSettings: storeUISettings,
    initializeSettings,
  } = useSettingsStore();

  const [localUISettings, setLocalUISettings] = useState<UISettings>({
    show_llm_call_events: false,
    expanded_messages_by_default: false,
    show_agent_flow_by_default: false,
    human_input_timeout_minutes: 3,
  });

  const [isDirty, setIsDirty] = useState(false);
  const [isSaving, setIsSaving] = useState(false);
  const [messageApi, contextHolder] = message.useMessage();

  // ... handlers

  return (
    <div>
      <div className="flex justify-between items-center mb-4">
        <h3 className="text-lg font-medium">UI Settings</h3>
        <div className="space-x-2 inline-flex">
          <Button icon={<RotateCcw />} onClick={handleReset}>Reset</Button>
          <Button type="primary" icon={<Save />} onClick={handleSave}>Save</Button>
        </div>
      </div>
      <div className="space-y-0 rounded border border-secondary">
        <SettingToggle ... />
        <SettingToggle ... />
        <SettingToggle ... />
        <SettingNumberInput ... />
      </div>
    </div>
  );
};

interface SettingToggleProps {
  checked: boolean;
  onChange: (checked: boolean) => void;
  label: string;
  description?: string;
  disabled?: boolean;
}

const SettingToggle: React.FC<SettingToggleProps> = ({ ... }) => (
  <div className="flex justify-between items-start p-4 hover:bg-secondary/5">
    <div className="flex flex-col gap-1">
      <label className="font-medium">{label}</label>
      {description && <span className="text-sm text-secondary">{description}</span>}
    </div>
    <input type="checkbox" ... />
  </div>
);

interface SettingNumberInputProps {
  value: number;
  onChange: (value: number) => void;
  label: string;
  description?: string;
  disabled?: boolean;
  min?: number;
  max?: number;
  suffix?: string;
}

const SettingNumberInput: React.FC<SettingNumberInputProps> = ({ ... }) => (
  <div className="flex justify-between items-start p-4">
    <div className="flex flex-col gap-1">
      <label className="font-medium">{label}</label>
      {description && <span className="text-sm text-secondary">{description}</span>}
    </div>
    <div className="flex items-center gap-2">
      <input type="number" min={min} max={max} ... />
      {suffix && <span className="text-sm text-secondary">{suffix}</span>}
    </div>
  </div>
);

Import:

import { UISettingsPanel } from "./components/views/settings/view/ui";
// or
import UISettingsPanel from "./components/views/settings/view/ui";

I/O Contract

Props

Name Type Required Description
userId string Yes Authenticated user ID for API operations

Outputs

Type Description
JSX.Element Renders a settings form with toggles and number inputs for UI preferences

UISettings Type

interface UISettings {
  show_llm_call_events: boolean;
  expanded_messages_by_default: boolean;
  show_agent_flow_by_default: boolean;
  human_input_timeout_minutes: number;
}

Default Settings

const DEFAULT_UI_SETTINGS: UISettings = {
  show_llm_call_events: false,
  expanded_messages_by_default: false,
  show_agent_flow_by_default: false,
  human_input_timeout_minutes: 3,
};

State Management

State Variable Type Description
localUISettings UISettings Local working copy of UI settings
isDirty boolean Tracks whether unsaved changes exist
isSaving boolean Loading state during save/reset operations
messageApi MessageInstance Ant Design message API for toast notifications

Store Dependencies

Store Method/Property Description
serverSettings Complete Settings object from server
uiSettings Current UI settings from store (subset of serverSettings.config.ui)
initializeSettings(userId) Fetches latest settings from server and updates store

API Interactions

Method When Called Description
settingsAPI.updateSettings(settings, userId) handleSave() or handleReset() Persists settings to server

Usage Examples

Example 1: Basic Integration

import { UISettingsPanel } from "./components/views/settings/view/ui";
import { useContext } from "react";
import { appContext } from "./hooks/provider";

function SettingsPage() {
  const { user } = useContext(appContext);

  return (
    <div className="p-6">
      <UISettingsPanel userId={user.id} />
    </div>
  );
}

Example 2: Toggle Change Flow

// User clicks "Show LLM Events" toggle
// SettingToggle calls: onChange(true)
// Triggers: handleSettingChange("show_llm_call_events", true)

const handleSettingChange = (key: keyof UISettings, value: boolean | number) => {
  setLocalUISettings(prev => ({
    ...prev,
    [key]: value,  // Updates local state
  }));
  setIsDirty(true);  // Shows red dot on Save button
};

// Local state is updated immediately for responsive UI
// Changes are NOT persisted until user clicks Save

Example 3: Number Input with Validation

// SettingNumberInput for human_input_timeout_minutes:
<SettingNumberInput
  value={localUISettings.human_input_timeout_minutes ?? 3}
  onChange={(value) => handleSettingChange("human_input_timeout_minutes", value)}
  label="Human Input Timeout"
  description="How long to wait for user input before timing out (1-30 minutes)"
  min={1}
  max={30}
  suffix="minutes"
/>

// onChange handler:
onChange={(e) => {
  const newValue = parseInt(e.target.value);
  if (!isNaN(newValue) && newValue >= min && newValue <= max) {
    onChange(newValue);  // Only calls parent if valid
  }
}}

// Invalid entries (outside 1-30 range) are silently ignored
// HTML5 min/max attributes provide additional validation

Example 4: Saving Settings

// User clicks "Save" button (enabled when isDirty=true)
// Triggers: handleSave()

const handleSave = async () => {
  setIsSaving(true);  // Disables buttons, shows loading spinner

  // Merge local UI settings with server settings:
  const updatedSettings: Settings = {
    ...serverSettings,
    config: {
      ...serverSettings.config,
      ui: localUISettings,  // Replace UI config
    },
    created_at: undefined,  // Remove timestamps
    updated_at: undefined,  // API will set these
  };

  // Persist to server:
  await settingsAPI.updateSettings(updatedSettings, userId);

  // Refresh from server (ensures sync):
  await initializeSettings(userId);

  // Reset flags:
  setIsDirty(false);
  setIsSaving(false);
  messageApi.success("UI settings saved successfully");
};

Example 5: Reset to Defaults

// User clicks "Reset" button
// Triggers: handleReset()

const handleReset = async () => {
  setIsSaving(true);

  const DEFAULT_UI_SETTINGS: UISettings = {
    show_llm_call_events: false,
    expanded_messages_by_default: false,
    show_agent_flow_by_default: false,
    human_input_timeout_minutes: 3,
  };

  // Update local state immediately for responsive UI:
  setLocalUISettings(DEFAULT_UI_SETTINGS);

  // Prepare settings update:
  const updatedSettings: Settings = {
    ...serverSettings,
    config: {
      ...serverSettings.config,
      ui: DEFAULT_UI_SETTINGS,
    },
    created_at: undefined,
    updated_at: undefined,
  };

  // Persist to server:
  await settingsAPI.updateSettings(updatedSettings, userId);
  await initializeSettings(userId);

  setIsDirty(false);
  setIsSaving(false);
  messageApi.success("UI settings reset successfully");
};

Example 6: Store Synchronization

// On mount and whenever store settings change:
useEffect(() => {
  setLocalUISettings(storeUISettings);
}, [storeUISettings]);

// This ensures local state stays in sync with:
// - Initial load from server
// - Changes from other components
// - Refresh after save/reset

// Settings flow:
// Server → Store → Local state → User edits → Local state → Server → Store → Local state

Example 7: Custom Toggle Component Accessibility

// SettingToggle implements accessible checkbox pattern:

<input
  type="checkbox"
  checked={checked}
  onChange={(e) => onChange(e.target.checked)}
  disabled={disabled}
  className="sr-only"  // Visually hidden but screen-reader accessible
  id={`toggle-${label.replace(/\s+/g, "-").toLowerCase()}`}
/>
<label
  htmlFor={`toggle-${label.replace(/\s+/g, "-").toLowerCase()}`}
  className={`... cursor-pointer ${checked ? "bg-accent" : "bg-gray-300"}`}
>
  <span className={`... ${checked ? "translate-x-6" : "translate-x-1"}`} />
</label>

// Clicking the visible label triggers the hidden checkbox
// Keyboard navigation works (Tab to focus, Space to toggle)
// Screen readers announce "checkbox, [label], [checked/unchecked]"

Example 8: Effect on Chat Interface

// Settings are consumed by ChatView and related components:

// show_llm_call_events:
if (uiSettings.show_llm_call_events) {
  // Display LLMCallEvent messages in thread
  // Show token counts, model info, latency
}

// expanded_messages_by_default:
const [isExpanded, setIsExpanded] = useState(
  uiSettings.expanded_messages_by_default ?? false
);

// show_agent_flow_by_default:
const [showAgentFlow, setShowAgentFlow] = useState(
  uiSettings.show_agent_flow_by_default ?? false
);

// human_input_timeout_minutes:
const timeoutMs = (uiSettings.human_input_timeout_minutes ?? 3) * 60 * 1000;
setTimeout(() => {
  // Cancel waiting for human input
}, timeoutMs);

Related Pages

Page Connections

Double-click a node to navigate. Hold to expand connections.
Principle
Implementation
Heuristic
Environment