🎚️ feat: Let Chat Users Switch a Saved Agent's Tools - #84
Open
TomasPalsson wants to merge 24 commits into
Open
TomasPalsson wants to merge 24 commits into
TomasPalsson wants to merge 24 commits into
Conversation
…I#16455) * 🕘 feat: Distinguish Tool Preparation From Tool Call Time * 🎞️ fix: Format timing specs and flatten phase labels * 🧷 fix: Narrow Tool-Step Timing Before Stream Callback * ⏱️ fix: Show Measured Subsecond Tool Calls * 🧮 fix: Attribute Earliest Tool Fragment to Its Call * 🧵 fix: Preserve Tool Timing Across Replay and Parallel Calls * 📦 chore: Upgrade Agents SDK To 3.9.8 * 🧭 fix: Restore Tool Timing Across Redis And Child Activity --------- Co-authored-by: Lia <lia@librechat.ai>
…eChat-AI#16477) * feat: Route Linked Worktree Requests into Per-Worktree Lanes Workers that advertise the git_linked_worktree workspace scope run each .worktrees/<name> of a registered checkout in its own scheduling lane. Accept the scope in worker status, map worktree-scoped paths and command working directories onto the worktree field, and restore the prefix on returned paths so tool output stays relative to the checkout. * fix: Advertise Worktree cwd Routing in Model-Facing Bash Definitions * refactor: Normalize the Lane Flag in TypeScript, Pass It Through /api Unchanged * feat: Gate Linked Worktree Lanes Behind an Environment configSchema Toggle * test: Give the Lane Toggle Fixture a Default Environment
Saved agents can mark a built-in tool or a whole MCP server as switchable by the chat user, with an on/off starting state. Adds the option type, the helpers that read the switchable set and apply a chat's switch state (only ever removing tools), and validation of the field on agent save.
…alized Server Is Switched Off
|
Important
This repository does not receive automatic reviews because it has fewer than 10 stars. ⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Advanced Run ID: Comment |
TomasPalsson
marked this pull request as ready for review
September 29, 2026 18:28
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Pull Request
Summary
Today a saved agent's tools are all-or-nothing: whatever the creator attaches (web search, code execution, file search, MCP servers) runs on every message, and a chat user has no way to turn one off or opt into one. This PR lets a creator mark each built-in tool (web search, code, file search) and each MCP server as locked (today's behavior, the default), switchable, starts on, or switchable, starts off. Chat users see the switchable ones in the chat input of a saved-agent chat, flip them per chat, and the server only ever removes tools the creator made switchable — a request can never add a tool the agent does not have or enable a locked one. Agents with no switchable tools, ephemeral chats and plain-endpoint chats behave exactly as before.
How it works
The setting is stored per agent as
tool_options[<tool key>].user_toggle: 'on' | 'off'(absent = locked), validated by the agent create/update schema. MCP servers use the existingsys__server__sys_mcp_<configured name>key. Two pure helpers inlibrechat-data-providerown the rules:getAgentToolSwitches(agent)returns the switchable set with creator defaults, andapplyAgentToolSwitches(agent, requested)resolves the request against those defaults and returns the filtered tool list — it only drops switchable tools that resolve to off.sequenceDiagram participant B as Agent builder participant C as Chat input (BadgeRow) participant S as Server (loadAgent) B->>B: tool_options[key].user_toggle = on/off C->>C: getAgentToolSwitches(agent) → show switches, seed per-chat state from defaults C->>S: ephemeralAgent { web_search, execute_code, file_search, mcp[] } S->>S: primary agent only: applyAgentToolSwitches(agent, ephemeralAgent) S->>S: MCP instructions follow the filtered tools, not the request listpackages/api/src/agents/load.tsfilters the primary agent only (the memory agent and other agents loaded in the same request are untouched);api/server/services/Endpoints/agents/build.jsonly passesreq.body.ephemeralAgentthrough.context.tsbuilds MCP instructions from the filtered tools when the agent has server switches, so a switched-off server's instructions are never injected and a paused/resumed turn rebuilds the same tool set.GET /api/agents/:idfor view-only users now also returnstoolsand atool_optionstrimmed touser_toggleonly, so shared chat users get their switches.UserToggleSelect(built-in and MCP sections); chat switches inBadgeRow/BadgeRowContext/ToolsDropdown;useApplyAgentToolSwitchesseeds a new chat from the creator's defaults, keeps the user's choices through the first message and reloads, and clears the previous agent's switches when the agent changes. A saved agent's switchable MCP servers are offered even whenchatMenu: falsehides them from the general menu._mcp_.Type of change
Testing
Tested environments/configuration: local build on macOS, MongoDB 7 in Docker, a streamable-http MCP server with one tool, Chrome. Manually verified steps 1–3 in the running app.
Automated tests:
packages/data-provider:npx jest agentToolOptions(20) +tsc --noEmitpackages/api:npx jest src/agents/__tests__/load.spec.ts src/agents/validation.spec.ts src/agents/context.spec.ts(125) +tsc --noEmitapi:npx jest server/controllers/agents/v1.spec.js(150)client:npx jest SidePanel/Agents Chat/Input utils/__tests__ hooks/Agents hooks/MCP Providers useToolToggle timestamps(162 suites, 2648) +tsc --noEmitnpm run static-checks:full -- --against <base>andnpm run -w @librechat/api openapi:check/openapi:testpass.Risk / compatibility
tool_optionsmixed field; agents withoutuser_toggleare unchanged. The OpenAPI spec is regenerated foruser_toggle.GET /api/agents/:idnow includestools(already exposed by the list endpoint) and only theuser_togglepart oftool_options._mcp_<name>suffix (e.g.barandfoo_mcp_bar) can resolve that locked server's tools as its own; a switchable server hidden bychatMenu: falsecan be pruned if the agent loads after the MCP server list. OpenAI-compatible and Responses API agent endpoints do not apply switches (no switch state there), matching today's behavior. Artifacts, memory and skills are not switchable in this PR.packages/api/src/agents/hooks/reaper.spec.tsandexecutor.spec.ts(process-group signal escalation) reproduce locally without this change and are untouched here. The repository-wideeslint . --fixreports pre-existing errors in unrelated files; the branch-scoped static checks are clean.load.spec.tsassertion that required the request'smcplist to be deleted now asserts the request is left untouched, and acatalog.spec.tscase that only asserted the removed, unreaduserProvidedAuthflag was deleted along with that flag.Checklist