mirror of
https://github.com/danny-avila/LibreChat.git
synced 2026-11-02 12:12:17 +00:00
* feat: introduce optional content protection seam * feat: enforce source-aware content filters * feat: complete source-aware content enforcement * test: activate skill file-text fail-close fixtures * fix: harden source-aware content filters * fix: harden model-bound content filtering * fix: preserve legacy filters and generated files * fix: inspect shared scalar metadata * test: align mocks with current dev dependencies * feat: add persisted content filter safeguards * feat: complete source-aware content filter enforcement * fix: move resume content preflight into TypeScript * fix: close content inspection edge cases * fix: harden content protection boundaries * fix: complete content protection safeguards * test: align persisted memory filter coverage * fix: reconcile content protection with current dev * fix: reconcile content protection with latest dev * fix: close content protection review gaps * fix: enforce source-aware provider boundaries * fix: preserve legacy PII preflight semantics * test: stabilize stored branch preflight fixture * fix: defer agent writes until protected model admission * perf: harden source-aware model-bound filtering * fix: canonicalize provider lineage before validation * fix: satisfy model-bound callback type checks * perf: Bound content protection filtering work * fix: Bound submission array traversal * fix: Stabilize bounded content snapshots * fix: Scope model-bound traversal overflows * fix: Preserve scoped content inspection * fix: Accumulate aggregate traversal scopes * fix: centralize content policy boundaries * test: align deferred tool policy context * test: align controller policy mocks * style: normalize content protection imports * fix: close content policy review gaps * fix: narrow active skill policy config * fix: address content protection review boundaries * fix: retain exact provenance overflow sentinel * fix: preserve literal and scoped provenance updates * fix: narrow persisted edit provenance * fix: isolate exact overflow attribution * fix: centralize stored prompt protection * fix: fail closed on incomplete transcript evidence * fix: align canonical transcript routing * refactor: centralize content policy preflights * fix: isolate upload policy error typing * style: sort policy preflight imports * refactor: centralize content policy boundaries
110 lines
3 KiB
JavaScript
110 lines
3 KiB
JavaScript
const mockCache = {
|
|
set: jest.fn(),
|
|
};
|
|
const mockSaveConvo = jest.fn();
|
|
const mockInitializeClient = jest.fn();
|
|
|
|
jest.mock('@librechat/api', () => ({
|
|
...jest.requireActual('@librechat/api'),
|
|
isEnabled: (value) => value === true || value === 'true',
|
|
sanitizeTitle: (title) => title,
|
|
}));
|
|
|
|
jest.mock('@librechat/data-schemas', () => ({
|
|
logger: { debug: jest.fn(), info: jest.fn(), warn: jest.fn(), error: jest.fn() },
|
|
}));
|
|
|
|
jest.mock('~/cache/getLogStores', () => jest.fn(() => mockCache));
|
|
jest.mock(
|
|
'./initalize',
|
|
() =>
|
|
(...args) =>
|
|
mockInitializeClient(...args),
|
|
);
|
|
jest.mock('~/models', () => ({
|
|
saveConvo: (...args) => mockSaveConvo(...args),
|
|
}));
|
|
|
|
const addTitle = require('./title');
|
|
|
|
describe('assistants addTitle content policy', () => {
|
|
beforeEach(() => {
|
|
jest.clearAllMocks();
|
|
});
|
|
|
|
it('replaces a blocked generated title before caching or saving it', async () => {
|
|
const create = jest.fn().mockResolvedValue({
|
|
choices: [{ message: { content: 'BLOCKED-GENERATED-TITLE' } }],
|
|
});
|
|
mockInitializeClient.mockResolvedValue({
|
|
openai: { chat: { completions: { create } } },
|
|
});
|
|
const req = {
|
|
user: { id: 'user-1' },
|
|
body: {},
|
|
config: {
|
|
filters: {
|
|
conversationTitles: {
|
|
pii: {
|
|
starterPatterns: [],
|
|
customPatterns: [{ id: 'blocked', label: 'blocked', regex: 'BLOCKED' }],
|
|
},
|
|
},
|
|
},
|
|
},
|
|
};
|
|
|
|
await addTitle(req, {
|
|
text: 'submitted text',
|
|
responseText: 'response',
|
|
conversationId: 'conversation-generated',
|
|
});
|
|
|
|
expect(mockCache.set).toHaveBeenCalledWith('user-1-conversation-generated', 'New Chat', 120000);
|
|
expect(mockSaveConvo).toHaveBeenCalledWith(
|
|
expect.anything(),
|
|
expect.objectContaining({
|
|
conversationId: 'conversation-generated',
|
|
title: 'New Chat',
|
|
}),
|
|
expect.objectContaining({ noUpsert: true }),
|
|
);
|
|
});
|
|
|
|
it('replaces a blocked submitted-text fallback before caching or saving it', async () => {
|
|
const create = jest.fn().mockRejectedValue(new Error('title model unavailable'));
|
|
mockInitializeClient.mockResolvedValue({
|
|
openai: { chat: { completions: { create } } },
|
|
});
|
|
const req = {
|
|
user: { id: 'user-1' },
|
|
body: {},
|
|
config: {
|
|
filters: {
|
|
conversationTitles: {
|
|
pii: {
|
|
starterPatterns: [],
|
|
customPatterns: [{ id: 'blocked', label: 'blocked', regex: 'BLOCKED' }],
|
|
},
|
|
},
|
|
},
|
|
},
|
|
};
|
|
|
|
await addTitle(req, {
|
|
text: 'BLOCKED-SUBMISSION',
|
|
responseText: 'response',
|
|
conversationId: 'conversation-1',
|
|
});
|
|
|
|
expect(mockCache.set).toHaveBeenCalledWith('user-1-conversation-1', 'New Chat', 120000);
|
|
expect(mockSaveConvo).toHaveBeenCalledWith(
|
|
expect.anything(),
|
|
expect.objectContaining({
|
|
conversationId: 'conversation-1',
|
|
title: 'New Chat',
|
|
}),
|
|
expect.objectContaining({ noUpsert: true }),
|
|
);
|
|
});
|
|
});
|