Commit graph

4675 commits

Author SHA1 Message Date
Marco Beretta
9c188631da
fix: exact MCP token matching and keep errored skill lookups removable
The mcp_<server>_ prefix clause in matchesMcpServer was invented by the
redesign, not a persisted format (mcp_prefix is only ever used as the
exact mcp_<serverName> pluginKey), and it claimed longer server names
sharing a prefix: with servers github and github_extra, removing github
also stripped github_extra's tokens. The predicate now only matches exact
or delimiter-bounded shapes.

An off-page selected skill whose per-id lookup failed with a transient
error (retry disabled) vanished from the selected list until remount. Any
settled lookup failure now keeps the placeholder entry so the allowlist id
stays visible and removable; only in-flight lookups are briefly hidden.
2026-07-04 01:12:16 +02:00
Marco Beretta
5d8274221f
fix: strip legacy prefix MCP tokens in useRemoveMCPTool
The hook only filtered the raw server name and suffix-delimiter tokens,
so confirming removal in the selected-tools section left persisted
prefix-format tokens (mcp_<server>, mcp_<server>_<tool>) in the form and
the row reappeared as selected. It now shares the matchesMcpServer
predicate with the selection logic so removal can never lag selection.
2026-07-03 23:18:53 +02:00
Marco Beretta
3a7cf02715
fix: strip legacy MCP tokens on removal, guard action creation, model button spacing
MCP selection accepts every historical token format (server placeholder,
raw server name, mcp_-prefixed, and per-tool ids in prefix/suffix shapes)
but removal only filtered the new placeholder plus the server's current
tool ids, so a legacy token left the server permanently selected and its
tools still expanded after save. Selection and removal now share a
matchesMcpServer predicate.

Creating an action from the marketplace on an unsaved agent opened an
editor whose save was guaranteed to fail; it now surfaces the existing
save-the-agent-first error, matching the action-removal guard.

The model picker button keeps its tight px-1 with a provider icon but gets
px-3 in the empty Select-a-model state so the placeholder is not flush
against the border.
2026-07-03 22:45:32 +02:00
Marco Beretta
cf00c4fd83
fix: hide plugin tools from the marketplace when the tools capability is off
buildCatalog gated built-ins, MCP, and skills on their capabilities and
permissions but pushed regular plugin tools unconditionally, so deployments
that removed the tools capability still offered attachable tool cards in
the marketplace. The loop now requires AgentCapabilities.tools, matching
the old Add Tools gate.
2026-07-03 19:24:55 +02:00
Marco Beretta
0e262eda5b
fix: sync skills_enabled with selection edits and hydrate agent file entries
skills_enabled is the master opt-in for the skill allowlist, and an empty
allowlist with the flag on means the full accessible catalog. Selection
edits now sync the flag on empty/non-empty transitions via a shared
skillsEnabledTransition helper: picking the first skill enables it so the
choice takes effect on save, and removing the last one disables it so the
agent doesn't silently escalate to every skill. Mid-selection edits leave
the flag alone, preserving the Advanced kill switch's
disable-without-clearing behavior.

Agents loaded from the API carry only tool_resources.*.file_ids; the
client-only context/knowledge/code file entry arrays were read directly,
so existing attachments rendered as empty and could not be removed. A new
useAgentFileEntries hook restores the legacy derivation (agent files query
merged into the file map via processAgentOption) and now feeds AgentConfig,
the item dialog, and the selected-items pipeline.
2026-07-03 12:27:59 +02:00
Marco Beretta
05ac524fd9
fix: refetch favorites when toggled before the list loads, lint fixes
An optimistic favorite written over an unpopulated cache seeded the list
with only the toggled item, and cancelQueries killed the initial fetch
that would have corrected it, hiding existing favorites until reload. The
optimistic write now only applies over known data; otherwise onSettled
invalidates so the authoritative list is refetched.

Also unnest the version date-label ternary and drop an unused form watch
flagged by CI.
2026-07-03 03:57:36 +02:00
Marco Beretta
2a3e14c850
fix: gate marketplace creation entries and resolve off-page selected skills
The Create New menu exposed MCP server creation to users without the
MCP_SERVERS create permission and action creation on deployments with the
actions capability disabled; both entries are now gated like their
pre-redesign counterparts, and the button hides when neither applies.

Selected skills missing from the first catalog page (limit 100) were
dropped from the Skills section entirely, leaving them impossible to
inspect or remove. useResolvedSkills restores the per-id lookup: off-page
skills are fetched individually and confirmed misses (deleted or no longer
shared) stay visible under an Unavailable skill placeholder so the stale
allowlist entry remains removable.
2026-07-03 03:41:42 +02:00
Marco Beretta
45d0d34c9e
chore: remove translation keys orphaned by the tool library redesign 2026-07-03 02:10:15 +02:00
Marco Beretta
a213b2e10f
feat: anchor the favorite star at the card's right edge
Swap the ToolCard action-bar order so the star sits rightmost with the
configure/info icon to its left. Every card can be favorited but only some
are configurable, so anchoring the star keeps it in a consistent position
across the grid.
2026-07-03 01:49:06 +02:00
Marco Beretta
d5cccb5f18
feat: add favorites for marketplace tools, MCP servers, and skills
Reintroduce the favorite star from the old skill picker, generalized to
every marketplace item kind except per-agent actions. Cards in the Tool
Library and Skills dialogs get a hover-revealed star (always visible once
favorited), and the existing Favorites views in both dialogs now filter to
starred items.

Favorites persist in a dedicated ToolFavorite collection, one document per
(user, itemType, itemId) with a unique compound index, exposed through
atomic per-item PUT/DELETE endpoints under /api/user/settings/favorites/
tools. Per-item writes are idempotent and race-free across tabs/devices
(the unique index backstops concurrent toggles), reads are a single
index-backed query capped at 100 favorites per user, and the client keeps
React Query as the source of truth with optimistic updates. Handlers live
in @librechat/api with a thin route wrapper; methods follow the
data-schemas factory pattern with tenant isolation.

The favorites filter now matches on compound kind:id keys instead of bare
ids, closing a cross-kind collision where a tool and a skill sharing an id
would both match. The skill-favorites data-service stubs and the reserved
TUserFavorite.skillId field are replaced by the new tool-favorites service.
2026-07-03 01:12:31 +02:00
Marco Beretta
f6eccee9c7
fix: scope tooltip elevation to dialogs and restore dialog close button size
Tooltips go back to z-150 globally; inside a dialog they now borrow the
depth-aware popover z-index so they still clear nested dialogs (the Tool
Library item dialog) without outranking freshly opened modals everywhere
else. The default dialog close icon returns to its original size, and the
lc-field pointer-focus suppression ships with the package next to Input and
Textarea so external consumers get the whole mechanism from @librechat/client.
2026-07-02 21:06:42 +02:00
Marco Beretta
5c1e0b831a
fix: restore MCP attach semantics and confirmations in the tools marketplace
Connecting an MCP server from the item dialog now enables all of its tools
once the connection settles, deselect-all keeps the server attached via its
placeholder token instead of detaching it, adding a server writes the token
so a zero-tool attachment survives a save, and removing a server from the
tools list asks for confirmation again. Consume-only servers are excluded
from the catalog, matching the old select dialog.

Also share the catalog/selection pipeline between ToolsSection and the
marketplace through useAgentItems, hoist NEW_ACTION_ID next to ActionItem,
drop unused status/view union members and stale TranslationKeys casts,
document the phase-2 Favorites/Made-by-you views, fix the needs-setup dot
semantics and card focus suppression, remove the redundant close button in
CreateSkillDialog, move useInputModality into @librechat/client so external
consumers can mount it, and delete dead files and orphaned translation keys.
2026-07-02 21:06:33 +02:00
Marco Beretta
9fa19a71d2
feat: make the skills create button a compact icon button 2026-07-02 17:12:57 +02:00
Marco Beretta
77d1cb58ae
feat: show a saving spinner and allow cancelling credential edits
Drive the tool credential Save button from the real mutation state so it
shows a spinner while the request is in flight, and add a Cancel button
when re-editing already-saved credentials so the edit can be dismissed.
2026-07-02 16:28:52 +02:00
Marco Beretta
cec2b92459
feat: match Code Interpreter file upload to the File Search dropzone
Swap Code Interpreter's thin btn-neutral bar for the same dashed dropzone
(DropzoneContent + dropzoneClassName) File Search already uses, so the two
capabilities' upload UIs are consistent.
2026-07-02 16:28:52 +02:00
Marco Beretta
7d18dd6dc4
feat: smoothly animate auth field changes in the MCP server dialog 2026-07-02 16:28:52 +02:00
Marco Beretta
d189f126d1
fix: vertically center OAuth dialog title against the MCP icon 2026-07-02 16:28:52 +02:00
Marco Beretta
2782af34c8
feat: show MCP server icon in OAuth dialog title 2026-07-02 16:28:52 +02:00
Marco Beretta
999301f10b
feat: cross-fade MCP tools between loading, list, and empty states 2026-07-02 16:28:51 +02:00
Marco Beretta
da551558fa
feat: smoothly collapse MCP connect button once connected 2026-07-02 16:28:51 +02:00
Marco Beretta
b31dbfa0c6
refactor: streamline MCP OAuth dialog
- Remove the Cancel button (the flow auto-closes on connect / times out)
- Show the URL in a read-only single-line scrollable input (cursor moves
  through it, not fully visible) with the shared CopyButton's smooth
  Copy/Check icon swap, matching the OAuth callback-URL field
- Put the primary Continue with OAuth action (icon trailing) and an
  icon-only QR toggle together in a row at the bottom, below the URL
- The QR reveals between the description and the URL with a smooth height
  animation (grid-rows 0fr to 1fr, matching MCPToolItem's reveal)
2026-07-02 16:28:51 +02:00
Marco Beretta
6c53a83a9e
feat: refine agent tools picker (skills, MCP connect/OAuth, web search)
- Skills picker: per-card visibility (public) and shared-author badges,
  category filtering, and an in-place Create skill flow that auto-attaches
  the new skill without leaving the builder
- MCP: inline Connect button in the first dialog plus a dedicated OAuth
  dialog (continue, copyable URL, QR code) shown only when OAuth is required
- Web search: auth-aware affordance, settings cog when user-provided and an
  info icon when system-defined
- Remove orphaned com_ui_unavailable/com_ui_initializing keys and the dead
  Tools/MCPToolItem component
2026-07-02 16:28:51 +02:00
Marco Beretta
71eb21d80c
feat: restore Memory capability toggle in agent builder tools catalog 2026-07-02 16:28:51 +02:00
Marco Beretta
178be2d4c7
feat: refine agent builder tools, actions, and MCP sections 2026-07-02 16:28:51 +02:00
Marco Beretta
e3ec9544ef
feat: redesign the agent builder tools, skills, and advanced panels
Replace the stacked capability/MCP/skill/tool/action form sections with a unified tools marketplace, per-item configuration dialogs, and a consolidated Advanced panel.

- unified tools marketplace (catalog, sidebar, polymorphic cards/rows) covering built-in capabilities, plugins, MCP servers, and actions, each with a detail/config dialog
- dedicated Skills picker and a Tools section with selected-item summaries and empty states
- redesigned action editor and authentication dialog (method cards, segmented controls)
- rebuilt Advanced panel: orchestration hub (subagents, handoffs, chain), max steps, skills kill-switch, copyable agent id
- restyled version history (timeline, tool/capability counts, in-app restore confirmation)
- shared component updates (Radio, Input/Textarea, dropdown z-index, dialog primitives) and keyboard-only focus rings via useInputModality
- format-hint placeholders for tool credential fields
- sanitize numeric parameter inputs to prevent comma truncation
2026-07-02 16:28:51 +02:00
Danny Avila
477ee3439c
🧪 ci: De-flake ConversationsSection memoization spec on slow runners (#14071)
waitFor resolves as soon as BookmarkNav's data hook has fired once, but the Suspense resolution commit can still have a trailing render pass pending on slow runners (Windows CI shards). The first stream tick then flushes that leftover pass alongside the tick, inflating the memoized children's render counts past the captured baseline (Expected: 1, Received: 2). Flush pending commits with an empty async act() before capturing baselines.
2026-07-02 10:11:43 -04:00
Danny Avila
0eef64344d
🌍 i18n: Update translation.json with latest translations (#14070) 2026-07-02 09:19:43 -04:00
Danny Avila
e452a130e9
perf: Minimize group membership query in principal resolution (#14055)
getUserPrincipals resolves a user's ACL principals on nearly every
authenticated request. It fetched full group documents (including entire
memberIds arrays) only to read each group _id, and always issued a
separate User lookup for idOnTheSource.

- Project { _id: 1 } on the memberIds group query so it returns only ids
  and can be served from the { memberIds: 1 } index instead of fetching
  and decoding whole group docs.
- Accept role and idOnTheSource from the already-loaded request user and
  thread them from the capability middleware, collapsing the hot path to
  a single indexed group query (idOnTheSource: null means known-local).
2026-07-02 08:44:40 -04:00
Danny Avila
6b049c2eed
🧠 fix: Default Bedrock thinking maxTokens to model max output (#14058)
Some checks are pending
Docker Dev Branch Images Build / build (Dockerfile, lc-dev, node) (push) Waiting to run
Docker Dev Branch Images Build / build (Dockerfile.multi, lc-dev-api, api-build) (push) Waiting to run
GitNexus Index / index (push) Waiting to run
GitNexus Index / post-index (push) Blocked by required conditions
* 🧠 fix: Default Bedrock thinking maxTokens to model max output

Thinking tokens share the maxTokens output budget with tool-call
arguments (e.g. a create_file content), so the low Bedrock defaults
(8192 for enabled thinking, ~4096 server-side for adaptive when unset)
truncated large authored files mid-argument — surfacing as
OutputTruncationError once reasoning actually emits.

Default maxTokens to the model's full max output via
anthropicSettings.maxOutputTokens.reset(model), mirroring the
direct-Anthropic path. Explicit maxTokens/maxOutputTokens are respected.

* fix: canonicalize number-first Claude aliases before resolving max output
2026-07-01 18:29:45 -04:00
Danny Avila
8683eccbbc
🧠 fix: Apply Bedrock thinking config to bare inference-profile model IDs (#14054)
Some checks are pending
Docker Dev Branch Images Build / build (Dockerfile, lc-dev, node) (push) Waiting to run
Docker Dev Branch Images Build / build (Dockerfile.multi, lc-dev-api, api-build) (push) Waiting to run
GitNexus Index / index (push) Waiting to run
GitNexus Index / post-index (push) Blocked by required conditions
Docker Dev Images Build / build (Dockerfile, librechat-dev, node) (push) Waiting to run
Docker Dev Images Build / build (Dockerfile.multi, librechat-dev-api, api-build) (push) Waiting to run
Sync Locize Translations & Create Translation PR / Sync Translation Keys with Locize (push) Waiting to run
Sync Locize Translations & Create Translation PR / Create Translation PR on Version Published (push) Blocked by required conditions
Sync Helm Chart Tags / Ignore non-main push (push) Waiting to run
Sync Helm Chart Tags / Sync chart tags (push) Waiting to run
* 🧠 fix: Apply Bedrock thinking config to bare inference-profile model IDs

The Bedrock request parser gated thinking config, sampling handling, and the
anthropic_beta headers on the model ID literally containing `anthropic.`. When
a deployment uses an application inference profile, the LibreChat model ID is a
bare `claude-*` (e.g. `claude-sonnet-5`) that maps to the profile ARN — so the
gate never matched, no `thinking` config was sent, and reasoning models
returned empty thinking blocks (most visibly: Claude Sonnet 5 never streamed
reasoning, while `us.anthropic.claude-opus-4-8` did).

Match on the `claude` family token instead of the `anthropic.` prefix so
prefixed (`anthropic.`, `us.`, `global.`) and bare inference-profile IDs are
handled identically. Verified e2e against live Bedrock via the agents SDK: a
bare `claude-sonnet-5` now sends `{type:'adaptive', display:'summarized'}` and
streams reasoning. Non-Claude Bedrock models (llama/cohere) and pre-thinking
Claude (3.5 sonnet) are unaffected.

* 🧹 fix: Strip stale thinking fields for non-thinking Claude Bedrock IDs

Follow-up to the bare-ID matching change: broadening the anthropic guard to
match bare `claude-*` meant a non-thinking Claude profile (e.g. a bare
`claude-3-5-sonnet` inference profile) took the Claude cleanup branch, which
kept persisted `thinking`/`anthropic_beta`/`output_config` from a
previously-selected thinking model — leaking unsupported fields after a model
switch. Extract `isThinkingModel` and, in the Claude cleanup branch, strip the
thinking fields when the model isn't thinking-capable. Also fixes the
pre-existing prefixed `anthropic.claude-3-5-sonnet` case (which already kept
stale thinking). Thinking-capable models (sonnet-5, 3.7-sonnet) still keep
their config.

* 🩹 fix: Preserve user anthropic_beta on non-thinking Claude cleanup

The non-thinking stale-cleanup deleted amrf.anthropic_beta, but that is the
generic Bedrock Anthropic beta field and may carry a user opt-in (e.g.
max-tokens-3-5-sonnet-2024-07-15 for extended output on Claude 3.5). Strip only
the thinking-specific fields (thinking/thinkingBudget/effort/output_config) and
leave anthropic_beta intact.

* fix: clear persisted AMRF (output_config, thinking, generated betas) on bare Bedrock profiles

* fix: preserve persisted effort on resume + strip stale thinking/betas across bare profiles

* fix: normalize string/comma-delimited anthropic_beta before stripping generated betas
2026-07-01 14:19:34 -04:00
Danny Avila
53ee82fe5d
🩹 fix: Coerce Stringified edit_file Edits (JSON-in-JSON) (#14056)
Models sometimes pass edit_file's `edits` as a JSON-encoded string
(or stringify individual edit entries) instead of a real array. That
failed validation with "Provide old_text and new_text, or a non-empty
edits array" and forced a full retry round-trip.

normalizeEditArgs now JSON-parses a stringified `edits` value (and
stringified entries) before validating. Non-strings and unparseable
strings are left untouched, so the existing explicit errors still fire.
2026-07-01 12:41:26 -04:00
Arjun Vijay
89931baf22
🚪 fix: Support Admin Redirect Detection for Same-Origin Subpaths (#14040) 2026-07-01 11:40:02 -04:00
Danny Avila
e6f5b6e70a
🌍 i18n: Update translation.json with latest translations (#14053) 2026-07-01 11:18:00 -04:00
Danny Avila
bb7d99d56c
🫷 feat: Exclude File Authoring Tools From Eager Execution (#14051)
* feat: exclude create_file/edit_file from eager execution

Side-effecting host file-authoring tools should not be speculatively
eager-executed: a write can land before the turn commits, and the eager path's
incrementally-streamed args can diverge from the final tool call, tripping the
SDK's 'changed after eager execution' guard so the model is told the write
failed and loops (observed with create_file writing a large file to /mnt/data).

Pass excludeToolNames so these tools run on the normal ToolNode path with the
final args. Requires @librechat/agents with eager-exclusion support; older
versions ignore the field.

* chore: Bump `@librechat/agents` to v3.2.56

* refactor: reorder imports in run.ts for clarity

* fix: also exclude execute_code/bash_tool from eager execution

The eager 'changed after eager execution' corruption isn't specific to file
authoring — any tool with a large free-form streamed arg is exposed. Observed
live: a bash_tool heredoc (a full Python script in `command`) tripped the guard
and the write never landed. execute_code (`code`) and bash_tool (`command`)
carry large args and run code (side effects), so exclude them from eager
alongside create_file/edit_file.

* feat: wire codeSessionToolNames so create_file/edit_file share the code sandbox

Activates the agents#283 capability: pass create_file/edit_file as
codeSessionToolNames so their exec session/files fold into the shared code
session and a file they write is visible to later execute_code/bash_tool calls
(and the existing session is injected into their requests). No-op until
@librechat/agents ships codeSessionToolNames (agents#283).

* test: guard code-tool eager/session wiring in createRun

Asserts createRun passes excludeToolNames (create_file/edit_file/execute_code/
bash_tool) and codeSessionToolNames (create_file/edit_file) to Run.create — the
wiring the create_file->bash_tool sandbox-sharing chain depends on, which was
silently missing before. Guards against a future edit dropping it. Mirrors the
run-summarization test harness (mocks Run.create).

The full create_file->bash_tool chain runs through the real code sandbox and
can't run in the mock CI harness; the SDK mechanism is covered by
@librechat/agents unit tests, and this guards the LibreChat wiring.

* style: fix prettier formatting in run-codeTools test

* chore: Bump `@librechat/agents` to v3.2.57
2026-07-01 11:07:30 -04:00
Danny Avila
f5c64a4d6d
📐 test: Guard Web Search Description Length (#14044)
* test: Guard web search description length

* test: Check registered web search description

* style: Format web search description assertion
2026-07-01 10:42:53 -04:00
Malte Polley
e88f7a8f19
📧 fix: Add .eml (message/rfc822) Support to File Upload (#13989)
* fix: add .eml (message/rfc822) support to file upload

* chore: restore package lock metadata

---------

Co-authored-by: Malte Polley <ahabsfriend@posteo.de>
Co-authored-by: Danny Avila <danny@librechat.ai>
2026-07-01 09:21:14 -04:00
matt burnett
b20abb2593
fix: bound peak memory of concurrent base64 attachment encoding (#14023)
* fix: bound peak memory of concurrent base64 attachment encoding

* chore: sort encode imports

---------

Co-authored-by: Danny Avila <danny@librechat.ai>
2026-07-01 08:22:16 -04:00
matt burnett
38ab4add3d
fix: preserve role SHARE permissions across boot in initializeRoles (#14022)
* fix: preserve role SHARE permissions across boot in initializeRoles

* chore: sort role method spec imports

---------

Co-authored-by: Danny Avila <danny@librechat.ai>
2026-07-01 08:21:46 -04:00
Jaka Centa
68bb533083
🔥 fix: Firebase CDN Initialization Under tsdown CJS Interop (#14046)
The `@librechat/api` build migrated to tsdown (rolldown/oxc) in #13595.
tsdown externalizes third-party deps and uses strict CJS interop, so a
default import of the Firebase v9+ modular SDK — whose CJS entry is
`__esModule`-marked with only named exports and no `default` — resolves
to `undefined`. `firebase.initializeApp(...)` then throws:

  TypeError: Cannot read properties of undefined (reading 'initializeApp')

crashing startup whenever the Firebase file strategy is configured
(`fileStrategy: firebase` or a granular `fileStrategies` entry).

Switch to the idiomatic modular named import (`initializeApp`) and use
the already-imported `FirebaseApp` type for the return annotation.
2026-07-01 08:20:40 -04:00
Marco Beretta
6576688f1b
📥 fix: Download Original File From Artifact Preview Panel for Office Documents (#14026)
* fix: download original file from artifact preview panel for office documents

The preview panel download button serialized the rendered HTML preview
instead of the original binary for office artifacts (pptx/xlsx/docx)
produced by the code interpreter, so users got an `index.html` text
scrape rather than the file. The inline chat card was unaffected because
it downloads the real file via `useAttachmentLink`.

Thread the original-file download metadata (filepath/file_id/source/user)
through `fileToArtifact` onto the Artifact, and update `DownloadArtifact`
to fetch the original file through that same path for preview-only office
artifacts. Text, source, and markdown artifacts keep the blob path so
their in-panel content (and edits) still download as-is.

Closes #14002

* fix: require a usable route before downloading the original artifact file

A shared link to a non-snapshotted code-execution office artifact strips
source/user and deletes filepath while keeping file_id (share
sanitization + applyShareFileRoute). The preview-panel download gate
treated that lone file_id as sufficient, so it routed to an empty
useCodeOutputDownload fetch and downloaded nothing instead of falling
back to the preview-content blob.

Take the original-file branch only when useAttachmentLink can actually
fetch: a non-empty filepath (http target, share route, or code-output
URL) or full local-file metadata (isLocallyStoredSource + file_id +
user). Export isLocallyStoredSource from LogLink so the panel reuses the
same predicate.

* fix: only show artifact download success after the file is delivered

useAttachmentLink swallows fetch errors (an expired code-output URL or a
404 share download) and resolves without throwing, so the preview-panel
download button flipped to the success checkmark even when no file was
downloaded.

Return a boolean from handleDownload (true once a download is initiated,
false on error/empty response) and only mark the artifact download as
succeeded when a file was actually delivered. The return value is
ignored by the existing onClick callers.
2026-07-01 08:19:34 -04:00
matt burnett
c00fb2d73d
fix: stripHeavyErrorFields Winston format (defense-in-depth) (#14018)
Some checks are pending
Docker Dev Branch Images Build / build (Dockerfile, lc-dev, node) (push) Waiting to run
Docker Dev Branch Images Build / build (Dockerfile.multi, lc-dev-api, api-build) (push) Waiting to run
GitNexus Index / index (push) Waiting to run
GitNexus Index / post-index (push) Blocked by required conditions
2026-06-30 20:35:51 -04:00
matt burnett
84329ab0ff
fix: use logAxiosError at the RAG file_search/context call sites (#14014) 2026-06-30 20:35:01 -04:00
Danny Avila
954caef3a3
🔄 chore: Bump @librechat/agents to v3.2.55
Some checks failed
Docker Dev Images Build / build (Dockerfile, librechat-dev, node) (push) Waiting to run
Docker Dev Images Build / build (Dockerfile.multi, librechat-dev-api, api-build) (push) Waiting to run
GitNexus Index / index (push) Waiting to run
GitNexus Index / post-index (push) Blocked by required conditions
Sync Locize Translations & Create Translation PR / Sync Translation Keys with Locize (push) Waiting to run
Sync Locize Translations & Create Translation PR / Create Translation PR on Version Published (push) Blocked by required conditions
Sync Helm Chart Tags / Ignore non-main push (push) Waiting to run
Sync Helm Chart Tags / Sync chart tags (push) Waiting to run
Publish `@librechat/client` to NPM / pack (push) Has been cancelled
Publish `@librechat/client` to NPM / publish-npm (push) Has been cancelled
2026-06-30 20:28:40 -04:00
Alexey Korepanov
ac759ef2f7
🥷 feat: Add showInMenu Option to Model Specs (#14034)
Add an optional `showInMenu` flag to model specs. When set to false, the
spec is dropped from the model selector menu and from the client startup
config (GET /api/config), but remains resolvable server-side by name — a
request that sends `spec: "<name>"` still works, since server-side
resolution uses the full, unfiltered list.

Unlike `showIconInMenu` (which only hides the icon), this hides the whole
entry. The flag is optional and defaults to listed, so existing specs are
unaffected.

Adds an `excludeHiddenModelSpecs()` helper (applied before
`sanitizeModelSpecs`) plus unit tests.
2026-06-30 19:32:59 -04:00
Danny Avila
927a5957cb
📏 fix: Make create_file Missing-Content Error Truncation-Aware (#14043)
A large SKILL.md/file authored in one create_file call can exceed the model's
max output token budget; the response is cut off before the content argument
finishes, the arg is dropped, and the handler returns a bare 'content is
required'. The model reads that as a forgotten field and retries the same
oversized write, looping.

Make the error actionable: tell the model the response may have been truncated
and to keep the main file lean, moving bulky sections into separate files
written in their own calls.
2026-06-30 19:31:48 -04:00
Danny Avila
9f8b6d92c0
🤖 feat: Add Claude Sonnet 5 Support (#14042)
*  feat: Add Claude Sonnet 5 Support

Wire up the claude-sonnet-5 model across token, pricing, and model-list
config:

- Context window (1M) and max output (128K) in @librechat/api token maps
- Standard pricing ($3/$15 per MTok) and cache rates in data-schemas tx
- 128K output-token carve-out in anthropicSettings (the family-wide 64K
  rule capped Sonnet 5 below its real limit); Bedrock/Vertex thinking and
  1M-context detection already cover sonnet major >= 5 generically
- Add to shared Anthropic, Bedrock, and Vertex default model lists, plus
  the .env.example examples
- Tests for context/output/pricing/matching across the affected packages

*  test: Align Sonnet 5+ maxOutputTokens defaults with 128K spec

getLLMConfig defaults flow from anthropicSettings.maxOutputTokens.reset(),
which now returns 128K for Sonnet 5+. Update the future-proofing assertions
in llm.spec.ts (Sonnet 5.x and 6-9.x) that still expected the old family-wide
64K cap. Haiku stays 64K; Opus stays 128K.

* 🎚️ fix: Gate Sonnet 5 capability behaviors (sampling, thinking)

Adding claude-sonnet-5 to the default list exposed it without the Anthropic
capability gates, all confirmed against the live API:

- omitsSamplingParameters: Sonnet 5 returns 400 on non-default temperature/
  top_p/top_k ('deprecated for this model'); now dropped so selecting the
  model with saved sampling settings no longer fails.
- requiresExplicitThinkingDisabled: omitting 'thinking' runs adaptive ON by
  default on Sonnet 5, so disabling thinking now sends { type: 'disabled' }
  (verified: 200, no thinking block) instead of omitting the field.
- omitsThinkingByDefault: thinking.display defaults to omitted (empty thinking
  blocks); the display resolver now returns 'summarized' for Sonnet 5+ so the
  Thoughts UI keeps working (verified: 757-char summary returned).

Gates apply to both the direct Anthropic and Bedrock paths. Tests added in
bedrock.spec and llm.spec.

* 🩹 fix: Sonnet 5 Bedrock availability + thinking-off persistence

Round-2 Codex review (all verified against the live API / Anthropic docs):

- Sonnet 5 is NOT available on the legacy Bedrock InvokeModel/Converse surface
  (Anthropic docs: 'use Claude in Amazon Bedrock or Claude Platform on AWS'),
  which is what LibreChat's ChatBedrockConverse uses. Removed it from the
  default Bedrock model lists (config + .env.example). Opus 4.8/4.7/Fable 5
  stay — those ARE reachable via InvokeModel. Sonnet 5 remains on the direct
  Anthropic API and Vertex, where it works.
- Reverted the Bedrock-side explicit-disabled thinking handling added last
  round: with Sonnet 5 off Bedrock, no Bedrock model needs { type: 'disabled' },
  so that path (and its round-trip concern) no longer applies.
- Direct Anthropic path: a persisted { type: 'disabled' } thinking object now
  normalizes to a boolean flag in getLLMConfig, so a user's Sonnet 5
  'thinking off' setting stays off across the model_parameters round trip
  instead of flipping back to adaptive (a truthy object skipped the disabled
  branch).

* ↩️ fix: Restore Sonnet 5 on Bedrock (Converse) — verified live

Reverses the round-2 removal: Sonnet 5 IS available on AWS Bedrock. Tested
live via the Converse API:

- global.anthropic.claude-sonnet-5 returns a normal response
- bare anthropic.claude-sonnet-5 needs an inference profile — but that's
  identical to the already-shipping Opus 4.8 / Fable 5 / Sonnet 4.6 entries,
  which all fail bare on-demand the same way
- temperature=0.5 -> 400 'deprecated for this model'; thinking {type:disabled}
  suppresses reasoning — same as the direct API

The 'legacy' Bedrock docs page that claimed Sonnet 5 wasn't on the surface is
stale. Restored:
- anthropic.claude-sonnet-5 in bedrockModels + .env.example
- the Bedrock explicit-disabled thinking handling (requiresExplicitThinkingDisabled
  -> { type: 'disabled' })
- the Finding 4 round-trip fix in bedrockInputSchema (coerce a persisted
  disabled AMRF.thinking to thinking=false instead of !!thinking -> true), with
  an end-to-end schema->parser test proving 'thinking off' stays sticky.

Direct-path round-trip fix (getLLMConfig thinkingFlag) is unchanged.

* 💵 fix: Sonnet 5 intro pricing + sticky disabled thinking on Bedrock reload

Round-4 Codex review (both verified):

- Pricing: Anthropic lists Sonnet 5 at introductory $2/$10 per MTok (cache
  $2.50/$0.20) through 2026-08-31, reverting to $3/$15 ($3.75/$0.30) on
  Sep 1 (confirmed on platform.claude.com/pricing). The static tx multiplier
  table is used for real balance transactions, so the post-intro rates were
  overcharging ~50% during the launch window. Switched to the intro rates with
  a revert comment on both the token and cache entries.

- Bedrock disabled-thinking persistence: initializeBedrock feeds persisted
  model_parameters straight through bedrockInputParser (NOT bedrockInputSchema),
  where additionalModelRequestFields is a known key — so a prior
  thinking:{type:'disabled'} was ignored and rebuilt as adaptive on reload.
  bedrockInputParser now surfaces a persisted disabled AMRF.thinking as
  thinking=false so it re-emits {type:'disabled'}. Verified end-to-end against
  the real initializeBedrock call path.
2026-06-30 19:26:33 -04:00
Danny Avila
6523a5add6
🗺️ refactor: Light Up In-Viewport Ribs at Rest in Message Nav (#14041)
At rest (no hover/focus) the rail now reads like a minimap: only the
in-viewport message ribs are at full opacity while the rest fade to 40%,
updating live as you scroll. Replaces the blanket nav opacity-30 with
per-rib opacity driven by the existing viewport-visibility highlight, so
hover/focus still brings every rib to full opacity for the fisheye.
2026-06-30 16:49:01 -04:00
Danny Avila
dd8a4558f1
🪗 feat: Dock-Style Fisheye Nav Rail With Instant Hover Preview (#14021)
Some checks are pending
Docker Dev Branch Images Build / build (Dockerfile, lc-dev, node) (push) Waiting to run
Docker Dev Branch Images Build / build (Dockerfile.multi, lc-dev-api, api-build) (push) Waiting to run
GitNexus Index / index (push) Waiting to run
GitNexus Index / post-index (push) Blocked by required conditions
*  feat: Dock-Fisheye Message Nav Rail with Instant Hover Preview

* 🎚️ refactor: Uniform resting ribs + clickable cursor for message nav

* 🧹 fix: One rib per message in nav rail (dedupe nested message-render)

* 🎯 fix: Accurate fisheye focus + click-anywhere-to-jump in message nav

- Measure rib centers relative to the column (getBoundingClientRect) instead
  of offsetTop, which was relative to the positioned <nav> and shifted the
  pointer->rib mapping by the chevron height (hovered line wasn't the peak,
  preview showed an earlier message).
- Column-level click jumps to the focused rib, so clicking anywhere the
  preview is showing works even when the pointer is off the thin line.
- Restore @librechat/client jest stub to keep the unit isolated.

* 💡 fix: Highlight only the hovered rib white in message nav

* 🫥 style: Transparent message nav (drop pill background)

*  feat: Keyboard focus mirrors hover (magnify + highlight + preview) in message nav

Tabbing to / Shift+Alt+M focusing a rib now drives the same fisheye
pipeline as pointer hover via onFocus/onBlur on the column: the focused
rib magnifies, highlights white, and shows the shared preview. Also
addresses Codex finding on keyboard-focus previews.

* 🩹 fix: Live tooltip preview + legacy media-query fallback in message nav

- Derive the shared preview text from entryById at render time instead of
  snapshotting it into tip state, so a streaming/updating message refreshes
  the open tooltip without leaving and re-entering the rail.
- Feature-detect MediaQueryList.addEventListener and fall back to
  addListener/removeListener so the reduced-motion watcher no longer throws
  (and breaks the nav) on Safari/iOS < 14.

Addresses both Codex findings on review 4601236141.
2026-06-30 14:21:22 -04:00
Marco Beretta
e5d5018d7f
perf: memoize FavoritesList and BookmarkNav to prevent re-renders during streaming (#14011)
* perf: memoize FavoritesList and BookmarkNav to prevent streaming re-renders

ConversationsSection re-renders during message streaming as its
conversation-list query and title generation update the cache. Its
FavoritesList and BookmarkNav children were not memoized, so they
re-rendered on every parent commit despite their props and
subscriptions never changing during a stream.

Wrap both in React.memo to insulate them from the parent cascade.
Their props (toggleNav, isSmallScreen, tags, setTags) are referentially
stable, so memo fully decouples them. Add a regression test asserting
FavoritesList does not re-run when its parent re-renders with stable
props.

* test: verify ConversationsSection insulates Favorites/Bookmarks from streaming re-renders

Renders the real ConversationsSection (mocking only data hooks) and
forces repeated re-renders via a subscription it depends on, mirroring
the conversation-list/title-generation cache churn during streaming.
Asserts FavoritesList and BookmarkNav do not re-render, proving the
parent passes referentially stable props so React.memo holds in the
real render path (not just with hand-fed stable props).
2026-06-30 11:30:04 -04:00
Danny Avila
8545af91f2
📦 chore: bump @librechat/agents to v3.2.54 (#14035) 2026-06-30 10:42:57 -04:00