Technical docs
Settings
Overview
Support reference for personal settings at `/settings` and organization settings at `/org-settings`.
Shared settings shell
- Personal and organization settings use the same full-height, scrollable settings shell.
- The visible content does not repeat the former large page title and description. A hidden `Settings` heading remains available to assistive technology.
- Organization settings add a compact, horizontally scrollable route navigation control above the content.
Personal settings
Routes
- `/settings` is the unified personal settings page.
- Legacy routes redirect to `/settings`:
- `/settings/appearance`
- `/settings/connectedAccounts`
Connected accounts
- Section title: `Connected accounts`
- Description: `Manage external accounts linked to your profile.`
- Accounts shown:
- `Gmail`
- `Telegram`
- Gmail reflects the current Google-linked profile and is display-only on this page.
- Telegram behavior:
- an unlinked account shows `Connect`
- a linked account shows its identifier and `Disconnect`
- the identifier prefers `@username`, then linked name, then the Telegram account ID
- disconnect requires confirmation in a `Disconnect Telegram` dialog
- Connecting Telegram starts with `GET /api/auth/telegram` and redirects to the returned authorization URL.
- Disconnecting uses `DELETE /api/auth/telegram`, refreshes the current user from the returned payload, and reports `Telegram account disconnected`.
Language
- Section title: `Language`
- Description: `Choose interface language.`
- Choices:
- `Automatic`
- `English`
- `Russian`
- `Spanish`
- `Ukrainian`
- `Serbian`
- `Kazakh`
- `Romanian`
- `Automatic` uses the browser's preferred language and falls back to English when that language is unsupported.
Appearance
- Theme choices:
- `Light`
- `Latte`
- `Dark`
- `Dark Blue`
- `System`
- Theme selection applies immediately.
- `Full-width AI responses` controls internal-chat presentation:
- enabled: AI responses use the full chat width
- disabled: AI responses use bubbles
- `Hide admin sidebar items` hides the built-in main sidebar links below organization-defined custom links, including regular, admin, and developer tiers. Custom links and top/bottom sidebar controls remain visible. This is a personal browser-local preference, not an organization-wide permission change; it is saved in browser storage and synchronized across open tabs. If browser storage is unavailable, it lasts only for the current session.
Organization settings routes
- `/org-settings` redirects to `/org-settings/organization`.
- Navigation items:
- `Organization`
- `AI Providers`
- `AI Models`
- `Webchat`
- `Navigation`
- `Proxy`
- `AI Providers`, `AI Models`, `Webchat`, `Navigation`, and `Proxy` are visible only to org admins, owners, and developer users who pass the org-admin access check. Direct visits by other users render `AccessDenied`. Model-management API writes independently require organization admin access.
- The organization shell no longer contains the interface-language picker. Language is managed on `/settings`.
- Organization settings tabs share these initial states:
- centered `Loading` indicator while required data loads
- `Failed to load data` with `Retry` when initial loading fails
- `No organization selected` when organization context is unavailable
- Data loaded for a previous organization is discarded when the active organization changes.
Navigation
- Route: `/org-settings/navigation`. Organization owners and admins can customize links shown to everyone in the organization's sidebar. Other members can read links but cannot manage them. AI-initiated navigation actions apply the same read/manage authorization: management requires an initiating owner or admin, and requests without an authorized initiating user are denied.
- `Add item` and `Edit` set a title (up to 80 characters), icon, internal `/path` or HTTP(S) URL, `Open in a new tab`, `Show in sidebar`, and `Use as home page`. URLs with credentials are rejected. The list can be reordered by dragging or keyboard, disabled without deleting, and removed with confirmation. Changes propagate to open clients.
- Only one item can be the home page at a time. Home must point to an internal app page other than `/`, `/login`, or `/logout`; choosing another item clears the previous Home designation. A `Home` badge identifies the configured item. A disabled Home item is not used as the landing destination.
Proxy
- Route: `/org-settings/proxy`. Organization owners and admins can list, add, edit, turn on/off, and delete outbound proxies. An active proxy appears above `Other proxies`; only one can be active at a time. Turning one off or deleting an active proxy returns covered requests to direct connections.
- `Add proxy` and `Edit proxy` accept a name (up to 80 characters), protocol (`HTTP`, `HTTPS`, or `SOCKS5`), hostname or IP address without a URL scheme/path, port (1–65535), and optional username/password. An edit never displays the saved password; leave its field blank to keep it, or clear the username to remove it. The UI offers `Block requests` (default) or `Send directly` if the proxy is unavailable. Direct fallback applies to recognized connection/proxy failures, not arbitrary errors after a request may have reached its destination. A hosted deployment requires a publicly reachable proxy address; customer-hosted deployments may permit private-network proxy addresses when configured.
- Covered traffic includes supported LLM, speech-to-text, and text-to-speech calls on the organization's own provider keys and Telegram, Slack, and Microsoft Teams channel traffic. Calls on Alloy keys, realtime voice, and other unrelated traffic continue directly. When using HTTPS to the proxy, it can observe destinations, timing, and volume, but not encrypted content.
- Authenticated admin routes: `GET`/`POST /api/organizations/{organization_id}/proxies` to list/create; `PATCH`/`DELETE /api/organizations/{organization_id}/proxies/{organization_proxy_id}` to edit/delete; `POST` on that item with `/activate` or `/deactivate` to switch it on or off. Creation starts inactive. Responses provide `has_password` rather than the saved password. These routes are not available through the general AI organization-action tool.
Organization
- Route: `/org-settings/organization`
- Main content uses a responsive two-column card layout.
General information
- Card title: `General Information`
- Description: `Basic details about your organization`
- Fields:
- `Organization`
- `Base LLM`
- `Base LLM` lists non-realtime, non-TTS, non-STT text models from the shared model catalog.
- `Auto` clears the organization default model.
- The general Save action updates organization name and base model together.
- An empty organization name cannot be saved.
- When an AI teammate or Ally has no explicit model, runtime resolution tries the organization base model before the system fallback model.
AI teammate spending limit
- The separate `AI teammate spending limit` card applies one optional daily model-spending limit independently to every AI teammate.
- The input uses a `$` prefix and accessible label `Daily limit`.
- Valid configured values start at `$0.01` and allow at most two decimal places.
- `Remove daily limit` clears the draft to restore unlimited usage after Save.
- This card has its own Save action and reports `Daily spending limit updated` or `Failed to update daily spending limit`.
- Organization owners and admins can edit the limit. Other members see it read-only. Developer access alone does not grant edit permission.
- Route: `PUT /api/organizations/{organization_id}/ai-employee-daily-cost-limit`
- Body: `{ ai_employee_daily_cost_limit_usd: number | null }`
- The allowance resets at `00:00 UTC`. Changing or removing the limit applies immediately to usage accumulated during the current UTC day.
Debug Mode
- `Debug Mode` is an immediate-save switch.
- Description: `Enable debug mode for additional logging and diagnostics`
- Success feedback is `Debug mode enabled` or `Debug mode disabled`.
Lazy Tools
- `Lazy Tools` is an immediate-save switch.
- Description: `Load agent tools on demand instead of sending the whole tool list in every request`
- It defaults to enabled.
- When enabled, non-eager built-in and assigned MCP/OAuth tools load on demand. When disabled, those tools are exposed directly to the model.
- Feedback is `Lazy tools enabled`, `Lazy tools disabled`, or `Failed to update lazy tools`.
Auto Compacting
- `Auto Compacting` is an immediate-save switch backed by `is_auto_compacting_enabled` and defaults to disabled.
- Description: `Let agents summarise and archive their own conversation history once it outgrows the context window`
- When enabled, Alloy summarizes older conversation context after runtime limits are crossed while keeping recent messages verbatim. Summarization model usage is recorded as normal attributable usage.
- If summarization fails, Alloy keeps and sends the original history rather than dropping it.
- Feedback is `Auto compacting enabled`, `Auto compacting disabled`, or `Failed to update auto compacting`.
Organization Slack connection
- The `Slack` card manages the organization-wide Slack app used by Personal Ally.
- Description: `Interact with Ally directly in Slack`
- All organization members can see current connection information. Connect, reconnect, and disconnect require organization-admin access in both UI and backend.
- Controls:
- disconnected: `Connect`
- invalid: `Reconnect`
- active: `Disconnect`
- Active connections can show workspace name and ID, installer identity, and connection date.
- Disconnect requires entering the exact confirmation text `disconnect`.
- A successful OAuth callback returns to `/org-settings/organization?slack=connected`, reports `Connected`, and removes callback parameters from the URL.
- Connection state updates through `organization_channel_connection.updated`.
- API routes:
- `GET /api/organizations/{orgId}/slack`
- `POST /api/organizations/{orgId}/slack/oauth/start`
- `POST /api/slack/oauth/callback`
- `DELETE /api/organizations/{orgId}/slack`
Alloy API keys
- Authorized organization editors see the brand-specific API key card.
- Rows:
- `Public`
- `Private`
- The public key is displayed and can be copied.
- The private key remains masked and is fetched only when its copy action is used.
Organization data flow and permissions
- General and immediate-save settings use `PUT /api/organizations/{id}`.
- Supported page fields are `name`, `ai_default_model`, `is_debug_mode`, `use_lazy_tools`, and `is_auto_compacting_enabled`.
- The backend validates a non-null model against the model catalog and requires the lazy-tools and auto-compacting flags to be boolean.
- General editing is enabled for owners/admins and developer users through the frontend org-admin access helper. The backend independently rejects non-admin organization members.
- Organization state refreshes through `organization.updated`; reached daily-limit transitions use `ai_employee.updated`.
- Initial page rendering waits for both the model catalog and Slack connection state. `Retry` reloads both after an initial failure.
- A later model refetch failure reports `Failed to load AI models` without replacing already loaded settings content.
AI Models
- Route: `/org-settings/ai-models`; nav label: `AI Models`.
- Admins add their own OpenAI-compatible endpoint models, edit them, and remove them. These models appear beside Alloy models to AI teammates and workflow steps. Reusing a system alias makes the organization's model take precedence for this organization; deleting it falls back to the system model when available.
- Model configuration has a name, alias, endpoint model identifier, HTTP(S) API URL, API token, image-input option, and optional per-million-token cost fields. A saved token is not displayed; leaving the edit field empty preserves it. Calls using the model's own endpoint/token do not spend Alloy tokens. See `models-and-voices.md` for validation, access, and API routes.
AI Providers
- Route: `/org-settings/api-keys`
- Nav label: `AI Providers`
- Main layout:
- `Provider API Keys`
- `Custom provider`
- `OpenAI Codex`
- Initial provider and Codex state is loaded before the cards render. Failure shows `Failed to load data` with `Retry`.
Manual provider keys
- Provider rows:
- `OpenAI`
- `OpenRouter`
- `Google`
- `DeepSeek`
- `Anthropic`
- Saved keys use a masked prefix/suffix preview and cannot be copied from the UI.
- Saving or clearing uses `PATCH /api/organizations/{id}/providers/{provider}` with `{ api_key: "<key>" }` or `{ api_key: null }`.
- Provider rows stay in sync through `organization_ai_provider.updated`.
Custom provider
- This is an organization-scoped OpenAI-compatible provider.
- Fields:
- `API key`
- `Base URL`
- The Base URL helper asks for the API root including any required version path and gives an example such as `https://api.example.com/v1`.
- Both fields are required before Save becomes available.
- After Save, the key uses a masked preview and the Base URL becomes read-only.
- `Reset` clears both values. The reset toast offers `Undo` for the current five-minute restore window.
OpenAI Codex
- States:
- `Connect`
- authorization with copyable `Code`, countdown, and `Open authorization page`
- active connection with `Disconnect` plus a `Details` hover card showing the Codex account `User name`, `Email`, `Connected by`, and `Connected on`
- `Disconnect` opens a `Disconnect OpenAI Codex?` confirmation dialog before revoking the connection.
- Device authorization lasts 15 minutes. The UI countdown starts from backend `remaining_seconds`, while expiration checks and polling use database time.
- Connection attempts and provider state update in real time.
- Routes:
- `POST /api/organizations/{id}/providers/codex/connection-attempts`
- `GET /api/organizations/{id}/providers/codex/connection-attempts/current`
- `POST /api/organizations/{id}/providers/codex/revoke`
Provider runtime behavior
- Runtime uses a matching active organization provider credential before the system credential for the same provider.
- Usage with organization credentials is still recorded for usage and cost reporting but does not reduce organization `available_tokens`.
- The page listens to `organization.updated`, `organization_ai_provider.updated`, and `organization_ai_provider_connection_attempt.updated`.
Webchat
- Route: `/org-settings/webchat`
- Initial loading fetches widget settings and the first webchat trigger together.
- Failure shows `Failed to load data` with `Retry`.
- Main layout uses a scrollable settings form plus `Live Preview`.
- Theme choices:
- `System`
- `Light`
- `Dark`
- `Custom`
- `System` mode has Light and Dark editing tabs.
- Color sections:
- `Minimized widget`: `Bubble color`, `Icon color`
- `Maximized widget`: `Chat background`, `Primary color`
- `Message colors`: `Customer bubble color`, `Customer text color`, `Agent bubble color`, `Agent text color`
- Each color control provides a visual picker, text value, and field-level reset.
- `Custom` mode exposes `Custom CSS` and warns that it overrides the other settings.
- Footer actions:
- `Reset to defaults`
- `Save changes`
- Backend values:
- `mode`: `system`, `light`, `dark`, `custom`
- `widgetDomain`: `default`, `proxy`
- API routes:
- `GET /api/organizations/{id}/settings/webchat-widget-settings`
- `POST /api/organizations/{id}/settings/webchat-widget-settings`
- Reset to defaults sends an empty POST body.
- Defaults can also contain runtime fields not currently editable here: `opacity`, `primaryTextColor`, `secondaryTextColor`, `borderColor`, and `systemMessageColor`.
- The preview loads the widget script, initializes it with the organization public key and first webchat trigger ID, and destroys it when leaving the page.
Not in these settings shells
- The developer-only system `Models` and `Voices` tools are separate from organization settings; the organization's own `AI Models` page is under `/org-settings/ai-models`.
- `/defaults` is the separate developer-only system defaults page.