mirror of
https://github.com/danny-avila/LibreChat.git
synced 2026-02-23 02:44:08 +01:00
refactor: port llm.spec.js over to typescript
This commit is contained in:
parent
f1dab7f924
commit
5b63aceda9
4 changed files with 29 additions and 19 deletions
|
|
@ -1,4 +1,4 @@
|
||||||
const { getLLMConfig } = require('./llm');
|
import { getLLMConfig } from './llm';
|
||||||
|
|
||||||
jest.mock('https-proxy-agent', () => ({
|
jest.mock('https-proxy-agent', () => ({
|
||||||
HttpsProxyAgent: jest.fn().mockImplementation((proxy) => ({ proxy })),
|
HttpsProxyAgent: jest.fn().mockImplementation((proxy) => ({ proxy })),
|
||||||
|
|
@ -25,9 +25,9 @@ describe('getLLMConfig', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(result.llmConfig.clientOptions).toHaveProperty('fetchOptions');
|
expect(result.llmConfig.clientOptions).toHaveProperty('fetchOptions');
|
||||||
expect(result.llmConfig.clientOptions.fetchOptions).toHaveProperty('dispatcher');
|
expect(result.llmConfig.clientOptions?.fetchOptions).toHaveProperty('dispatcher');
|
||||||
expect(result.llmConfig.clientOptions.fetchOptions.dispatcher).toBeDefined();
|
expect(result.llmConfig.clientOptions?.fetchOptions?.dispatcher).toBeDefined();
|
||||||
expect(result.llmConfig.clientOptions.fetchOptions.dispatcher.constructor.name).toBe(
|
expect(result.llmConfig.clientOptions?.fetchOptions?.dispatcher.constructor.name).toBe(
|
||||||
'ProxyAgent',
|
'ProxyAgent',
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
@ -93,9 +93,10 @@ describe('getLLMConfig', () => {
|
||||||
};
|
};
|
||||||
const result = getLLMConfig('test-key', { modelOptions });
|
const result = getLLMConfig('test-key', { modelOptions });
|
||||||
const clientOptions = result.llmConfig.clientOptions;
|
const clientOptions = result.llmConfig.clientOptions;
|
||||||
expect(clientOptions.defaultHeaders).toBeDefined();
|
expect(clientOptions?.defaultHeaders).toBeDefined();
|
||||||
expect(clientOptions.defaultHeaders).toHaveProperty('anthropic-beta');
|
expect(clientOptions?.defaultHeaders).toHaveProperty('anthropic-beta');
|
||||||
expect(clientOptions.defaultHeaders['anthropic-beta']).toBe(
|
const defaultHeaders = clientOptions?.defaultHeaders as Record<string, string>;
|
||||||
|
expect(defaultHeaders['anthropic-beta']).toBe(
|
||||||
'prompt-caching-2024-07-31,context-1m-2025-08-07',
|
'prompt-caching-2024-07-31,context-1m-2025-08-07',
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
@ -111,9 +112,10 @@ describe('getLLMConfig', () => {
|
||||||
const modelOptions = { model, promptCache: true };
|
const modelOptions = { model, promptCache: true };
|
||||||
const result = getLLMConfig('test-key', { modelOptions });
|
const result = getLLMConfig('test-key', { modelOptions });
|
||||||
const clientOptions = result.llmConfig.clientOptions;
|
const clientOptions = result.llmConfig.clientOptions;
|
||||||
expect(clientOptions.defaultHeaders).toBeDefined();
|
expect(clientOptions?.defaultHeaders).toBeDefined();
|
||||||
expect(clientOptions.defaultHeaders).toHaveProperty('anthropic-beta');
|
expect(clientOptions?.defaultHeaders).toHaveProperty('anthropic-beta');
|
||||||
expect(clientOptions.defaultHeaders['anthropic-beta']).toBe(
|
const defaultHeaders = clientOptions?.defaultHeaders as Record<string, string>;
|
||||||
|
expect(defaultHeaders['anthropic-beta']).toBe(
|
||||||
'prompt-caching-2024-07-31,context-1m-2025-08-07',
|
'prompt-caching-2024-07-31,context-1m-2025-08-07',
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
@ -254,9 +256,9 @@ describe('getLLMConfig', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(result.llmConfig.clientOptions).toHaveProperty('fetchOptions');
|
expect(result.llmConfig.clientOptions).toHaveProperty('fetchOptions');
|
||||||
expect(result.llmConfig.clientOptions.fetchOptions).toHaveProperty('dispatcher');
|
expect(result.llmConfig.clientOptions?.fetchOptions).toHaveProperty('dispatcher');
|
||||||
expect(result.llmConfig.clientOptions.fetchOptions.dispatcher).toBeDefined();
|
expect(result.llmConfig.clientOptions?.fetchOptions?.dispatcher).toBeDefined();
|
||||||
expect(result.llmConfig.clientOptions.fetchOptions.dispatcher.constructor.name).toBe(
|
expect(result.llmConfig.clientOptions?.fetchOptions?.dispatcher.constructor.name).toBe(
|
||||||
'ProxyAgent',
|
'ProxyAgent',
|
||||||
);
|
);
|
||||||
expect(result.llmConfig.clientOptions).toHaveProperty('baseURL', 'https://reverse-proxy.com');
|
expect(result.llmConfig.clientOptions).toHaveProperty('baseURL', 'https://reverse-proxy.com');
|
||||||
|
|
@ -272,7 +274,7 @@ describe('getLLMConfig', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
// claude-3-5-sonnet supports prompt caching and should get the appropriate headers
|
// claude-3-5-sonnet supports prompt caching and should get the appropriate headers
|
||||||
expect(result.llmConfig.clientOptions.defaultHeaders).toEqual({
|
expect(result.llmConfig.clientOptions?.defaultHeaders).toEqual({
|
||||||
'anthropic-beta': 'max-tokens-3-5-sonnet-2024-07-15,prompt-caching-2024-07-31',
|
'anthropic-beta': 'max-tokens-3-5-sonnet-2024-07-15,prompt-caching-2024-07-31',
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
@ -28,7 +28,7 @@ import { checkPromptCacheSupport, getClaudeHeaders, configureReasoning } from '.
|
||||||
* @returns {Object} Configuration options for creating an Anthropic LLM instance, with null and undefined values removed.
|
* @returns {Object} Configuration options for creating an Anthropic LLM instance, with null and undefined values removed.
|
||||||
*/
|
*/
|
||||||
function getLLMConfig(
|
function getLLMConfig(
|
||||||
apiKey: string,
|
apiKey?: string,
|
||||||
options: AnthropicConfigOptions = {} as AnthropicConfigOptions,
|
options: AnthropicConfigOptions = {} as AnthropicConfigOptions,
|
||||||
): AnthropicLLMConfigResult {
|
): AnthropicLLMConfigResult {
|
||||||
const systemOptions = {
|
const systemOptions = {
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
import { z } from 'zod';
|
import { z } from 'zod';
|
||||||
import { AnthropicClientOptions } from '@librechat/agents';
|
import { Dispatcher } from 'undici';
|
||||||
import { anthropicSchema } from 'librechat-data-provider';
|
import { anthropicSchema } from 'librechat-data-provider';
|
||||||
|
import { AnthropicClientOptions } from '@librechat/agents';
|
||||||
|
|
||||||
export type AnthropicParameters = z.infer<typeof anthropicSchema>;
|
export type AnthropicParameters = z.infer<typeof anthropicSchema>;
|
||||||
|
|
||||||
|
|
@ -22,7 +23,11 @@ export interface AnthropicConfigOptions {
|
||||||
*/
|
*/
|
||||||
export interface AnthropicLLMConfigResult {
|
export interface AnthropicLLMConfigResult {
|
||||||
/** Configuration options for creating an Anthropic LLM instance */
|
/** Configuration options for creating an Anthropic LLM instance */
|
||||||
llmConfig: AnthropicClientOptions;
|
llmConfig: AnthropicClientOptions & {
|
||||||
|
clientOptions?: {
|
||||||
|
fetchOptions?: { dispatcher: Dispatcher };
|
||||||
|
};
|
||||||
|
};
|
||||||
/** Array of tools to be used */
|
/** Array of tools to be used */
|
||||||
tools: Array<{
|
tools: Array<{
|
||||||
type: string;
|
type: string;
|
||||||
|
|
|
||||||
|
|
@ -619,14 +619,14 @@ export const tConversationSchema = z.object({
|
||||||
userLabel: z.string().optional(),
|
userLabel: z.string().optional(),
|
||||||
model: z.string().nullable().optional(),
|
model: z.string().nullable().optional(),
|
||||||
promptPrefix: z.string().nullable().optional(),
|
promptPrefix: z.string().nullable().optional(),
|
||||||
temperature: z.number().optional(),
|
temperature: z.number().nullable().optional(),
|
||||||
topP: z.number().optional(),
|
topP: z.number().optional(),
|
||||||
topK: z.number().optional(),
|
topK: z.number().optional(),
|
||||||
top_p: z.number().optional(),
|
top_p: z.number().optional(),
|
||||||
frequency_penalty: z.number().optional(),
|
frequency_penalty: z.number().optional(),
|
||||||
presence_penalty: z.number().optional(),
|
presence_penalty: z.number().optional(),
|
||||||
parentMessageId: z.string().optional(),
|
parentMessageId: z.string().optional(),
|
||||||
maxOutputTokens: coerceNumber.optional(),
|
maxOutputTokens: coerceNumber.nullable().optional(),
|
||||||
maxContextTokens: coerceNumber.optional(),
|
maxContextTokens: coerceNumber.optional(),
|
||||||
max_tokens: coerceNumber.optional(),
|
max_tokens: coerceNumber.optional(),
|
||||||
/* Anthropic */
|
/* Anthropic */
|
||||||
|
|
@ -634,6 +634,7 @@ export const tConversationSchema = z.object({
|
||||||
system: z.string().optional(),
|
system: z.string().optional(),
|
||||||
thinking: z.boolean().optional(),
|
thinking: z.boolean().optional(),
|
||||||
thinkingBudget: coerceNumber.optional(),
|
thinkingBudget: coerceNumber.optional(),
|
||||||
|
stream: z.boolean().optional(),
|
||||||
/* artifacts */
|
/* artifacts */
|
||||||
artifacts: z.string().optional(),
|
artifacts: z.string().optional(),
|
||||||
/* google */
|
/* google */
|
||||||
|
|
@ -1152,6 +1153,8 @@ export const anthropicBaseSchema = tConversationSchema.pick({
|
||||||
maxContextTokens: true,
|
maxContextTokens: true,
|
||||||
web_search: true,
|
web_search: true,
|
||||||
fileTokenLimit: true,
|
fileTokenLimit: true,
|
||||||
|
stop: true,
|
||||||
|
stream: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
export const anthropicSchema = anthropicBaseSchema
|
export const anthropicSchema = anthropicBaseSchema
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue