mirror of
https://github.com/danny-avila/LibreChat.git
synced 2026-03-16 20:56:35 +01:00
📎 fix: Respect fileConfig.disabled for Agents Endpoint Upload Button (#12238)
* fix: respect fileConfig.disabled for agents endpoint upload button The isAgents check was OR'd without the !isUploadDisabled guard, bypassing the fileConfig.endpoints.agents.disabled setting and always rendering the attach file menu for agents. * test: add regression tests for fileConfig.disabled upload guard Cover the isUploadDisabled rendering gate for agents and assistants endpoints, preventing silent reintroduction of the bypass bug. * test: cover disabled fallback chain in useAgentFileConfig Verify agents-disabled propagates when no provider is set, when provider has no specific config (agents as fallback), and that provider-specific enabled overrides agents disabled.
This commit is contained in:
parent
0c27ad2d55
commit
93a628d7a2
3 changed files with 103 additions and 5 deletions
|
|
@ -91,7 +91,7 @@ function AttachFileChat({
|
||||||
|
|
||||||
if (isAssistants && endpointSupportsFiles && !isUploadDisabled) {
|
if (isAssistants && endpointSupportsFiles && !isUploadDisabled) {
|
||||||
return <AttachFile disabled={disableInputs} />;
|
return <AttachFile disabled={disableInputs} />;
|
||||||
} else if (isAgents || (endpointSupportsFiles && !isUploadDisabled)) {
|
} else if ((isAgents || endpointSupportsFiles) && !isUploadDisabled) {
|
||||||
return (
|
return (
|
||||||
<AttachFileMenu
|
<AttachFileMenu
|
||||||
endpoint={endpoint}
|
endpoint={endpoint}
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ const mockEndpointsConfig: TEndpointsConfig = {
|
||||||
Moonshot: { type: EModelEndpoint.custom, userProvide: false, order: 9999 },
|
Moonshot: { type: EModelEndpoint.custom, userProvide: false, order: 9999 },
|
||||||
};
|
};
|
||||||
|
|
||||||
const mockFileConfig = mergeFileConfig({
|
const defaultFileConfig = mergeFileConfig({
|
||||||
endpoints: {
|
endpoints: {
|
||||||
Moonshot: { fileLimit: 5 },
|
Moonshot: { fileLimit: 5 },
|
||||||
[EModelEndpoint.agents]: { fileLimit: 20 },
|
[EModelEndpoint.agents]: { fileLimit: 20 },
|
||||||
|
|
@ -21,6 +21,8 @@ const mockFileConfig = mergeFileConfig({
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let mockFileConfig = defaultFileConfig;
|
||||||
|
|
||||||
let mockAgentsMap: Record<string, Partial<Agent>> = {};
|
let mockAgentsMap: Record<string, Partial<Agent>> = {};
|
||||||
let mockAgentQueryData: Partial<Agent> | undefined;
|
let mockAgentQueryData: Partial<Agent> | undefined;
|
||||||
|
|
||||||
|
|
@ -65,6 +67,7 @@ function renderComponent(conversation: Record<string, unknown> | null, disableIn
|
||||||
|
|
||||||
describe('AttachFileChat', () => {
|
describe('AttachFileChat', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
|
mockFileConfig = defaultFileConfig;
|
||||||
mockAgentsMap = {};
|
mockAgentsMap = {};
|
||||||
mockAgentQueryData = undefined;
|
mockAgentQueryData = undefined;
|
||||||
mockAttachFileMenuProps = {};
|
mockAttachFileMenuProps = {};
|
||||||
|
|
@ -148,6 +151,60 @@ describe('AttachFileChat', () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('upload disabled rendering', () => {
|
||||||
|
it('renders null for agents endpoint when fileConfig.agents.disabled is true', () => {
|
||||||
|
mockFileConfig = mergeFileConfig({
|
||||||
|
endpoints: {
|
||||||
|
[EModelEndpoint.agents]: { disabled: true },
|
||||||
|
},
|
||||||
|
});
|
||||||
|
const { container } = renderComponent({
|
||||||
|
endpoint: EModelEndpoint.agents,
|
||||||
|
agent_id: 'agent-1',
|
||||||
|
});
|
||||||
|
expect(container.innerHTML).toBe('');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('renders null for agents endpoint when disableInputs is true', () => {
|
||||||
|
const { container } = renderComponent(
|
||||||
|
{ endpoint: EModelEndpoint.agents, agent_id: 'agent-1' },
|
||||||
|
true,
|
||||||
|
);
|
||||||
|
expect(container.innerHTML).toBe('');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('renders AttachFile for assistants endpoint when not disabled', () => {
|
||||||
|
renderComponent({ endpoint: EModelEndpoint.assistants });
|
||||||
|
expect(screen.getByTestId('attach-file')).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('renders AttachFileMenu when provider-specific config overrides agents disabled', () => {
|
||||||
|
mockFileConfig = mergeFileConfig({
|
||||||
|
endpoints: {
|
||||||
|
Moonshot: { disabled: false, fileLimit: 5 },
|
||||||
|
[EModelEndpoint.agents]: { disabled: true },
|
||||||
|
},
|
||||||
|
});
|
||||||
|
mockAgentsMap = {
|
||||||
|
'agent-1': { provider: 'Moonshot', model_parameters: {} } as Partial<Agent>,
|
||||||
|
};
|
||||||
|
renderComponent({ endpoint: EModelEndpoint.agents, agent_id: 'agent-1' });
|
||||||
|
expect(screen.getByTestId('attach-file-menu')).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('renders null for assistants endpoint when fileConfig.assistants.disabled is true', () => {
|
||||||
|
mockFileConfig = mergeFileConfig({
|
||||||
|
endpoints: {
|
||||||
|
[EModelEndpoint.assistants]: { disabled: true },
|
||||||
|
},
|
||||||
|
});
|
||||||
|
const { container } = renderComponent({
|
||||||
|
endpoint: EModelEndpoint.assistants,
|
||||||
|
});
|
||||||
|
expect(container.innerHTML).toBe('');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe('endpointFileConfig resolution', () => {
|
describe('endpointFileConfig resolution', () => {
|
||||||
it('passes Moonshot-specific file config for agent with Moonshot provider', () => {
|
it('passes Moonshot-specific file config for agent with Moonshot provider', () => {
|
||||||
mockAgentsMap = {
|
mockAgentsMap = {
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ const mockEndpointsConfig: TEndpointsConfig = {
|
||||||
'Some Endpoint': { type: EModelEndpoint.custom, userProvide: false, order: 9999 },
|
'Some Endpoint': { type: EModelEndpoint.custom, userProvide: false, order: 9999 },
|
||||||
};
|
};
|
||||||
|
|
||||||
let mockFileConfig = mergeFileConfig({
|
const defaultFileConfig = mergeFileConfig({
|
||||||
endpoints: {
|
endpoints: {
|
||||||
Moonshot: { fileLimit: 5 },
|
Moonshot: { fileLimit: 5 },
|
||||||
[EModelEndpoint.agents]: { fileLimit: 20 },
|
[EModelEndpoint.agents]: { fileLimit: 20 },
|
||||||
|
|
@ -26,6 +26,8 @@ let mockFileConfig = mergeFileConfig({
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let mockFileConfig = defaultFileConfig;
|
||||||
|
|
||||||
jest.mock('~/data-provider', () => ({
|
jest.mock('~/data-provider', () => ({
|
||||||
useGetEndpointsQuery: () => ({ data: mockEndpointsConfig }),
|
useGetEndpointsQuery: () => ({ data: mockEndpointsConfig }),
|
||||||
useGetFileConfig: ({ select }: { select?: (data: unknown) => unknown }) => ({
|
useGetFileConfig: ({ select }: { select?: (data: unknown) => unknown }) => ({
|
||||||
|
|
@ -118,13 +120,16 @@ describe('AgentPanel file config resolution (useAgentFileConfig)', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('disabled state', () => {
|
describe('disabled state', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
mockFileConfig = defaultFileConfig;
|
||||||
|
});
|
||||||
|
|
||||||
it('reports not disabled for standard config', () => {
|
it('reports not disabled for standard config', () => {
|
||||||
render(<TestWrapper provider="Moonshot" />);
|
render(<TestWrapper provider="Moonshot" />);
|
||||||
expect(screen.getByTestId('disabled').textContent).toBe('false');
|
expect(screen.getByTestId('disabled').textContent).toBe('false');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('reports disabled when provider-specific config is disabled', () => {
|
it('reports disabled when provider-specific config is disabled', () => {
|
||||||
const original = mockFileConfig;
|
|
||||||
mockFileConfig = mergeFileConfig({
|
mockFileConfig = mergeFileConfig({
|
||||||
endpoints: {
|
endpoints: {
|
||||||
Moonshot: { disabled: true },
|
Moonshot: { disabled: true },
|
||||||
|
|
@ -135,8 +140,44 @@ describe('AgentPanel file config resolution (useAgentFileConfig)', () => {
|
||||||
|
|
||||||
render(<TestWrapper provider="Moonshot" />);
|
render(<TestWrapper provider="Moonshot" />);
|
||||||
expect(screen.getByTestId('disabled').textContent).toBe('true');
|
expect(screen.getByTestId('disabled').textContent).toBe('true');
|
||||||
|
});
|
||||||
|
|
||||||
mockFileConfig = original;
|
it('reports disabled when agents config is disabled and no provider set', () => {
|
||||||
|
mockFileConfig = mergeFileConfig({
|
||||||
|
endpoints: {
|
||||||
|
[EModelEndpoint.agents]: { disabled: true },
|
||||||
|
default: { fileLimit: 10 },
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
render(<TestWrapper />);
|
||||||
|
expect(screen.getByTestId('disabled').textContent).toBe('true');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('reports disabled when agents is disabled and provider has no specific config', () => {
|
||||||
|
mockFileConfig = mergeFileConfig({
|
||||||
|
endpoints: {
|
||||||
|
[EModelEndpoint.agents]: { disabled: true },
|
||||||
|
default: { fileLimit: 10 },
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
render(<TestWrapper provider="Some Endpoint" />);
|
||||||
|
expect(screen.getByTestId('disabled').textContent).toBe('true');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('provider-specific enabled overrides agents disabled', () => {
|
||||||
|
mockFileConfig = mergeFileConfig({
|
||||||
|
endpoints: {
|
||||||
|
Moonshot: { disabled: false, fileLimit: 5 },
|
||||||
|
[EModelEndpoint.agents]: { disabled: true },
|
||||||
|
default: { fileLimit: 10 },
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
render(<TestWrapper provider="Moonshot" />);
|
||||||
|
expect(screen.getByTestId('disabled').textContent).toBe('false');
|
||||||
|
expect(screen.getByTestId('fileLimit').textContent).toBe('5');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue