mirror of
https://github.com/danny-avila/LibreChat.git
synced 2025-12-21 02:40:14 +01:00
📨 feat: Pass Custom Headers to Model Discovery (v1/models) (#10564)
This commit is contained in:
parent
ce1812b7c2
commit
69c6d023e1
2 changed files with 125 additions and 1 deletions
|
|
@ -80,7 +80,9 @@ const fetchModels = async ({
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const options = {
|
const options = {
|
||||||
headers: {},
|
headers: {
|
||||||
|
...(headers ?? {}),
|
||||||
|
},
|
||||||
timeout: 5000,
|
timeout: 5000,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -81,6 +81,70 @@ describe('fetchModels', () => {
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should pass custom headers to the API request', async () => {
|
||||||
|
const customHeaders = {
|
||||||
|
'X-Custom-Header': 'custom-value',
|
||||||
|
'X-API-Version': 'v2',
|
||||||
|
};
|
||||||
|
|
||||||
|
await fetchModels({
|
||||||
|
user: 'user123',
|
||||||
|
apiKey: 'testApiKey',
|
||||||
|
baseURL: 'https://api.test.com',
|
||||||
|
name: 'TestAPI',
|
||||||
|
headers: customHeaders,
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(axios.get).toHaveBeenCalledWith(
|
||||||
|
expect.stringContaining('https://api.test.com/models'),
|
||||||
|
expect.objectContaining({
|
||||||
|
headers: expect.objectContaining({
|
||||||
|
'X-Custom-Header': 'custom-value',
|
||||||
|
'X-API-Version': 'v2',
|
||||||
|
Authorization: 'Bearer testApiKey',
|
||||||
|
}),
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle null headers gracefully', async () => {
|
||||||
|
await fetchModels({
|
||||||
|
user: 'user123',
|
||||||
|
apiKey: 'testApiKey',
|
||||||
|
baseURL: 'https://api.test.com',
|
||||||
|
name: 'TestAPI',
|
||||||
|
headers: null,
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(axios.get).toHaveBeenCalledWith(
|
||||||
|
expect.stringContaining('https://api.test.com/models'),
|
||||||
|
expect.objectContaining({
|
||||||
|
headers: expect.objectContaining({
|
||||||
|
Authorization: 'Bearer testApiKey',
|
||||||
|
}),
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle undefined headers gracefully', async () => {
|
||||||
|
await fetchModels({
|
||||||
|
user: 'user123',
|
||||||
|
apiKey: 'testApiKey',
|
||||||
|
baseURL: 'https://api.test.com',
|
||||||
|
name: 'TestAPI',
|
||||||
|
headers: undefined,
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(axios.get).toHaveBeenCalledWith(
|
||||||
|
expect.stringContaining('https://api.test.com/models'),
|
||||||
|
expect.objectContaining({
|
||||||
|
headers: expect.objectContaining({
|
||||||
|
Authorization: 'Bearer testApiKey',
|
||||||
|
}),
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
jest.clearAllMocks();
|
jest.clearAllMocks();
|
||||||
});
|
});
|
||||||
|
|
@ -410,6 +474,64 @@ describe('getAnthropicModels', () => {
|
||||||
const models = await getAnthropicModels();
|
const models = await getAnthropicModels();
|
||||||
expect(models).toEqual(['claude-1', 'claude-2']);
|
expect(models).toEqual(['claude-1', 'claude-2']);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should use Anthropic-specific headers when fetching models', async () => {
|
||||||
|
delete process.env.ANTHROPIC_MODELS;
|
||||||
|
process.env.ANTHROPIC_API_KEY = 'test-anthropic-key';
|
||||||
|
|
||||||
|
axios.get.mockResolvedValue({
|
||||||
|
data: {
|
||||||
|
data: [{ id: 'claude-3' }, { id: 'claude-4' }],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
await fetchModels({
|
||||||
|
user: 'user123',
|
||||||
|
apiKey: 'test-anthropic-key',
|
||||||
|
baseURL: 'https://api.anthropic.com/v1',
|
||||||
|
name: EModelEndpoint.anthropic,
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(axios.get).toHaveBeenCalledWith(
|
||||||
|
expect.any(String),
|
||||||
|
expect.objectContaining({
|
||||||
|
headers: {
|
||||||
|
'x-api-key': 'test-anthropic-key',
|
||||||
|
'anthropic-version': expect.any(String),
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should pass custom headers for Anthropic endpoint', async () => {
|
||||||
|
const customHeaders = {
|
||||||
|
'X-Custom-Header': 'custom-value',
|
||||||
|
};
|
||||||
|
|
||||||
|
axios.get.mockResolvedValue({
|
||||||
|
data: {
|
||||||
|
data: [{ id: 'claude-3' }],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
await fetchModels({
|
||||||
|
user: 'user123',
|
||||||
|
apiKey: 'test-anthropic-key',
|
||||||
|
baseURL: 'https://api.anthropic.com/v1',
|
||||||
|
name: EModelEndpoint.anthropic,
|
||||||
|
headers: customHeaders,
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(axios.get).toHaveBeenCalledWith(
|
||||||
|
expect.any(String),
|
||||||
|
expect.objectContaining({
|
||||||
|
headers: {
|
||||||
|
'x-api-key': 'test-anthropic-key',
|
||||||
|
'anthropic-version': expect.any(String),
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('getGoogleModels', () => {
|
describe('getGoogleModels', () => {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue