mirror of
https://github.com/danny-avila/LibreChat.git
synced 2026-08-29 05:20:49 +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
91 lines
2.7 KiB
JavaScript
91 lines
2.7 KiB
JavaScript
const mockSendEvent = jest.fn();
|
|
const mockLogger = {
|
|
debug: jest.fn(),
|
|
error: jest.fn(),
|
|
warn: jest.fn(),
|
|
};
|
|
|
|
jest.mock('@librechat/api', () => ({
|
|
...jest.requireActual('@librechat/api'),
|
|
sendEvent: (...args) => mockSendEvent(...args),
|
|
}));
|
|
|
|
jest.mock('@librechat/data-schemas', () => ({
|
|
...jest.requireActual('@librechat/data-schemas'),
|
|
logger: mockLogger,
|
|
}));
|
|
|
|
const { createOnTextProgress } = require('../AssistantService');
|
|
const StreamRunManager = require('../Runs/StreamRunManager');
|
|
|
|
describe('Assistant service log hygiene', () => {
|
|
beforeEach(() => {
|
|
jest.clearAllMocks();
|
|
});
|
|
|
|
it('logs only structural metadata for non-text assistant content', async () => {
|
|
const privateArguments = 'PRIVATE-TOOL-ARGUMENTS';
|
|
const openai = { res: {} };
|
|
await createOnTextProgress({
|
|
openai,
|
|
conversationId: 'conversation-1',
|
|
userMessageId: 'user-message-1',
|
|
messageId: 'assistant-message-1',
|
|
thread_id: 'thread-1',
|
|
});
|
|
|
|
openai.addContentData({
|
|
type: 'tool_call',
|
|
index: 0,
|
|
tool_call: {
|
|
type: 'function',
|
|
function: { name: 'example', arguments: privateArguments },
|
|
},
|
|
});
|
|
|
|
expect(JSON.stringify(mockLogger.debug.mock.calls)).not.toContain(privateArguments);
|
|
expect(mockLogger.debug).toHaveBeenCalledWith(
|
|
'Assistant content event',
|
|
expect.objectContaining({
|
|
type: 'tool_call',
|
|
index: 0,
|
|
hasContent: true,
|
|
}),
|
|
);
|
|
expect(JSON.stringify(mockSendEvent.mock.calls)).toContain(privateArguments);
|
|
});
|
|
|
|
it('does not include raw tool deltas in warning logs', async () => {
|
|
const privateDelta = 'PRIVATE-DELTA';
|
|
const manager = new StreamRunManager({
|
|
req: {},
|
|
res: {},
|
|
openai: { apiKey: 'test-key' },
|
|
parentMessageId: 'parent-1',
|
|
thread_id: 'thread-1',
|
|
runBody: {},
|
|
responseMessage: { content: [], messageId: 'message-1', conversationId: 'conversation-1' },
|
|
attachedFileIds: new Set(),
|
|
handlers: {},
|
|
});
|
|
const handler = manager.createToolCallStream(0, {
|
|
type: 'function',
|
|
function: { name: 'example', arguments: '' },
|
|
});
|
|
|
|
await handler({ unexpected: privateDelta });
|
|
await manager.handleRunStepDeltaEvent({
|
|
data: { id: 'step-1', delta: { unknown: privateDelta } },
|
|
});
|
|
|
|
expect(JSON.stringify(mockLogger.warn.mock.calls)).not.toContain(privateDelta);
|
|
expect(mockLogger.warn).toHaveBeenCalledWith(
|
|
'Unhandled tool call delta key',
|
|
expect.objectContaining({ key: 'unexpected' }),
|
|
);
|
|
expect(mockLogger.warn).toHaveBeenCalledWith(
|
|
'Undefined or unhandled run step delta',
|
|
expect.objectContaining({ stepId: 'step-1' }),
|
|
);
|
|
});
|
|
});
|