[pull] main from danny-avila:main#168
Merged
Merged
Conversation
#13642) * 🎯 fix: Soft Default Model Spec Overriding User Selections * 🎯 fix: Detect Agents-Only Allow-List Before Endpoints Config Loads * 🎯 fix: Preserve Explicit Soft Default Selections over Older History * 🎯 fix: Limit Soft Default Residue to Spec-Named State, Disable E2E Enforcement
* 🧹 fix: Close Leaked Redis Clients in Cache Integration Tests
Importing `redisClients` constructs and connects BOTH `ioredisClient`
and `keyvRedisClient` as module side effects, but most cache/mcp
integration specs disconnected at most one of them — and specs that
re-import the module per test via `jest.resetModules()` leaked a fresh
pair of connected clients (sockets + ping timers) for every test.
On runners where jest resolves to a single worker (2-core machines with
`maxWorkers: '50%'`), the suite runs in-band and the leaked handles keep
the main process alive after all tests pass — the run hangs until the
CI job timeout. On larger runners jest recovers only by force-exiting
the leaked worker ("A worker process has failed to exit gracefully...").
- add a `closeRedisClients()` test helper that settles the connect
promise and closes both clients of a `redisClients` module instance
- call it from every cache/mcp integration spec that creates clients,
mirroring what LeaderElection.cache_integration.spec.ts already does
- remove the rethrow in the `keyvRedisClientReady.catch(...)` logging
handler — rethrowing inside `.catch` creates a new, never-observed
rejected promise, turning any failed initial connect into a
guaranteed unhandled rejection; callers awaiting
`keyvRedisClientReady` still observe the original rejection
All four `test:cache-integration` stages now pass AND exit cleanly with
`--maxWorkers=1` against both single-node and cluster Redis, with no
force-exit warning in worker mode.
* 🧹 chore: Treat testRedisOperations as Assertion in expect-expect Rule
* 🗂️ chore: Sort Imports per Repo Convention
* 🪟 ci: Shard Windows Frontend Unit Tests Mirror the 4-way jest sharding the Ubuntu frontend test job already uses onto the Windows job, which currently runs the whole client suite in a single 20-minute job. Also drops the `--verbose` flag, which npm consumed itself (it preceded `--`) and only raised npm's own log level. * 🪟 ci: Trigger Frontend Tests on Workflow Changes
* 🛡️ feat: Reject chat messages matching configured credential patterns Adds an opt-in `messagePiiFilter` middleware mounted on the agent chat route ahead of `moderateText`. When the configured patterns match the user's input the request is refused with 400, so the credential never reaches OpenAI moderation, the model, or MongoDB. Three starter patterns ship by default and operators can subset them or add their own regex via `customPatterns` in librechat.yaml. * 🧪 test: Memoize compiled patterns + add middleware spec Memoize the compiled pattern array via a WeakMap keyed by the messagePiiFilter config object so repeat requests against the same config skip the per-request RegExp construction. Cache entries are released automatically when the config object itself rotates. Adds packages/api/src/middleware/messagePiiFilter.spec.ts covering the default-starter rejections, the starterPatterns subset and empty-array semantics, customPatterns matching layered on top of and in place of the starters, the no-config and empty-text pass-through paths, and a memoization regression check. * 🛡️ fix: Skip invalid customPattern regexes instead of crashing the request Admin DB overrides for `messagePiiFilter.customPatterns` reach `req.config` via `mergeConfigOverrides`, which deep-merges raw override values without re-running `configSchema`. A typo'd regex like `(` would slip past the YAML-load validation and throw inside `new RegExp(...)` during `compile()`, returning 500 for every chat request until the operator rolled the override back. Wrapped the per-pattern compile in a try/catch that logs the invalid pattern id + reason and skips it, so other valid patterns (starters and other custom entries) keep filtering. Added a regression test alongside the existing spec. * 🛡️ feat: Extend PII filter to OpenAI-compatible and Responses agent APIs The chat-route middleware operates on `req.body.text`, but the remote agent API endpoints (`/api/agents/v1/chat/completions`, `/api/agents/v1/responses`) accept the same prompt content as a `messages` array or an `input` field. A caller using their API key could send a credential-shaped value through either route and bypass the configured PII filter even though they share the same agent and model backbone the middleware is meant to guard. Factored out `findPiiMatchInMessages`, a tolerant walker that handles both `content: string` and `content: ContentPart[]` user-message shapes against the same compiled, cached pattern list. Wired it into the OpenAI-compat controller after agent lookup and into the Responses controller right after `convertToInternalMessages`. Each returns the endpoint's native 400 error shape (`sendErrorResponse` / `sendResponsesErrorResponse`) with the `message_pii_filter_block` code when a user message matches. * 🩹 test: Add findPiiMatchInMessages to OpenAI + Responses controller mocks The OpenAI-compat and Responses controller specs mock `@librechat/api` with a hand-listed object. The new `findPiiMatchInMessages` export wired into both controllers in 3ea35af was missing from those mocks, so the production lookup returned undefined and the controllers threw at request time under jest. Added the missing entries (default mock: returns null so the handlers fall through to the existing happy paths). All 278 agents-controller tests pass locally. * 🧹 refactor: Namespace messagePiiFilter under messageFilter.pii + fix import order Renames the yaml field `messagePiiFilter` to `messageFilter.pii`, the module to `messageFilterPii`, the factory to `createMessageFilterPii`, the type to `MessageFilterPiiConfig`, and the error code to `message_filter_pii_block`. The wrapper `messageFilter` namespace gives future safety filters (e.g. `messageFilter.toxicity`) a place to plug in without restructuring the config later. The `findPiiMatchInMessages` helper kept its name because it already describes what it does at the value level. Also fixes import order Danny flagged on the OpenAI-compatible and Responses controllers: `findPiiMatchInMessages` was appended at the bottom of two `require('@librechat/api')` destructures rather than placed in the length-sorted slot the house style expects. * 🧹 chore: Length-sort the general require destructure in responses.js Reorders the general sub-group inside the `require('@librechat/api')` destructure shortest to longest so the whole block conforms to the length-sort rule the file's `// Responses API` sub-group already follows. Pure reorder, no other changes. * 🧹 chore: Length-sort the defaultConfig block in AppService Reorders the `defaultConfig` keys in `packages/data-schemas/src/app/service.ts` shortest-line to longest-line, with the explicit-value entries (`mcpConfig`, `fileStrategies`, `cloudfront`) trailing the shorthand ones. Pure reorder, no behavior change.
…13589) * ✅ Add mock e2e coverage for agents, prompts, MCP, and chat flows * 🎯 fix: Change enforce modelSpecs to false --------- Co-authored-by: Danny Avila <danny@librechat.ai>
* 🧭 fix: Mobile Sidebar Navigation on Projects View * 🧭 fix: Align Sidebar Toggle with JS Mobile Breakpoint at 768px
* 🗜️ ci: Cache Dependencies and Builds in Cache Integration Tests Port the node_modules and package-dist caching pattern from backend-review.yml to cache-integration-tests.yml, which ran a full npm ci (~72s) and rebuilt data-provider, data-schemas, and api on every run. Cache keys are identical to backend-review.yml so the two workflows share entries. Drops setup-node's npm tarball cache, superseded by the node_modules restore, matching backend-review.yml. * 🗜️ ci: Exercise Warm-Cache Path
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 subscribe to this conversation on GitHub.
Already have an account?
Sign in.
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.
See Commits and Changes for more details.
Created by
pull[bot] (v2.0.0-alpha.4)
Can you help keep this open source service alive? 💖 Please sponsor : )