diff --git a/content/docs/features/access_control.mdx b/content/docs/features/access_control.mdx index f3cb6483b..b10261506 100644 --- a/content/docs/features/access_control.mdx +++ b/content/docs/features/access_control.mdx @@ -1,22 +1,15 @@ --- title: Access Control icon: ShieldCheck -description: LibreChat's granular authorization system - control who can use, share, edit, and manage agents, prompts, MCP servers, and other resources at the user, group, role, and instance level. +description: "LibreChat's granular authorization system: control who can use, share, edit, and manage agents, prompts, MCP servers, and other resources at the user, group, role, and instance level." --- # Granular Access Control -LibreChat ships with a full authorization system on top of authentication. Access is not "all-or-nothing": every shareable entity in the app (agents, prompts, MCP servers, remote agents, files, conversations) has its own Access Control List (ACL), and every feature can be independently enabled or restricted per **user**, **group**, **role**, or **publicly**. +LibreChat ships with a full authorization system on top of authentication. Access is not "all-or-nothing": every shareable entity in the app (agents, prompts, MCP servers, remote agents, skills, code environments, shared links) has its own Access Control List (ACL), and every feature can be independently enabled or restricted per **user**, **group**, **role**, or **publicly**. This page explains how the pieces fit together so you can model permissions to match your organization, from a small team where everyone shares freely, to an enterprise deployment with sync'd Entra ID groups, custom roles, and delegated admins. - - A dedicated [**LibreChat Admin Panel**](/docs/features/admin_panel) is the upcoming UI for - managing users, groups, roles, custom permission profiles, and system-wide grants introduced in - [v0.8.5](/changelog/v0.8.5). This page documents the underlying model, which is available today in - LibreChat itself. - - ## The Access Model at a Glance LibreChat's authorization has three independent layers that compose together: @@ -106,12 +99,12 @@ Resource ACLs currently apply to: - **MCP Servers** (`mcpServer`) - **Skills** (`skill`), see [Skills](/docs/features/skills) - **Remote Agents** (`remoteAgent`), for the [Agents API](/docs/features/agents_api) -- **Files** (`file`), typically inherited from the resource that uses them -- **Projects** (`project`), supports inheritance so resources shared to a project automatically inherit ACLs +- **Code Environments** (`codeEnvironment`), for deployment-owned code workers; see [Code Interpreter](/docs/features/code_interpreter) +- **Shared Links** (`sharedLink`), see [Shareable Links](/docs/features/shareable_links) ### Access Roles (Permission Presets) -Rather than exposing raw permission bits to end users, sharing uses three named roles per resource type: +Rather than exposing raw permission bits to end users, sharing uses three named roles per resource type (shared links have only Viewer and Owner): | Role | Permission bits | What the grantee can do | | ---------- | ----------------------------------------------- | ------------------------------------------------------------------- | @@ -121,6 +114,8 @@ Rather than exposing raw permission bits to end users, sharing uses three named Under the hood, permissions are stored as a bitmask (`permBits`) against each (resource, principal) pair; supersets are handled automatically, so granting Editor implies Viewer. +A fifth bit, `VIEW_INSIGHTS` (`0b10000`), applies to agents only. It lets a principal that also holds `VIEW` see that agent's [Insights](/docs/features/insights). It is not part of the Viewer, Editor, or Owner presets: only administrators can grant it, through the **View insights** toggle in an agent's share dialog, and it cannot be given to the public principal. + ### Granting Access from the UI 1. Open the resource (agent builder, prompt form, MCP server settings, etc.) @@ -145,10 +140,6 @@ Under the hood, permissions are stored as a bitmask (`permBits`) against each (r - **Owners** have the same UI as the original author, and can delete and re-share freely. - **The original author** always retains full control regardless of ACL state, and admins can manage any resource on the instance. -### Project Inheritance - -Permissions can be inherited from a parent **project**. When an ACL entry is inherited, the `inheritedFrom` link points back to the source. This is what powers the "Global" project in LibreChat, where a resource added to the global project becomes available to all users without needing an entry per principal. - ## Layer 3: System Grants (Admin Capabilities) System grants are a separate grant table used for **admin-level capabilities**, answering questions like _"Can this user access the admin panel?"_ or _"Can this group manage MCP servers globally?"_. They are always scoped to a principal (user, group, or role) and a capability string. @@ -167,13 +158,20 @@ The canonical capabilities include: | `read:usage` | View platform usage and telemetry | | `read:agents` / `manage:agents` | View / moderate every agent on the instance | | `read:prompts` / `manage:prompts` | View / moderate every prompt | +| `read:skills` / `manage:skills` | View / moderate every skill | +| `read:sharedlinks` / `manage:sharedlinks` | View / moderate every shared link | | `manage:mcpservers` | Manage MCP servers globally | +| `manage:code_environments` | Enroll and revoke deployment-owned code workers | +| `read:insights` | View [Insights](/docs/features/insights) for every agent | +| `read:audit_log` | List, view, and export the grant audit log (read-only; there is no manage counterpart) | Manage capabilities imply their corresponding read capability (e.g. holding `manage:users` automatically grants `read:users`). This also applies to configuration sections: `manage:configs:endpoints` satisfies `read:configs:endpoints`. Users with only section-scoped config access receive admin configuration responses filtered to the sections they can read; users with no config-read grant receive `403`. +`read:assistants` and `manage:assistants` also exist but are reserved: no middleware enforces them yet. + A `SystemRoles.ADMIN` user implicitly holds all capabilities; grants let you **delegate** a subset of admin powers to non-admin principals without making them full admins. Access to the admin UI itself still requires `access:admin`. -System grants are issued and revoked via the admin panel. +System grants are issued and revoked via the [Admin Panel](/docs/features/admin_panel). ## Principals in Depth diff --git a/content/docs/features/admin_panel.mdx b/content/docs/features/admin_panel.mdx index 5cbd5ccfa..f5d6e2328 100644 --- a/content/docs/features/admin_panel.mdx +++ b/content/docs/features/admin_panel.mdx @@ -1,7 +1,7 @@ --- title: Admin Panel icon: LayoutDashboard -description: A standalone web UI for managing LibreChat users, groups, roles, configuration overrides, and system grants - without editing librechat.yaml by hand. +description: A standalone web UI for managing LibreChat users, groups, roles, configuration overrides, and system grants, without editing librechat.yaml by hand. --- # LibreChat Admin Panel @@ -9,8 +9,8 @@ description: A standalone web UI for managing LibreChat users, groups, roles, co The **LibreChat Admin Panel** is a standalone browser-based management interface for LibreChat. It connects to the same database as LibreChat itself and provides a GUI for the administrative tasks that power [granular access control](/docs/features/access_control): user and group administration, role management, configuration overrides scoped to roles or groups, and system-level capability grants. - The admin panel is available for testing now and is the upcoming management surface that builds on - the admin APIs introduced in [LibreChat v0.8.5](/changelog/v0.8.5). Source, issues, and releases + The admin panel ships as the `admin-panel` service in `docker-compose.yml` and `deploy-compose.yml` + and builds on the admin APIs introduced in [LibreChat v0.8.5](/changelog/v0.8.5). Source, issues, and releases live at [github.com/ClickHouse/librechat-admin-panel](https://github.com/ClickHouse/librechat-admin-panel). @@ -20,7 +20,7 @@ The **LibreChat Admin Panel** is a standalone browser-based management interface The admin panel is a thin client: all data lives in LibreChat's database, and every action goes through the versioned `/api/admin/*` endpoints on the LibreChat API server. It gives administrators a single place to: - **Manage configuration**: view and edit every LibreChat setting through a dynamic, schema-driven form. New fields added to the config schema appear automatically, no admin-panel release required. -- **Apply per-principal overrides**: scope configuration overrides to specific roles or groups, with a priority-based cascade that determines the final resolved value each user sees at login. +- **Apply per-principal overrides**: scope configuration overrides to specific roles, groups, or users, with a priority-based cascade that determines the final resolved value each user sees at login. - **Administer users**: list, search, and view every account on the instance. - **Manage groups**: create and delete groups, add/remove members, and use groups as first-class principals in ACLs and overrides. - **Manage roles**: create custom roles beyond the built-in `USER` / `ADMIN`, edit their feature-permission matrix, and assign users to roles. @@ -54,6 +54,12 @@ The admin API surface exposed by LibreChat is: | `/api/admin/roles` | Custom role CRUD + permission editing + member management | | `/api/admin/grants` | System capability grants (assign/revoke/list) | | `/api/admin/config` | Base + per-principal configuration overrides | +| `/api/admin/skills` | GitHub skill sync: status, run, and sync credentials | +| `/api/admin/code-environments` | Pair and revoke code environment workers (`manage:code_environments`) | +| `/api/admin/langfuse` | Langfuse connection read, update, and test, plus per-conversation session links | +| `/api/admin/audit-log` | Grant audit log (`read:audit_log`) | + +The audit log endpoints are `GET /` (list), `GET /export.csv` (CSV export), `GET /verify` (integrity check), and `GET /:id` (single entry). They require `access:admin` and `read:audit_log`. The log is append-only, so there is no manage capability and no write endpoint. ## Getting Started @@ -65,7 +71,7 @@ The admin API surface exposed by LibreChat is: ### Bundled with LibreChat (recommended) -If you run LibreChat with its official [`docker-compose.yml`](https://github.com/LibreChat-AI/LibreChat/blob/main/docker-compose.yml) or [`deploy-compose.yml`](https://github.com/LibreChat-AI/LibreChat/blob/main/deploy-compose.yml), the admin panel ships as a service and starts automatically alongside LibreChat -- no separate deployment needed. +If you run LibreChat with its official [`docker-compose.yml`](https://github.com/LibreChat-AI/LibreChat/blob/main/docker-compose.yml) or [`deploy-compose.yml`](https://github.com/LibreChat-AI/LibreChat/blob/main/deploy-compose.yml), the admin panel ships as a service and starts automatically alongside LibreChat, with no separate deployment needed. | Compose file | Admin panel URL | How it is served | | ------------------------------ | ------------------------ | ----------------------------------------------------------------- | @@ -96,7 +102,7 @@ The compose files wire the rest automatically: `API_SERVER_URL` points at the `a ### Standalone (separate deployment) -To host the admin panel on its own -- pointed at a LibreChat instance running elsewhere -- use the published image from GHCR: +To host the admin panel on its own, pointed at a LibreChat instance running elsewhere, use the published image from the LibreChat registry (`registry.librechat.ai/librechat-ai/librechat-admin-panel:latest`, the image the bundled compose files use): ```bash # 1. Create an env file @@ -118,7 +124,7 @@ docker run -p 3000:3000 \ --add-host=host.docker.internal:host-gateway \ -e SESSION_SECRET=replace-with-32-char-random-string \ -e VITE_API_BASE_URL=http://host.docker.internal:3080 \ - ghcr.io/clickhouse/librechat-admin-panel:latest + registry.librechat.ai/librechat-ai/librechat-admin-panel:latest ``` @@ -163,7 +169,7 @@ When the admin panel is hosted on a separate URL from LibreChat, set `ADMIN_PANE ADMIN_PANEL_URL=https://admin.example.com/admin ``` -When set, LibreChat also shows an **Admin Panel** link to administrators under **Settings -> General**. Non-admin users do not see the link. +When set, LibreChat also shows an **Admin Panel** link to administrators under **Settings > General**. Non-admin users do not see the link. For Helm deployments, set `librechat.adminPanelUrl` in your values file. The chart renders it as `ADMIN_PANEL_URL` for LibreChat's admin OAuth flow: @@ -207,7 +213,9 @@ Google admin SSO requests offline access and consent so the panel can refresh an The panel renders the LibreChat config as a dynamic form driven by the config schema. This has two useful properties: - **Forward-compatible**: when LibreChat ships a new config field, the panel picks it up automatically from the schema. No admin-panel upgrade or redeploy is required. -- **Layered overrides**: the base config (from `librechat.yaml`) can be shadowed by per-principal overrides scoped to a role or group. When a user logs in, overrides are resolved in priority order and merged on top of the base to produce the effective config that user sees. +- **Layered overrides**: the base config (from `librechat.yaml`) can be shadowed by per-principal overrides scoped to a role, group, or user. When a user logs in, the documents that apply merge in one fixed order: the Base profile first regardless of its priority, then ascending priority, then role before group before user, then creation order. A new profile written without a priority gets its principal type's default (role 10, group 20, user 100, Base 0), and a write that omits the priority keeps the stored one. +- **Encrypted credentials**: MCP server credentials, Azure group keys, and web search keys stored through the admin API are encrypted at rest and returned only as masked previews. A write that keeps a stored key while changing where it is sent (such as a server URL or base URL) must enter the key again. +- **Environment references**: `${ENV_VAR}` references in overrides are limited to the names `librechat.yaml` already references, the built-in endpoint credentials, and the names listed in `CONFIG_OVERRIDE_ENV_ALLOWLIST`. Any other reference is rejected on write. MCP servers that use `type: stdio` or process fields such as `command`, `args`, `env`, `cwd`, or `stderr` are operator-owned. Configure them only in `librechat.yaml`; the admin API rejects attempts to create or modify them, and overrides cannot replace or remove them. Remote MCP server configuration remains available through the normal override system. @@ -226,7 +234,7 @@ This is the surface behind LibreChat's [DB-backed per-principal configuration ov - Let a "FinanceAdmins" role manage remote MCP servers while regular users can only use them - Scope stricter `interface` permissions to external-contractor groups -Administrators can also use the opt-in [Admin Insights](/docs/features/insights) dashboard to review tenant-scoped MongoDB activity. Set `ENABLE_INSIGHTS=true`, then grant both `access:admin` and `read:insights` to an account with the `ADMIN` role. +Administrators can also use the opt-in [Admin Insights](/docs/features/insights) dashboard to review tenant-scoped MongoDB activity. Set `ENABLE_INSIGHTS=true`; who can review which Agents is described in [Admin Insights](/docs/features/insights#access-requirements). ### Override Validation diff --git a/content/docs/features/agent_plugins.mdx b/content/docs/features/agent_plugins.mdx index 0820e3d06..eaad532df 100644 --- a/content/docs/features/agent_plugins.mdx +++ b/content/docs/features/agent_plugins.mdx @@ -20,7 +20,7 @@ DEPLOYMENT_PLUGINS_DIR=./plugin DEPLOYMENT_PLUGIN_DATA_DIR=./data/plugins # Optional and disabled by default; see Command Hooks below -DEPLOYMENT_PLUGIN_HOOKS=true +# DEPLOYMENT_PLUGIN_HOOKS=true ``` Relative paths are resolved from the LibreChat project root. If the default `./plugin` directory does not exist, startup continues with no plugins. If `DEPLOYMENT_PLUGINS_DIR` is set explicitly but cannot be read, startup fails so a deployment mistake is not silently ignored. @@ -96,6 +96,14 @@ Supported transports are `stdio`, `streamable-http`, and `sse`. Remote HTTP tran For `stdio` servers, `${PLUGIN_ROOT}` and `${PLUGIN_DATA}` are expanded once in `args`, `env`, and `cwd`; both values are also added to the launched process environment. Plugin MCP configuration does not expand arbitrary variables from LibreChat's host environment. A value such as `${OPENAI_API_KEY}` remains literal through registry storage and runtime initialization. Keep credentials outside plugin files and provide them through a purpose-built authenticated service or another deployment-controlled mechanism. +LibreChat validates each `mcp.json` before registering its servers: + +- `command` must be a single executable token: either a bare name such as `node` or a `./` path inside the plugin. Shell strings and absolute paths are rejected, and `${PLUGIN_ROOT}` is not expanded in `command`. +- `cwd` must start with `./`, `${PLUGIN_ROOT}`, or `${PLUGIN_DATA}`, and must resolve inside the base it names. +- `env` cannot declare `PLUGIN_ROOT` or `PLUGIN_DATA`; LibreChat sets them. +- Remote `url` values must be absolute `http` or `https` URLs without user information or a fragment, and must use `https` unless the host is a loopback address (such as `localhost` or `127.0.0.1`). +- A server entry with an unknown field is rejected and skipped. An unknown top-level field, or a `$schema` that does not match the supported `1.0.0` schema URL, disables MCP for the whole plugin. + An MCP server declared in `librechat.yaml` takes precedence over a plugin server with the same name. Duplicate plugin server names are skipped and logged. ## Persistent Plugin Data @@ -148,7 +156,8 @@ Declare hooks at `ai.librechat/hooks/hooks.json`: - The child environment contains only `PATH`, `HOME`, `LANG`, `LC_ALL`, and `TZ` when present, the three plugin path variables, and names explicitly listed in `allowedEnvVars`. - Exit code `0` succeeds. JSON written to standard output can return event-appropriate decisions and bounded context; plain output is treated as additional context only for `SessionStart` and `UserPromptSubmit`. - Exit code `2` blocks the applicable action or continuation and uses standard error as the reason. Other nonzero exits are logged and otherwise ignored. -- LibreChat terminates the process when the hook is aborted or times out. On POSIX hosts, commands run through Bash. Windows plugins must provide `commandWindows` or select PowerShell. +- `timeout` is in seconds, an integer from 1 to 3600. +- LibreChat terminates the process when the hook is aborted or times out. On POSIX hosts, commands run through `bash`, which must be available on the API host. On Windows hosts they run through `powershell.exe`, so plugins must provide `commandWindows` or select PowerShell. If the shell cannot start, LibreChat logs a startup warning and blocking hooks fail closed. LibreChat translates the common Claude tool names `Bash`, `Write`, `Edit`, `Read`, and `WebSearch` and their file argument names to the corresponding LibreChat tools. A matcher written with LibreChat's native tool name keeps the native payload shape. diff --git a/content/docs/features/agents.mdx b/content/docs/features/agents.mdx index ccb559328..956eb8e04 100644 --- a/content/docs/features/agents.mdx +++ b/content/docs/features/agents.mdx @@ -33,6 +33,12 @@ The **Tools** and **Skills** controls open searchable libraries for built-in cap ![Agents - Mention](/images/agents/mention.png) +### Linking a Prompt as Instructions + +Instead of typing instructions inline, an agent can use a saved Prompt from the prompt library. Use the **Instructions source** toggle above the instructions field to switch between **Inline** and **Prompt**. In Prompt mode, search for a prompt by name under **Select a prompt**, then choose a **Version**: the **Production** version, or a specific saved version. The agent uses the linked prompt as its instructions. Selecting a prompt is required before the agent can be saved in Prompt mode. + +Access to the prompt library is required to link a prompt. If you lack access to a prompt that is already linked, the builder shows it as a **Restricted prompt**, and you can replace it or switch back to inline instructions. + ### Tool Library The Agent Builder keeps enabled items in separate **Tools** and **Skills** sections. Open **Add tools** to search the complete catalog or filter it by **Official**, **Tools**, **MCP**, or **Actions**. **Made by you** collects MCP servers and Actions you created, while **Favorites** keeps starred items available across agents. Each user can save up to 100 tool-library favorites. @@ -102,13 +108,13 @@ Stateful code sessions let an agent reuse a sandbox workspace across code execut Administrators can also configure named backends under [`statefulCodeSessions.environments`](/docs/configuration/librechat_yaml/object_structure/agents#statefulcodesessions). When present, the separate **Execution environment** selector chooses the managed Code API, operator-attached VM, or personal worker that owns the workspace; **Deployment default** uses the configured default executable environment. The sharing scope above remains independent of that backend choice. -When a deployment enables self-service workers, users with Code Environment management permission can open **Settings > Code environments** to pair an outbound `@librechat/code` worker on their own VM, select it in the Agent Builder, and revoke it later. Personal environments are owner-bound and use the same route for code, shell, and Programmatic Tool Calling. See [Attached environments and pairing](/docs/features/code_interpreter#attached-environments-and-pairing) for the experimental setup and security model. +When a deployment enables self-service workers, users with Code Environment management permission can open **Settings > Data & Privacy > Code execution > Code environments** to pair an outbound `@librechat/code` worker on their own VM, select it in the Agent Builder, and revoke it later. Personal environments are owner-bound and use the same route for code, shell, and Programmatic Tool Calling. See [Attached environments and pairing](/docs/features/code_interpreter#attached-environments-and-pairing) for the experimental setup and security model. Within an attached workspace, Agents can list directories, read files, search text, author files, and run Bash through the selected worker. A per-Agent Git name and email can identify commits made there without supplying repository credentials. Deployments can limit new personal workers with [`statefulCodeSessions.principalWorkers`](/docs/configuration/librechat_yaml/object_structure/agents#statefulcodesessions). When an attached worker advertises multiple workspace roots, the chat composer requires one selection for each attached environment used by the Agent or its Subagents. The conversation retains those selections across turns and approval resumes; LibreChat validates them against the live worker and blocks sending if a required workspace is missing or unavailable. A worker that advertises exactly one workspace is selected automatically for a new conversation. See [Attached environments and pairing](/docs/features/code_interpreter#attached-environments-and-pairing) for details and current limitations. -New Agents initially use the signed-in user's **Default stateful workspace** from **Settings > Data Controls > Code execution**. The personal default is **User workspace** until changed. Updating this preference does not alter existing Agents or enable Stateful Code Sessions by itself. Administrators can restrict the available scopes with [`statefulCodeSessions.allowedEnvironments`](/docs/configuration/librechat_yaml/object_structure/agents#statefulcodesessions); when a saved personal default is no longer allowed, new Agents use the first permitted scope. +New Agents initially use the signed-in user's **Default stateful workspace** from **Settings > Data & Privacy > Code execution**. The personal default is **User workspace** until changed. Updating this preference does not alter existing Agents or enable Stateful Code Sessions by itself. Administrators can restrict the available scopes with [`statefulCodeSessions.allowedEnvironments`](/docs/configuration/librechat_yaml/object_structure/agents#statefulcodesessions); when a saved personal default is no longer allowed, new Agents use the first permitted scope. Stateful Code Sessions are in an early experimentation phase. Their behavior, configuration, persistence characteristics, and underlying integration may change substantially. Do not treat the current implementation as a stable production contract. @@ -202,7 +208,7 @@ This is especially useful when an agent has access to many MCP servers with doze 1. Open the Agent Builder and add MCP tools 2. Click the dropdown on any MCP tool -3. Toggle "Defer Loading" — deferred tools show a clock icon +3. Turn on **Defer** for that tool, or use **Defer all tools** to defer every tool from the server **Note:** The `deferred_tools` capability is enabled by default. It can be toggled via the [`librechat.yaml` agents configuration](/docs/configuration/librechat_yaml/object_structure/agents#capabilities). @@ -301,6 +307,18 @@ Administrators can also require review before matching tool calls run. Depending While the composer review panel is open for a pending approval, the corresponding thread card shows the request as a record rather than duplicating decision buttons. Review the calls in the panel above the message box and select **Continue**. Collapsing the panel from the composer chip restores the thread card's controls with your decisions retained; reopening it hands review back to the panel. Cards for other actions keep their own controls. +#### Per-Agent Tool Approval Modes + +When an administrator enables agent-scoped approval modes, each tool in an Agent's configuration shows a **Tool approval mode** selector, with **Approval mode for all listed tools** to set every tool of a server at once. The options are: + +- **Use inherited policy**: follow the deployment's approval policy +- **Always ask**: review every call +- **Always approve**: run the tool without review +- **Ask once per chat**: approving a call remembers the tool for this agent in that chat, including calls with different arguments +- **Ask once, then always approve**: approving a call remembers the tool for you and this agent across chats + +Administrator allow, ask, and deny rules still apply on top of these choices. **Reset my remembered approvals** clears the approvals you have saved. If the controls are disabled, the builder shows "An administrator must enable agent tool approval modes." Administrators turn this on with `agentModes` (and the `allowAlways` options) under [`toolApproval`](/docs/configuration/librechat_yaml/object_structure/agents#toolapproval). + ### Skills Skills let agents load reusable instructions from `SKILL.md` definitions. They can be selected manually from chat with `$`, automatically discovered by the model through the skill catalog, or always applied on every turn. The Agent Builder can also enable standalone runtime authoring: an agent may create a Skill without receiving the existing catalog, or edit selected Skills when the user has the corresponding permission. @@ -404,33 +422,19 @@ With the Actions capability, you can dynamically create tools from [OpenAPI spec Handoffs let a primary agent transfer a conversation to a specialist agent with the relevant context. In **Advanced settings**, open the orchestration section and add up to 10 handoff agents. Each configured handoff creates a transfer tool that the model can choose dynamically when the specialist's expertise is needed. -For each handoff, you can add a description that helps the model choose the right specialist. You can also provide passthrough instructions describing what content the primary agent should generate for the specialist and optionally rename the content parameter from its default, `instructions`. Handoffs are always available in the Agent Builder; unlike Agent Chain and Subagents, they do not require an endpoint capability to be enabled. Tool calls from reachable handoff agents remain structured in later turns, so providers receive valid tool-call history instead of flattened text. +For each handoff, you can add a description that helps the model choose the right specialist. You can also provide passthrough instructions describing what content the primary agent should generate for the specialist and optionally rename the content parameter from its default, `instructions`. Handoffs are always available in the Agent Builder; unlike Subagents, they do not require an endpoint capability to be enabled. Tool calls from reachable handoff agents remain structured in later turns, so providers receive valid tool-call history instead of flattened text. ### Agent Chain -The Agent Chain capability enables a Mixture-of-Agents (MoA) approach, allowing you to create a sequence of agents that work together: - -- Create chains of specialized agents for complex tasks -- Each agent in the chain can access outputs from previous agents -- Configure the maximum number of steps for the agent chain -- **Note:** Access this feature from the Advanced Settings panel in the Agent Builder -- **Note:** This feature is currently in beta and may be subject to change - - The current maximum of agents that can be chained is 10, but this may be configurable in the future +Agent chains are deprecated. Existing chains still run, but new multi-agent workflows should use [Handoffs](#handoffs) or [Subagents](/docs/features/subagents) instead. -Agent Chain - -This feature introduces a layered Mixture-of-Agents architecture to LibreChat, where each agent takes all the outputs from agents in the previous layer as auxiliary information in generating its response, as described in [the eponymous "Mixture-of-Agents" paper](https://arxiv.org/abs/2406.04692). +A chain is a sequence of agents in which each agent receives the outputs of the agents before it, following the layered approach described in [the "Mixture-of-Agents" paper](https://arxiv.org/abs/2406.04692). The chain settings remain in the orchestration section of the Agent Builder's Advanced settings for agents that already use them. ### Subagents Subagents let an agent delegate a focused task to an isolated child run or a saved Agent team. Each child gets isolated context and tool execution, then returns a compact result to the parent instead of filling the parent context with every intermediate step. Detached child work is also preserved as a navigable, view-only thread. -Subagents are different from Agent Chain: chain runs coordinate multiple agents as graph participants, while subagents are spawned by an agent as a tool call for scoped delegation. LibreChat preserves the structured tool-call history needed by reachable children and saved-team members across later turns while keeping unavailable tools out of the active run. For setup and limits, see [Subagents](/docs/features/subagents). +Subagents are different from legacy Agent Chains and from Handoffs: chain runs coordinate multiple agents as graph participants and handoffs transfer the conversation to another agent, while subagents are spawned by an agent as a tool call for scoped delegation. LibreChat preserves the structured tool-call history needed by reachable children and saved-team members across later turns while keeping unavailable tools out of the active run. For setup and limits, see [Subagents](/docs/features/subagents). ### Advanced Settings @@ -440,7 +444,7 @@ Advanced settings for your agent (found in the Advanced view of the Agent form) This setting allows you to limit the number of steps an agent can take in a "run," which refers to the agent loop before a final response is given. -If left unconfigured, the default is 25 steps, but you can adjust this to suit your needs. For admins, you can set a global default as well as a global maximum in the [`librechat.yaml`](/docs/configuration/librechat_yaml/object_structure/agents#recursionlimit) file. +If left unconfigured, the default is 50 steps, but you can adjust this to suit your needs. For admins, you can set a global default as well as a global maximum in the [`librechat.yaml`](/docs/configuration/librechat_yaml/object_structure/agents#recursionlimit) file. When a turn uses its complete step budget, LibreChat preserves the partial response and tool calls instead of replacing them with an error. The message offers **Keep going**, which starts a new turn with a fresh tool budget, and **Answer now**, which asks the agent to answer from the work already completed without more tools. Dismissing the notice affects only the current browser view. @@ -578,28 +582,27 @@ Individual users can: ## Steering and Queued Messages -While an Agent is responding, you can send another message from the [composer](/docs/features/composer) in either of two ways: +While an Agent is responding, you can send another message from the [composer](/docs/features/composer) in one of three ways: -- **Steer** inserts the message into the current run at its next tool or agent step, so the agent can adjust its work before finishing. +- **Steer** inserts the message into the current run at the next safe insertion point, without cancelling tools or reasoning, so the agent can adjust its work before finishing. +- **Interrupt** requests cancellation of active tools and reasoning, keeps completed output, then continues with your message. External effects already performed cannot be undone. - **Queue** holds the message and sends it as a normal follow-up turn after the current response completes. For saved Agent conversations on a current server, ordinary queued follow-ups are stored in MongoDB. LibreChat preserves their FIFO order and carries their text, attachments, quoted excerpts, and manually selected Skills across browser disconnects, app restarts, and replica handoffs. Processing waits for the preceding response to settle before admitting the next turn. This durability is automatic and has no YAML or environment toggle; older servers and short startup windows without an active generation epoch retain the client-side compatibility queue. Server admission is serialized within each conversation queue lane. If predecessor evidence or mixed-version ownership is ambiguous, LibreChat shows **Awaiting reconciliation** and blocks or fails the affected queued turn instead of guessing and starting it out of order. -**Steer sooner** asks the agent to take the message at the next safe point instead of waiting for the next tool step. If no answer text or tool activity is safe to keep yet, LibreChat waits through a short grace period, discards the silent or reasoning-only attempt, inserts the message, and restarts the model with that instruction. Once answer text can be kept, LibreChat stops at a provider-safe boundary, preserves the partial response, inserts the message, and resumes the same assistant response. A running tool call is not discarded or interrupted by steering; the message applies when that work reaches a safe boundary. - -Use **Stop** to end active reasoning and request cancellation of a foreground tool call. Stop forwards cancellation to signal-aware foreground tools; detached background work keeps its independent lifecycle. Use the dedicated composer control, choose it from the send-button menu, or press `Command/Ctrl + Shift + .`. The action falls back to ordinary steering when the deployment cannot interrupt the active provider stream. +Interrupt is unavailable for some runs, including those that use provider-hosted tools such as native search. In that case the message remains a Steer and waits for a safe insertion point. -Under **Settings → Chat**, **While generating, Enter will** chooses the default action. The send-button menu can override that choice for an individual message, and **Steer sooner on Enter** makes Enter request that earlier safe point when steering is the default. +Under **Settings → Chat**, **While generating, Enter will** chooses the default action: **Steer**, **Interrupt**, or **Queue**. The send-button menu can override that choice for an individual message. Pressing `Alt + Enter` while generating sends the message as an interrupt. Files and [quoted excerpts](/docs/features/message_actions#quote-excerpts) travel with steer, queue, and interrupt messages. Manually selected Skills remain staged for the next full turn instead of being attached to a mid-run steer. -Pending steers appear at the end of the streaming reply, where they will land, until the server inserts them into the run. Their receipt progresses from **Sending** to **Delivered**, then **Steer sooner requested** when an earlier safe point was requested, and finally **Applied** with a double checkmark at the inline message's bottom-right edge. Confirmed applied receipts remain visible after reload and in share or search views; uncertain or failed delivery never shows a confirming checkmark. Once acknowledged, the message menu can reclaim the steer for editing, convert it into a queued follow-up, or cancel it and restore its text and attachments to the composer. LibreChat avoids overwriting a newer draft; if the composer is no longer available, it preserves the reclaimed message in the queue instead. A failed steer remains available to retry, edit, queue, or remove. +Pending steers appear at the end of the streaming reply, where they will land, until the server inserts them into the run. Their receipt progresses from **Sending…** to **Waiting to apply** (or **Interrupt requested** for an interrupt), and finally to a double checkmark whose tooltip begins "Applied" at the inline message's bottom-right edge. Confirmed applied receipts remain visible after reload and in share or search views; uncertain or failed delivery never shows a confirming checkmark. Once acknowledged, the message menu can reclaim the steer for editing, convert it into a queued follow-up, or cancel it and restore its text and attachments to the composer. LibreChat avoids overwriting a newer draft; if the composer is no longer available, it preserves the reclaimed message in the queue instead. A failed steer remains available to retry, edit, queue, or remove. -Queued follow-ups appear in a list above the composer. Each one can be edited (**Edit message**), removed (**Remove message**), sent right away with **Send now**, or reordered by dragging its handle or pressing the arrow keys on it. Queued follow-ups can also be converted into a steer while the run is still active or escalated with **Steer sooner**. In-flight steers offer the same escalation when they are still waiting for a tool boundary. Removing a server-backed queued message first cancels its durable source, then restores it to an empty composer when possible. If the preceding response is aborted or fails, LibreChat marks the affected queued turn as failed for review instead of silently sending it. +Queued follow-ups appear in a list above the composer. Each one can be edited (**Edit message**), removed (**Remove message**), sent right away with **Send now**, or reordered by dragging its handle or pressing the arrow keys on it. Queued follow-ups can also be converted into a steer while the run is still active. A waiting steer or queued follow-up can be escalated to an interrupt with **Interrupt now**, or by pressing `Command/Ctrl + Shift + .` to escalate the newest waiting message. Removing a server-backed queued message first cancels its durable source, then restores it to an empty composer when possible. If the preceding response is aborted or fails, LibreChat marks the affected queued turn as failed for review instead of silently sending it. -A conversation can have up to 100 active queued turns. Each queued turn accepts up to 16,000 characters and 10 files. Separately, one active run accepts up to 10 pending steers; each steer can include up to 10 files and is limited by [`STEER_MAX_LENGTH`](/docs/configuration/dotenv#agent-conversation-controls). **Steer sooner** continues to use the live steering path rather than moving a queued turn to the front of the durable FIFO lane. +A conversation can have up to 100 active queued turns. Each queued turn accepts up to 16,000 characters and 10 files. Separately, one active run accepts up to 10 pending steers; each steer can include up to 10 files and is limited by [`STEER_MAX_LENGTH`](/docs/configuration/dotenv#agent-conversation-controls). Redis-backed multi-replica deployments negotiate generation protocol v2 automatically. Follow the [generation protocol compatibility guidance](/docs/configuration/redis#generation-protocol-compatibility) when upgrading from a release older than `v0.8.8-rc1`. diff --git a/content/docs/features/agents_api.mdx b/content/docs/features/agents_api.mdx index ed731c1c2..32863821a 100644 --- a/content/docs/features/agents_api.mdx +++ b/content/docs/features/agents_api.mdx @@ -14,11 +14,11 @@ LibreChat exposes agents to external applications, scripts, and services through The Agents API provides two inference interfaces, authenticated event delivery, and beta management routes: -- **OpenAI-compatible Chat Completions** — `POST /api/agents/v1/chat/completions` -- **Open Responses API** — `POST /api/agents/v1/responses` -- **Agent Events** — `POST /api/agents/v1/events` -- **Agent Management** — `/api/agents/v1/agents` -- **Skill Management** — `/api/agents/v1/skills` +- **OpenAI-compatible Chat Completions**: `POST /api/agents/v1/chat/completions` +- **Open Responses API**: `POST /api/agents/v1/responses` +- **Agent Events**: `POST /api/agents/v1/events` +- **Agent Management**: `/api/agents/v1/agents` +- **Skill Management**: `/api/agents/v1/skills` The inference interfaces support API-key authentication, optional OIDC authentication, and streaming responses. Agent Events use Remote Agents API-key authentication so LibreChat can bind each delivery to a stable source identity. Management routes instead use a deployment allowlist that binds an OIDC machine client to one existing LibreChat user and tenant. @@ -35,7 +35,7 @@ interface: create: true ``` -See [Interface Configuration — remoteAgents](/docs/configuration/librechat_yaml/object_structure/interface#remoteagents) for all available options. +See [Interface Configuration: remoteAgents](/docs/configuration/librechat_yaml/object_structure/interface#remoteagents) for all available options. **Note:** Admin users have all remote agent permissions enabled by default. @@ -48,7 +48,7 @@ openapi: enabled: true ``` -The specification covers the public inference, event, Agent management, and Skill management routes described on this page. Keep the routes disabled unless your deployment intends to expose API documentation. +The specification covers only the Agent management and Skill management routes. Inference (Chat Completions and Open Responses) and Agent Events routes are not part of it. Keep the routes disabled unless your deployment intends to expose API documentation. ## API Key Management @@ -153,12 +153,17 @@ File uploads use `multipart/form-data` with one `file` and a `tool_resource` val | Method | Route | Purpose | | ------- | ---------------------------------------------------- | ------------------------------------- | -| `GET` | `/api/agents/v1/skills` | List accessible Skills | -| `GET` | `/api/agents/v1/skills/{id}` | Read one accessible Skill | -| `PATCH` | `/api/agents/v1/skills/{id}` | Update supported Skill metadata | -| `GET` | `/api/agents/v1/skills/{id}/files` | List files in the Skill | -| `GET` | `/api/agents/v1/skills/{id}/files/{relativePath}` | Read one Skill file | -| `PUT` | `/api/agents/v1/skills/{id}/files/{relativePath}` | Create or replace one supported file | +| `GET` | `/api/agents/v1/skills` | List accessible Skills | +| `POST` | `/api/agents/v1/skills` | Create a Skill | +| `GET` | `/api/agents/v1/skills/{id}` | Read one accessible Skill | +| `PATCH` | `/api/agents/v1/skills/{id}` | Update a Skill | +| `DELETE` | `/api/agents/v1/skills/{id}` | Delete a Skill | +| `GET` | `/api/agents/v1/skills/{id}/files` | List files in the Skill | +| `GET` | `/api/agents/v1/skills/{id}/files/{relativePath}` | Read one Skill file | +| `PUT` | `/api/agents/v1/skills/{id}/files/{relativePath}` | Create or replace one supported file | +| `DELETE` | `/api/agents/v1/skills/{id}/files/{relativePath}` | Delete one Skill file | + +Create accepts `name`, `description`, `body`, and optional `displayTitle`, `frontmatter`, `category`, and `alwaysApply`. Update requires a positive integer `expectedVersion` (the Skill's current version) plus at least one field to change, which can include `body` and `frontmatter`. Both reject unknown fields. Skill operations are limited to Skills visible to the bound user. Reads require Skill access, while metadata or file writes require the corresponding edit and Skill-authoring permissions. Paths are normalized beneath the Skill root; traversal, unsupported files, and oversized content are rejected. @@ -219,6 +224,12 @@ GET /api/agents/v1/models Returns available agents as models. Useful for discovering which agents are accessible with your API key. +``` +GET /api/agents/v1/models/{model} +``` + +Returns a single agent as a model object. + ### Open Responses API ``` @@ -237,6 +248,11 @@ curl -X POST https://your-librechat-instance/api/agents/v1/responses \ }' ``` +Related routes: + +- `GET /api/agents/v1/responses/models` lists the agents available through the Responses API. +- `GET /api/agents/v1/responses/{id}` retrieves a stored response by ID. + #### Caller-Executed Function Tools The Open Responses endpoint accepts standard `function` tools supplied by the caller. LibreChat exposes these definitions to the model but does not execute them. When the model selects one, the response contains a `function_call` output item for the caller to execute. @@ -407,14 +423,14 @@ All Agents API inference requests track token usage against the user's balance w ## Roadmap -- **Open Responses as primary interface** — We plan to expand the Open Responses endpoint with full support for agentic loops, tool orchestration, and streaming semantic events. -- **Anthropic Messages API** — We may add support for the Anthropic Messages API format as an additional interface in the future. +- **Open Responses as primary interface**: We plan to expand the Open Responses endpoint with full support for agentic loops, tool orchestration, and streaming semantic events. +- **Anthropic Messages API**: We may add support for the Anthropic Messages API format as an additional interface in the future. ## Related Documentation -- [Agents](/docs/features/agents) — Creating and configuring agents -- [Subagents](/docs/features/subagents) — Configuring direct child Agents -- [Agents Endpoint Configuration](/docs/configuration/librechat_yaml/object_structure/agents) — Event runtime and authentication settings -- [Interface Configuration — remoteAgents](/docs/configuration/librechat_yaml/object_structure/interface#remoteagents) — Access control settings -- [Token Usage](/docs/configuration/token_usage) — Configuring token spending and balance -- [Open Responses Specification](https://www.openresponses.org/) — The open inference standard +- [Agents](/docs/features/agents): Creating and configuring agents +- [Subagents](/docs/features/subagents): Configuring direct child Agents +- [Agents Endpoint Configuration](/docs/configuration/librechat_yaml/object_structure/agents): Event runtime and authentication settings +- [Interface Configuration: remoteAgents](/docs/configuration/librechat_yaml/object_structure/interface#remoteagents): Access control settings +- [Token Usage](/docs/configuration/token_usage): Configuring token spending and balance +- [Open Responses Specification](https://www.openresponses.org/): The open inference standard diff --git a/content/docs/features/artifacts.mdx b/content/docs/features/artifacts.mdx index d809c4b2b..209fa5329 100644 --- a/content/docs/features/artifacts.mdx +++ b/content/docs/features/artifacts.mdx @@ -76,8 +76,11 @@ Once you have a self-hosted bundler set up, simply configure LibreChat to use it ```bash # `.env` file SANDPACK_BUNDLER_URL=http://your-bundler-url +SANDPACK_STATIC_BUNDLER_URL=http://your-static-bundler-url ``` +`SANDPACK_BUNDLER_URL` serves React and other framework artifacts. `SANDPACK_STATIC_BUNDLER_URL` serves the static templates used for HTML, Markdown, code, text, and office-document previews. A self-hosted setup needs both URLs; with only one set, the other artifact types still load from the public CDN. + ### General Considerations Self-hosting the bundler introduces some additional overhead: diff --git a/content/docs/features/code_interpreter.mdx b/content/docs/features/code_interpreter.mdx index eacab678e..a92e398db 100644 --- a/content/docs/features/code_interpreter.mdx +++ b/content/docs/features/code_interpreter.mdx @@ -86,7 +86,7 @@ Stateful code sessions let a LibreChat Agent reuse one Code Interpreter sandbox - **Agent + user workspace:** one workspace for each user and agent combination - **Conversation workspace:** one workspace for each user and conversation -For newly created Agents, the initial scope comes from **Settings > Data Controls > Code execution > Default stateful workspace**. The personal setting defaults to **User workspace**; changing it does not modify existing Agents or enable stateful sessions. Deployment administrators can restrict selectable scopes with [`statefulCodeSessions.allowedEnvironments`](/docs/configuration/librechat_yaml/object_structure/agents#statefulcodesessions). If a saved personal default becomes unavailable, new Agents use the first allowed scope; an existing enabled Agent with a now-disallowed scope must be reconfigured before it can run. +For newly created Agents, the initial scope comes from **Settings > Data & Privacy > Code execution > Default stateful workspace**. The personal setting defaults to **User workspace**; changing it does not modify existing Agents or enable stateful sessions. Deployment administrators can restrict selectable scopes with [`statefulCodeSessions.allowedEnvironments`](/docs/configuration/librechat_yaml/object_structure/agents#statefulcodesessions). If a saved personal default becomes unavailable, new Agents use the first allowed scope; an existing enabled Agent with a now-disallowed scope must be reconfigured before it can run. The workspace scope is separate from its execution backend. When administrators configure named [`statefulCodeSessions.environments`](/docs/configuration/librechat_yaml/object_structure/agents#statefulcodesessions), the Agent Builder adds an **Execution environment** selector: @@ -115,7 +115,7 @@ An operator can pin a deployment-owned attached environment to one worker with ` For self-service workers, configure a deployment-owned attached control plane with `pairing.allowPrincipalWorkers: true` and `pairing.tokenEnv`. It may omit both worker IDs and exist only as an enrollment control plane; such an entry is not selectable for execution and cannot be the deployment default. -Users with Code Environment management permission can then open **Settings > Code environments**, name an environment, choose an approved control plane, and select **Connect VM**. LibreChat shows a short-lived, one-time `librechat-code pair ...` command. Run it on the user's VM, then start `@librechat/code` with `LIBRECHAT_CODE_SANDBOX_ENDPOINT` pointing to that machine's sandbox service. The UI lists the user's environments and can revoke and remove them later; sandbox files remain on the VM. +Users with Code Environment management permission can then open **Settings > Data & Privacy > Code execution > Code environments**, name an environment, choose an approved control plane, and select **Connect VM**. LibreChat shows a short-lived, one-time `librechat-code pair ...` command. Run it on the user's VM, then start `@librechat/code` with `LIBRECHAT_CODE_SANDBOX_ENDPOINT` pointing to that machine's sandbox service. The UI lists the user's environments and can revoke and remove them later; sandbox files remain on the VM. Administrators can bound enrollment with [`statefulCodeSessions.principalWorkers`](/docs/configuration/librechat_yaml/object_structure/agents#statefulcodesessions). Enrollment defaults to enabled with at most five registered environments per user when this block is omitted. The count includes offline workers across every control plane. Deployment configuration is the ceiling: principal-specific configuration may lower or disable it, but cannot raise it. Tightening the policy does not revoke machines that are already registered. @@ -133,13 +133,23 @@ For an attached execution environment, the Agent Builder can set a **Workspace d #### Saved-chat workspace changes -By default a saved conversation's attached workspace decision is sealed. With [`statefulCodeSessions.conversationMoves.enabled`](/docs/configuration/librechat_yaml/object_structure/agents#statefulcodesessions) enabled, the owner can explicitly move to another authorized workspace or recover a missing workspace. Recovery preserves chat history, **not** the lost workspace's files. Setting `allowAttachDetach: true` additionally lets the owner attach a workspace to a saved non-coding chat or leave an attached workspace to continue normal chat; enabling moves alone does not enable attach/detach. These transitions cannot take place while a generation is running and are revalidated on the server. Upgrade all API replicas and enable `CODE_ENVIRONMENT_DECISION_VERSION=1` before opting in. Without the switches, existing move-only and sealed-conversation behavior is unchanged. +By default a saved conversation's attached workspace decision is sealed. With [`statefulCodeSessions.conversationMoves.enabled`](/docs/configuration/librechat_yaml/object_structure/agents#statefulcodesessions) enabled, the owner can explicitly move to another authorized workspace or recover a missing workspace. Recovery preserves chat history, **not** the lost workspace's files. Setting `allowAttachDetach: true` additionally lets the owner attach a workspace to a saved non-coding chat or leave an attached workspace to continue normal chat; enabling moves alone does not enable attach/detach. These transitions cannot take place while a generation is running and are revalidated on the server. Upgrade all API replicas before opting in. The decision protocol (v1) is advertised by default; setting `CODE_ENVIRONMENT_DECISION_VERSION=0` opts out, keeps the legacy path, and also disables per-chat machine choice. In a rolling upgrade from a release without v1, set it to `0` before the first upgraded replica starts, and remove it once every replica is upgraded. Without the switches, existing move-only and sealed-conversation behavior is unchanged. Attached Bash uses a 30-second timeout by default. An environment can expose a larger model-requestable budget with [`configSchema.limits.maxCommandTimeoutMs`](/docs/configuration/librechat_yaml/object_structure/agents#statefulcodesessions), up to the five-minute protocol ceiling. The requested timeout never exceeds the deployment limit. Administrators can separately bound capacity retries with [`configSchema.limits.maxQueueWaitMs`](/docs/configuration/librechat_yaml/object_structure/agents#statefulcodesessions); this queue wait does not cancel an admitted or running command. To allow longer **individual** admission attempts, use `configSchema.limits.maxRequestTimeoutMs` only after the Code API honors the per-request queue allowance and the shortest proxy timeout on the live route is verified. The optional `configSchema.limits.minCommandAdmissionMs` reserves 10 seconds by default (valid 1–300 seconds) for admission before a command. The advertised Bash timeout is fitted to the request budget after this reserve and another 10 seconds for settlement and delivery. This budget does not replace `maxQueueWaitMs`. #### Linked-worktree lanes -Attached environments can opt into [per-worktree request scheduling](/docs/configuration/librechat_yaml/object_structure/agents#statefulcodesessions) with `configSchema.workspaces.linkedWorktrees: true`. First upgrade LibreChat, then deploy a compatible Code API bridge and start the worker with `--linked-worktree-lanes`; enable the YAML setting only after that worker advertises `git_linked_worktree`. Requests that structurally target `.worktrees//` use that worktree's lane without changing the checkout-relative paths shown to the Agent. For Bash, pass the worktree directory in the tool's `cwd` argument; running `cd .worktrees/` inside the command stays in the root lane. Checkout-root operations, environment actions, and conversation workspace instances also stay root-scoped. Without the opt-in, all requests keep their existing checkout-wide scheduling. +Attached environments use [per-worktree request scheduling](/docs/configuration/librechat_yaml/object_structure/agents#statefulcodesessions) by default; only `configSchema.workspaces.linkedWorktrees: false` disables it. The worker must be a compatible Code API bridge started with `--linked-worktree-lanes` and advertising `git_linked_worktree`. Requests that structurally target `.worktrees//` use that worktree's lane without changing the checkout-relative paths shown to the Agent. For Bash, pass the worktree directory in the tool's `cwd` argument; running `cd .worktrees/` inside the command stays in the root lane. Checkout-root operations, environment actions, and conversation workspace instances also stay root-scoped. With `linkedWorktrees: false`, all requests keep checkout-wide scheduling. + +#### Choosing a machine per chat + +Administrators control per-chat machine choice with `statefulCodeSessions.allowEnvironmentSelection`. It is allowed unless set to `false`, which keeps every agent on its fixed machine; it also requires the decision protocol above. In the Agent Builder, **Machines available in new chats** lets an agent's editor choose which machines the agent may use. A new chat can then pick one of them with **Choose machine**, provided the user has access; the default machine is always allowed and existing chats are unchanged. The number of additional machines is bounded by `maxEnvironmentChoices`. + +`configSchema.workspaces.allowCheckoutSelection: true` additionally permits explicit per-conversation checkout choices. It defaults to `false`, which preserves automatic worker isolation and hides the selector. See the [`statefulCodeSessions` reference](/docs/configuration/librechat_yaml/object_structure/agents#statefulcodesessions). + +#### Browser-approved machine setup + +When `statefulCodeSessions.principalWorkers.browserSetup` is enabled, a user can set up a personal machine by approving the request in the browser instead of copying a pairing code. The setup command run on the machine opens the `code/setup/:attemptId` page on your LibreChat instance, titled **Approve Machine Setup**. It shows the account you are signed in as and the details of the request, and nothing is approved until you choose **Approve setup** (or **Deny setup**). Requests expire, so start a new setup from the machine if one has expired. A completed setup does not mean the worker is online or the workspace is ready; check its status before use. The `instance`, rate-limit, and pending-request keys are documented in the [agents configuration reference](/docs/configuration/librechat_yaml/object_structure/agents#statefulcodesessions). #### Workspace edit matching and conflicts @@ -151,7 +161,7 @@ These attached-worker features require compatible Code API and worker builds imp #### Attached-environment tool permissions -Attached and personal environments use an ask-by-default approval policy for file writes and command or code execution. Read-only and search operations continue under the deployment's regular tool policy. If the administrator exposes either category through [`configSchema.permissions`](/docs/configuration/librechat_yaml/object_structure/agents#statefulcodesessions), users with Code Environment management permission can choose among the allowed **Allow**, **Ask**, or **Deny** values under **Settings > Code environments**. Missing, stale, or disallowed settings fall back safely to **Ask**. +Attached and personal environments use an ask-by-default approval policy for file writes and command or code execution. Read-only and search operations continue under the deployment's regular tool policy. If the administrator exposes either category through [`configSchema.permissions`](/docs/configuration/librechat_yaml/object_structure/agents#statefulcodesessions), users with Code Environment management permission can choose among the allowed **Allow**, **Ask**, or **Deny** values under **Settings > Data & Privacy > Code execution > Code environments**. Missing, stale, or disallowed settings fall back safely to **Ask**. The composer shows a conversation-level **Code approval mode** whenever the selected attached environment supports it: diff --git a/content/docs/features/composer.mdx b/content/docs/features/composer.mdx index c35bd3cf3..60fe3a94b 100644 --- a/content/docs/features/composer.mdx +++ b/content/docs/features/composer.mdx @@ -18,7 +18,7 @@ The message composer is the box at the bottom of every chat. Besides the text fi | **Use microphone** | Dictates your message with speech to text, when speech to text is enabled. | | Send / Stop | Sends the message, or stops the response that is streaming. | -To see which keys apply right now, such as `/ for prompts`, `@ for models` or `Enter to send`, turn on **Show composer tips** in **Settings > General**. A one-line tip then appears under the text field. It is off by default. +The keys that apply at the moment, such as `/ for prompts`, `@ for models` or the send keys, are not shown as text under the field. They are a visually hidden description of the text field that screen readers announce. ![The composer with the + palette open, showing the Attach and Tools sections](/images/composer/composer-palette.png) @@ -98,7 +98,7 @@ For models with a reasoning setting, the **Thinking** control opens a slider tha ## Queue and steer while a response streams -You can keep typing while a response is streaming. Depending on the endpoint and your settings, pressing Enter either queues the message to send after the response, or steers an agent's current response. The composer tip names the action that Enter performs at that moment. +You can keep typing while a response is streaming. Depending on the endpoint and your settings, sending either queues the message to send after the response, steers an agent's current response, or interrupts it. Choose the default under **While generating, Enter will** in **Settings > Chat** (see [Personal Settings](/docs/features/settings#chat)). The send key is Enter only when **Press Enter to send messages** is on; otherwise it is Ctrl+Enter (Cmd+Enter). Queued messages appear in a **Queued messages** rail above the composer, where you can: @@ -115,17 +115,18 @@ For how steering works and when it is available, see [Steering and Queued Messag | Keys | Action | |---|---| -| Enter | Send the message (queue or steer while a response streams). | +| Enter | Sends the message by default (queues, steers or interrupts while a response streams, per **While generating, Enter will**). With **Press Enter to send messages** turned off, it inserts a new line instead. | | Shift+Enter | New line. | -| Ctrl+Enter (Cmd+Enter) | While a response streams: the alternate action, **send now** when Enter queues, or **queue** when Enter steers. | -| Alt+Enter (Option+Enter) | While an agent responds: interrupt and send, when available. | +| Ctrl+Enter (Cmd+Enter) | With **Press Enter to send messages** on (the default), inserts a new line, except while a response streams, where it runs the alternate action: **send now** when Enter queues, or **queue** when Enter steers. With the setting off, sends the message. | +| Alt+Enter (Option+Enter) | While an agent responds: **Interrupt** and send, when available. | +| Ctrl+Shift+Enter (Cmd+Shift+Enter) | While an agent responds: the same **Interrupt** action as Alt+Enter. | | Ctrl+Shift+X (Cmd+Shift+X) | Stop the response. | | `/` | Insert a saved prompt. | | `@` | Switch to another model, preset or agent. | | `+` | Add a model or preset for an additional response. | | `$` | Pick a skill for the next message. | -If you turned off **Press Enter to send messages**, Ctrl+Enter (Cmd+Enter) sends and Enter adds a new line. +Shortcuts can be rebound or turned off from the account menu; see [Keyboard Shortcuts](/docs/features/settings#keyboard-shortcuts). ### In the palette diff --git a/content/docs/features/image_gen.mdx b/content/docs/features/image_gen.mdx index 54bcef186..d25eed67e 100644 --- a/content/docs/features/image_gen.mdx +++ b/content/docs/features/image_gen.mdx @@ -157,9 +157,13 @@ Gemini Image Tools integrate Google's latest image generation models, supporting - **prompt**: detailed text description of the desired image (required, up to 32,000 characters) - **image_ids**: optional array of image IDs to use as visual context for generation +- **aspectRatio**: optional; one of `1:1` (default), `2:3`, `3:2`, `3:4`, `4:3`, `4:5`, `5:4`, `9:16`, `16:9`, or `21:9` +- **imageSize**: optional; `1K` (default), `2K`, or `4K` ### Setup +LibreChat picks credentials in this order: the user's own key (entered in the UI), `GEMINI_API_KEY`, `GOOGLE_KEY` (shared with the Google chat endpoint), then a Vertex AI service account. + For the Gemini API, get a key from [Google AI Studio](https://aistudio.google.com/app/apikey): ```bash filename=".env" @@ -173,6 +177,8 @@ GOOGLE_SERVICE_KEY_FILE=/path/to/service-account.json GOOGLE_CLOUD_LOCATION=us-central1 # optional, default: global ``` +`GOOGLE_LOC` is also accepted as the location when `GOOGLE_CLOUD_LOCATION` is not set. + ### Model Selection ```bash filename=".env" diff --git a/content/docs/features/import_convos.mdx b/content/docs/features/import_convos.mdx index 1f05e0726..13cfa90e4 100644 --- a/content/docs/features/import_convos.mdx +++ b/content/docs/features/import_convos.mdx @@ -4,10 +4,10 @@ icon: Import description: Conversations Import allows user to import conversations exported from other AI chat applications. Currently, we support importing conversations from ChatGPT, Claude, and ChatbotUI v1. --- -Conversations Import lets you bring conversations exported from other AI chat applications into LibreChat. Supported sources are [ChatGPT](https://chatgpt.com/), [Claude](https://claude.ai/), and [ChatbotUI v1](https://github.com/mckaywrigley/chatbot-ui/tree/b865b0555f53957e96727bc0bbb369c9eaecd83b?tab=readme-ov-file#legacy-code). +Conversations Import lets you bring conversations exported from other AI chat applications into LibreChat. Supported sources are [ChatGPT](https://chatgpt.com/), [Claude](https://claude.ai/), [ChatbotUI v1](https://github.com/mckaywrigley/chatbot-ui/tree/b865b0555f53957e96727bc0bbb369c9eaecd83b?tab=readme-ov-file#legacy-code), and LibreChat's own JSON export (see [Export from LibreChat](#export-from-librechat)). -Import lives under **Settings** → **Data Controls** in LibreChat. +Import lives under **Settings** > **Data & Privacy** > **Your data** > **Import conversations** in LibreChat. ## Export from the source application @@ -73,12 +73,12 @@ Export your conversations from [ChatbotUI v1](https://github.com/mckaywrigley/ch -**Open Data Controls.** In LibreChat, go to **Settings** → **Data Controls**. +**Open Data & Privacy.** In LibreChat, go to **Settings** > **Data & Privacy** and find **Import conversations** under **Your data**. -**Select your file.** Click **Import** and choose the `conversations.json` file from your extracted archive (or the exported JSON file for ChatbotUI v1). +**Select your file.** Click **Import** and choose the `conversations.json` file from your extracted archive (or the exported JSON file for ChatbotUI v1 or LibreChat). The file picker accepts `.json` files only, so extract ChatGPT and Claude zip archives first. @@ -88,13 +88,15 @@ Export your conversations from [ChatbotUI v1](https://github.com/mckaywrigley/ch +Administrators can cap the upload size with [`CONVERSATION_IMPORT_MAX_FILE_SIZE_BYTES`](/docs/configuration/dotenv#conversation-import). + ## Imported Code approval settings When importing a LibreChat conversation, its saved Code approval mode (including **Full access**) is not carried over. New imports use the recipient's existing preference/default and current deployment/worker policy. A bulk update cannot overwrite a locally stored approval choice. This safeguard does not retroactively reset existing conversations; users can still choose and save a supported mode through LibreChat. See [Attached-environment tool permissions](/docs/features/code_interpreter#attached-environment-tool-permissions). ## Export from LibreChat -Export is per conversation, and lives in the **Export and Share** menu in the chat header (under the overflow menu on mobile). Open the conversation you want, choose **Export**, pick a format, and confirm. +Export is per conversation, and lives in the **Chat options** menu in the chat header (under the overflow menu on mobile), alongside **Share**, **Rename**, **Pin**, **Duplicate**, **Archive** and **Delete**. Open the conversation you want, choose **Export**, pick a format, and confirm. +A `json` export can be imported back into LibreChat from **Settings** > **Data & Privacy** > **Your data** > **Import conversations**. + Two options in the dialog depend on the format you pick: - **Export all message branches** applies to `json` and `csv` only. Other formats export just the visible branch. diff --git a/content/docs/features/insights.mdx b/content/docs/features/insights.mdx index fb4ea6ac6..8bf7867db 100644 --- a/content/docs/features/insights.mdx +++ b/content/docs/features/insights.mdx @@ -4,7 +4,7 @@ icon: ChartColumn description: Review tenant-scoped LibreChat usage and activity from MongoDB. --- -Admin Insights is an opt-in dashboard for reviewing LibreChat activity stored in the deployment's primary MongoDB. It reports conversations, unique users, persisted messages, and recorded tokens over time, with top-user, churn, and recent-conversation views. +Admin Insights is an opt-in dashboard for reviewing how Agents are used, from activity stored in the deployment's primary MongoDB. It reports conversations, unique users, persisted messages, and recorded tokens over time for the Agents the viewer can see, with top-user, churn, and recent-conversation views. ## Enable Insights @@ -14,36 +14,40 @@ Set `ENABLE_INSIGHTS=true` in `.env`, then restart LibreChat: ENABLE_INSIGHTS=true ``` -When enabled for an authorized account, **Insights** appears in the desktop sidebar and mobile panel switcher. When disabled, the access and data routes return `404` and the navigation item stays hidden. +When enabled for an account that can see at least one Agent's insights, **Insights** appears in the desktop sidebar and mobile panel switcher. When disabled, the access and data routes return `404` and the navigation item stays hidden. ## Access Requirements -The signed-in account must satisfy all three checks: +Which Agents a signed-in account can review depends on who it is: -- Have the `ADMIN` role -- Hold the `access:admin` system capability -- Hold the `read:insights` system capability +- Accounts with the `ADMIN` role see all Agents. +- Accounts that hold the `read:insights` system capability see all Agents. +- Everyone else sees only the Agents on which they hold both **VIEW** and **View insights** through the Agent's access list. -Use the [Admin Panel](/docs/features/admin_panel) to assign system capabilities. Every Insights query derives tenant scope from the authenticated administrator. Tenant administrators only see records for their own tenant; an administrator without a tenant sees only unscoped records. +`GET /api/insights/access` returns `403` only when no Agent is accessible to the account, and the dashboard routes return `403` when a request names an Agent outside that set. + +Only administrators can grant **View insights** on an Agent. It is a separate toggle in the Agent's share dialog that other users do not see, and it cannot be granted to public principals. Administrators always have access. Use the [Admin Panel](/docs/features/admin_panel) to assign the `read:insights` capability, and see [Access Control](/docs/features/access_control) for the permission bits. + +Every Insights query derives tenant scope from the authenticated account. Tenant accounts only see Agents and records for their own tenant; an account without a tenant sees only unscoped records. Insights can display user names and email addresses, conversation IDs, and the first message from - recent conversations. Grant `read:insights` only to administrators who should review this data. + recent conversations. Grant `read:insights` or **View insights** only to people who should review this data. ## Dashboard Metrics -The four summary metrics and their daily sparklines use the selected date range: +Metrics are scoped to conversations with the Agents the viewer can see, narrowed by the Agent filter. The four summary metrics and their daily sparklines use the selected date range: -- **Conversations:** conversations created in the range -- **Unique users:** users represented by matching persisted message activity -- **Messages:** persisted user and assistant messages attributed to those users +- **Conversations:** conversations with the selected Agents created in the range +- **Unique users:** users represented by matching persisted message activity in those conversations +- **Messages:** persisted user and assistant messages in those conversations - **Tokens:** the sum of recorded message `tokenCount` values The dashboard also includes: - **Top users:** up to eight users ordered by message count, with their conversation and message totals -- **Churned users:** up to eight users whose latest message sent to an assistant became 28 days old during the selected range +- **Churned users:** up to eight users whose latest message sent to any selected Agent became 28 days old during the selected range - **Latest conversations:** paginated conversations with date, owner, first message, persisted message count, and recorded tokens These are database activity metrics, not billing or Langfuse analytics. Token totals depend on the values persisted with messages and do not calculate monetary cost. diff --git a/content/docs/features/mcp.mdx b/content/docs/features/mcp.mdx index 3aa008a13..e99ea19bc 100644 --- a/content/docs/features/mcp.mdx +++ b/content/docs/features/mcp.mdx @@ -165,13 +165,15 @@ Your new MCP server is also available in the Agent Builder, where you can add it #### Credential Variables for UI-Created Servers -When adding an MCP server through the UI, you can require users to provide their own API keys. In the Authentication section of the MCP Server Builder dialog, select "API Key" and check **"User provides key"**. Choose the header format (Bearer, Basic, or Custom) and save the server. +When adding an MCP server through the UI, you can require users to provide their own API keys. In the Authentication section of the MCP Server Builder dialog, select **API Key** and check **Each user provides their own key**. Choose the header format (Bearer, Basic, or Custom) and save the server. + +The authentication options are **None (Auto-detect)**, **API Key**, **OAuth**, and **On-Behalf-Of (OBO)**. OBO appears only for users who may configure it, which an administrator controls with [`interface.mcpServers.configureObo`](/docs/configuration/librechat_yaml/object_structure/interface#mcpservers). OBO requires OpenID Connect authentication such as Entra ID, and you set the scopes to request for the downstream server. Behind the scenes, LibreChat creates a destination-bound `customUserVars` entry named `MCP_API_KEY_` and configures the matching authentication header. The name is managed automatically; users still enter their key in the MCP Tool Select Dialog or MCP Settings panel. Existing servers may retain the legacy `MCP_API_KEY` name while their request boundary is unchanged. This uses the same key-entry UI as [YAML-defined `customUserVars`](#user-provided-credentials). Changing a UI-created server's URL (including path or query), proxy, transport, authorization format, custom auth header, or configured OAuth client/destination requires each user to enter a key for the new boundary. Old saved keys are not forwarded to that replacement destination. Cosmetic edits, equivalent normalized URLs, and fragment-only outbound URL edits preserve the existing key. Shared servers can resolve only credential variables declared by their current configuration, so an editor cannot reference an old generated name to recover a previous key. No bulk credential migration is needed. Upgrade **every API replica**, including replicas serving server-edit requests, before relying on this protection; an older writer can still recreate an unbound configuration. -When an administrator or user API key is configured, LibreChat treats the server as API-key authenticated and skips OAuth auto-detection. An explicit OAuth configuration still takes precedence. If a UI-created API-key server was saved by an older LibreChat version and remains stuck in **OAuth Required**, edit and save the server once so its stored connection metadata is refreshed. +When an administrator or user API key is configured, LibreChat treats the server as API-key authenticated and skips OAuth auto-detection. An explicit OAuth configuration still takes precedence. If a UI-created API-key server was saved by an older LibreChat version and remains stuck in **Needs Auth**, edit and save the server once so its stored connection metadata is refreshed. For security, UI-created (DB-sourced) MCP servers can **only** resolve `customUserVars` placeholders (`{{VAR_NAME}}`). Server-side environment variables (`${ENV_VAR}`), user profile fields (`{{LIBRECHAT_USER_*}}`), and OIDC tokens (`{{LIBRECHAT_OPENID_*}}`) are intentionally blocked to prevent unauthorized access to server secrets or other users' data. For full placeholder support, configure the server in `librechat.yaml` instead. @@ -232,12 +234,12 @@ LibreChat displays dynamic status icons showing the current state of each MCP se **Status Types:** -- **Connected** (green gear): Server is connected and has configurable customUserVars -- **OAuth Required** (amber key): Server requires OAuth authentication -- **Disconnected** (orange plug): Server connection failed or lost -- **Initializing** (blue loader): Server is starting up or reconnecting -- **Error** (red triangle): Server encountered an error -- **Cancelling** (red x): OAuth flow is being cancelled +- **Connected**: The server is connected. If it defines `customUserVars`, a key button lets you configure them. +- **Connecting** and **Initializing**: A spinner shows while the server connects or starts. When an OAuth flow can be cancelled, hovering the spinner reveals a cancel control. +- **Needs Auth**: The server is disconnected and requires OAuth authentication. +- **Disconnected** and **Error**: The connection failed or was lost. A connect button (plug icon) lets you retry. +- **On-demand**: The server connects only while serving a request, so there is no persistent connection to show. +- **Unknown**: No status is available yet. ### Cancelling OAuth from the Agent Tool Dialog @@ -281,11 +283,15 @@ LibreChat classifies Streamable HTTP responses from the parsed `Content-Type` me ### MCP Settings Panel Visibility -The MCP Settings Panel appears in the right sidebar when LibreChat detects MCP servers that might require user intervention during their initialization. The panel will be visible when any configured server meets one of these criteria: +The MCP Settings panel appears in the right sidebar when the user has `USE` access to MCP servers and at least one MCP server is available to them, or when the user has `CREATE` access to MCP servers. Servers that need user input, such as those with `customUserVars`, OAuth, or `startup: false`, are initialized from this panel. + +### MCP Apps + +MCP servers can return interactive interfaces (MCP Apps) alongside tool results. When MCP Apps are enabled, a tool result that includes an app shows an **Open app** control, and **Close app** hides it again. Apps render inside a sandboxed frame, and the number of apps open at once is limited: close another app before opening a new one. -- **Custom User Variables**: Server has `customUserVars` defined which may contain user-provided credentials -- **OAuth Authentication**: Server is detected as requiring OAuth authentication during startup -- **Manual Initialization**: Server has `startup: false` configured, requiring manual initialization +An app cannot act on its own. When it asks to call a tool, LibreChat shows **Run tool from app?**, and when it asks to post a message, **Send message from app?**. Sending a message starts a model response in the current conversation, so the selected agent and its tools may be used. The app can proceed only after you approve the request. MCP Apps are not viewable in shared conversations. + +Administrators enable apps with [`mcpSettings.apps`](/docs/configuration/librechat_yaml/object_structure/mcp_settings#apps) and configure the sandbox with [`mcpAppSandbox`](/docs/configuration/librechat_yaml/object_structure/mcp_app_sandbox). ## LibreChat-Specific Features @@ -428,6 +434,8 @@ mcpServers: LibreChat supports OAuth authentication for MCP servers, following Anthropic's recommendation for secure MCP connections. OAuth provides a standardized, secure way to authenticate without storing long-lived credentials. +By default, LibreChat asks the user to sign in when a conversation turn starts. For servers whose tools are deferred, [`oauthPrompt: on_use`](/docs/configuration/librechat_yaml/object_structure/mcp_servers#oauthprompt) delays the sign-in prompt until the agent first calls one of the server's tools. + #### Supported OAuth Flows LibreChat MCP servers support OAuth 2.0 with: diff --git a/content/docs/features/message_actions.mdx b/content/docs/features/message_actions.mdx index 61c5c91d5..a8daccf30 100644 --- a/content/docs/features/message_actions.mdx +++ b/content/docs/features/message_actions.mdx @@ -35,7 +35,7 @@ Use **Fork** to branch a conversation from a selected message. See [Forking Conv Select text in a message and choose **Add to chat** to stage it as quoted context. You can attach up to 10 excerpts to one message, with up to 1,500 characters per excerpt. LibreChat sends the excerpts as Markdown blockquotes alongside the message text and any files. -During an active Agent run, quoted excerpts follow **Steer**, **Queue**, and **Interrupt & steer** messages and remain associated with the pending action across reconnects. On a current server, an ordinary queued follow-up also keeps its quoted excerpts through app restarts and replica handoffs. If an older replica cannot accept the quoted context during a rolling deployment, LibreChat returns it to the composer instead of silently dropping it. Manually selected Skills remain staged for the next full turn rather than being added to a mid-run steer. See [Steering and Queued Messages](/docs/features/agents#steering-and-queued-messages). +During an active Agent run, quoted excerpts follow **Steer**, **Queue**, and **Interrupt** messages and remain associated with the pending action across reconnects. On a current server, an ordinary queued follow-up also keeps its quoted excerpts through app restarts and replica handoffs. If an older replica cannot accept the quoted context during a rolling deployment, LibreChat returns it to the composer instead of silently dropping it. Manually selected Skills remain staged for the next full turn rather than being added to a mid-run steer. See [Steering and Queued Messages](/docs/features/agents#steering-and-queued-messages). ## Code Block Actions diff --git a/content/docs/features/mod_system.mdx b/content/docs/features/mod_system.mdx index 396097c7a..a614fee23 100644 --- a/content/docs/features/mod_system.mdx +++ b/content/docs/features/mod_system.mdx @@ -11,8 +11,9 @@ In production, you should have Cloudflare or some other DDoS protection in place ### Notes -- Uses Caching for basic security and violation logging (bans, concurrent messages, exceeding rate limits) - - In the near future, I will add **Redis** support for production instances, which can be easily injected into the current caching setup +- Uses caching for basic security and violation logging (bans, concurrent messages, exceeding rate limits) + - When `USE_REDIS=true`, violation scores and bans are stored in **Redis**, so they are shared across replicas. Without Redis they use the in-memory cache + - Violation scores expire after a quiet period set by `VIOLATION_SCORE_TTL` (milliseconds, default one hour; each new violation restarts the countdown, and a non-positive value disables expiry). See [Automated Moderation](/docs/configuration/mod_system) - Exceeding any of the rate limiters (login/registration/messaging) is considered a violation, default score is 1 - Non-browser origin is a violation - Default score for each violation is configurable @@ -22,8 +23,7 @@ In production, you should have Cloudflare or some other DDoS protection in place - `violations.json` keeps track of the total count for each violation per user - `logs.json` records each individual violation per user - Ban logs are stored in MongoDB under the `logs` collection. They are transient as they only exist for the ban duration - - If you would like to remove a ban manually, you would have to remove them from the database manually and restart the server - - **Redis** support is also planned for this. + - To remove a ban manually, remove the entry from the database and restart the server ### Rate Limiter Types @@ -41,9 +41,9 @@ Prevents abuse of the conversation import feature by limiting how many conversat - Automated scripts attempting to flood the system with imported data - Resource exhaustion from processing large numbers of imports -Default limits: -- IP-based: 100 imports per minute -- User-based: 50 imports per minute (disabled by default) +Default limits (both limiters are always applied): +- IP-based: 100 imports per 15 minutes +- User-based: 50 imports per 15 minutes #### Conversation Forking Rate Limiting Controls how often users can create forks (copies) of existing conversations. This prevents: @@ -51,9 +51,9 @@ Controls how often users can create forks (copies) of existing conversations. Th - Resource exhaustion from fork operations - Abuse of the forking feature for spam or data harvesting -Default limits: -- IP-based: 30 forks per minute -- User-based: 7 forks per minute (disabled by default) +Default limits (both limiters are always applied): +- IP-based: 30 forks per 1 minute +- User-based: 7 forks per 1 minute #### File Upload Rate Limiting Configured through the librechat.yaml file, this controls how often users can upload files to prevent storage abuse and bandwidth exhaustion. @@ -105,8 +105,8 @@ The project's current rate limiters are as follows (see below under setup for de - Login and registration rate limiting - `Optional:` Concurrent Message limiting (only X messages at a time per user) - `Optional:` Message limiting (how often a user can send a message, configurable by IP and User) -- `Optional:` Import conversation limiting (how often a user can import conversations, configurable by IP and User) -- `Optional:` Conversation forking limiting (how often a user can fork conversations, configurable by IP and User) +- Import conversation limiting (how often a user can import conversations, configurable by IP and User) +- Conversation forking limiting (how often a user can fork conversations, configurable by IP and User) - `Optional:` Text-to-Speech (TTS) limiting (configurable through [`librechat.yaml` config file](/docs/configuration/librechat_yaml/object_structure/config#ratelimits)) - `Optional:` Speech-to-Text (STT) limiting (configurable through [`librechat.yaml` config file](/docs/configuration/librechat_yaml/object_structure/config#ratelimits)) - `Optional:` File Upload limiting (configurable through [`librechat.yaml` config file](/docs/configuration/librechat_yaml/object_structure/config#ratelimits)) diff --git a/content/docs/features/navigation.mdx b/content/docs/features/navigation.mdx index 9163bb641..fdb7f1171 100644 --- a/content/docs/features/navigation.mdx +++ b/content/docs/features/navigation.mdx @@ -40,6 +40,21 @@ To come back to a chat later, open its menu and choose **Mark as unread**. The o Temporary chats never show as unread, and neither does a reply that has nothing to read, such as one stopped before its first token. For tab-title counts, desktop notifications, and sounds, see [Notifications](/docs/features/settings#notifications). +## Chat Options Menu + +The ellipsis button in the chat header opens **Chat options** for the open conversation (the label reads **Chat options, link active** while the chat has a shared link). On mobile, these items sit in the header overflow menu. The menu offers: + +- **Share**, when shared links are enabled and you may create them; see [Shareable Links](/docs/features/shareable_links). +- **Export**; see [Export from LibreChat](/docs/features/import_convos#export-from-librechat). +- **Rename**. +- **Pin** or **Unpin**. +- **Change project**, to move the chat into a [Project](/docs/features/projects) or remove it from one. +- **Duplicate**. +- **Archive** or **Unarchive**. +- **Delete**, after confirmation. + +The menu does not appear for a new chat or for search results, and **Pin**, **Change project** and **Archive** are not offered for a temporary chat. + ## Mobile Drawer On mobile, the sidebar opens as a full-screen drawer by default. Its header holds the sidebar toggle, a labeled panel switcher, a **New chat** icon button, and account controls, and stays the same on every panel. Users with access to the Agent Marketplace also see an **Agent Marketplace** row above the panel content. The bottom bar holds conversation search only, and only while the chat history panel is active. @@ -57,6 +72,6 @@ The drawer follows the gesture and settles open or closed based on distance and Open **Archived chats** from the account menu to browse or restore archived conversations, or switch the sidebar list to archived chats with **Show** in the [chat list menu](#filter-and-sort-the-chat-list). Newly archived chats are ordered by when they were archived. Conversations archived before LibreChat recorded that timestamp fall back to their creation date. -To clear the active chat list without deleting its conversations, use **Archive all chats** under **Settings > Data Controls > Your data** and confirm the action. +To clear the active chat list without deleting its conversations, use **Archive all chats** under **Settings > Data & Privacy > Your data** and confirm the action. Archiving, unarchiving, pinning, and unpinning no longer update a conversation's chat-activity time, so history and project activity remain based on actual conversation changes. diff --git a/content/docs/features/ocr.mdx b/content/docs/features/ocr.mdx index 5c9fcf444..114fafba9 100644 --- a/content/docs/features/ocr.mdx +++ b/content/docs/features/ocr.mdx @@ -11,19 +11,19 @@ OCR (Optical Character Recognition) in LibreChat is an optional enhancement for The "Upload as Text" feature (from the chat) works the same way: - Files matching `fileConfig.ocr.supportedMimeTypes` use OCR if available -- Falls back to text parsing if OCR is not configured +- Without OCR, PDF, DOCX, spreadsheet, and ODT files fall back to the [built-in document parser](#built-in-document-parser); images and other types the parser cannot read need OCR - Especially useful for images with text, scanned documents, and complex PDFs -- Processing priority: **OCR > STT > text parsing** +- Processing order: **OCR > RAG text extraction > built-in document parser > STT > plain text** - See the [Upload as Text](/docs/features/upload_as_text) documentation for details. ### File Context (for agents) When you upload files through the Agent Builder's File Context section: -1. Text is extracted using text parsing by default (OCR/STT if configured and file matches) +1. Text is extracted using the built-in document parser or plain text reading by default (OCR/STT if configured and file matches) 2. Extracted text is stored as part of the agent's system instructions 3. Agent can reference this context in all conversations -4. **OCR service is optional** - the feature works without it using text parsing +4. **OCR service is optional** - the feature works without it for plain text files and for documents the built-in parser handles Files uploaded as "File Context" are processed to extract text, which is then added to the Agent's system instructions. This is ideal for documents, code files, PDFs, or images with text where you need the full text content to be included in the agent's instructions. @@ -31,7 +31,7 @@ Files uploaded as "File Context" are processed to extract text, which is then ad ## Optional OCR Configuration -Both Agent File Context and Upload as Text work out-of-the-box using text parsing. To enhance extraction quality for images and scanned documents, you can optionally configure an OCR service: +Both Agent File Context and Upload as Text work out-of-the-box for plain text files and for the document types the built-in parser handles. To extract text from images, scanned documents, and other formats, you can optionally configure an OCR service: ```yaml # librechat.yaml @@ -48,10 +48,21 @@ ocr: mistralModel: "mistral-ocr-latest" ``` -**Note:** The `context` capability is enabled by default. You only need to configure OCR (the `ocr` capability) if you want enhanced extraction quality for images and scanned documents. +**Note:** The `context` capability is enabled by default, as is `ocr` in the default capability list. If you set a custom `endpoints.agents.capabilities` list that omits `ocr` while OCR is configured, uploads that match the OCR MIME types fail with "OCR capability is not enabled for Agents". OCR connections block private, loopback, link-local, and cloud-metadata destinations by default. For a trusted private OCR service, add its exact private host and port to [`ocr.allowedAddresses`](/docs/configuration/librechat_yaml/object_structure/ocr#allowedaddresses). This is an exemption from SSRF protection, so list only infrastructure you control. +## Built-in Document Parser + +When no OCR service handles a file, agent File Context and Upload as Text use a built-in `document_parser` strategy. It also serves as the fallback if a configured OCR service fails. It handles only: + +- PDF (text layer only, no image recognition) +- DOCX (not legacy `.doc`) +- Spreadsheets: xlsx, xls, and ods +- ODT + +Files larger than 15 MB are rejected by the parser, and a document with no extractable text returns an error. PowerPoint files, `.doc`, EPUB, and images require an OCR service (or the RAG API text route, see [Upload as Text](/docs/features/upload_as_text)). + ## Overview of OCR Capabilities OCR functionality in LibreChat allows: @@ -165,9 +176,9 @@ ocr: 3. Download the service account JSON key file 4. Set the `GOOGLE_SERVICE_KEY_FILE` environment variable using one of the supported methods -### 4. Custom OCR (Planned) +### 4. Custom OCR (Not Implemented) -Support for custom OCR providers and user-defined strategies is planned for future releases. +`custom_ocr` appears as a value in the strategy list, but LibreChat has no implementation behind it. Support for custom OCR providers and user-defined strategies is planned for future releases. ### 5. Upload Files to Provider (Direct) @@ -217,7 +228,7 @@ fileConfig: Files matching these patterns will use OCR when: - Uploaded to agent file context (always, if OCR is configured) -- Uploaded as text in chat (if OCR is configured; otherwise falls back to text parsing) +- Uploaded as text in chat (if OCR is configured; otherwise the built-in document parser or plain text reading applies where it supports the file) For more details on file processing configuration, see [File Config Object Structure](/docs/configuration/librechat_yaml/object_structure/file_config). diff --git a/content/docs/features/rag_api.mdx b/content/docs/features/rag_api.mdx index c5ee81f8f..25043412d 100644 --- a/content/docs/features/rag_api.mdx +++ b/content/docs/features/rag_api.mdx @@ -14,11 +14,9 @@ It leverages LangChain, PostgresQL + PGVector, and Python FastAPI to index and r --- -**Currently, this feature is available through [Agents](/docs/features/agents), as well as through Custom Endpoints, OpenAI, Azure OpenAI, Anthropic, and Google.** +In LibreChat, RAG powers the [Agents](/docs/features/agents#file-search) **File Search** capability (`file_search`). Files attached to an agent's File Search, or to a run that selects File Search, are indexed by the RAG API and retrieved on demand. Other chat endpoints do not use RAG indexing or retrieval, though they can still use the RAG API to extract text, as described below. -OpenAI Assistants have their own implementation of RAG through the "Retrieval" capability. Learn more about it [here.](https://platform.openai.com/docs/assistants/tools/knowledge-retrieval) - -It will still be useful to implement usage of the RAG API with the Assistants API since OpenAI charges for both file storage, and use of "Retrieval," and will be introduced in a future update. +The RAG API also exposes a `/text` route that LibreChat can use to extract text from uploads; see [Upload as Text](/docs/features/upload_as_text#what-happens-under-the-hood) for when it applies. **Still confused about RAG?** [Read the section I wrote below](#what-is-rag) explaining the general concept in more detail with a link to a helpful video. diff --git a/content/docs/features/resumable_streams.mdx b/content/docs/features/resumable_streams.mdx index 0524399f4..40503648b 100644 --- a/content/docs/features/resumable_streams.mdx +++ b/content/docs/features/resumable_streams.mdx @@ -67,7 +67,7 @@ REDIS_URI=redis://node1:7001,redis://node2:7002,redis://node3:7003 LibreChat uses hash-tagged keys so that multi-key operations land on the same cluster slot. -For high-token-rate deployments, `STREAM_DELTA_COALESCE_MS=25` can batch Redis delta publications and reduce Redis work at the cost of up to 25 ms of delivery latency. Leave it unset or set it to `0` to disable batching, and enable it only after every replica supports batch frames. See [Stream Delta Coalescing](/docs/configuration/redis#stream-delta-coalescing). +Redis delta publications are batched by default with a 25 ms window (`STREAM_DELTA_COALESCE_MS=25`), which reduces Redis work at the cost of up to 25 ms of delivery latency. Set a different positive value to change the window (values above 1000 are capped at 1000). Only an explicit `0`, or an invalid or non-positive value, disables batching; do that only if a replica in the deployment does not support batch frames. See [Stream Delta Coalescing](/docs/configuration/redis#stream-delta-coalescing). ## What Gets Reconstructed diff --git a/content/docs/features/scheduled_chats.mdx b/content/docs/features/scheduled_chats.mdx index 9713e4cbc..7a1319a2e 100644 --- a/content/docs/features/scheduled_chats.mdx +++ b/content/docs/features/scheduled_chats.mdx @@ -74,7 +74,27 @@ Each occurrence starts a new conversation with the selected Agent. Schedule card If a run pauses for Ask User or tool approval, its status becomes **Needs approval** and the conversation can be opened to complete the decision. LibreChat prevents overlapping occurrences of the same schedule and may skip an occurrence when another run is active or the account has insufficient balance. -Before consuming generation capacity, LibreChat checks every selected MCP tool required by the scheduled Agent and its runnable Subagent graph. A missing tool, unavailable server, revoked permission, incomplete catalog, or authentication flow requiring interaction prevents the run and identifies the Agent that needs repair. The schedule UI provides an **Open agent** recovery action. Disabled schedules can still be edited while an MCP server is unavailable. +Before consuming generation capacity, LibreChat checks every selected MCP tool required by the scheduled Agent and its runnable Subagent graph. A missing tool, unavailable server, revoked permission, incomplete catalog, or authentication flow requiring interaction prevents the run and identifies the Agent that needs repair. The schedule UI provides an **Open agent to reconnect MCPs** recovery action. Disabled schedules can still be edited while an MCP server is unavailable. + +### Scheduled MCP authorization + +When a deployment enables `interface.schedules.mcpConsent`, a schedule that uses MCP tools needs a stored **Scheduled MCP authorization** before it can run them unattended. The authorization covers only the listed Agent and resources until a fixed deadline. It does not reconnect a provider, enable the schedule, or permit writes. + +In the schedule editor you can: + +- Set the **Authorization lifetime (hours)**. +- Choose **Confirm authorization** to record it; the card then shows **Authorized** and an absolute expiry time. +- Choose **Revoke authorization** to withdraw it. + +The status reads **Authorization required** until you confirm, **Authorization expired** once the deadline passes, and **Authorization revoked** after a revoke. Changing the Agent, the schedule, or a resource binding invalidates the authorization, and you must review and confirm again. + +Administrators configure this under [`interface.schedules`](/docs/configuration/librechat_yaml/object_structure/interface#schedules): + +- `mcpConsent.enabled` turns the feature on. +- `mcpConsent.maxLifetimeHours` caps the authorization lifetime (1 to 8760 hours). +- `mcpConsent.resources` binds MCP resources that may be authorized. +- `mcpConsent.readOnlyPolicy` lists trusted read-only tool declarations, keyed by server and upstream tool name. +- `mcpReceiptRetry.baseMs` and `mcpReceiptRetry.maxMs` set the bounded exponential retry interval for consent receipts, with jitter. Schedules can disable themselves after repeated failures, or when their Agent is deleted, its configuration is invalid, access is revoked, the account lacks sufficient balance, a required project is missing, or the effective project was deleted or is not owned by the schedule owner. Project policy is rechecked at every run so tightening `requireProject` or changing a pin also applies to existing schedules. Fix the underlying issue before enabling the schedule again. diff --git a/content/docs/features/settings.mdx b/content/docs/features/settings.mdx index 29978a742..ad7aba068 100644 --- a/content/docs/features/settings.mdx +++ b/content/docs/features/settings.mdx @@ -4,7 +4,7 @@ icon: Settings description: Find and manage LibreChat's per-user and per-browser preferences. --- -Open your account menu and choose **Settings** to manage LibreChat's personal preferences and data controls. Use **Search settings** to find a control by its label or related keywords; selecting a result opens the matching tab and section. The settings layout adapts to mobile screens without hiding the tab navigation. +Open your account menu and choose **Settings** to manage LibreChat's personal preferences and data controls. The tabs are General, Chat, Speech, Data & Privacy and Account, plus About when the deployment shows it. Use **Search settings** to find a control by its label or related keywords; selecting a result opens the matching tab and section. The settings layout adapts to mobile screens without hiding the tab navigation. ## General @@ -18,7 +18,18 @@ Both regional preferences are stored in the current browser, so different device **Show chat beside the sidebar on mobile**, under **Layout**, is off by default. When enabled, the mobile drawer stops at 80% of the viewport and leaves a strip of the current conversation visible. Tapping that strip closes the drawer. The preference is stored in the current browser; see [Mobile Drawer](/docs/features/navigation#mobile-drawer). -**Show composer tips**, under **Layout**, is off by default and stored in the current browser. Turn it on to show keyboard shortcut hints in the message composer. +Other controls on this tab are stored in the current browser: + +| Setting | What it does | Default | +|---|---|---| +| UI scale | Scales the whole interface between 50% and 150%. Browser zoom is unaffected. | 100% | +| Message Font Size | Text size of messages: Extra Small, Small, Medium, Large or Extra Large. | Medium | +| Chat direction | Text direction of the chat: Auto, left to right or right to left. Auto resolves the direction from what is typed. | Auto | +| Maximize chat space | Gives the conversation more room on screen. | Off | +| Center Chat Input on Welcome Screen | Centers the composer on the welcome screen of a new chat. | On | +| Scroll to the end button | Shows a button that jumps to the latest message. | On | +| Keep screen awake during response generation | Asks the browser not to dim or lock the screen while a response is generated. | On | +| Show Lia on the Welcome Screen | Shows Lia, a decorative pixel mascot, around the composer on the welcome screen. Appears only when the deployment allows it. | Off | **Archived chats** is in the account menu rather than this tab; see [Archived Conversations](/docs/features/navigation#archived-conversations). @@ -36,18 +47,40 @@ These preferences are stored per device, so a laptop and a phone can differ; the **Switch to Chat History on new chat**, under **Conversations**, is on by default and stored in the current browser. Starting a new chat from the sidebar while another panel, such as Prompts or Memories, is open switches the sidebar back to the chat list. Turn it off to keep the current panel. -**Auto-Scroll to latest message on chat open** moves a newly opened conversation to its newest rendered message. Turn it off to preserve the current scroll position when returning to a chat. LibreChat waits for the target conversation rows to render before landing, including when navigation and message loading finish at different times. +**Auto-Scroll to latest message on chat open** is on by default and moves a newly opened conversation to its newest rendered message. Turn it off to preserve the current scroll position when returning to a chat. LibreChat waits for the target conversation rows to render before landing, including when navigation and message loading finish at different times. -**Resize images before upload** lets a user downscale large JPEG, PNG, and WebP files in the browser before sending them. The preference defaults to off and is stored in the current browser. +**Resize images before upload** lets a user downscale large JPEG, PNG, and WebP files in the browser before sending them. The preference defaults to on and is stored in the current browser. Administrators control whether this remains a personal choice. If [`fileConfig.clientImageResize.enabled`](/docs/configuration/librechat_yaml/object_structure/config#clientimageresize) is explicitly set to `true` or `false`, LibreChat enforces that value and locks the user toggle. If the field is omitted, the user's setting applies. **Paste long text as a file** is enabled by default and stored in the current browser. When Upload as Text context uploads are available, pasting more than 2,500 characters in the normal message composer attaches the text as `pasted-text.txt` instead of filling the input. Shorter pastes and pastes made without the `context` capability remain inline. See [Upload Files as Text](/docs/features/upload_as_text#paste-long-text-as-a-file). -**Collapse long user messages** is off by default. When enabled, user messages taller than 256 pixels open as a compact preview with **Show more** and **Show less** controls. The collapse is visual only: the complete message remains available to copying, browser search, and assistive technology. +**Collapse long user messages** is on by default. When enabled, user messages taller than 256 pixels open as a compact preview with **Show more** and **Show less** controls. The collapse is visual only: the complete message remains available to copying, browser search, and assistive technology. **Parsing LaTeX in messages** is enabled by default. The toggle controls the ambiguous single-dollar `$...$` inline-math form, which follows boundary rules that keep currency-like text such as `$50` literal. Unambiguous `$$...$$`, `\(...\)`, and `\[...\]` math remains supported when the toggle is off. Inline code, fenced code, and automatic links are not interpreted as single-dollar math. +The send key is covered in the [composer](/docs/features/composer#keyboard-shortcuts). The other controls on this tab are stored in the current browser: + +| Setting | What it does | Default | +|---|---|---| +| Press Enter to send messages | When on, Enter sends. When off, Enter inserts a new line and Ctrl/Cmd+Enter sends. | On | +| While generating, Enter will | What sending does while a response streams: Steer, Interrupt or Queue. See [Steering and Queued Messages](/docs/features/agents#steering-and-queued-messages). | Steer | +| Save drafts locally | Keeps unsent text and attachments as drafts on this device, and deletes them once the message is sent. | On | +| Save badges state | Keeps the chat badges (tools) as they were when you start a new chat, instead of resetting them. | Off | +| Toggle command "@" for switching endpoints, models, presets, etc. | Turns the `@` command on or off. | On | +| Toggle command "+" for adding a multi-response setting | Turns the `+` command on or off. Shown only when multi-response is available. | On | +| Toggle command "/" for selecting a prompt via keyboard | Turns the `/` command on or off. Shown only when prompts are available. | On | +| Render user messages as markdown | Renders your own messages as Markdown. | On | +| Display username in messages | Shows your username above your messages instead of "You". | On | +| Open Thinking Dropdowns by Default | Expands model reasoning blocks instead of collapsing them. | Off | +| Auto-expand tool details | Expands tool call details by default. | Off | +| Advanced prompts editor | Enables versioning and production control for prompts. | Off | +| Always make new prompt versions production | Marks each new prompt version as the production version. Turning off the advanced prompts editor sets it back to on. | On | +| Send prompts on select | Submits a prompt to the chat as soon as you select it. | On | +| Enable switching Endpoints mid-conversation | Lets you change endpoint or model within one conversation. | On | + +Voice input and playback live on the **Speech** tab; see [Speech Settings](/docs/configuration/stt_tts). + ## Model Parameters The model **Parameters** panel in the side panel groups a conversation's settings under headings: **Identity**, **Sampling**, **Limits**, **Reasoning**, **Context**, **Advanced**, and **Misc.** Only sections that the current endpoint uses appear, and settings the panel does not recognize, such as a custom endpoint's own parameters, are listed under **Misc.** A heading shows how many settings in that section the conversation has changed, so you can see what differs before choosing **Reset**. **Reset** and **Save As Preset** sit together at the bottom of the panel. See [Presets](/docs/user_guides/presets). @@ -58,18 +91,56 @@ Open **Keyboard Shortcuts** from the account menu to review or customize binding Shortcut enablement and custom bindings are stored in the current browser. Binding rows remain visible while shortcuts are off, but editing and reset controls stay disabled until shortcuts are enabled again. -## Data Controls +## Data & Privacy -The **Data Controls** tab groups personal data-management actions in one place: +The **Data & Privacy** tab is divided into sections: -- **Manage files** opens the uploaded-file manager. -- **Import conversations** imports a supported conversation export. -- **Shared chats** lists and manages published conversation links. -- **Provider API keys** manages keys supplied for configured providers. -- **Revoke all provider API keys** removes every user-provided provider key. -- **Default stateful workspace**, under **Code execution**, selects the workspace scope proposed for newly created Agents. It appears only when Stateful Code Sessions are available; changing it does not enable stateful sessions or alter existing Agents. -- **Delete TTS cache storage** removes text-to-speech audio cached in the browser; it is unavailable when the cache is empty. -- **Archive all chats** moves active conversations into **Archived chats** after confirmation without deleting them. -- **Delete all chats** permanently removes the user's conversations after confirmation. +- **Memory**: **Reference saved memories** lets the assistant use your saved memories when responding. It is saved to your account and appears only when memory preferences apply to your deployment. +- **Code execution**: **Default stateful workspace** selects the workspace scope proposed for newly created Agents. It appears only when Stateful Code Sessions are available; changing it does not enable stateful sessions or alter existing Agents. **Code environments** pairs a sandboxed worker running on a VM you control, under the same availability condition. +- **Your data**: **Manage files** opens the uploaded-file manager. **Import conversations** imports a supported conversation export. **Shared chats** lists and manages published conversation links. **Archive all chats** moves active conversations into **Archived chats** after confirmation without deleting them. **Allow analytics** changes your answer to the analytics prompt and appears only when the deployment configured analytics. +- **API keys**: **Provider API keys** manages keys supplied for configured providers and appears only when an endpoint takes user-provided keys. **Agent API keys** manages keys for the Agents API and appears only when remote agents are available. **Revoke all provider API keys** removes every user-provided provider key. +- **Danger zone**: **Delete cache** removes text-to-speech audio cached in the browser; it is unavailable when the cache is empty. **Delete all chats** permanently removes the user's conversations after confirmation. Data deletion and key-revocation actions are server-backed and can be irreversible. Browser-only preferences and caches apply to the current browser profile rather than every device. + +## Account + +The **Account** tab holds profile, security, billing and deletion controls. Several appear only when the deployment supports them: + +| Setting | What it does | +|---|---| +| Avatar | Changes your profile picture. | +| Backup codes | Shows and regenerates two-factor backup codes. Appears only when two-factor authentication is enabled. | +| Token balance | Shows your token credits. Appears only when balance tracking is enabled. | +| Auto-refill | Shows or configures automatic balance refills. Appears only when balance tracking is enabled. | +| Delete account | Permanently deletes your account and data. Appears only when the deployment allows account deletion. | + +## Default Keyboard Shortcuts + +These are the shortcuts bound by default. Cmd replaces Ctrl on macOS. Rebind them under [Keyboard Shortcuts](#keyboard-shortcuts). + +| Action | Keys | +|---|---| +| Show keyboard shortcuts | Ctrl+Shift+/ | +| New chat | Ctrl+Shift+O | +| Focus chat input | Shift+Esc | +| Copy last response | Ctrl+Shift+; | +| Upload file | Ctrl+Shift+U | +| Submit message | Ctrl+Enter, which sends only when **Press Enter to send messages** is off. With that setting on (the default), Ctrl+Enter inserts a new line; see [Composer](/docs/features/composer#keyboard-shortcuts). | +| Toggle sidebar | Ctrl+Shift+S | +| Open model selector | Ctrl+Shift+M | +| Focus search | Ctrl+/ | +| Settings | Ctrl+Shift+, | +| Bookmark conversation | Ctrl+Shift+B | +| Stop generating | Ctrl+Shift+X | +| Interrupt now | Ctrl+Shift+. | +| Regenerate response | Ctrl+Shift+E | +| Edit last message | Ctrl+Shift+I | +| Copy last code block | Ctrl+Shift+K | +| Scroll to top | Ctrl+Shift+↑ | +| Scroll to bottom | Ctrl+Shift+↓ | +| Temporary Chat | Ctrl+Shift+Y | +| Archive conversation | Ctrl+Shift+L | +| Delete conversation | Ctrl+Shift+Backspace | +| Continue response | Ctrl+Shift+C | +| Read last response aloud | Ctrl+Shift+V | diff --git a/content/docs/features/shareable_links.mdx b/content/docs/features/shareable_links.mdx index 7b4b6c9f2..dcb0de67e 100644 --- a/content/docs/features/shareable_links.mdx +++ b/content/docs/features/shareable_links.mdx @@ -51,9 +51,10 @@ Creating a link opens a modal where you control how the conversation appears to Once a link exists, the modal offers these actions: - **Update link**: Republish the latest messages through the selected branch tail and the current file-sharing choice while keeping the same URL. -- **Generate QR code**: Create a QR code for mobile access. -- **Copy link to clipboard**: Copy the shareable URL. -- **Delete link**: Remove the link and revoke access for anyone who has it. +- **Show QR Code** / **Hide QR Code**: Toggle a QR code for mobile access. +- **Copy link**: Copy the shareable URL. +- **Manage Access**: Open the access dialog to control who can open the link. It appears only when your role has the share permission for shared links and you hold the share bit on that link. +- **Delete Link**: Remove the link and revoke access for anyone who has it. When file snapshots are enabled, users can choose whether the link includes files referenced in the published messages. The selected files are pinned to that share revision and served through share-specific routes without granting access to the owner's live file ACL. Updating the link replaces the pinned set and file-sharing choice; stable file URLs revalidate so a removed or replaced snapshot is not served from an older browser cache. @@ -117,7 +118,7 @@ Viewers can adjust the interface to their own preferences without affecting your ## Managing Your Shared Links -Open the Shared Links dashboard under **Settings → Data Controls** to review every conversation you've shared. +Open the **Shared chats** dashboard under **Settings > Data & Privacy > Your data > Shared chats** to review every conversation you've shared. ![Shared links management dashboard](/images/shared-links/management-modal.png) diff --git a/content/docs/features/subagents.mdx b/content/docs/features/subagents.mdx index 65d1381ec..ca47e665a 100644 --- a/content/docs/features/subagents.mdx +++ b/content/docs/features/subagents.mdx @@ -14,18 +14,18 @@ Use subagents for: - Multi-agent team workflows that should execute behind one delegated task - Parallel-style decomposition where the parent coordinates and summarizes -## How Subagents Differ from Agent Chain +## How Subagents Differ from Handoffs -Agent Chain builds a multi-agent graph where agents pass results through configured chain steps. Subagents are spawned by an agent as a tool call during a run. +Handoffs transfer the conversation from a primary agent to a specialist agent, which then continues the exchange. Subagents are spawned by an agent as a tool call during a run, do their work in isolation, and return a compact result to the parent. -- **Agent Chain**: graph-level multi-agent workflow -- **Subagents**: runtime delegation from a parent agent to isolated child runs +- **Handoffs**: the conversation moves to another agent +- **Subagents**: runtime delegation from a parent agent to isolated child runs, with the parent staying in control -Both can use existing agents, but subagents are designed for scoped delegation from inside a single agent's reasoning loop. +Both can use existing agents, but subagents are designed for scoped delegation from inside a single agent's reasoning loop. Legacy Agent Chains are deprecated; use Handoffs or Subagents for new orchestration. See [Agents](/docs/features/agents#handoffs). ## Enable the Capability -The `subagents` capability is enabled by default. Admins can remove it from the agents endpoint capability list to disable the feature. +The `subagents` capability is enabled by default. Admins can remove it from the agents endpoint capability list to disable the feature. The default capability list is: ```yaml filename="librechat.yaml" endpoints: @@ -40,19 +40,23 @@ endpoints: - 'actions' - 'context' - 'skills' + - 'memory' + - 'ask_user_question' - 'tools' - - 'chain' - 'ocr' ``` +If you set `capabilities` yourself, list every capability you want to keep, because your list replaces the default. Background execution (`run_in_background`) is not in the default list; see [Detached Subagent Threads](#detached-subagent-threads). + ## Configure an Agent -In the Agent Builder, open **Advanced Settings** and enable **Subagents**. +In the Agent Builder, open **Add tools**, choose **Subagents** in the tool library, and turn on the enable switch (**Enable subagents**). Available settings: - **Enable subagents**: adds the subagent spawn tool to the agent. - **Allow self-spawn**: lets the agent spawn a fresh copy of itself in an isolated context. This is enabled by default when subagents are enabled. +- **Share files with subagents**: shares the message's files with authorized foreground subagents. This option appears only when `endpoints.agents.fileSharing.enabled` is true. - **Additional subagents**: selects specific agents the parent may spawn. Saved Agent teams are embedded as `subagents.graphs` in Agent create or update payloads. The current Agent Builder preserves these definitions while you edit the self-spawn and individual-Agent settings, but it does not author graph definitions. Each team names a bounded directed acyclic graph, its entry Agent, and the Agent whose result is returned to the parent: @@ -127,7 +131,7 @@ Across later turns, LibreChat keeps prior calls from reachable child and team to ## Detached Subagent Threads -When `run_in_background` is enabled for the Agents endpoint, a parent Agent can detach subagent work and continue without waiting for it. LibreChat persists each detached child with private execution lineage and a canonical transcript. Child threads stay out of normal conversation navigation and search and cannot be read directly; the authorized parent view exposes only bounded child activity. +`run_in_background` is opt-in: add it to `endpoints.agents.capabilities` to enable it for the Agents endpoint. When it is enabled, a parent Agent can detach subagent work and continue without waiting for it. LibreChat persists each detached child with private execution lineage and a canonical transcript. Child threads stay out of normal conversation navigation and search and cannot be read directly; the authorized parent view exposes only bounded child activity. Child threads are view-only execution records. A user cannot edit or delete the canonical child in place. For a completed durable direct-Agent child, **Continue in a new chat** forks the exact completed branch into a separate normal, writable Agent conversation while leaving the original child hidden and read-only. The activity panel keeps one composer mounted throughout the run and across incoming task deliveries, preserving focus and half-typed guidance while a new task view loads. Submission remains unavailable until the task can accept controls. Text entered after settlement is carried into the fork, and a failed fork restores the draft in the panel. This action is unavailable for running, graph, anonymous-Agent, and shared views. Deleting the parent cascades to its child lineage. The parent Agent can poll, steer, queue, interrupt, cancel, collect, and later continue the canonical child through its task tools; Mongo-backed leases serialize those continuations across API replicas. diff --git a/content/docs/features/upload_as_text.mdx b/content/docs/features/upload_as_text.mdx index fb5324c3a..ae1bb141c 100644 --- a/content/docs/features/upload_as_text.mdx +++ b/content/docs/features/upload_as_text.mdx @@ -11,7 +11,7 @@ Ever wanted to hand a PDF, a code file, or a spreadsheet to the AI and just say You attach a file, LibreChat extracts the text from it, and the full content gets pasted straight into your conversation. The AI can then read every word of it — no plugins, no vector databases, no extra services to configure. It works out of the box. - Upload as Text works immediately on any LibreChat instance. It uses built-in text parsing — you don't need OCR, a RAG pipeline, or any external service to get started. + Upload as Text works immediately on any LibreChat instance. It uses a built-in document parser for common formats, so plain text, code, PDF, DOCX, spreadsheets, and ODT work without OCR, a RAG pipeline, or any external service. Images and some office formats do need an extra service; see [Which files are supported](#which-files-are-supported). --- @@ -66,32 +66,35 @@ Pasted-text attachments follow the same file-size, token, and [`fileTokenLimit`] When an upload is routed to text, LibreChat doesn't dump raw bytes into the prompt. It runs through a processing pipeline to extract clean, readable text: 1. **MIME type detection** — LibreChat checks what kind of file you uploaded (PDF, image, audio, source code, etc.) by inspecting its MIME type. -2. **Method selection** — Based on the file type and what services are available, it picks the best extraction method using this priority: +2. **Method selection**: Based on the file type and what services are available, it picks an extraction method in this order: | Priority | Method | When it's used | |----------|--------|---------------| - | 1st | **OCR** | File is an image or scanned document, _and_ OCR is configured | - | 2nd | **STT** (Speech-to-Text) | File is audio, _and_ STT is configured | - | 3rd | **Text parsing** | File matches a known text MIME type | - | 4th | **Fallback** | None of the above matched — tries text parsing anyway | + | 1st | **OCR** | OCR is configured _and_ the file matches `fileConfig.ocr.supportedMimeTypes`. If OCR fails, LibreChat falls back to the built-in document parser. | + | 2nd | **RAG API `/text`** | `RAG_API_URL` is set, `fileConfig.text.supportedMimeTypes` has been narrowed, and the file matches it. If the RAG API is unavailable, LibreChat falls back to the built-in document parser. | + | 3rd | **Built-in document parser** | File is a PDF, DOCX, xlsx/xls/ods spreadsheet, or ODT, up to 15 MB. | + | 4th | **STT** (Speech-to-Text) | File is audio and matches `fileConfig.stt.supportedMimeTypes`. | + | 5th | **Plain text** | File matches `fileConfig.text.supportedMimeTypes`. Text and code files are read directly; other types are sent to the RAG API `/text` route when `RAG_API_URL` is set, and fail otherwise. | + + A file that matches none of these is rejected as not supported for text parsing. **A `.pdf` on an instance with OCR configured:** → OCR kicks in. Great for scanned docs and complex layouts. **A `.pdf` on a default instance (no OCR):** - → Text parsing handles it. Works well for digitally-created PDFs. + → The built-in document parser handles it. Works well for digitally-created PDFs. **A `.py` Python file:** - → Straight to text parsing. Source code is already text — no conversion needed. + → Plain text. Source code is already text, so no conversion is needed. **An `.mp3` on an instance with STT configured:** → Speech-to-Text transcribes it into text for the conversation. **A `.png` screenshot with no OCR configured:** - → Falls back to text parsing (limited results — consider setting up OCR for images). + → The upload returns an error rather than text. Configure OCR for images. @@ -114,16 +117,21 @@ When you preview or download an Upload as Text attachment, LibreChat serves the - Shell scripts, SQL files - Text parsing handles these out of the box. If OCR is configured, it takes over for better accuracy on complex layouts. + The built-in document parser handles these out of the box, up to 15 MB per file. If OCR is configured, it takes over for better accuracy on complex layouts. + + - **PDF**: digital text layer (scanned PDFs need OCR) + - **Word**: `.docx` (not legacy `.doc`) + - **Spreadsheets**: `.xlsx`, `.xls`, `.ods` + - **OpenDocument text**: `.odt` + + These need OCR, or the RAG API `/text` route, because the built-in parser does not read them: - - **PDF** — digital and scanned (scanned PDFs benefit from OCR) - - **Word** — `.docx`, `.doc` + - **Word**: `.doc` - **PowerPoint** — `.pptx`, `.potx`, `.ppt` - - **Excel** — `.xlsx`, `.xls` - **EPUB** books - Images **require OCR** to produce useful text. Without it, results will be poor. + Images **require OCR** to produce text. Without it, the upload returns an error instead of text. - JPEG, PNG, GIF, WebP - HEIC, HEIF (Apple formats) @@ -218,7 +226,7 @@ fileConfig: ## Optional: boosting extraction with OCR -Text parsing works fine for digitally-created documents (PDFs saved from Word, code files, plain text). But if you're uploading **scanned documents, photos of pages, or images with text**, the built-in parser won't get great results. +The built-in parser works fine for digitally-created PDFs, DOCX, spreadsheets, ODT, code files, and plain text. But **scanned documents, photos of pages, images with text, and formats such as `.doc`, PowerPoint, and EPUB** need OCR. That's where OCR comes in. When configured, LibreChat automatically uses OCR for file types that benefit from it — you don't need to do anything differently as a user. @@ -254,7 +262,8 @@ This section is for admins who want to control which file types get processed by # Max tokens extracted from a single file before truncation fileTokenLimit: 100000 - # Files matching these MIME patterns use OCR (if configured) + # Example only: files matching these MIME patterns use OCR (if configured). + # These are examples for narrowing or extending, not required settings. ocr: supportedMimeTypes: - "^image/(jpeg|gif|png|webp|heic|heif)$" @@ -263,18 +272,19 @@ This section is for admins who want to control which file types get processed by - "^application/vnd\\.ms-(word|powerpoint|excel)$" - "^application/epub\\+zip$" - # Files matching these MIME patterns use text parsing + # Example only: narrowing this list sends the matching types to the RAG API /text + # route when RAG_API_URL is set text: supportedMimeTypes: - "^text/(plain|markdown|csv|json|xml|html|css|javascript|typescript|x-python|x-java|x-csharp|x-php|x-ruby|x-go|x-rust|x-kotlin|x-swift|x-scala|x-perl|x-lua|x-shell|x-sql|x-yaml|x-toml)$" - # Files matching these MIME patterns use STT (if configured) + # Example only: files matching these MIME patterns use STT (if configured) stt: supportedMimeTypes: - "^audio/(mp3|mpeg|mpeg3|wav|wave|x-wav|ogg|vorbis|mp4|x-m4a|flac|x-flac|webm)$" ``` - **Priority reminder:** OCR > STT > text parsing > fallback. + **Priority reminder:** OCR > RAG `/text` (when `RAG_API_URL` is set and the text list is narrowed) > built-in document parser > STT > plain text. For the full reference, see [File Config Object Structure](/docs/configuration/librechat_yaml/object_structure/file_config). @@ -297,10 +307,10 @@ This section is for admins who want to control which file types get processed by A few things to check: - - **Scanned PDFs / images** — These need OCR to extract text properly. Without it, the parser might return garbage or nothing. Ask your admin to [configure OCR](/docs/features/ocr). + - **Scanned PDFs / images**: These need OCR to extract text properly. Without it, the parser returns nothing for a scanned PDF and images return an error. Ask your admin to [configure OCR](/docs/features/ocr). - **Audio files** — These need STT. There's no text fallback for audio. - **Corrupted files** — Try opening the file locally to make sure it's not damaged. - - **Unsupported format** — If the MIME type doesn't match any configured pattern, LibreChat attempts a text parse fallback, which may not work for binary formats. + - **Unsupported format**: The built-in parser handles only PDF, DOCX, xlsx/xls/ods, and ODT (up to 15 MB). Formats such as `.doc`, PowerPoint, and EPUB need OCR or the RAG API `/text` route. A MIME type that matches no configured pattern is rejected. LibreChat returns the rejected MIME type in the upload error. Check the active endpoint's [`fileConfig.endpoints..supportedMimeTypes`](/docs/configuration/librechat_yaml/object_structure/file_config#supportedmimetypes-3) patterns and allow the canonical type you intend to accept. For shell scripts, use `application/x-sh`; LibreChat normalizes the common `application/x-shellscript` and `text/x-shellscript` variants before matching. @@ -314,7 +324,7 @@ This section is for admins who want to control which file types get processed by - Split the file into smaller parts and upload them separately - Without OCR, images are processed through text parsing, which can't actually "see" text in an image. You need OCR configured for this to work. See [OCR for Documents](/docs/features/ocr). + Without OCR, there is nothing that can read text in an image, so the upload returns an error. You need OCR configured for this to work. See [OCR for Documents](/docs/features/ocr). Alternatively, use a **vision model** with standard file upload — the model itself can read text in images. diff --git a/content/docs/features/url_query.mdx b/content/docs/features/url_query.mdx index bb47a786a..242e0fd4d 100644 --- a/content/docs/features/url_query.mdx +++ b/content/docs/features/url_query.mdx @@ -179,15 +179,34 @@ Supported model parameters vary by endpoint. Values must be valid according to t ```bash temperature, presence_penalty, frequency_penalty, stop, top_p, max_tokens, -reasoning_effort, reasoning_summary, verbosity, useResponsesApi, web_search, disableStreaming +reasoning_effort, reasoning_summary, reasoning_mode, reasoning_context, verbosity, +useResponsesApi, disableStreaming ``` +`reasoning_mode` and `reasoning_context` apply to the OpenAI Responses API: + +| Parameter | Allowed values | +| --------- | -------------- | +| `reasoning_mode` | `standard`, `pro` | +| `reasoning_context` | `auto`, `current_turn`, `all_turns` | + +`web_search` applies to the `openAI`, `anthropic`, and `google` endpoints only. Set it to `true` or `false`. + **Google, Anthropic:** ```bash topP, topK, maxOutputTokens, thinking, thinkingBudget, thinkingLevel, web_search, url_context ``` +**Anthropic:** + +| Parameter | Allowed values | +| --------- | -------------- | +| `effort` | `low`, `medium`, `high`, `xhigh`, `max` | +| `thinkingDisplay` | `auto`, `summarized`, `omitted`, `updates` | + +`effort` sets the reasoning effort. `thinkingDisplay` controls whether reasoning content is returned: `auto` lets LibreChat decide, `summarized` requests a summary of the reasoning, `omitted` suppresses it, and `updates` returns only the progress notes written between tool calls. + For Google endpoints, set `url_context=true` to let supported Gemini text models read URLs included in the user message. YouTube URLs are handled with native video understanding when URL Context is enabled. **Anthropic, Bedrock (Anthropic models), OpenRouter custom endpoints:** @@ -242,6 +261,10 @@ https://your-domain.com/c/new?spec=meeting-notes-gpt4&prompt=Here%20is%20the%20t When using `spec`, other model parameters are ignored in favor of the spec's configuration. +### Color mode + +`?theme=dark`, `?theme=light`, or `?theme=system` sets the color mode when an administrator enables [`interface.colorModeFromUrl`](/docs/configuration/librechat_yaml/object_structure/interface#colormodefromurl). It is off by default. + ## Validation All parameters are validated against LibreChat's schema before they are applied. Invalid parameters and values are ignored; valid settings are applied to the conversation. diff --git a/content/docs/features/web_search.mdx b/content/docs/features/web_search.mdx index 942884569..49690076e 100644 --- a/content/docs/features/web_search.mdx +++ b/content/docs/features/web_search.mdx @@ -183,18 +183,17 @@ Rerankers analyze the scraped content to determine the most relevant parts and r Admins can configure the web search feature using environment variables. The YAML configuration allows you to specify custom environment variable names for each component. -⚠️ **Important: Never put actual API keys or values in the YAML file (they won't work)- only use environment variable names.** +**Recommended: reference environment variables with `${ENV_VAR}`.** Literal keys and URLs are also accepted in `librechat.yaml`, but they are stored in the file, so environment references remain the safer choice. + +A literal key is sent only to a URL set alongside it in the same configuration. An environment key or a user's own key never reaches a URL written in the config; reference both from the environment, or set both together. ```yaml webSearch: # Search Provider Configuration - serperApiKey: "${CUSTOM_SERPER_API_KEY}" # ✅ Correct: Using environment variable name - # serperApiKey: "sk-123..." # ❌ Wrong: Never put actual API keys here + serperApiKey: "${CUSTOM_SERPER_API_KEY}" # or - searxngInstanceUrl: "${CUSTOM_SEARXNG_INSTANCE_URL}" # ✅ Correct: Using environment variable name - searxngApiKey: "${CUSTOM_SEARXNG_API_KEY}" # ✅ Correct: Using environment variable name - # searxngInstanceUrl: "http://..." # ❌ Wrong: Never put actual URLs here - # searxngApiKey: "sk-123..." # ❌ Wrong: Never put actual API keys here + searxngInstanceUrl: "${CUSTOM_SEARXNG_INSTANCE_URL}" + searxngApiKey: "${CUSTOM_SEARXNG_API_KEY}" searxngSearchOptions: # Query options, not secrets, so real values belong here engines: "google,bing,startpage" language: "en" @@ -219,22 +218,17 @@ webSearch: # Scraper Configuration firecrawlApiKey: "${CUSTOM_FIRECRAWL_API_KEY}" firecrawlApiUrl: "${CUSTOM_FIRECRAWL_API_URL}" - # firecrawlApiKey: "fc-123..." # ❌ Wrong: Never put actual API keys here - # firecrawlApiUrl: "https://..." # ❌ Wrong: Never put actual URLs here # Reranker Configuration jinaApiKey: "${CUSTOM_JINA_API_KEY}" jinaApiUrl: "${CUSTOM_JINA_API_URL}" cohereApiKey: "${CUSTOM_COHERE_API_KEY}" - # jinaApiKey: "jn-123..." # ❌ Wrong: Never put actual API keys here - # jinaApiUrl: "https://..." # ❌ Wrong: Never put actual URLs here - # cohereApiKey: "ch-123..." # ❌ Wrong: Never put actual API keys here # General Settings safeSearch: 1 # Options: 0 (OFF), 1 (MODERATE - default), 2 (STRICT) ``` -**Note:** The YAML configuration should only contain environment variable names (in the format `${VARIABLE_NAME}`). This flexibility enables: +**Note:** Prefer environment variable names (in the format `${VARIABLE_NAME}`) in the YAML configuration. This flexibility enables: - Using different variable names in different environments - Supporting multiple configurations for different user groups - Future integration with role-based configurations @@ -249,6 +243,7 @@ webSearch: # searchProvider: "tavily" # Only use Tavily for search # searchProvider: "keenable" # Use keyless Keenable search scraperProvider: "firecrawl" # Only use Firecrawl for scraping + # scraperProvider: "serper" # Only use Serper for scraping # scraperProvider: "tavily" # Only use Tavily for scraping # scraperProvider: "keenable" # Use keyless Keenable page fetch rerankerType: "jina" # Options: "jina", "cohere", "none" diff --git a/content/docs/user_guides/ai_overview.mdx b/content/docs/user_guides/ai_overview.mdx index 3106f26a0..9ff5abe32 100644 --- a/content/docs/user_guides/ai_overview.mdx +++ b/content/docs/user_guides/ai_overview.mdx @@ -8,7 +8,7 @@ LibreChat allows you to configure and integrate various AI providers, APIs, and ## Key Concepts -- **Endpoints**: An endpoint refers to an AI provider, configuration, or API that determines the available models and settings for a chat request. Examples include OpenAI, Google, Plugins, Anthropic, and others. +- **Endpoints**: An endpoint refers to an AI provider, configuration, or API that determines the available models and settings for a chat request. Examples include OpenAI, Google, Anthropic, and others. - **Presets**: A preset is a saved combination of an endpoint, model, and conversation settings. You can create and manage multiple presets to suit different use cases. diff --git a/content/docs/user_guides/presets.mdx b/content/docs/user_guides/presets.mdx index 21c246796..30e8a93c7 100644 --- a/content/docs/user_guides/presets.mdx +++ b/content/docs/user_guides/presets.mdx @@ -53,7 +53,7 @@ The "presets" feature in our app is a powerful tool that allows users to save an - Optionally provide a custom name for your preset. This is the name that will be shown in the UI when using it. - **Custom Instructions:** - - Define instructions or guidelines that will be displayed before each prompt to guide the user in providing input. + - Define instructions that are sent to the model as system instructions. They are not displayed to the user. - **Temperature:** - Adjust this parameter to control the randomness of the model's output. A higher value makes the output more random, while a lower value makes it more focused and deterministic.