mirror of
https://github.com/danny-avila/LibreChat.git
synced 2025-09-21 21:50:49 +02:00
🔗 feat: Custom Jina API URL for Web Search Reranking (#9236)
* feat: added support for custom JINA_API_URL * fixed tests * chore: Update @librechat/agents dependency to version 2.4.77 in package-lock.json and package.json files * fix: Update Jina API URL to use environment variable in configuration files * Refactor AppService, web.ts, and config.ts to replace hardcoded Jina API URL with an environment variable placeholder. * Ensure consistency across tests and configuration for Jina API URL. * chore: alphabetical order translation.json * fix: alphabetical order --------- Co-authored-by: Danny Avila <danny@librechat.ai>
This commit is contained in:
parent
fff1f1cf27
commit
6f6a34d126
13 changed files with 68 additions and 8 deletions
|
@ -75,6 +75,7 @@
|
|||
- 🔍 **Web Search**:
|
||||
- Search the internet and retrieve relevant information to enhance your AI context
|
||||
- Combines search providers, content scrapers, and result rerankers for optimal results
|
||||
- **Customizable Jina Reranking**: Configure custom Jina API URLs for reranking services
|
||||
- **[Learn More →](https://www.librechat.ai/docs/features/web_search)**
|
||||
|
||||
- 🪄 **Generative UI with Code Artifacts**:
|
||||
|
|
|
@ -49,7 +49,7 @@
|
|||
"@langchain/google-vertexai": "^0.2.13",
|
||||
"@langchain/openai": "^0.5.18",
|
||||
"@langchain/textsplitters": "^0.1.0",
|
||||
"@librechat/agents": "^2.4.76",
|
||||
"@librechat/agents": "^2.4.77",
|
||||
"@librechat/api": "*",
|
||||
"@librechat/data-schemas": "*",
|
||||
"@microsoft/microsoft-graph-client": "^3.0.7",
|
||||
|
|
|
@ -152,6 +152,7 @@ describe('AppService', () => {
|
|||
webSearch: expect.objectContaining({
|
||||
safeSearch: 1,
|
||||
jinaApiKey: '${JINA_API_KEY}',
|
||||
jinaApiUrl: '${JINA_API_URL}',
|
||||
cohereApiKey: '${COHERE_API_KEY}',
|
||||
serperApiKey: '${SERPER_API_KEY}',
|
||||
searxngApiKey: '${SEARXNG_API_KEY}',
|
||||
|
|
|
@ -91,6 +91,14 @@ export default function ApiKeyDialog({
|
|||
text: localize('com_ui_web_search_reranker_jina_key'),
|
||||
},
|
||||
},
|
||||
jinaApiUrl: {
|
||||
placeholder: localize('com_ui_web_search_jina_url'),
|
||||
type: 'text' as const,
|
||||
link: {
|
||||
url: 'https://api.jina.ai/v1/rerank',
|
||||
text: localize('com_ui_web_search_reranker_jina_url_help'),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
|
|
|
@ -15,6 +15,7 @@ export type SearchApiKeyFormData = {
|
|||
firecrawlApiKey: string;
|
||||
firecrawlApiUrl: string;
|
||||
jinaApiKey: string;
|
||||
jinaApiUrl: string;
|
||||
cohereApiKey: string;
|
||||
};
|
||||
|
||||
|
@ -54,6 +55,7 @@ const useAuthSearchTool = (options?: { isEntityTool: boolean }) => {
|
|||
firecrawlApiKey: data.firecrawlApiKey,
|
||||
firecrawlApiUrl: data.firecrawlApiUrl,
|
||||
jinaApiKey: data.jinaApiKey,
|
||||
jinaApiUrl: data.jinaApiUrl,
|
||||
cohereApiKey: data.cohereApiKey,
|
||||
}).reduce(
|
||||
(acc, [key, value]) => {
|
||||
|
|
|
@ -1251,6 +1251,7 @@
|
|||
"com_ui_web_search_cohere_key": "Enter Cohere API Key",
|
||||
"com_ui_web_search_firecrawl_url": "Firecrawl API URL (optional)",
|
||||
"com_ui_web_search_jina_key": "Enter Jina API Key",
|
||||
"com_ui_web_search_jina_url": "Jina API URL (optional)",
|
||||
"com_ui_web_search_processing": "Processing results",
|
||||
"com_ui_web_search_provider": "Search Provider",
|
||||
"com_ui_web_search_provider_searxng": "SearXNG",
|
||||
|
@ -1262,6 +1263,7 @@
|
|||
"com_ui_web_search_reranker_cohere_key": "Get your Cohere API key",
|
||||
"com_ui_web_search_reranker_jina": "Jina AI",
|
||||
"com_ui_web_search_reranker_jina_key": "Get your Jina API key",
|
||||
"com_ui_web_search_reranker_jina_url_help": "Learn about Jina Rerank API",
|
||||
"com_ui_web_search_scraper": "Scraper",
|
||||
"com_ui_web_search_scraper_firecrawl": "Firecrawl API",
|
||||
"com_ui_web_search_scraper_firecrawl_key": "Get your Firecrawl API key",
|
||||
|
|
|
@ -350,6 +350,24 @@ endpoints:
|
|||
# # See the Custom Configuration Guide for more information on Assistants Config:
|
||||
# # https://www.librechat.ai/docs/configuration/librechat_yaml/object_structure/assistants_endpoint
|
||||
|
||||
# Web Search Configuration (optional)
|
||||
# webSearch:
|
||||
# # Jina Reranking Configuration
|
||||
# jinaApiKey: '${JINA_API_KEY}' # Your Jina API key
|
||||
# jinaApiUrl: '${JINA_API_URL}' # Custom Jina API URL (optional, defaults to https://api.jina.ai/v1/rerank)
|
||||
#
|
||||
# # Other rerankers
|
||||
# cohereApiKey: '${COHERE_API_KEY}'
|
||||
#
|
||||
# # Search providers
|
||||
# serperApiKey: '${SERPER_API_KEY}'
|
||||
# searxngInstanceUrl: '${SEARXNG_INSTANCE_URL}'
|
||||
# searxngApiKey: '${SEARXNG_API_KEY}'
|
||||
#
|
||||
# # Content scrapers
|
||||
# firecrawlApiKey: '${FIRECRAWL_API_KEY}'
|
||||
# firecrawlApiUrl: '${FIRECRAWL_API_URL}'
|
||||
|
||||
# Memory configuration for user memories
|
||||
# memory:
|
||||
# # (optional) Disable memory functionality
|
||||
|
|
10
package-lock.json
generated
10
package-lock.json
generated
|
@ -64,7 +64,7 @@
|
|||
"@langchain/google-vertexai": "^0.2.13",
|
||||
"@langchain/openai": "^0.5.18",
|
||||
"@langchain/textsplitters": "^0.1.0",
|
||||
"@librechat/agents": "^2.4.76",
|
||||
"@librechat/agents": "^2.4.77",
|
||||
"@librechat/api": "*",
|
||||
"@librechat/data-schemas": "*",
|
||||
"@microsoft/microsoft-graph-client": "^3.0.7",
|
||||
|
@ -21909,9 +21909,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@librechat/agents": {
|
||||
"version": "2.4.76",
|
||||
"resolved": "https://registry.npmjs.org/@librechat/agents/-/agents-2.4.76.tgz",
|
||||
"integrity": "sha512-DkWKpKcLgv9tA6bXJ8pSzHOA3iZRFQRt9oBjEEeW0onhEdPTmHVR3/dY5bxMKSP8rlA65M0yx1KaoLL8bhg06Q==",
|
||||
"version": "2.4.77",
|
||||
"resolved": "https://registry.npmjs.org/@librechat/agents/-/agents-2.4.77.tgz",
|
||||
"integrity": "sha512-x7fWbbdJpy8VpIYJa7E0laBUmtgveTmTzYS8QFkXUMjzqSx7nN5ruM6rzmcodOWRXt7IrB12k4VehJ1zUnb29A==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@langchain/anthropic": "^0.3.26",
|
||||
|
@ -51972,7 +51972,7 @@
|
|||
},
|
||||
"peerDependencies": {
|
||||
"@langchain/core": "^0.3.62",
|
||||
"@librechat/agents": "^2.4.76",
|
||||
"@librechat/agents": "^2.4.77",
|
||||
"@librechat/data-schemas": "*",
|
||||
"@modelcontextprotocol/sdk": "^1.17.1",
|
||||
"axios": "^1.8.2",
|
||||
|
|
|
@ -74,7 +74,7 @@
|
|||
},
|
||||
"peerDependencies": {
|
||||
"@langchain/core": "^0.3.62",
|
||||
"@librechat/agents": "^2.4.76",
|
||||
"@librechat/agents": "^2.4.77",
|
||||
"@librechat/data-schemas": "*",
|
||||
"@modelcontextprotocol/sdk": "^1.17.1",
|
||||
"axios": "^1.8.2",
|
||||
|
|
|
@ -81,6 +81,7 @@ describe('web.ts', () => {
|
|||
firecrawlApiKey: '${FIRECRAWL_API_KEY}',
|
||||
firecrawlApiUrl: '${FIRECRAWL_API_URL}',
|
||||
jinaApiKey: '${JINA_API_KEY}',
|
||||
jinaApiUrl: '${JINA_API_URL}',
|
||||
cohereApiKey: '${COHERE_API_KEY}',
|
||||
safeSearch: SafeSearchTypes.MODERATE,
|
||||
};
|
||||
|
@ -300,6 +301,7 @@ describe('web.ts', () => {
|
|||
firecrawlApiKey: '${FIRECRAWL_API_KEY}',
|
||||
firecrawlApiUrl: '${FIRECRAWL_API_URL}',
|
||||
jinaApiKey: '${JINA_API_KEY}',
|
||||
jinaApiUrl: '${JINA_API_URL}',
|
||||
cohereApiKey: '${COHERE_API_KEY}',
|
||||
safeSearch: SafeSearchTypes.MODERATE,
|
||||
};
|
||||
|
@ -351,6 +353,7 @@ describe('web.ts', () => {
|
|||
firecrawlApiKey: '${FIRECRAWL_API_KEY}',
|
||||
firecrawlApiUrl: '${FIRECRAWL_API_URL}',
|
||||
jinaApiKey: '${JINA_API_KEY}',
|
||||
jinaApiUrl: '${JINA_API_URL}',
|
||||
cohereApiKey: '${COHERE_API_KEY}',
|
||||
safeSearch: SafeSearchTypes.MODERATE,
|
||||
// Specify which services to use
|
||||
|
@ -432,6 +435,7 @@ describe('web.ts', () => {
|
|||
CUSTOM_FIRECRAWL_URL: 'https://custom.firecrawl.dev',
|
||||
CUSTOM_JINA_KEY: 'custom-jina-key',
|
||||
CUSTOM_COHERE_KEY: 'custom-cohere-key',
|
||||
CUSTOM_JINA_URL: 'https://custom.jina.ai',
|
||||
};
|
||||
|
||||
// Initialize webSearchConfig with custom variable names
|
||||
|
@ -442,6 +446,7 @@ describe('web.ts', () => {
|
|||
firecrawlApiKey: '${CUSTOM_FIRECRAWL_KEY}',
|
||||
firecrawlApiUrl: '${CUSTOM_FIRECRAWL_URL}',
|
||||
jinaApiKey: '${CUSTOM_JINA_KEY}',
|
||||
jinaApiUrl: '${CUSTOM_JINA_URL}',
|
||||
cohereApiKey: '${CUSTOM_COHERE_KEY}',
|
||||
safeSearch: SafeSearchTypes.MODERATE,
|
||||
// Specify which services to use
|
||||
|
@ -512,6 +517,7 @@ describe('web.ts', () => {
|
|||
firecrawlApiKey: '${FIRECRAWL_API_KEY}',
|
||||
firecrawlApiUrl: '${FIRECRAWL_API_URL}',
|
||||
jinaApiKey: '${JINA_API_KEY}',
|
||||
jinaApiUrl: '${JINA_API_URL}',
|
||||
cohereApiKey: '${COHERE_API_KEY}',
|
||||
safeSearch: SafeSearchTypes.MODERATE,
|
||||
};
|
||||
|
@ -573,6 +579,7 @@ describe('web.ts', () => {
|
|||
firecrawlApiKey: '${FIRECRAWL_API_KEY}',
|
||||
firecrawlApiUrl: '${FIRECRAWL_API_URL}',
|
||||
jinaApiKey: '${JINA_API_KEY}',
|
||||
jinaApiUrl: '${JINA_API_URL}',
|
||||
cohereApiKey: '${COHERE_API_KEY}',
|
||||
safeSearch: SafeSearchTypes.MODERATE,
|
||||
};
|
||||
|
@ -682,6 +689,7 @@ describe('web.ts', () => {
|
|||
firecrawlApiKey: '${FIRECRAWL_API_KEY}',
|
||||
firecrawlApiUrl: '${FIRECRAWL_API_URL}',
|
||||
jinaApiKey: '${JINA_API_KEY}',
|
||||
jinaApiUrl: '${JINA_API_URL}',
|
||||
cohereApiKey: '${COHERE_API_KEY}',
|
||||
safeSearch: SafeSearchTypes.MODERATE,
|
||||
searchProvider: 'serper' as SearchProviders,
|
||||
|
@ -722,6 +730,7 @@ describe('web.ts', () => {
|
|||
firecrawlApiKey: '${FIRECRAWL_API_KEY}',
|
||||
firecrawlApiUrl: '${FIRECRAWL_API_URL}',
|
||||
jinaApiKey: '${JINA_API_KEY}',
|
||||
jinaApiUrl: '${JINA_API_URL}',
|
||||
cohereApiKey: '${COHERE_API_KEY}',
|
||||
safeSearch: SafeSearchTypes.MODERATE,
|
||||
scraperType: 'firecrawl' as ScraperTypes,
|
||||
|
@ -762,6 +771,7 @@ describe('web.ts', () => {
|
|||
firecrawlApiKey: '${FIRECRAWL_API_KEY}',
|
||||
firecrawlApiUrl: '${FIRECRAWL_API_URL}',
|
||||
jinaApiKey: '${JINA_API_KEY}',
|
||||
jinaApiUrl: '${JINA_API_URL}',
|
||||
cohereApiKey: '${COHERE_API_KEY}',
|
||||
safeSearch: SafeSearchTypes.MODERATE,
|
||||
rerankerType: 'jina' as RerankerTypes,
|
||||
|
@ -808,6 +818,7 @@ describe('web.ts', () => {
|
|||
firecrawlApiKey: '${FIRECRAWL_API_KEY}',
|
||||
firecrawlApiUrl: '${FIRECRAWL_API_URL}',
|
||||
jinaApiKey: '${JINA_API_KEY}',
|
||||
jinaApiUrl: '${JINA_API_URL}',
|
||||
cohereApiKey: '${COHERE_API_KEY}',
|
||||
safeSearch: SafeSearchTypes.MODERATE,
|
||||
searchProvider: 'invalid-provider' as SearchProviders,
|
||||
|
@ -842,6 +853,7 @@ describe('web.ts', () => {
|
|||
firecrawlApiKey: '${FIRECRAWL_API_KEY}',
|
||||
firecrawlApiUrl: '${FIRECRAWL_API_URL}',
|
||||
jinaApiKey: '${JINA_API_KEY}',
|
||||
jinaApiUrl: '${JINA_API_URL}',
|
||||
cohereApiKey: '${COHERE_API_KEY}',
|
||||
safeSearch: SafeSearchTypes.MODERATE,
|
||||
rerankerType: 'jina' as RerankerTypes,
|
||||
|
@ -892,6 +904,7 @@ describe('web.ts', () => {
|
|||
firecrawlApiKey: '${FIRECRAWL_API_KEY}',
|
||||
firecrawlApiUrl: '${FIRECRAWL_API_URL}',
|
||||
jinaApiKey: '${JINA_API_KEY}',
|
||||
jinaApiUrl: '${JINA_API_URL}',
|
||||
cohereApiKey: '${COHERE_API_KEY}',
|
||||
safeSearch: SafeSearchTypes.MODERATE,
|
||||
};
|
||||
|
@ -932,6 +945,7 @@ describe('web.ts', () => {
|
|||
firecrawlApiKey: '${FIRECRAWL_API_KEY}',
|
||||
firecrawlApiUrl: '${FIRECRAWL_API_URL}',
|
||||
jinaApiKey: '${JINA_API_KEY}',
|
||||
jinaApiUrl: '${JINA_API_URL}',
|
||||
cohereApiKey: '${COHERE_API_KEY}',
|
||||
safeSearch: SafeSearchTypes.MODERATE,
|
||||
firecrawlOptions: {
|
||||
|
@ -991,6 +1005,7 @@ describe('web.ts', () => {
|
|||
firecrawlApiKey: '${FIRECRAWL_API_KEY}',
|
||||
firecrawlApiUrl: '${FIRECRAWL_API_URL}',
|
||||
jinaApiKey: '${JINA_API_KEY}',
|
||||
jinaApiUrl: '${JINA_API_URL}',
|
||||
safeSearch: SafeSearchTypes.MODERATE,
|
||||
scraperTimeout: 15000, // This should take priority
|
||||
firecrawlOptions: {
|
||||
|
@ -1032,6 +1047,7 @@ describe('web.ts', () => {
|
|||
firecrawlApiKey: '${FIRECRAWL_API_KEY}',
|
||||
firecrawlApiUrl: '${FIRECRAWL_API_URL}',
|
||||
jinaApiKey: '${JINA_API_KEY}',
|
||||
jinaApiUrl: '${JINA_API_URL}',
|
||||
safeSearch: SafeSearchTypes.MODERATE,
|
||||
firecrawlOptions: {
|
||||
includeTags: ['p'],
|
||||
|
@ -1070,6 +1086,7 @@ describe('web.ts', () => {
|
|||
firecrawlApiKey: '${FIRECRAWL_API_KEY}',
|
||||
firecrawlApiUrl: '${FIRECRAWL_API_URL}',
|
||||
jinaApiKey: '${JINA_API_KEY}',
|
||||
jinaApiUrl: '${JINA_API_URL}',
|
||||
safeSearch: SafeSearchTypes.MODERATE,
|
||||
firecrawlOptions: {
|
||||
timeout: 12000, // Only timeout provided
|
||||
|
@ -1106,6 +1123,7 @@ describe('web.ts', () => {
|
|||
firecrawlApiKey: '${FIRECRAWL_API_KEY}',
|
||||
firecrawlApiUrl: '${FIRECRAWL_API_URL}',
|
||||
jinaApiKey: '${JINA_API_KEY}',
|
||||
jinaApiUrl: '${JINA_API_URL}',
|
||||
safeSearch: SafeSearchTypes.MODERATE,
|
||||
firecrawlOptions: {
|
||||
formats: ['html', 'markdown'], // Only formats provided
|
||||
|
@ -1142,6 +1160,7 @@ describe('web.ts', () => {
|
|||
firecrawlApiKey: '${FIRECRAWL_API_KEY}',
|
||||
firecrawlApiUrl: '${FIRECRAWL_API_URL}',
|
||||
jinaApiKey: '${JINA_API_KEY}',
|
||||
jinaApiUrl: '${JINA_API_URL}',
|
||||
safeSearch: SafeSearchTypes.MODERATE,
|
||||
firecrawlOptions: {
|
||||
timeout: 8000,
|
||||
|
|
|
@ -21,6 +21,7 @@ export function loadWebSearchConfig(
|
|||
const firecrawlApiKey = config?.firecrawlApiKey ?? '${FIRECRAWL_API_KEY}';
|
||||
const firecrawlApiUrl = config?.firecrawlApiUrl ?? '${FIRECRAWL_API_URL}';
|
||||
const jinaApiKey = config?.jinaApiKey ?? '${JINA_API_KEY}';
|
||||
const jinaApiUrl = config?.jinaApiUrl ?? '${JINA_API_URL}';
|
||||
const cohereApiKey = config?.cohereApiKey ?? '${COHERE_API_KEY}';
|
||||
const safeSearch = config?.safeSearch ?? SafeSearchTypes.MODERATE;
|
||||
|
||||
|
@ -28,6 +29,7 @@ export function loadWebSearchConfig(
|
|||
...config,
|
||||
safeSearch,
|
||||
jinaApiKey,
|
||||
jinaApiUrl,
|
||||
cohereApiKey,
|
||||
serperApiKey,
|
||||
searxngInstanceUrl,
|
||||
|
@ -44,6 +46,7 @@ export type TWebSearchKeys =
|
|||
| 'firecrawlApiKey'
|
||||
| 'firecrawlApiUrl'
|
||||
| 'jinaApiKey'
|
||||
| 'jinaApiUrl'
|
||||
| 'cohereApiKey';
|
||||
|
||||
export type TWebSearchCategories =
|
||||
|
@ -70,7 +73,11 @@ export const webSearchAuth = {
|
|||
},
|
||||
},
|
||||
rerankers: {
|
||||
jina: { jinaApiKey: 1 as const },
|
||||
jina: {
|
||||
jinaApiKey: 1 as const,
|
||||
/** Optional (0) */
|
||||
jinaApiUrl: 0 as const,
|
||||
},
|
||||
cohere: { cohereApiKey: 1 as const },
|
||||
},
|
||||
};
|
||||
|
|
|
@ -708,6 +708,7 @@ export const webSearchSchema = z.object({
|
|||
firecrawlApiKey: z.string().optional().default('${FIRECRAWL_API_KEY}'),
|
||||
firecrawlApiUrl: z.string().optional().default('${FIRECRAWL_API_URL}'),
|
||||
jinaApiKey: z.string().optional().default('${JINA_API_KEY}'),
|
||||
jinaApiUrl: z.string().optional().default('${JINA_API_URL}'),
|
||||
cohereApiKey: z.string().optional().default('${COHERE_API_KEY}'),
|
||||
searchProvider: z.nativeEnum(SearchProviders).optional(),
|
||||
scraperType: z.nativeEnum(ScraperTypes).optional(),
|
||||
|
|
|
@ -178,6 +178,7 @@ export interface SearchToolConfig extends SearchConfig, ProcessSourcesConfig, Fi
|
|||
logger?: Logger;
|
||||
safeSearch?: SafeSearchLevel;
|
||||
jinaApiKey?: string;
|
||||
jinaApiUrl?: string;
|
||||
cohereApiKey?: string;
|
||||
rerankerType?: RerankerType;
|
||||
onSearchResults?: (results: SearchResult, runnableConfig?: RunnableConfig) => void;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue