* 🎯 fix: Ask Because a Successor Is Owed, Not Because One Might Be The handover window guessed at how long admission takes. For a queued turn it never had to: the backend reports the turn as `queued` or `claimed`, which is positive evidence that a run is coming and that this client will not be the one to start it. Declare that outright and keep the active-job list live for exactly as long as it holds. Read from the server's receipts rather than the chip projection, so admission semantics stay in one place — `shouldPollAgentQueuedTurns`, shared with the queue itself — instead of being restated here and drifting. `useSteering` owns that fetch; subscribing with `enabled: false` observes its cache without competing for it, and an unpopulated cache falls back to the window. It also keeps this off Recoil, which the client is migrating away from. The window stays for successors nothing local predicts — a background-tool continuation has no receipt to report itself — and is now documented as the fallback rather than the mechanism. * 🔗 fix: Carry the Owed Successor Across the Receipt Handover Codex found the gap in the deterministic path: the receipt that announces a queued turn reports `admitted` for one fetch at most and is then dropped from the projection — before the active-job list has necessarily observed the run it started. If admission outlasted the handover window, the wall-clock fallback was already spent, and a pane keyed on the receipt alone stopped listening in exactly the window that mattered. Two structural changes, so this is not another edge patched. Owed is held, not read. Once a successor is known to be owed it stays owed until it is delivered — this pane attaches, or the list names the conversation. A bounded expiry backstops the case where neither ever happens, and it starts only once the receipt has gone quiet, so a long wait behind an unadmitted turn does not burn the window before the handover begins. `admitted` now counts as owed: the receipt poll stops there because nothing is left to wait for, but an unattached pane is in the opposite position, and it is the strongest evidence that pane will get. The receipt arms on its own. The arm had one announcement source, the list, which can miss a run that starts and finishes between two polls. An owed turn is a second source, and the status read the arm enables is the authoritative answer either way: active attaches, inactive means the history refetch the arm already performs is the repair. Neither source has to wait on the other. * 🧹 chore: Sort Imports in useResumeOnLoad * 🧭 fix: Deliver an Owed Successor Only When the Successor Itself Is Seen Codex: the latch treated the pane's own live attachment as delivery of the owed successor. But the successor is usually announced while its predecessor is still attached — the turn was queued behind it — so the latch was cleared, or never recorded, in exactly the window it exists for. Once that predecessor closed and the receipt was dropped, a successor that started and finished between two list polls was never seen. Remember which generation was live when the turn became owed. Delivery is then attachment to a different generation, or the list naming the conversation while nothing of ours is live. The predecessor no longer counts. Each half is proved against its own defect: reverting to the old predicate fails the predecessor-attached case; dropping the generation-aware attach fails the different-epoch case; and forgetting which generation was the predecessor livelocks — the latch is set, "delivered" by the very generation it should have excluded, cleared, and set again. * 🧷 fix: Judge Successor Delivery by Generation, Re-Arm on Transitions, Expire Off-Screen Three codex findings on the owed-successor latch, each a way the latch could be cleared, never recorded, or held too long. Delivery by generation only. The active-job list carries no generation identity, so "the conversation is listed" was satisfying delivery while the listed run was the predecessor — running elsewhere, unattached here — and the latch was never recorded. The receipt knows the predecessor better than this pane does: `expectedPredecessorCreatedAt` is stamped from the live epoch at enqueue and `effectivePredecessorCreatedAt` is the boundary admission actually consumed. Delivery is now attachment to a generation other than that boundary; a turn still owed cannot have started, so a generation live when it is first seen is its predecessor and refines the boundary rather than delivering. Re-arm on transitions, not heartbeats. A `queued` receipt is refetched every two seconds during a long wait and advances `dataUpdatedAt` without changing, and the arm was keyed on that stamp — after the throttle it invalidated status and history again and again while nothing had happened. It now keys on a signature of receipt ids and statuses, and refetches history only when a run is listed or the receipts actually transitioned. Expire on an absolute window, off-screen too. The expiry effect skipped when the latched conversation was not the one on screen, so navigating away held the latch indefinitely and returning later reopened a fresh window. The window now starts from `quietSince` — set when the receipt stops reporting or the conversation leaves the screen — and is never pushed back by a remount. Each change is proved against its own defect: re-adding list-based delivery fails the listed-predecessor case; removing the transition gate fails the heartbeat case; skipping expiry off-screen fails the absolute-window case; and forgetting to learn a live predecessor livelocks the latch. * 🧽 test: Restore the Admin Allowlist Override This Spec Leaks Into the Shard The spec writes a per-user `mcpSettings.allowedDomains` override for the shared primary user and never removes it. The list holds only its own fixture's origin, and allowlist matching is protocol- and port-inclusive, so for the rest of the shard every other MCP fixture is blocked: `e2e-oauth` fails inspection, and an agent expecting its tools initializes into AGENT_EXPECTED_MCP_TOOLS_UNAVAILABLE (503) instead of producing its OAuth prompt. Whether that bites depends only on which specs the shard runs afterwards, so it surfaces as a deterministic failure in an unrelated spec — `mcp-oauth-resume` failing an assertion that fires before any resume happens — which passes whenever it runs first. A client-only PR whose path selection reordered the shard hit it three times across two heads. Delete the override in a `finally`, and confirm against the stored config rather than by re-running `reinitialize`: the connection this test established stays live, so reinitialize keeps succeeding once the allowlist is gone. * 🩹 test: Read the Config Wrapper and Treat 404 as Cleared in the Override Teardown `GET /api/admin/config/:principalType/:principalId` returns `{ config }`, and deleting the last override removes the document, so the follow-up read is a 404 — the cleared state, not a read failure. The poll treated both as unreadable and timed out. * 🧷 fix: Remember Delivered Receipts, Restart the Grace on Delivery, Gate Reopening on Newer Data Three more codex findings on the owed-successor latch. Delivered receipts are remembered. An `admitted` receipt stays in the cache for a fetch after the successor attaches, and it still counts as owed — so the latch cleared on attachment and was re-recorded from the same receipt on the next render, synchronously, until the cache moved on. That is React's maximum-update-depth failure, reachable in the ordinary queued-turn handoff. The receipt signature that delivered is recorded, and a receipt set with that signature neither latches nor counts as owing a run; a genuinely new turn can. Delivery restarts the fallback grace. The list may never have seen the run a queued turn produced — it can start and finish between two polls — so its own "recently active" clock is stale, and clearing the latch would have removed the only reason left to poll. An unpredicted continuation after that run (a background-tool dispatch finishing) would then go unnoticed until a focus or reload. Observing the successor live now restarts the handover window. The window reopens only on newer evidence. Returning to a conversation first exposes the receipt cached before the turn went quiet, while the authoritative refetch is still in flight; treating that as "still reporting" reset the start of an expiry meant to be absolute, so repeated navigation could extend it indefinitely. Only a server observation newer than the window's start counts, for reopening and for the reporting check alike. Each is proved against its defect: forgetting delivered receipts livelocks the handoff test; skipping the grace restart fails its assertion; reopening on any report fails the stale-remount case. * 🧷 fix: Track Delivery Per Turn, Ratchet the Boundary, Keep One Latch Per Conversation Three more codex findings on the owed-successor latch, plus a bug the second one's regression test exposed. Delivery is tracked per queued turn. Two turns queued behind the same generation deliver one at a time; marking the whole receipt set on the first would let the still-attached first successor pass as delivery of the second. While any owed turn is still waiting, nothing is delivered at all — a waiting turn cannot have produced the live run, so that run is its predecessor. The boundary ratchets forward. A receipt can name the chain's root long after a sibling's successor became the link the turn actually waits behind, and the latch learns that link while the turn waits. Taking the receipt's boundary first would have "delivered" the second turn on its own predecessor. The predecessor is the latest link known: the max of what the receipt says, what the latch learned, and, while waiting, what is live. With no boundary known at all, a live generation is not delivery; the bounded expiry is the fallback. Latches are keyed by conversation. Navigating to a conversation that also owes a run replaced the previous one's latch, cancelling its expiry and the history repair it performs. Every latch keeps its own absolute window now, and expiry runs for all of them regardless of which conversation is on screen. The cherry-picked allowlist-override teardown is synced to its final form (see #15543): cleanup always runs, only definitive answers end its poll, and `reinitialize` is no longer used as the reverted signal. Proofs: marking the whole receipt set is indistinguishable only because the waiting rule already blocks it; forgetting to learn the live link, or letting the receipt's root outrank it, both fail the two-turn case; a single-slot latch fails the two-conversation case; delivering without a boundary fails its case. |
||
|---|---|---|
| .claude/skills | ||
| .devcontainer | ||
| .github | ||
| .husky | ||
| .vscode | ||
| api | ||
| client | ||
| config | ||
| e2e | ||
| helm | ||
| otel/langfuse-fanout | ||
| packages | ||
| redis-config | ||
| scripts | ||
| search | ||
| skill | ||
| src/tests | ||
| utils | ||
| .codex | ||
| .dockerignore | ||
| .env.example | ||
| .gitattributes | ||
| .gitignore | ||
| .nvmrc | ||
| .prettierrc | ||
| AGENTS.md | ||
| bun.lock | ||
| CLAUDE.md | ||
| CONTEXT.md | ||
| deploy-compose.langfuse-fanout.yml | ||
| deploy-compose.yml | ||
| docker-compose.langfuse-fanout.yml | ||
| docker-compose.override.yml.example | ||
| docker-compose.yml | ||
| Dockerfile | ||
| Dockerfile.multi | ||
| eslint.config.mjs | ||
| librechat.example.yaml | ||
| LICENSE | ||
| package-lock.json | ||
| package.json | ||
| rag.yml | ||
| README.md | ||
| README.zh.md | ||
| tool-intent-spec.md | ||
| turbo.json | ||
LibreChat
English · 中文
🚀 What's New in v0.8.8-rc2
- Agent run control: Interrupt an Agent before visible answer text, steer runs with files and quoted excerpts, durably queue follow-ups, and recover saved partial work with Keep going or Answer now.
- Agent activity: Optional generated labels group reasoning and tool work, fold completed groups into live phase cards, keep generated files visible, summarize multi-step phases, and show the current reasoning direction.
- Human-in-the-loop Agents: Stream up to four related questions, pause for input or tool approval, and resume durably.
- Unified Agent Builder: Configure Skills, MCP, Code Interpreter, orchestration, Programmatic Tool Calling, model-spec controls, and per-tool background and intent settings in one Tools marketplace; Skills can be enabled for standalone runtime authoring without exposing the existing catalog.
- Durable Agent automation: Authenticated Agent Events support bound child actors, expected-action receipts, per-actor mailboxes, event batching, durable human pauses, and automatic detached Actions across built-in stream stores.
- Deeper Subagent history: Browse branch-aware child turns with bounded reasoning and stable live event views, load earlier activity, inspect event details, continue completed child chats, and automatically wake saved parent Agents when detached work settles.
- Background tools: Eligible Code Interpreter, MCP, Plugin, and Action tools can run while an Agent keeps working, with automatic delivery for supported completions and polling controls when needed.
- Code Interpreter workflows: Sandbox images return as viewable artifacts; highly experimental stateful sessions add scoped managed, attached, or personal environments, per-message file downloads, and guarded file-write and command permissions.
- Agent extensibility: Experimental Agent Plugins bundle deployment Skills, MCP servers, and opt-in command hooks; saved Agent teams run as isolated Subagent graphs.
- Scheduled Chats (experimental): Run saved Agents with presets or custom cron, selectable time zones, multi-day weekly cadence, and optional Chat Project destinations.
- Memory and context: Agents can use optionally isolated memory, preserve adaptive context fading across turns, and show categorized current-window usage, tokens, and optional cost.
- Editable long pastes: Long pasted text becomes an editable attachment that can be moved back into the composer; attachment-only turns and reliable Upload as Text downloads are also supported.
- Projects, settings, and navigation: Search conversation titles and message contents, manage project chats, use searchable settings and shortcuts, pin chats, choose clock/week conventions, and navigate faster on mobile.
- Sharing and artifacts: Stable shared links support personal copies; fullscreen previews, Mermaid export, PowerPoint templates, shell scripts, and original Office downloads expand file workflows.
- Web search: Keenable adds keyless search and page fetch, while SearXNG and Tavily gain richer controls and all web-tool egress uses stronger SSRF protection.
- Security and authentication: Default HTTP security headers, opt-in nonce CSP, authenticated local images, per-user Code Interpreter JWTs, stable SAML identity binding, live-session OpenID token refresh, and retired JWT-secret rejection harden deployments.
- Models and reasoning: Added GPT-5.6 with Responses reasoning controls, Claude Fable 5.1, Opus 5, and Sonnet 5, plus Gemini 3.8/3.7/3.6 Flash and Gemini 3.5 Flash-Lite.
- Langfuse observability: Configure encrypted in-app connections, tenant fanout, authenticated gateways, export-decision telemetry, and authorized session links in chats and shared views.
- Administration: Source-aware content filters can audit or block model-bound data, while tenant Insights, delegated configuration, encrypted secrets, and expiring violation scores improve operations.
- Streaming and reliability: Adaptive smoothing, Redis delta batching and failover recovery, automatic generation protocol v2, live MCP catalog refresh, Agent circuit breakers, and DocumentDB support improve long runs and scaled deployments.
Read the full v0.8.8-rc2 changelog.
✨ Features
-
🖥️ UI & Experience inspired by ChatGPT with enhanced design and features
-
🤖 AI Model Selection:
- Anthropic (Claude), AWS Bedrock, OpenAI, Azure OpenAI, Google, Vertex AI, OpenAI Responses API (incl. Azure)
- Custom Endpoints: Use any OpenAI-compatible API with LibreChat, no proxy required
- Compatible with Local & Remote AI Providers:
- Ollama, groq, Cohere, Mistral AI, Apple MLX, koboldcpp, together.ai,
- OpenRouter, Helicone, Perplexity, ShuttleAI, Deepseek, Qwen, and more
-
- Secure, Sandboxed Execution in Python, Node.js (JS/TS), Go, C/C++, Java, PHP, Rust, and Fortran
- Seamless File Handling: Upload, process, and download files directly
- No Privacy Concerns: Fully isolated and secure execution
- Open-Source & Self-Hostable: powered by ClickHouse/code-interpreter
-
🔦 Agents & Tools Integration:
- LibreChat Agents:
- No-Code Custom Assistants: Build specialized, AI-driven helpers
- Agent Marketplace: Discover and deploy community-built agents
- Collaborative Sharing: Share agents with specific users and groups
- Flexible & Extensible: Use MCP Servers, tools, file search, code execution, and more
- Skills: Create reusable
SKILL.mdinstruction bundles for manual, automatic, or always-on agent workflows - Agent Plugins: Experimentally bundle deployment Skills and MCP servers into startup-loaded packages
- Subagents: Delegate focused work to isolated child agent runs with their own context windows
- Compatible with Custom Endpoints, OpenAI, Azure, Anthropic, AWS Bedrock, Google, Vertex AI, Responses API, and more
- Model Context Protocol (MCP) Support for Tools
- LibreChat Agents:
-
🔍 Web Search:
- Search the internet and retrieve relevant information to enhance your AI context
- Combines search providers, content scrapers, and result rerankers for optimal results
- Customizable Jina Reranking: Configure custom Jina API URLs for reranking services
- Learn More →
-
🪄 Generative UI with Code Artifacts:
- Code Artifacts create React, HTML, and Mermaid content directly in chat
- Open previews fullscreen and export Mermaid diagrams as SVG or PNG
-
🎨 Image Generation & Editing
- Text-to-image and image-to-image with GPT-Image-1
- Text-to-image with DALL-E (3/2), Stable Diffusion, Flux, or any MCP server
- Produce stunning visuals from prompts or refine existing images with a single instruction
-
💾 Presets & Context Management:
- Create, Save, & Share Custom Presets
- Switch between AI Endpoints and Presets mid-chat
- Edit, Resubmit, and Continue Messages with Conversation branching
- Create and share prompts with specific users and groups
- Fork Messages & Conversations for Advanced Context control
-
💬 Multimodal & File Interactions:
- Upload and analyze images with Claude 3, GPT-4.5, GPT-4o, o1, Llama-Vision, and Gemini 📸
- Chat with Files using Custom Endpoints, OpenAI, Azure, Anthropic, AWS Bedrock, & Google 🗃️
-
🌎 Multilingual UI:
- English, 中文 (简体), 中文 (繁體), العربية, Deutsch, Español, Français, Italiano
- Polski, Português (PT), Português (BR), Русский, 日本語, Svenska, 한국어, Tiếng Việt
- Türkçe, Nederlands, עברית, Català, Čeština, Dansk, Eesti, فارسی
- Suomi, Magyar, Հայերեն, Bahasa Indonesia, ქართული, Latviešu, ไทย, ئۇيغۇرچە
-
🧠 Reasoning UI:
- Dynamic Reasoning UI for Chain-of-Thought/Reasoning AI models like DeepSeek-R1
-
🎨 Customizable Interface:
- Customizable Dropdown & Interface that adapts to both power users and newcomers
-
- Never lose a response: AI responses automatically reconnect and resume if your connection drops
- Multi-Tab & Multi-Device Sync: Open the same chat in multiple tabs or pick up on another device
- Production-Ready: Works from single-server setups to horizontally scaled deployments with Redis
-
🗣️ Speech & Audio:
- Chat hands-free with Speech-to-Text and Text-to-Speech
- Automatically send and play Audio
- Supports OpenAI, Azure OpenAI, and Elevenlabs
-
📥 Import & Export Conversations:
- Import Conversations from LibreChat, ChatGPT, Chatbot UI
- Export conversations as screenshots, markdown, text, json
-
🔍 Search & Discovery:
- Search all messages/conversations
-
👥 Multi-User & Secure Access:
- Multi-User, Secure Authentication with OAuth2, LDAP, & Email Login Support
- Built-in Moderation, and Token spend tools
-
🎛️ Admin Panel:
- Browser-based UI to manage users, groups, roles, and configuration overrides
- Edit settings and per-role/group permissions live, without redeploying
- Bundled with the Docker Compose stacks for one-command setup
-
⚙️ Configuration & Deployment:
- Configure Proxy, Reverse Proxy, Docker, & many Deployment options
- Use S3 with CloudFront for stable media links, edge delivery, signed cookies, and secured downloads
- Use completely local or deploy on the cloud
-
📖 Open-Source & Community:
- Completely Open-Source & Built in Public
- Community-driven development, support, and feedback
For a thorough review of our features, see our docs here 📚
🪶 All-In-One AI Conversations with LibreChat
LibreChat is a self-hosted AI chat platform that unifies all major AI providers in a single, privacy-focused interface.
Beyond chat, LibreChat provides AI Agents, Model Context Protocol (MCP) support, Artifacts, Code Interpreter, custom actions, conversation search, and enterprise-ready multi-user authentication.
Open source, actively developed, and built for anyone who values control over their AI infrastructure.
🌐 Resources
GitHub Repo:
- RAG API: github.com/danny-avila/rag_api
- Website: github.com/LibreChat-AI/librechat.ai
Other:
- Website: librechat.ai
- Documentation: librechat.ai/docs
- Blog: librechat.ai/blog
📝 Changelog
Keep up with the latest updates by visiting the releases page and notes:
⚠️ Please consult the changelog for breaking changes before updating.
⭐ Star History
✨ Contributions
Contributions, suggestions, bug reports and fixes are welcome!
For new features, components, or extensions, please open an issue and discuss before sending a PR.
If you'd like to help translate LibreChat into your language, we'd love your contribution! Improving our translations not only makes LibreChat more accessible to users around the world but also enhances the overall user experience. Please check out our Translation Guide.
💖 This project exists in its current state thanks to all the people who contribute
🎉 Special Thanks
We thank Locize for their translation management tools that support multiple languages in LibreChat.