mirror of
https://github.com/danny-avila/LibreChat.git
synced 2025-12-16 08:20:14 +01:00
🖥️ feat: Add Proxy Support for Tavily API Tool (#10770)
* 🖥️ feat: Add Proxy Support for Tavily API Tool
- Integrated ProxyAgent from undici to enable proxy support for API requests in TavilySearch and TavilySearchResults.
- Updated fetch options to conditionally include the proxy configuration based on the environment variable, enhancing flexibility for network requests.
* ci: TavilySearchResults with Proxy Support Tests
- Added tests to verify the integration of ProxyAgent for API requests in TavilySearchResults.
- Implemented conditional logic to check for the PROXY environment variable, ensuring correct usage of ProxyAgent based on its presence.
- Updated test setup to clear mocks before each test for improved isolation and reliability.
This commit is contained in:
parent
ef5540f278
commit
1477da4987
3 changed files with 66 additions and 6 deletions
|
|
@ -1,4 +1,5 @@
|
|||
const { z } = require('zod');
|
||||
const { ProxyAgent, fetch } = require('undici');
|
||||
const { tool } = require('@langchain/core/tools');
|
||||
const { getApiKey } = require('./credentials');
|
||||
|
||||
|
|
@ -19,13 +20,19 @@ function createTavilySearchTool(fields = {}) {
|
|||
...kwargs,
|
||||
};
|
||||
|
||||
const response = await fetch('https://api.tavily.com/search', {
|
||||
const fetchOptions = {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify(requestBody),
|
||||
});
|
||||
};
|
||||
|
||||
if (process.env.PROXY) {
|
||||
fetchOptions.dispatcher = new ProxyAgent(process.env.PROXY);
|
||||
}
|
||||
|
||||
const response = await fetch('https://api.tavily.com/search', fetchOptions);
|
||||
|
||||
const json = await response.json();
|
||||
if (!response.ok) {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
const { z } = require('zod');
|
||||
const { ProxyAgent, fetch } = require('undici');
|
||||
const { Tool } = require('@langchain/core/tools');
|
||||
const { getEnvironmentVariable } = require('@langchain/core/utils/env');
|
||||
|
||||
|
|
@ -102,13 +103,19 @@ class TavilySearchResults extends Tool {
|
|||
...this.kwargs,
|
||||
};
|
||||
|
||||
const response = await fetch('https://api.tavily.com/search', {
|
||||
const fetchOptions = {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify(requestBody),
|
||||
});
|
||||
};
|
||||
|
||||
if (process.env.PROXY) {
|
||||
fetchOptions.dispatcher = new ProxyAgent(process.env.PROXY);
|
||||
}
|
||||
|
||||
const response = await fetch('https://api.tavily.com/search', fetchOptions);
|
||||
|
||||
const json = await response.json();
|
||||
if (!response.ok) {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
const { fetch, ProxyAgent } = require('undici');
|
||||
const TavilySearchResults = require('../TavilySearchResults');
|
||||
|
||||
jest.mock('node-fetch');
|
||||
jest.mock('undici');
|
||||
jest.mock('@langchain/core/utils/env');
|
||||
|
||||
describe('TavilySearchResults', () => {
|
||||
|
|
@ -13,6 +14,7 @@ describe('TavilySearchResults', () => {
|
|||
|
||||
beforeEach(() => {
|
||||
jest.resetModules();
|
||||
jest.clearAllMocks();
|
||||
process.env = {
|
||||
...originalEnv,
|
||||
TAVILY_API_KEY: mockApiKey,
|
||||
|
|
@ -20,7 +22,6 @@ describe('TavilySearchResults', () => {
|
|||
});
|
||||
|
||||
afterEach(() => {
|
||||
jest.clearAllMocks();
|
||||
process.env = originalEnv;
|
||||
});
|
||||
|
||||
|
|
@ -35,4 +36,49 @@ describe('TavilySearchResults', () => {
|
|||
});
|
||||
expect(instance.apiKey).toBe(mockApiKey);
|
||||
});
|
||||
|
||||
describe('proxy support', () => {
|
||||
const mockResponse = {
|
||||
ok: true,
|
||||
json: jest.fn().mockResolvedValue({ results: [] }),
|
||||
};
|
||||
|
||||
beforeEach(() => {
|
||||
fetch.mockResolvedValue(mockResponse);
|
||||
});
|
||||
|
||||
it('should use ProxyAgent when PROXY env var is set', async () => {
|
||||
const proxyUrl = 'http://proxy.example.com:8080';
|
||||
process.env.PROXY = proxyUrl;
|
||||
|
||||
const mockProxyAgent = { type: 'proxy-agent' };
|
||||
ProxyAgent.mockImplementation(() => mockProxyAgent);
|
||||
|
||||
const instance = new TavilySearchResults({ TAVILY_API_KEY: mockApiKey });
|
||||
await instance._call({ query: 'test query' });
|
||||
|
||||
expect(ProxyAgent).toHaveBeenCalledWith(proxyUrl);
|
||||
expect(fetch).toHaveBeenCalledWith(
|
||||
'https://api.tavily.com/search',
|
||||
expect.objectContaining({
|
||||
dispatcher: mockProxyAgent,
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
it('should not use ProxyAgent when PROXY env var is not set', async () => {
|
||||
delete process.env.PROXY;
|
||||
|
||||
const instance = new TavilySearchResults({ TAVILY_API_KEY: mockApiKey });
|
||||
await instance._call({ query: 'test query' });
|
||||
|
||||
expect(ProxyAgent).not.toHaveBeenCalled();
|
||||
expect(fetch).toHaveBeenCalledWith(
|
||||
'https://api.tavily.com/search',
|
||||
expect.not.objectContaining({
|
||||
dispatcher: expect.anything(),
|
||||
}),
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue