mirror of
https://github.com/danny-avila/LibreChat.git
synced 2026-11-12 00:57:27 +00:00
* feat(prompts): sync Langfuse prompts into the catalog * refactor(prompts): compose the Langfuse prompt sync runner outside the admin handler Add createLangfusePromptSyncRunner, which binds the lock, the prompt-group methods, the ACL grant and the Mongo error predicates once and returns a runner that takes the per-request source, connection-bound listPrompts, lock lease and page cap. The admin handler receives that runner as one dependency instead of forwarding its parts, and its config method signatures return a LangfuseAdminConfig interface in place of Mongoose document types. In api, api/cache/distributedLock.js creates the one DistributedLock for the process and api/server/services/LangfusePromptSync.js composes the runner once with it; the admin route imports the composed runner. * fix(prompts): report incomplete Langfuse syncs and gate the sync action - Refresh the prompt-group and effective-permission queries after a failed sync too, because earlier imports can already be committed. - Return `complete: false` when the page limit stops a sync before the last upstream page, and show a warning instead of the success message. - Show the Sync prompts action only to users with `manage:prompts`, the capability the sync route requires. Resolve the Langfuse startup-config capabilities in one batched lookup. - Document that an interrupted import can leave a group without its initial PUBLIC grant, and that a page in progress can outlast an expired lease. --------- Co-authored-by: Rebase Probe <probe@example.com>
18 lines
699 B
JavaScript
18 lines
699 B
JavaScript
const mockLock = { acquire: jest.fn(), extend: jest.fn(), release: jest.fn() };
|
|
const mockCreateDistributedLock = jest.fn(() => mockLock);
|
|
const sentinelRedisClient = {};
|
|
|
|
jest.mock('@librechat/api', () => ({
|
|
createDistributedLock: mockCreateDistributedLock,
|
|
ioredisClient: sentinelRedisClient,
|
|
}));
|
|
|
|
describe('distributedLock', () => {
|
|
it('builds the process-wide lock once with the shared Redis client', () => {
|
|
const { distributedLock } = require('./distributedLock');
|
|
|
|
expect(mockCreateDistributedLock).toHaveBeenCalledTimes(1);
|
|
expect(mockCreateDistributedLock).toHaveBeenCalledWith({ redisClient: sentinelRedisClient });
|
|
expect(distributedLock).toBe(mockLock);
|
|
});
|
|
});
|