Commit graph

629 commits

Author SHA1 Message Date
Pete Hampton
679672ad15
🪂 feat: Graceful HTTP shutdown on SIGTERM/SIGINT (#13211)
* 🪂 feat: Graceful HTTP shutdown on SIGTERM/SIGINT

* Address feedback

* don't treat ERR_SERVER_NOT_RUNNING as fatal; route telemetry shutdown through coordinator
2026-05-20 13:33:53 -04:00
Danny Avila
9dd062e42e
🧯 fix: Harden Data Retention Semantics (#13049)
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: support data retention for normal chats

Add retentionMode config variable supporting "all" and "temporary" values.
When "all" is set, data retention applies to all chats, not just temporary ones.
Adds isTemporary field to conversations for proper filtering.

Adapted to new TS method files in packages/data-schemas since upstream
moved models out of api/models/.

Based on danny-avila/LibreChat#10532

Co-Authored-By: WhammyLeaf <233105313+WhammyLeaf@users.noreply.github.com>
(cherry picked from commit 30109e90b0)

* feat: extend data retention to files, tool calls, and shared links

Add expiredAt field and TTL indexes to file, toolCall, and share schemas.
Set expiredAt on tool calls, shared links, and file uploads when
retentionMode is "all" or chat is temporary.

(cherry picked from commit 48973752d3)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: lint/test

(cherry picked from commit 310c514e6a)

* fix: address code review feedback for data retention PR

Critical:
- Fix BookmarkMenu crash: restore optional chaining on conversation
- Fix migration hazard: backward-compatible sidebar filter that also
  checks expiredAt for documents without isTemporary field

Major:
- Add logging to getRetentionExpiry error path, align with tools.js
- Add tests for retentionMode: ALL in saveConvo and saveMessage
- Fix share route: apply expiredAt for temporary chats too by
  querying the conversation's isTemporary flag server-side
- Add assertions for getRetentionExpiry mocks in process tests

Minor:
- Fix ChatRoute isTemporaryChat to be strictly boolean via Boolean()
- Fix stale test description (expired -> temporary)
- Comment out retentionMode default in example yaml
- Simplify verbose if/else to isTemporary === true
- Add compound index on { user: 1, isTemporary: 1 }
- Remove narrating comment from process.spec.js

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
(cherry picked from commit 6bad535f90)

* chore: fix typescript

(cherry picked from commit 826527a46b)

* fix: lint

(cherry picked from commit 77817e80ea)

* fix: use mockSanitizeArtifactPath in retention test

The 'getRetentionExpiry is called with the request object' test
referenced an undefined `mockSanitizeFilename` identifier, breaking
both lint (no-undef) and the test suite. Use the existing
`mockSanitizeArtifactPath` mock that the surrounding tests already
use, since `processCodeOutput` calls `sanitizeArtifactPath` (not
`sanitizeFilename`) before invoking `getRetentionExpiry`.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
(cherry picked from commit 52ea2da66d)

* fix: forward isTemporary from client for retention on file uploads and tool calls

Server-side `getRetentionExpiry` (file uploads) and the tool-call
controller both read `req.body.isTemporary`, but the file upload
multipart form and the tool-call payload did not include that field.
In `retentionMode: temporary` (default), files uploaded and tool
calls created from temporary chats were therefore retained
indefinitely.

Forward the Recoil `isTemporary` flag in both client paths so the
existing server checks can fire correctly. `ToolParams` gains an
optional `isTemporary` field.

Addresses Codex P1 review feedback on PR #29.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
(cherry picked from commit 7e937df05a)

* test: stub store.isTemporary in useFileHandling test mocks

Previous commit added `useRecoilValue(store.isTemporary)` to the
hook. The test file mocks `~/store` with only `ephemeralAgentByConvoId`
and does not stub `useRecoilValue`, so all 7 cases threw
"Invalid argument to useRecoilValue: expected an atom or selector but
got undefined". Add a stub default export with `isTemporary` and a
`useRecoilValue` mock returning `false`.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
(cherry picked from commit eb1609537d)

* fix: harden data retention semantics

* fix: provide sweep request context for expired files

* fix: preserve temporary flags in all-retention updates

* fix: honor assistant versions in retention sweeps

* fix: retain non-temporary flags in all mode

* fix: hide expired retained records

* fix: propagate retained conversation expiry

* fix: refresh meili retention cutoff

* fix: prevent overlapping file sweeps

* fix: show legacy retained conversations

* fix: index legacy retained records

* fix: harden retention cleanup edge cases

* fix: count failed file storage sweeps

* fix: preserve legacy temporary retention

* fix: assign retention sweep worker deterministically

* fix: hide expired shared links on reads

* fix: prevent retention refresh after parent expiry

* fix: break code output retention import cycle

* fix: harden retention review findings

* fix: ignore expired share duplicates

* fix: reject expired retained share creation

* fix: harden retention review edge cases

* fix: address retention audit findings

* fix: enforce expired conversation shares in all retention

* fix: scope temporary upload flag to chat files

* fix: address retention review findings

* fix: address codex retention review findings

* fix: tighten missing storage detection

* test: remove unused file process spec bindings

---------

Co-authored-by: WhammyLeaf <233105313+WhammyLeaf@users.noreply.github.com>
Co-authored-by: Aron Gates <aron@muonspace.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-19 21:58:42 -04:00
Peter Nancarrow
2418f854df
📡 fix: Handle Pre-Session 406 for Optional SSE MCP Stream (#13202) 2026-05-19 20:59:45 -04:00
Danny Avila
749eb06e67
🧭 fix: Reduce MCP Registry ACL Lookups (#13195) 2026-05-19 17:16:37 -04:00
Danny Avila
2414e9c7d2
🛟 refactor: Gracefully Skip Unavailable Web Search Rerankers (#13191)
Some checks failed
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
Docker Dev Images Build / build (Dockerfile, librechat-dev, node) (push) Has been cancelled
Docker Dev Images Build / build (Dockerfile.multi, librechat-dev-api, api-build) (push) Has been cancelled
GitNexus Index / index (push) Has been cancelled
Sync Locize Translations & Create Translation PR / Sync Translation Keys with Locize (push) Has been cancelled
GitNexus Index / post-index (push) Has been cancelled
Sync Locize Translations & Create Translation PR / Create Translation PR on Version Published (push) Has been cancelled
2026-05-19 09:48:12 -04:00
Danny Avila
909329a7e8
🍪 feat: Add Session Cookie Secure Override (#13189)
* fix: add session cookie secure override

* chore: remove empty whitespace
2026-05-19 09:44:14 -04:00
Danny Avila
9107000161
👟 feat: Eager Execution of Tool Calls (#13192)
* 📦 chore: Bump `@librechat/agents` to v3.1.89

* feat: enable eagerEventToolExecution in createRun function
2026-05-19 09:43:03 -04:00
Danny Avila
75d196f312
📦 chore: Bump @librechat/agents to v3.1.88 (#13187)
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
2026-05-18 21:39:21 -04:00
Danny Avila
fdffa9ac96
📦 chore: npm audit fix, bump otel & @librechat/agents (#13186)
* 📦 chore: npm audit fix 2026-05-18

- Added @js-sdsl/ordered-map version 4.4.2
- Updated @librechat/agents to version 3.1.87
- Upgraded @opentelemetry/sdk-node to version 0.218.0
- Added new dependencies for gRPC and OpenTelemetry exporters

* 🔧 chore: Update @librechat/agents to version 3.1.87 in package-lock.json and package.json files

* 🔧 chore: Upgrade @opentelemetry/sdk-node to version 0.218.0 in package.json and package-lock.json
2026-05-18 19:34:10 -04:00
Danny Avila
68eac104ad
🗂️ fix: Scope Handoff Agent Context Docs (#13167)
* fix: Scope agent context docs to handoff agents

* fix: Deduplicate scoped request context

* refactor: Extract agent attachment helpers
2026-05-18 15:36:22 -04:00
Danny Avila
394839a76b
🔍 fix: Prefer LibreChat Web Search over Anthropic's when Both Selected (#13166) 2026-05-18 15:35:29 -04:00
Gaurav Dubey
6466263493
🧹 chore: Type Agent MCP lean projection in ServerConfigsDB (#13171)
Replace the (a: any) cast and its eslint-disable directive in
ServerConfigsDB.getAll() with a precise lean-projection generic.
The Mongoose query already projects only mcpServerNames, so we
can use Pick<IAgent, 'mcpServerNames'> and let .lean<T[]>() carry
the shape through without resorting to any.

Switches the empty-array guard from || to ?? for clarity; both
behave identically for string[] | undefined.

Aligns with the project's "Never use any" rule (CLAUDE.md ->
Type Safety). No runtime change.
2026-05-18 15:32:43 -04:00
Danny Avila
77c523ea35
🧽 fix: Strip Admin OAuth Redirect Params (#13181) 2026-05-18 15:27:19 -04:00
Danny Avila
c342e2345b
🪪 fix: Resolve Group-Scoped Config Overrides (#13176)
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: resolve group-scoped config overrides

* test: fix endpoint config request mock typing

* fix: keep remote agent preauth config tenant-scoped

* test: align config scoping expectations

* test: reproduce group endpoint override resolution
2026-05-18 10:16:20 -04:00
Danny Avila
b549966e4a 🧭 fix: Tighten Action OAuth Endpoint Validation (#13142)
Some checks failed
Docker Dev Images Build / build (Dockerfile, librechat-dev, node) (push) Has been cancelled
Docker Dev Images Build / build (Dockerfile.multi, librechat-dev-api, api-build) (push) Has been cancelled
GitNexus Index / index (push) Has been cancelled
Sync Locize Translations & Create Translation PR / Sync Translation Keys with Locize (push) Has been cancelled
GitNexus Index / post-index (push) Has been cancelled
Sync Locize Translations & Create Translation PR / Create Translation PR on Version Published (push) Has been cancelled
* fix: tighten action OAuth endpoint validation

* fix: reuse action OAuth validation primitives

* fix: preserve action OAuth address exemptions
2026-05-15 14:53:41 -04:00
Danny Avila
27266bbcdc 🛰️ fix: Redact Outbound Telemetry URL Queries (#13133)
* fix: redact outbound telemetry URL queries

* fix: handle telemetry redaction edge cases

* fix: keep sanitized telemetry URLs absolute

* fix: infer https telemetry URL scheme

* fix: avoid port-only telemetry protocol inference

* fix: bracket ipv6 telemetry hosts
2026-05-15 14:53:41 -04:00
JorgeCosta87
5b11a5a076
🪵 chore: Restore Winston Format Factory Shape In Test Mocks (#13139)
Four jest mocks for `winston` in the test suite return the wrong shape:

  api/test/__mocks__/logger.js                                   (returns inner fn directly)
  packages/api/src/agents/__tests__/memory.test.ts               (`format` is a plain object)
  packages/api/src/agents/__tests__/run-summarization.test.ts    (same)
  packages/api/src/agents/__tests__/initialize.test.ts           (same)

Real `winston.format(fn)` returns a Format constructor whose instances
expose a `.transform(info, opts)` method that winston's pipeline calls
with the log info object. The current mocks collapse this:

- `(fn) => fn` returns the inner transform fn directly. When module-load
  code in `@librechat/data-schemas/dist/config/parsers.cjs:52` does
  `const redactFormat = winston.format((info) => ...)`, `redactFormat`
  becomes the inner fn. The next line in `winston.cjs` calls
  `parsers.redactFormat()` which invokes the inner fn with no `info`,
  throwing `TypeError: Cannot read properties of undefined (reading 'level')`.

- `format: { combine, colorize, simple }` makes `winston.format` not
  callable at all — `winston.format((info) => ...)` throws
  `TypeError: winston.format is not a function`.

These currently pass in CI on GitHub Actions Ubuntu / Node 20.19, but
fail reproducibly on Node 24.x and on some Linux distros (verified on
WSL Ubuntu with Node 24.9.0). The CI passes appears to be environmental
luck around jest's mock-hoisting interaction with the workspace symlink
chain — the mocks are genuinely wrong against the data-schemas contract.

The fix: return a thunk that yields `{ transform: fn }` — matches real
winston's shape just enough that module-load completes; the inner fn is
only ever invoked by winston's pipeline (never at load time). Also adds
the full `winston.format.*` method surface (printf, timestamp, errors,
splat, json) plus `addColors` and the `DailyRotateFile`/`File` transports
that data-schemas's dist code references at module-load.

Verification (Node 24.9.0):
  npm run build:data-provider && npm run build:data-schemas && npm run build:api
  cd packages/api && npx jest src/agents/__tests__/{memory,run-summarization,initialize}.test.ts
  → 3 suites, 106 tests, all pass

No production code or behavior changes — test-only patch.

Co-authored-by: Jorge Costa <8352477+JorgeCosta87@users.noreply.github.com>
2026-05-15 14:51:53 -04:00
Danny Avila
ca8c212c0d
🗝️ fix: Protect Model Spec Instructions (#13125)
Some checks failed
Docker Dev Branch Images Build / build (Dockerfile, lc-dev, node) (push) Has been cancelled
Docker Dev Branch Images Build / build (Dockerfile.multi, lc-dev-api, api-build) (push) Has been cancelled
GitNexus Index / index (push) Has been cancelled
GitNexus Index / post-index (push) Has been cancelled
Docker Dev Images Build / build (Dockerfile, librechat-dev, node) (push) Has been cancelled
Docker Dev Images Build / build (Dockerfile.multi, librechat-dev-api, api-build) (push) Has been cancelled
Sync Locize Translations & Create Translation PR / Sync Translation Keys with Locize (push) Has been cancelled
Sync Locize Translations & Create Translation PR / Create Translation PR on Version Published (push) Has been cancelled
* fix: prevent instruction exposure

* fix: tighten model spec preset restoration

* refactor: type model spec preset handling
2026-05-14 10:07:23 -04:00
Danny Avila
050b7fd43a
📡 feat: Add Backend OpenTelemetry Tracing (#12909)
* feat: add backend OpenTelemetry tracing

* fix: address telemetry type checks

* fix: mark aborted telemetry requests as errors

* fix: record telemetry identity after auth

* fix: avoid forced telemetry signal exit

* fix: harden telemetry request attribution

* fix: record telemetry errors on request span

* chore: order imports and reorganize middleware usage

* fix: reduce telemetry startup overhead

* fix: preserve live telemetry controller state

* fix: redact telemetry URL attributes
2026-05-14 09:08:55 -04:00
jingyeong
7e4c5d9ded
🧹 fix: Reset Redis Reorder State After Last Unsubscribe (#13117)
Co-authored-by: parkjingyeong <sand1166@hyundai.com>
2026-05-14 08:45:50 -04:00
Josh
c582e87e3b
🛡️ feat: Bedrock Guardrail Config Environment Variable Resolution (#11717)
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
* bedrock config loading

* Update packages/api/src/endpoints/bedrock/initialize.ts

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* test refactor

---------

Co-authored-by: Josh Fink <josh.fink@innovation.nj.gov>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-05-13 23:13:36 -04:00
Danny Avila
7f58e4c2ed
🧾 feat: Add Structured Logging Context (#13110)
* feat: add structured logging context

* fix: reduce cloudfront disabled logging

* fix: preserve strict reject logging context

* chore: format auth middleware test

* fix: omit system tenant from log context

* fix: type parser spec formatter info

* fix: normalize tenant guard before reject checks
2026-05-13 19:17:39 -04:00
Danny Avila
9e8b8c3705
🧰 fix: Scope MCP Registry Initialization To Config Fingerprints (#13115) 2026-05-13 16:50:07 -04:00
Danny Avila
34dd8d5f2a
📈 feat: Add Prometheus Metrics Endpoint + AWS Credential Providers (#13111)
* feat: add prometheus metrics endpoint

* fix: format metrics route spec

* chore: update dependencies in package.json and package-lock.json correctly

- Bump `@smithy/core` to version 3.24.1
- Update `@aws-sdk/credential-providers` to version 3.1045.0
- Reintroduce `prom-client` dependency in package.json
- Remove unnecessary dependencies from package.json

* chore: import order

* fix: declare s3 presigner peer dependency

* fix: normalize shared link metrics path

* fix: bound metrics path labels

* fix: tighten metrics auth and peers

* fix: collapse partial metrics paths
2026-05-13 16:49:25 -04:00
Dan Lew
83ea3efbc1
🚧 feat: Support Guardrail Config Option streamProcessingMode (#12815)
`streamProcessingMode` affects how guardrail processes the stream from
the model. If it's in "sync" mode, it chunks up the response and processes
them before returning them to the user. If it's in "async" mode, it
both processes the chunk & sends it to the user at the same time, allowing
for smoother streaming (at the cost of guardrail only reacting *after*
offending content starts to stream, in some cases).
2026-05-13 14:54:50 -04:00
Danny Avila
68d80f3324
v0.8.6-rc1 (#13094) 2026-05-12 21:40:23 -04:00
Danny Avila
8eb9de011f
📦 chore: bump @librechat/agents to v3.1.86, npm audit, build fix (#13105)
* 📦 chore: Bump `@librechat/agents` to v3.1.86 in package-lock.json and package.json files

* 📦 chore: Update dependencies in package-lock.json to latest versions, including @protobufjs/codegen, @protobufjs/inquire, @protobufjs/utf8, and protobufjs

* 📦 chore: Add `librechat-data-provider` dependency in package.json and package-lock.json, and update build dependencies in turbo.json
2026-05-12 16:19:55 -04:00
Danny Avila
6b5596ec36
🍪 refactor: Refresh CloudFront Media Cookies (#13091)
* fix: refresh CloudFront media cookies

* fix: satisfy changed-file lint

* fix: centralize CloudFront image retry

* fix: honor base path for CloudFront refresh

* fix: bypass auth refresh for CloudFront cookie retry

* fix: pass app auth header to CloudFront retry

* test: cover CloudFront refresh with OpenID reuse

* fix: avoid duplicate CloudFront refresh retries

* fix: clear CloudFront scope cookie with matching flags
2026-05-12 13:26:05 -04:00
Ravi Kumar L
05d4e90f91
🌩️ feat: Strict CloudFront signed cookie enforcement via requireSignedAccess (#13078)
* feat(cloudfront): add requireSignedAccess to enforce strict signed access

Introduces cloudfront.requireSignedAccess (default false). When enabled,
initializeCloudFront requires both CLOUDFRONT_KEY_PAIR_ID and
CLOUDFRONT_PRIVATE_KEY, rejects the unimplemented imageSigning="url"
mode, and initializeFileStorage throws to block startup on any
CloudFront init failure. OSS path is unchanged: missing keys still
log-and-continue when requireSignedAccess is false.

Adds low-noise startup and cookie-issuance logs without leaking signed
URLs, policies, signatures, private keys, or cookie values.

* fix(cloudfront): reject requireSignedAccess unless imageSigning is "cookies"

Previously requireSignedAccess=true was accepted with imageSigning="none"
or "url", but setCloudFrontCookies() only runs for "cookies" — leaving
strict mode toothless: CloudFront stayed publicly accessible, or image
delivery broke on a distribution that actually requires signed access.

Adds a Zod refinement plus a runtime guard in initializeCloudFront so
the only currently-functional strict configuration is imageSigning
"cookies". Signed URL mode can lift this restriction once implemented.

* fix(cloudfront): resolve strict access type checks

* chore(cloudfront): reduce strict startup log noise

---------

Co-authored-by: Danny Avila <danny@librechat.ai>
2026-05-11 23:30:01 -04:00
Danny Avila
3e7262cfe0
📦 chore: Bump @librechat/agents to v3.1.85 and mermaid to v11.15.0 (#13079)
* 📦 chore: Update @librechat/agents to version 3.1.85 in package-lock.json and package.json files

* 📦 chore: Update mermaid to version 11.15.0 in package.json and package-lock.json
2026-05-11 19:14:18 -04:00
Danny Avila
0a7255b234
🎭 feat: Support OpenID Audience On Refresh Grants (#13077) 2026-05-11 17:40:30 -04:00
Danny Avila
c385f2ba88
📦 feat: Configure Skill Import Size Limit (#13073)
* fix: configure skill import size limit

* fix: validate skill import size in ui

* fix: align skill import size boundary

* fix: show exact skill import limit
2026-05-11 16:24:04 -04:00
Danny Avila
8735c1763c
🧵 fix: Preserve Upload Context Across Multipart Routes (#13072)
* fix skill multipart imports under strict isolation

* fix file upload context after multipart parsing

* fix skill upload tenant resolution

* fix rejected upload cleanup
2026-05-11 15:46:48 -04:00
Danny Avila
0449c423a2
🗝️ fix: Enforce Skill Share Role Permission (#13062)
* fix: enforce skill share role permission

* fix: preserve share capability bypass

* refactor: move share policy middleware to api package

* style: order share middleware imports

* fix: satisfy share middleware type checks

* test: cover share policy resource types
2026-05-11 09:39:58 -04:00
Danny Avila
7631366f52
🪵 chore: Log Subagent Limit Hits (#13068) 2026-05-11 09:25:08 -04:00
Danny Avila
70b6bb69d3
🧬 fix: Bound Subagent Expansion (#13064)
* fix: Bound subagent expansion

* fix: Preserve subagent path depth
2026-05-11 08:53:53 -04:00
Danny Avila
9797c85e23
🧮 fix: Count Rejected Skill Import Bytes (#13063) 2026-05-11 08:40:31 -04:00
Danny Avila
52ccb1379b
🪪 refactor: Require Remote OIDC Audience for Agents API OAuth (#13066) 2026-05-11 08:38:13 -04:00
Danny Avila
7129b1b1e4
📜 refactor: Improve Skill Handling Logs (#13057)
* refactor: Streamline batch upload error handling in `uploadCodeEnvFile`
* refactor: Enhance session info error logging in `getSessionInfo`
* refactor: Update error logging to use `logAxiosError` in various agent handlers and skill file processing functions
* refactor: Consolidate missing resource checks in `createToolExecuteHandler` for better clarity
2026-05-11 02:15:51 -04:00
Danny Avila
846eb0aa2c
🛰️ fix: Validate Vertex Endpoint Overrides (#13054)
* fix: Validate Vertex endpoint overrides

* fix: Allow Vertex PSC endpoint overrides

* fix: Allow restricted Vertex PSC endpoints
2026-05-11 01:11:14 -04:00
Danny Avila
5bab22d236
🛡️ fix: Gate Bash PTC Capabilities (#13053) 2026-05-10 21:23:02 -04:00
Danny Avila
c3ec23f9b8
🌐 feat: Support Vertex AI Multi-Region Endpoints (#13044)
* feat: support Vertex AI multi-region endpoints

* fix: sync Vertex endpoint with final location
2026-05-10 13:41:58 -04:00
Danny Avila
8fc68ebac0
🧬 refactor: Align OpenRouter Reasoning Payloads (#13039)
* fix: Align OpenRouter reasoning payloads

* test: Update OpenRouter reasoning expectations

* fix: Preserve xhigh for future Claude models

* fix: Preserve OpenRouter Responses verbosity

* test: Type OpenRouter verbosity fixture

* fix: Preserve custom verbosity values
2026-05-09 21:04:21 -04:00
Danny Avila
715a4a5fc1
🧰 refactor: Use Bash PTC for Agent Tools (#13042)
* fix: Use Bash PTC for programmatic agent tools

* fix: Preserve legacy PTC event calls
2026-05-09 16:31:09 -04:00
Danny Avila
2e683f112b
🦘 fix: Skip OpenAI Model Fetch For User-Provided Keys (#13038)
* fix: skip OpenAI model fetch if using user-provided key

There was a check present (via `opts.userProvidedOpenAI`), but it wasn't
working because `loadDefaultModels()` doesn't provide that parameter. As a
result, the server would repeatedly try to request models from OpenAI and get
401 errors in return.

We now check the env var directly, which matches how
`getAnthropicModels()` works.

* chore: remove unused OpenAI model option

* fix: honor explicit OpenAI key for model fetch

* fix: fall back from empty OpenAI option key

---------

Co-authored-by: Dan Lew <daniel@mightyacorn.com>
2026-05-09 16:12:25 -04:00
Danny Avila
80ce956c94
📜 fix: Scope Read File Prompt For Code Agents (#13040)
* fix: Scope read_file prompt for code agents

* fix: Align code read_file prompt behavior
2026-05-09 16:09:56 -04:00
Danny Avila
c67e2b54dc
🔐 feat: Mint Code API Auth Tokens (#13028)
* feat: Mint CodeAPI auth tokens

* style: Format CodeAPI download route

* fix: Prune CodeAPI token cache

* fix: Propagate CodeAPI managed auth

* test: Mock CodeAPI auth in traversal suite

* fix: Pass auth context to invoked skill cache

* feat: Mint CodeAPI plan context

* chore: Refresh CodeAPI auth guidance

* fix: Guard OpenID JWT fallback

* fix: Default CodeAPI JWT tenant in single-tenant mode

* chore: Update @librechat/agents to version 3.1.84 in package-lock.json and package.json files

* chore: Standardize references to Code API in comments and tests
2026-05-09 16:09:10 -04:00
Danny Avila
8a654dc8b1
🧭 feat: Add OpenRouter Prompt Cache Setting (#13029)
* feat: add OpenRouter prompt cache setting

* fix: type OpenRouter schema lookup

* fix: honor proxied OpenRouter prompt cache

* refactor: flatten endpoint schema fallback

* chore: Bump `@librechat/agents` to version 3.1.82

* fix: Default OpenRouter prompt cache params

* test: Align OpenRouter config expectations

* test: Update OpenRouter default cache expectation

* fix: Align OpenRouter Detection

* chore: Bump `@librechat/agents` to version 3.1.83

* docs: Remove OpenRouter prompt cache setup note

* refactor: Use provider enum for OpenRouter defaults

* style: Format OpenRouter defaults guard
2026-05-09 11:46:09 -04:00
Danny Avila
c7a4e6d418
📦 chore: Bump @babel/preset-env to v7.29.5 (#13034) 2026-05-08 19:51:06 -04:00
Danny Avila
b922187abb
🛟 fix: Summarization Provider misses vertexai + case-mismatched custom endpoints (#13025)
`resolveSummarizationProvider` calls `getProviderConfig` to translate the
agent's resolved provider into an initializer + client overrides. Three
real-world inputs were unsupported and fell through to "raw provider"
fallback (silently dropping client overrides):

1. **`vertexai`** — not in `providerConfigMap` at all. Vertex shares
   initialization with Google (auth-only runtime distinction). Map
   `Providers.VERTEXAI` to `initializeGoogle`.

2. **`openrouter` (and other known custom providers) with CamelCase
   custom endpoint names** — agent main flow looks up endpoints
   case-sensitively (case-preserving keys are how
   `loadCustomEndpointsConfig` lets users have distinct entries
   differing only in case). Once it succeeds, `agent.provider` is
   normalized to lowercase. Downstream resolvers re-enter
   `getProviderConfig` with the lowercased value and miss configs
   whose `name` is camel-cased. Add a case-insensitive fallback,
   narrowly scoped to known custom providers and only after the
   case-sensitive direct lookup fails.

3. **Ambiguous case-insensitive matches (codex review feedback)** —
   if the user has e.g. `OpenRouter` and `OPENROUTER` (neither
   lowercase) and the agent runtime passes `openrouter`, the
   case-insensitive fallback could silently route to whichever entry
   appears first in the array (potentially different baseURL/apiKey).
   Detect multiple case-insensitive matches and throw a clear error
   with both names rather than picking arbitrarily.

## Tests

`providers.spec.ts` — new file, 7 tests:
- vertexai → Google initializer
- google (API key) → Google initializer (regression guard)
- case-insensitive fallback when only CamelCase entry exists
- exact-case match preserved when both casings exist (case identity)
- exact-case lowercase entry still resolves
- throws on ambiguous case-insensitive matches when no exact-case exists
- still throws when no match at all
2026-05-08 18:52:01 -04:00