From 00a99aca0ae4b7c17144e950fdd681f62c3b23af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B3n=20Levy?= Date: Sun, 17 Aug 2025 12:51:47 +0000 Subject: [PATCH 1/6] feat: add COHERE_BASE_URL configuration support for custom Cohere rerank endpoints - Add cohereBaseUrl to webSearchSchema configuration - Update loadWebSearchConfig to load cohereBaseUrl from environment - Add cohereBaseUrl to TWebSearchKeys type definition - Configure cohereBaseUrl as optional parameter for cohere reranker - Add COHERE_BASE_URL documentation to .env.example This enables configuration of custom Cohere endpoints (such as LiteLLM proxy) for web search reranking. The configuration infrastructure is ready for when the @librechat/agents package supports custom base URLs. Usage: COHERE_BASE_URL=http://litellm:8000/v1 COHERE_API_KEY=your_api_key --- .env.example | 1 + packages/data-provider/src/config.ts | 1 + packages/data-schemas/src/app/web.ts | 8 +++++++- packages/data-schemas/src/types/web.ts | 3 ++- 4 files changed, 11 insertions(+), 2 deletions(-) diff --git a/.env.example b/.env.example index b5613fdfca..d8a4aeb398 100644 --- a/.env.example +++ b/.env.example @@ -814,6 +814,7 @@ OPENWEATHER_API_KEY= # JINA_API_KEY=your_jina_api_key # or # COHERE_API_KEY=your_cohere_api_key +# COHERE_BASE_URL=your_custom_cohere_base_url #======================# # MCP Configuration # diff --git a/packages/data-provider/src/config.ts b/packages/data-provider/src/config.ts index ebfcfa93f1..7ce50c5160 100644 --- a/packages/data-provider/src/config.ts +++ b/packages/data-provider/src/config.ts @@ -836,6 +836,7 @@ export const webSearchSchema = z.object({ jinaApiKey: z.string().optional().default('${JINA_API_KEY}'), jinaApiUrl: z.string().optional().default('${JINA_API_URL}'), cohereApiKey: z.string().optional().default('${COHERE_API_KEY}'), + cohereBaseUrl: z.string().optional().default('${COHERE_BASE_URL}'), searchProvider: z.nativeEnum(SearchProviders).optional(), scraperProvider: z.nativeEnum(ScraperProviders).optional(), rerankerType: z.nativeEnum(RerankerTypes).optional(), diff --git a/packages/data-schemas/src/app/web.ts b/packages/data-schemas/src/app/web.ts index a61e1f1611..9dda3c6959 100644 --- a/packages/data-schemas/src/app/web.ts +++ b/packages/data-schemas/src/app/web.ts @@ -30,7 +30,11 @@ export const webSearchAuth = { /** Optional (0) */ jinaApiUrl: 0 as const, }, - cohere: { cohereApiKey: 1 as const }, + cohere: { + cohereApiKey: 1 as const, + /** Optional (0) */ + cohereBaseUrl: 0 as const, + }, }, }; @@ -72,6 +76,7 @@ export function loadWebSearchConfig( const jinaApiKey = config?.jinaApiKey ?? '${JINA_API_KEY}'; const jinaApiUrl = config?.jinaApiUrl ?? '${JINA_API_URL}'; const cohereApiKey = config?.cohereApiKey ?? '${COHERE_API_KEY}'; + const cohereBaseUrl = config?.cohereBaseUrl ?? '${COHERE_BASE_URL}'; const safeSearch = config?.safeSearch ?? SafeSearchTypes.MODERATE; return { @@ -80,6 +85,7 @@ export function loadWebSearchConfig( jinaApiKey, jinaApiUrl, cohereApiKey, + cohereBaseUrl, serperApiKey, searxngApiKey, firecrawlApiKey, diff --git a/packages/data-schemas/src/types/web.ts b/packages/data-schemas/src/types/web.ts index a9cc1f0cc6..a1c2b8e96e 100644 --- a/packages/data-schemas/src/types/web.ts +++ b/packages/data-schemas/src/types/web.ts @@ -9,7 +9,8 @@ export type TWebSearchKeys = | 'firecrawlVersion' | 'jinaApiKey' | 'jinaApiUrl' - | 'cohereApiKey'; + | 'cohereApiKey' + | 'cohereBaseUrl'; export type TWebSearchCategories = | SearchCategories.PROVIDERS From d0c0602edbfd90359ac20adf13a932afbe2e019b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B3n=20Levy?= Date: Sun, 17 Aug 2025 13:08:40 +0000 Subject: [PATCH 2/6] feat: simple COHERE_BASE_URL support using environment variable Replace enum with dynamic getter to enable runtime environment variable lookup. CohereConstants.API_URL now automatically uses COHERE_BASE_URL if set, otherwise defaults to https://api.cohere.ai/v1. This enables using custom Cohere endpoints (like LiteLLM proxy) for web search reranking by simply setting the COHERE_BASE_URL environment variable. Usage: export COHERE_BASE_URL=http://litellm:8000/v1 export COHERE_API_KEY=your_api_key The change is backwards compatible and requires no configuration changes. --- .env.example | 3 ++- packages/data-provider/src/config.ts | 20 +++++++++++--------- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/.env.example b/.env.example index d8a4aeb398..a36872d8e5 100644 --- a/.env.example +++ b/.env.example @@ -814,7 +814,8 @@ OPENWEATHER_API_KEY= # JINA_API_KEY=your_jina_api_key # or # COHERE_API_KEY=your_cohere_api_key -# COHERE_BASE_URL=your_custom_cohere_base_url +# Optional: Custom Cohere API base URL (defaults to https://api.cohere.ai/v1) +# COHERE_BASE_URL=http://litellm:8000/v1 #======================# # MCP Configuration # diff --git a/packages/data-provider/src/config.ts b/packages/data-provider/src/config.ts index 7ce50c5160..7cfd96dffb 100644 --- a/packages/data-provider/src/config.ts +++ b/packages/data-provider/src/config.ts @@ -836,7 +836,6 @@ export const webSearchSchema = z.object({ jinaApiKey: z.string().optional().default('${JINA_API_KEY}'), jinaApiUrl: z.string().optional().default('${JINA_API_URL}'), cohereApiKey: z.string().optional().default('${COHERE_API_KEY}'), - cohereBaseUrl: z.string().optional().default('${COHERE_BASE_URL}'), searchProvider: z.nativeEnum(SearchProviders).optional(), scraperProvider: z.nativeEnum(ScraperProviders).optional(), rerankerType: z.nativeEnum(RerankerTypes).optional(), @@ -1820,30 +1819,33 @@ export enum ForkOptions { } /** - * Enum for Cohere related constants + * Cohere related constants */ -export enum CohereConstants { +export const CohereConstants = { /** * Cohere API Endpoint, for special handling + * Uses COHERE_BASE_URL environment variable if set, otherwise defaults to official API */ - API_URL = 'https://api.cohere.ai/v1', + get API_URL(): string { + return process.env.COHERE_BASE_URL || 'https://api.cohere.ai/v1'; + }, /** * Role for "USER" messages */ - ROLE_USER = 'USER', + ROLE_USER: 'USER' as const, /** * Role for "SYSTEM" messages */ - ROLE_SYSTEM = 'SYSTEM', + ROLE_SYSTEM: 'SYSTEM' as const, /** * Role for "CHATBOT" messages */ - ROLE_CHATBOT = 'CHATBOT', + ROLE_CHATBOT: 'CHATBOT' as const, /** * Title message as required by Cohere */ - TITLE_MESSAGE = 'TITLE:', -} + TITLE_MESSAGE: 'TITLE:' as const, +} as const; export enum SystemCategories { ALL = 'sys__all__sys', From 1ddc3777b61094dd2e4937f671f40df8ecc6066d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B3n=20Levy?= Date: Tue, 19 Aug 2025 10:22:23 +0000 Subject: [PATCH 3/6] fix: COHERE_API_URL --- .env.example | 4 ++-- packages/data-provider/src/config.ts | 4 ++-- packages/data-schemas/src/app/web.ts | 6 +++--- packages/data-schemas/src/types/web.ts | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.env.example b/.env.example index a36872d8e5..ac0e851bcb 100644 --- a/.env.example +++ b/.env.example @@ -814,8 +814,8 @@ OPENWEATHER_API_KEY= # JINA_API_KEY=your_jina_api_key # or # COHERE_API_KEY=your_cohere_api_key -# Optional: Custom Cohere API base URL (defaults to https://api.cohere.ai/v1) -# COHERE_BASE_URL=http://litellm:8000/v1 +# Optional: Custom Cohere API URL (defaults to https://api.cohere.ai/v1) +# COHERE_API_URL=http://litellm:8000/v1 #======================# # MCP Configuration # diff --git a/packages/data-provider/src/config.ts b/packages/data-provider/src/config.ts index 7cfd96dffb..435fda101b 100644 --- a/packages/data-provider/src/config.ts +++ b/packages/data-provider/src/config.ts @@ -1824,10 +1824,10 @@ export enum ForkOptions { export const CohereConstants = { /** * Cohere API Endpoint, for special handling - * Uses COHERE_BASE_URL environment variable if set, otherwise defaults to official API + * Uses COHERE_API_URL environment variable if set, otherwise defaults to official API */ get API_URL(): string { - return process.env.COHERE_BASE_URL || 'https://api.cohere.ai/v1'; + return process.env.COHERE_API_URL || 'https://api.cohere.ai/v1'; }, /** * Role for "USER" messages diff --git a/packages/data-schemas/src/app/web.ts b/packages/data-schemas/src/app/web.ts index 9dda3c6959..c11cc5e71e 100644 --- a/packages/data-schemas/src/app/web.ts +++ b/packages/data-schemas/src/app/web.ts @@ -33,7 +33,7 @@ export const webSearchAuth = { cohere: { cohereApiKey: 1 as const, /** Optional (0) */ - cohereBaseUrl: 0 as const, + cohereApiUrl: 0 as const, }, }, }; @@ -76,7 +76,7 @@ export function loadWebSearchConfig( const jinaApiKey = config?.jinaApiKey ?? '${JINA_API_KEY}'; const jinaApiUrl = config?.jinaApiUrl ?? '${JINA_API_URL}'; const cohereApiKey = config?.cohereApiKey ?? '${COHERE_API_KEY}'; - const cohereBaseUrl = config?.cohereBaseUrl ?? '${COHERE_BASE_URL}'; + const cohereApiUrl = config?.cohereApiUrl ?? '${COHERE_API_URL}'; const safeSearch = config?.safeSearch ?? SafeSearchTypes.MODERATE; return { @@ -85,7 +85,7 @@ export function loadWebSearchConfig( jinaApiKey, jinaApiUrl, cohereApiKey, - cohereBaseUrl, + cohereApiUrl, serperApiKey, searxngApiKey, firecrawlApiKey, diff --git a/packages/data-schemas/src/types/web.ts b/packages/data-schemas/src/types/web.ts index a1c2b8e96e..7896a00dc8 100644 --- a/packages/data-schemas/src/types/web.ts +++ b/packages/data-schemas/src/types/web.ts @@ -10,7 +10,7 @@ export type TWebSearchKeys = | 'jinaApiKey' | 'jinaApiUrl' | 'cohereApiKey' - | 'cohereBaseUrl'; + | 'cohereApiUrl'; export type TWebSearchCategories = | SearchCategories.PROVIDERS From 868df81574806f1b5207d6fe0528f087cc0361f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B3n=20Levy?= Date: Wed, 10 Sep 2025 13:12:49 +0000 Subject: [PATCH 4/6] fix: simplified override --- packages/data-provider/src/config.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/packages/data-provider/src/config.ts b/packages/data-provider/src/config.ts index 435fda101b..0c826e0f4e 100644 --- a/packages/data-provider/src/config.ts +++ b/packages/data-provider/src/config.ts @@ -1826,9 +1826,7 @@ export const CohereConstants = { * Cohere API Endpoint, for special handling * Uses COHERE_API_URL environment variable if set, otherwise defaults to official API */ - get API_URL(): string { - return process.env.COHERE_API_URL || 'https://api.cohere.ai/v1'; - }, + API_URL: process.env.COHERE_API_URL || 'https://api.cohere.ai/v1', /** * Role for "USER" messages */ From d778205ecbc21c8fab1653b7b15db58651d0242a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B3n=20Levy?= Date: Tue, 13 Jan 2026 06:59:42 +0000 Subject: [PATCH 5/6] Revert "fix: simplified override" This reverts commit 868df81574806f1b5207d6fe0528f087cc0361f5. --- packages/data-provider/src/config.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/data-provider/src/config.ts b/packages/data-provider/src/config.ts index 0c826e0f4e..435fda101b 100644 --- a/packages/data-provider/src/config.ts +++ b/packages/data-provider/src/config.ts @@ -1826,7 +1826,9 @@ export const CohereConstants = { * Cohere API Endpoint, for special handling * Uses COHERE_API_URL environment variable if set, otherwise defaults to official API */ - API_URL: process.env.COHERE_API_URL || 'https://api.cohere.ai/v1', + get API_URL(): string { + return process.env.COHERE_API_URL || 'https://api.cohere.ai/v1'; + }, /** * Role for "USER" messages */ From ae45989eaad2cb9f805fa143a2cdb8829eee95b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B3n=20Levy?= Date: Tue, 13 Jan 2026 08:03:24 +0000 Subject: [PATCH 6/6] test: add cohereApiUrl to web search config tests Update web.spec.ts to include cohereApiUrl in: - Expected default config object - URL default placeholders test - Custom URLs preservation test Co-Authored-By: Claude --- packages/data-schemas/src/app/web.spec.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/data-schemas/src/app/web.spec.ts b/packages/data-schemas/src/app/web.spec.ts index 787d7809a3..fcf6b28b0f 100644 --- a/packages/data-schemas/src/app/web.spec.ts +++ b/packages/data-schemas/src/app/web.spec.ts @@ -55,6 +55,7 @@ describe('loadWebSearchConfig', () => { jinaApiKey: '${JINA_API_KEY}', jinaApiUrl: '${JINA_API_URL}', cohereApiKey: '${COHERE_API_KEY}', + cohereApiUrl: '${COHERE_API_URL}', safeSearch: SafeSearchTypes.MODERATE, }); }); @@ -154,6 +155,7 @@ describe('loadWebSearchConfig', () => { expect(result?.searxngInstanceUrl).toBe('${SEARXNG_INSTANCE_URL}'); expect(result?.firecrawlApiUrl).toBe('${FIRECRAWL_API_URL}'); expect(result?.jinaApiUrl).toBe('${JINA_API_URL}'); + expect(result?.cohereApiUrl).toBe('${COHERE_API_URL}'); }); it('should preserve custom URLs', () => { @@ -161,6 +163,7 @@ describe('loadWebSearchConfig', () => { searxngInstanceUrl: 'https://custom-searxng.com', firecrawlApiUrl: 'https://custom-firecrawl.com', jinaApiUrl: 'https://custom-jina.com', + cohereApiUrl: 'https://custom-cohere.com', }; const result = loadWebSearchConfig(config); @@ -168,6 +171,7 @@ describe('loadWebSearchConfig', () => { expect(result?.searxngInstanceUrl).toBe('https://custom-searxng.com'); expect(result?.firecrawlApiUrl).toBe('https://custom-firecrawl.com'); expect(result?.jinaApiUrl).toBe('https://custom-jina.com'); + expect(result?.cohereApiUrl).toBe('https://custom-cohere.com'); }); }); });