librechat-data-provider 0.7.87 → 0.7.89

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "librechat-data-provider",
3
- "version": "0.7.87",
3
+ "version": "0.7.89",
4
4
  "description": "data services for librechat apps",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.es.js",
@@ -1,6 +1,8 @@
1
- import axios from 'axios';
2
1
  import { z } from 'zod';
3
- import { OpenAPIV3 } from 'openapi-types';
2
+ import axios from 'axios';
3
+ import type { OpenAPIV3 } from 'openapi-types';
4
+ import type { ParametersSchema } from '../src/actions';
5
+ import type { FlowchartSchema } from './openapiSpecs';
4
6
  import {
5
7
  createURL,
6
8
  resolveRef,
@@ -15,9 +17,7 @@ import {
15
17
  scholarAIOpenapiSpec,
16
18
  swapidev,
17
19
  } from './openapiSpecs';
18
- import { AuthorizationTypeEnum, AuthTypeEnum } from '../src/types/assistants';
19
- import type { FlowchartSchema } from './openapiSpecs';
20
- import type { ParametersSchema } from '../src/actions';
20
+ import { AuthorizationTypeEnum, AuthTypeEnum } from '../src/types/agents';
21
21
 
22
22
  jest.mock('axios');
23
23
  const mockedAxios = axios as jest.Mocked<typeof axios>;
package/src/actions.ts CHANGED
@@ -3,15 +3,11 @@ import _axios from 'axios';
3
3
  import { URL } from 'url';
4
4
  import crypto from 'crypto';
5
5
  import { load } from 'js-yaml';
6
- import type {
7
- FunctionTool,
8
- Schema,
9
- Reference,
10
- ActionMetadata,
11
- ActionMetadataRuntime,
12
- } from './types/assistants';
6
+ import type { ActionMetadata, ActionMetadataRuntime } from './types/agents';
7
+ import type { FunctionTool, Schema, Reference } from './types/assistants';
8
+ import { AuthTypeEnum, AuthorizationTypeEnum } from './types/agents';
13
9
  import type { OpenAPIV3 } from 'openapi-types';
14
- import { Tools, AuthTypeEnum, AuthorizationTypeEnum } from './types/assistants';
10
+ import { Tools } from './types/assistants';
15
11
 
16
12
  export type ParametersSchema = {
17
13
  type: string;
@@ -70,8 +70,6 @@ export const revokeUserKey = (name: string) => `${keysEndpoint}/${name}`;
70
70
 
71
71
  export const revokeAllUserKeys = () => `${keysEndpoint}?all=true`;
72
72
 
73
- export const abortRequest = (endpoint: string) => `/api/ask/${endpoint}/abort`;
74
-
75
73
  export const conversationsRoot = '/api/convos';
76
74
 
77
75
  export const conversations = (params: q.ConversationListParams) => {
package/src/config.ts CHANGED
@@ -482,6 +482,12 @@ const termsOfServiceSchema = z.object({
482
482
 
483
483
  export type TTermsOfService = z.infer<typeof termsOfServiceSchema>;
484
484
 
485
+ const mcpServersSchema = z.object({
486
+ placeholder: z.string().optional(),
487
+ });
488
+
489
+ export type TMcpServersConfig = z.infer<typeof mcpServersSchema>;
490
+
485
491
  export const intefaceSchema = z
486
492
  .object({
487
493
  privacyPolicy: z
@@ -492,6 +498,7 @@ export const intefaceSchema = z
492
498
  .optional(),
493
499
  termsOfService: termsOfServiceSchema.optional(),
494
500
  customWelcome: z.string().optional(),
501
+ mcpServers: mcpServersSchema.optional(),
495
502
  endpointsMenu: z.boolean().optional(),
496
503
  modelSelect: z.boolean().optional(),
497
504
  parameters: z.boolean().optional(),
@@ -503,6 +510,7 @@ export const intefaceSchema = z
503
510
  prompts: z.boolean().optional(),
504
511
  agents: z.boolean().optional(),
505
512
  temporaryChat: z.boolean().optional(),
513
+ temporaryChatRetention: z.number().min(1).max(8760).optional(),
506
514
  runCode: z.boolean().optional(),
507
515
  webSearch: z.boolean().optional(),
508
516
  })
@@ -588,11 +596,25 @@ export type TStartupConfig = {
588
596
  scraperType?: ScraperTypes;
589
597
  rerankerType?: RerankerTypes;
590
598
  };
599
+ mcpServers?: Record<
600
+ string,
601
+ {
602
+ customUserVars: Record<
603
+ string,
604
+ {
605
+ title: string;
606
+ description: string;
607
+ }
608
+ >;
609
+ }
610
+ >;
611
+ mcpPlaceholder?: string;
591
612
  };
592
613
 
593
614
  export enum OCRStrategy {
594
615
  MISTRAL_OCR = 'mistral_ocr',
595
616
  CUSTOM_OCR = 'custom_ocr',
617
+ AZURE_MISTRAL_OCR = 'azure_mistral_ocr',
596
618
  }
597
619
 
598
620
  export enum SearchCategories {
@@ -884,7 +906,6 @@ export const defaultModels = {
884
906
  [EModelEndpoint.assistants]: [...sharedOpenAIModels, 'chatgpt-4o-latest'],
885
907
  [EModelEndpoint.agents]: sharedOpenAIModels, // TODO: Add agent models (agentsModels)
886
908
  [EModelEndpoint.google]: [
887
- // Shared Google Models between Vertex AI & Gen AI
888
909
  // Gemini 2.0 Models
889
910
  'gemini-2.0-flash-001',
890
911
  'gemini-2.0-flash-exp',
@@ -928,19 +949,11 @@ export const initialModelsConfig: TModelsConfig = {
928
949
  [EModelEndpoint.bedrock]: defaultModels[EModelEndpoint.bedrock],
929
950
  };
930
951
 
931
- export const EndpointURLs: { [key in EModelEndpoint]: string } = {
932
- [EModelEndpoint.openAI]: `/api/ask/${EModelEndpoint.openAI}`,
933
- [EModelEndpoint.google]: `/api/ask/${EModelEndpoint.google}`,
934
- [EModelEndpoint.custom]: `/api/ask/${EModelEndpoint.custom}`,
935
- [EModelEndpoint.anthropic]: `/api/ask/${EModelEndpoint.anthropic}`,
936
- [EModelEndpoint.gptPlugins]: `/api/ask/${EModelEndpoint.gptPlugins}`,
937
- [EModelEndpoint.azureOpenAI]: `/api/ask/${EModelEndpoint.azureOpenAI}`,
938
- [EModelEndpoint.chatGPTBrowser]: `/api/ask/${EModelEndpoint.chatGPTBrowser}`,
939
- [EModelEndpoint.azureAssistants]: '/api/assistants/v1/chat',
952
+ export const EndpointURLs = {
940
953
  [EModelEndpoint.assistants]: '/api/assistants/v2/chat',
954
+ [EModelEndpoint.azureAssistants]: '/api/assistants/v1/chat',
941
955
  [EModelEndpoint.agents]: `/api/${EModelEndpoint.agents}/chat`,
942
- [EModelEndpoint.bedrock]: `/api/${EModelEndpoint.bedrock}/chat`,
943
- };
956
+ } as const;
944
957
 
945
958
  export const modularEndpoints = new Set<EModelEndpoint | string>([
946
959
  EModelEndpoint.gptPlugins,
@@ -1135,6 +1148,10 @@ export enum CacheKeys {
1135
1148
  * Key for in-progress flow states.
1136
1149
  */
1137
1150
  FLOWS = 'flows',
1151
+ /**
1152
+ * Key for individual MCP Tool Manifests.
1153
+ */
1154
+ MCP_TOOLS = 'mcp_tools',
1138
1155
  /**
1139
1156
  * Key for pending chat requests (concurrency check)
1140
1157
  */
@@ -1363,7 +1380,7 @@ export enum Constants {
1363
1380
  /** Key for the app's version. */
1364
1381
  VERSION = 'v0.7.8',
1365
1382
  /** Key for the Custom Config's version (librechat.yaml). */
1366
- CONFIG_VERSION = '1.2.6',
1383
+ CONFIG_VERSION = '1.2.8',
1367
1384
  /** Standard value for the first message's `parentMessageId` value, to indicate no parent exists. */
1368
1385
  NO_PARENT = '00000000-0000-0000-0000-000000000000',
1369
1386
  /** Standard value for the initial conversationId before a request is sent */
@@ -1390,6 +1407,8 @@ export enum Constants {
1390
1407
  GLOBAL_PROJECT_NAME = 'instance',
1391
1408
  /** Delimiter for MCP tools */
1392
1409
  mcp_delimiter = '_mcp_',
1410
+ /** Prefix for MCP plugins */
1411
+ mcp_prefix = 'mcp_',
1393
1412
  /** Placeholder Agent ID for Ephemeral Agents */
1394
1413
  EPHEMERAL_AGENT_ID = 'ephemeral',
1395
1414
  }
@@ -1433,6 +1452,18 @@ export enum LocalStorageKeys {
1433
1452
  LAST_CODE_TOGGLE_ = 'LAST_CODE_TOGGLE_',
1434
1453
  /** Last checked toggle for Web Search per conversation ID */
1435
1454
  LAST_WEB_SEARCH_TOGGLE_ = 'LAST_WEB_SEARCH_TOGGLE_',
1455
+ /** Last checked toggle for File Search per conversation ID */
1456
+ LAST_FILE_SEARCH_TOGGLE_ = 'LAST_FILE_SEARCH_TOGGLE_',
1457
+ /** Key for the last selected agent provider */
1458
+ LAST_AGENT_PROVIDER = 'lastAgentProvider',
1459
+ /** Key for the last selected agent model */
1460
+ LAST_AGENT_MODEL = 'lastAgentModel',
1461
+ /** Pin state for MCP tools per conversation ID */
1462
+ PIN_MCP_ = 'PIN_MCP_',
1463
+ /** Pin state for Web Search per conversation ID */
1464
+ PIN_WEB_SEARCH_ = 'PIN_WEB_SEARCH_',
1465
+ /** Pin state for Code Interpreter per conversation ID */
1466
+ PIN_CODE_INTERPRETER_ = 'PIN_CODE_INTERPRETER_',
1436
1467
  }
1437
1468
 
1438
1469
  export enum ForkOptions {
@@ -17,23 +17,20 @@ export default function createPayload(submission: t.TSubmission) {
17
17
  endpoint: s.EModelEndpoint;
18
18
  endpointType?: s.EModelEndpoint;
19
19
  };
20
- const endpoint = _e as s.EModelEndpoint;
21
- let server = EndpointURLs[endpointType ?? endpoint];
22
- const isEphemeral = s.isEphemeralAgent(endpoint, ephemeralAgent);
23
20
 
24
- if (isEdited && s.isAssistantsEndpoint(endpoint)) {
25
- server += '/modify';
26
- } else if (isEdited) {
27
- server = server.replace('/ask/', '/edit/');
28
- } else if (isEphemeral) {
29
- server = `${EndpointURLs[s.EModelEndpoint.agents]}/${endpoint}`;
21
+ const endpoint = _e as s.EModelEndpoint;
22
+ let server = `${EndpointURLs[s.EModelEndpoint.agents]}/${endpoint}`;
23
+ if (s.isAssistantsEndpoint(endpoint)) {
24
+ server =
25
+ EndpointURLs[(endpointType ?? endpoint) as 'assistants' | 'azureAssistants'] +
26
+ (isEdited ? '/modify' : '');
30
27
  }
31
28
 
32
29
  const payload: t.TPayload = {
33
30
  ...userMessage,
34
31
  ...endpointOption,
35
32
  endpoint,
36
- ephemeralAgent: isEphemeral ? ephemeralAgent : undefined,
33
+ ephemeralAgent: s.isAssistantsEndpoint(endpoint) ? undefined : ephemeralAgent,
37
34
  isContinued: !!(isEdited && isContinued),
38
35
  conversationId,
39
36
  isTemporary,
@@ -2,6 +2,7 @@ import type { AxiosResponse } from 'axios';
2
2
  import type * as t from './types';
3
3
  import * as endpoints from './api-endpoints';
4
4
  import * as a from './types/assistants';
5
+ import * as ag from './types/agents';
5
6
  import * as m from './types/mutations';
6
7
  import * as q from './types/queries';
7
8
  import * as f from './types/files';
@@ -10,14 +11,6 @@ import request from './request';
10
11
  import * as s from './schemas';
11
12
  import * as r from './roles';
12
13
 
13
- export function abortRequestWithMessage(
14
- endpoint: string,
15
- abortKey: string,
16
- message: string,
17
- ): Promise<void> {
18
- return request.post(endpoints.abortRequest(endpoint), { arg: { abortKey, message } });
19
- }
20
-
21
14
  export function revokeUserKey(name: string): Promise<unknown> {
22
15
  return request.delete(endpoints.revokeUserKey(name));
23
16
  }
@@ -150,7 +143,11 @@ export const updateUserPlugins = (payload: t.TUpdateUserPlugins) => {
150
143
 
151
144
  /* Config */
152
145
 
153
- export const getStartupConfig = (): Promise<config.TStartupConfig> => {
146
+ export const getStartupConfig = (): Promise<
147
+ config.TStartupConfig & {
148
+ mcpCustomUserVars?: Record<string, { title: string; description: string }>;
149
+ }
150
+ > => {
154
151
  return request.get(endpoints.config());
155
152
  };
156
153
 
@@ -351,7 +348,7 @@ export const updateAction = (data: m.UpdateActionVariables): Promise<m.UpdateAct
351
348
  );
352
349
  };
353
350
 
354
- export function getActions(): Promise<a.Action[]> {
351
+ export function getActions(): Promise<ag.Action[]> {
355
352
  return request.get(
356
353
  endpoints.agents({
357
354
  path: 'actions',
@@ -407,7 +404,7 @@ export const updateAgent = ({
407
404
 
408
405
  export const duplicateAgent = ({
409
406
  agent_id,
410
- }: m.DuplicateAgentBody): Promise<{ agent: a.Agent; actions: a.Action[] }> => {
407
+ }: m.DuplicateAgentBody): Promise<{ agent: a.Agent; actions: ag.Action[] }> => {
411
408
  return request.post(
412
409
  endpoints.agents({
413
410
  path: `${agent_id}/duplicate`,
@@ -1,6 +1,6 @@
1
1
  import { z } from 'zod';
2
2
  import { EModelEndpoint } from './schemas';
3
- import type { FileConfig, EndpointFileConfig } from './types/files';
3
+ import type { EndpointFileConfig, FileConfig } from './types/files';
4
4
 
5
5
  export const supportsFiles = {
6
6
  [EModelEndpoint.openAI]: true,
@@ -49,6 +49,8 @@ export const fullMimeTypesList = [
49
49
  'text/javascript',
50
50
  'image/gif',
51
51
  'image/png',
52
+ 'image/heic',
53
+ 'image/heif',
52
54
  'application/x-tar',
53
55
  'application/typescript',
54
56
  'application/xml',
@@ -80,6 +82,8 @@ export const codeInterpreterMimeTypesList = [
80
82
  'text/javascript',
81
83
  'image/gif',
82
84
  'image/png',
85
+ 'image/heic',
86
+ 'image/heif',
83
87
  'application/x-tar',
84
88
  'application/typescript',
85
89
  'application/xml',
@@ -105,18 +109,18 @@ export const retrievalMimeTypesList = [
105
109
  'text/plain',
106
110
  ];
107
111
 
108
- export const imageExtRegex = /\.(jpg|jpeg|png|gif|webp)$/i;
112
+ export const imageExtRegex = /\.(jpg|jpeg|png|gif|webp|heic|heif)$/i;
109
113
 
110
114
  export const excelMimeTypes =
111
115
  /^application\/(vnd\.ms-excel|msexcel|x-msexcel|x-ms-excel|x-excel|x-dos_ms_excel|xls|x-xls|vnd\.openxmlformats-officedocument\.spreadsheetml\.sheet)$/;
112
116
 
113
117
  export const textMimeTypes =
114
- /^(text\/(x-c|x-csharp|tab-separated-values|x-c\+\+|x-java|html|markdown|x-php|x-python|x-script\.python|x-ruby|x-tex|plain|css|vtt|javascript|csv))$/;
118
+ /^(text\/(x-c|x-csharp|tab-separated-values|x-c\+\+|x-h|x-java|html|markdown|x-php|x-python|x-script\.python|x-ruby|x-tex|plain|css|vtt|javascript|csv))$/;
115
119
 
116
120
  export const applicationMimeTypes =
117
121
  /^(application\/(epub\+zip|csv|json|pdf|x-tar|typescript|vnd\.openxmlformats-officedocument\.(wordprocessingml\.document|presentationml\.presentation|spreadsheetml\.sheet)|xml|zip))$/;
118
122
 
119
- export const imageMimeTypes = /^image\/(jpeg|gif|png|webp)$/;
123
+ export const imageMimeTypes = /^image\/(jpeg|gif|png|webp|heic|heif)$/;
120
124
 
121
125
  export const supportedMimeTypes = [
122
126
  textMimeTypes,
@@ -138,6 +142,7 @@ export const codeTypeMapping: { [key: string]: string } = {
138
142
  c: 'text/x-c',
139
143
  cs: 'text/x-csharp',
140
144
  cpp: 'text/x-c++',
145
+ h: 'text/x-h',
141
146
  md: 'text/markdown',
142
147
  php: 'text/x-php',
143
148
  py: 'text/x-python',
@@ -155,7 +160,7 @@ export const codeTypeMapping: { [key: string]: string } = {
155
160
  };
156
161
 
157
162
  export const retrievalMimeTypes = [
158
- /^(text\/(x-c|x-c\+\+|html|x-java|markdown|x-php|x-python|x-script\.python|x-ruby|x-tex|plain|vtt|xml))$/,
163
+ /^(text\/(x-c|x-c\+\+|x-h|html|x-java|markdown|x-php|x-python|x-script\.python|x-ruby|x-tex|plain|vtt|xml))$/,
159
164
  /^(application\/(json|pdf|vnd\.openxmlformats-officedocument\.(wordprocessingml\.document|presentationml\.presentation)))$/,
160
165
  ];
161
166
 
@@ -187,6 +192,12 @@ export const fileConfig = {
187
192
  },
188
193
  serverFileSizeLimit: defaultSizeLimit,
189
194
  avatarSizeLimit: mbToBytes(2),
195
+ clientImageResize: {
196
+ enabled: false,
197
+ maxWidth: 1900,
198
+ maxHeight: 1900,
199
+ quality: 0.92,
200
+ },
190
201
  checkType: function (fileType: string, supportedTypes: RegExp[] = supportedMimeTypes) {
191
202
  return supportedTypes.some((regex) => regex.test(fileType));
192
203
  },
@@ -227,6 +238,14 @@ export const fileConfigSchema = z.object({
227
238
  px: z.number().min(0).optional(),
228
239
  })
229
240
  .optional(),
241
+ clientImageResize: z
242
+ .object({
243
+ enabled: z.boolean().optional(),
244
+ maxWidth: z.number().min(0).optional(),
245
+ maxHeight: z.number().min(0).optional(),
246
+ quality: z.number().min(0).max(1).optional(),
247
+ })
248
+ .optional(),
230
249
  });
231
250
 
232
251
  /** Helper function to safely convert string patterns to RegExp objects */
@@ -255,6 +274,14 @@ export function mergeFileConfig(dynamic: z.infer<typeof fileConfigSchema> | unde
255
274
  mergedConfig.avatarSizeLimit = mbToBytes(dynamic.avatarSizeLimit);
256
275
  }
257
276
 
277
+ // Merge clientImageResize configuration
278
+ if (dynamic.clientImageResize !== undefined) {
279
+ mergedConfig.clientImageResize = {
280
+ ...mergedConfig.clientImageResize,
281
+ ...dynamic.clientImageResize,
282
+ };
283
+ }
284
+
258
285
  if (!dynamic.endpoints) {
259
286
  return mergedConfig;
260
287
  }
package/src/mcp.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import { z } from 'zod';
2
+ import { TokenExchangeMethodEnum } from './types/agents';
2
3
  import { extractEnvVariable } from './utils';
3
4
 
4
5
  const BaseOptionsSchema = z.object({
@@ -7,13 +8,45 @@ const BaseOptionsSchema = z.object({
7
8
  initTimeout: z.number().optional(),
8
9
  /** Controls visibility in chat dropdown menu (MCPSelect) */
9
10
  chatMenu: z.boolean().optional(),
10
- /**
11
+ /**
11
12
  * Controls server instruction behavior:
12
13
  * - undefined/not set: No instructions included (default)
13
14
  * - true: Use server-provided instructions
14
15
  * - string: Use custom instructions (overrides server-provided)
15
16
  */
16
17
  serverInstructions: z.union([z.boolean(), z.string()]).optional(),
18
+ /**
19
+ * OAuth configuration for SSE and Streamable HTTP transports
20
+ * - Optional: OAuth can be auto-discovered on 401 responses
21
+ * - Pre-configured values will skip discovery steps
22
+ */
23
+ oauth: z
24
+ .object({
25
+ /** OAuth authorization endpoint (optional - can be auto-discovered) */
26
+ authorization_url: z.string().url().optional(),
27
+ /** OAuth token endpoint (optional - can be auto-discovered) */
28
+ token_url: z.string().url().optional(),
29
+ /** OAuth client ID (optional - can use dynamic registration) */
30
+ client_id: z.string().optional(),
31
+ /** OAuth client secret (optional - can use dynamic registration) */
32
+ client_secret: z.string().optional(),
33
+ /** OAuth scopes to request */
34
+ scope: z.string().optional(),
35
+ /** OAuth redirect URI (defaults to /api/mcp/{serverName}/oauth/callback) */
36
+ redirect_uri: z.string().url().optional(),
37
+ /** Token exchange method */
38
+ token_exchange_method: z.nativeEnum(TokenExchangeMethodEnum).optional(),
39
+ })
40
+ .optional(),
41
+ customUserVars: z
42
+ .record(
43
+ z.string(),
44
+ z.object({
45
+ title: z.string(),
46
+ description: z.string(),
47
+ }),
48
+ )
49
+ .optional(),
17
50
  });
18
51
 
19
52
  export const StdioOptionsSchema = BaseOptionsSchema.extend({
@@ -119,41 +152,3 @@ export const MCPOptionsSchema = z.union([
119
152
  export const MCPServersSchema = z.record(z.string(), MCPOptionsSchema);
120
153
 
121
154
  export type MCPOptions = z.infer<typeof MCPOptionsSchema>;
122
-
123
- /**
124
- * Recursively processes an object to replace environment variables in string values
125
- * @param {MCPOptions} obj - The object to process
126
- * @param {string} [userId] - The user ID
127
- * @returns {MCPOptions} - The processed object with environment variables replaced
128
- */
129
- export function processMCPEnv(obj: Readonly<MCPOptions>, userId?: string): MCPOptions {
130
- if (obj === null || obj === undefined) {
131
- return obj;
132
- }
133
-
134
- const newObj: MCPOptions = structuredClone(obj);
135
-
136
- if ('env' in newObj && newObj.env) {
137
- const processedEnv: Record<string, string> = {};
138
- for (const [key, value] of Object.entries(newObj.env)) {
139
- processedEnv[key] = extractEnvVariable(value);
140
- }
141
- newObj.env = processedEnv;
142
- } else if ('headers' in newObj && newObj.headers) {
143
- const processedHeaders: Record<string, string> = {};
144
- for (const [key, value] of Object.entries(newObj.headers)) {
145
- if (value === '{{LIBRECHAT_USER_ID}}' && userId != null && userId) {
146
- processedHeaders[key] = userId;
147
- continue;
148
- }
149
- processedHeaders[key] = extractEnvVariable(value);
150
- }
151
- newObj.headers = processedHeaders;
152
- }
153
-
154
- if ('url' in newObj && newObj.url) {
155
- newObj.url = extractEnvVariable(newObj.url);
156
- }
157
-
158
- return newObj;
159
- }
@@ -83,7 +83,7 @@ const createDefinition = (
83
83
  return { ...base, ...overrides } as SettingDefinition;
84
84
  };
85
85
 
86
- const librechat: Record<string, SettingDefinition> = {
86
+ export const librechat = {
87
87
  modelLabel: {
88
88
  key: 'modelLabel',
89
89
  label: 'com_endpoint_custom_name',
@@ -94,7 +94,7 @@ const librechat: Record<string, SettingDefinition> = {
94
94
  placeholder: 'com_endpoint_openai_custom_name_placeholder',
95
95
  placeholderCode: true,
96
96
  optionType: 'conversation',
97
- },
97
+ } as const,
98
98
  maxContextTokens: {
99
99
  key: 'maxContextTokens',
100
100
  label: 'com_endpoint_context_tokens',
@@ -107,7 +107,7 @@ const librechat: Record<string, SettingDefinition> = {
107
107
  descriptionCode: true,
108
108
  optionType: 'model',
109
109
  columnSpan: 2,
110
- },
110
+ } as const,
111
111
  resendFiles: {
112
112
  key: 'resendFiles',
113
113
  label: 'com_endpoint_plug_resend_files',
@@ -120,7 +120,7 @@ const librechat: Record<string, SettingDefinition> = {
120
120
  optionType: 'conversation',
121
121
  showDefault: false,
122
122
  columnSpan: 2,
123
- },
123
+ } as const,
124
124
  promptPrefix: {
125
125
  key: 'promptPrefix',
126
126
  label: 'com_endpoint_prompt_prefix',
@@ -131,7 +131,7 @@ const librechat: Record<string, SettingDefinition> = {
131
131
  placeholder: 'com_endpoint_openai_prompt_prefix_placeholder',
132
132
  placeholderCode: true,
133
133
  optionType: 'model',
134
- },
134
+ } as const,
135
135
  };
136
136
 
137
137
  const openAIParams: Record<string, SettingDefinition> = {
@@ -450,6 +450,37 @@ const google: Record<string, SettingDefinition> = {
450
450
  optionType: 'model',
451
451
  columnSpan: 2,
452
452
  },
453
+ thinking: {
454
+ key: 'thinking',
455
+ label: 'com_endpoint_thinking',
456
+ labelCode: true,
457
+ description: 'com_endpoint_google_thinking',
458
+ descriptionCode: true,
459
+ type: 'boolean',
460
+ default: googleSettings.thinking.default,
461
+ component: 'switch',
462
+ optionType: 'conversation',
463
+ showDefault: false,
464
+ columnSpan: 2,
465
+ },
466
+ thinkingBudget: {
467
+ key: 'thinkingBudget',
468
+ label: 'com_endpoint_thinking_budget',
469
+ labelCode: true,
470
+ description: 'com_endpoint_google_thinking_budget',
471
+ descriptionCode: true,
472
+ placeholder: 'com_ui_auto',
473
+ placeholderCode: true,
474
+ type: 'number',
475
+ component: 'input',
476
+ range: {
477
+ min: googleSettings.thinkingBudget.min,
478
+ max: googleSettings.thinkingBudget.max,
479
+ step: googleSettings.thinkingBudget.step,
480
+ },
481
+ optionType: 'conversation',
482
+ columnSpan: 2,
483
+ },
453
484
  };
454
485
 
455
486
  const googleConfig: SettingsConfiguration = [
@@ -461,6 +492,8 @@ const googleConfig: SettingsConfiguration = [
461
492
  google.topP,
462
493
  google.topK,
463
494
  librechat.resendFiles,
495
+ google.thinking,
496
+ google.thinkingBudget,
464
497
  ];
465
498
 
466
499
  const googleCol1: SettingsConfiguration = [
@@ -476,6 +509,8 @@ const googleCol2: SettingsConfiguration = [
476
509
  google.topP,
477
510
  google.topK,
478
511
  librechat.resendFiles,
512
+ google.thinking,
513
+ google.thinkingBudget,
479
514
  ];
480
515
 
481
516
  const openAI: SettingsConfiguration = [
package/src/parsers.ts CHANGED
@@ -122,19 +122,6 @@ export function errorsToString(errors: ZodIssue[]) {
122
122
  .join(' ');
123
123
  }
124
124
 
125
- /** Resolves header values to env variables if detected */
126
- export function resolveHeaders(headers: Record<string, string> | undefined) {
127
- const resolvedHeaders = { ...(headers ?? {}) };
128
-
129
- if (headers && typeof headers === 'object' && !Array.isArray(headers)) {
130
- Object.keys(headers).forEach((key) => {
131
- resolvedHeaders[key] = extractEnvVariable(headers[key]);
132
- });
133
- }
134
-
135
- return resolvedHeaders;
136
- }
137
-
138
125
  export function getFirstDefinedValue(possibleValues: string[]) {
139
126
  let returnValue;
140
127
  for (const value of possibleValues) {
@@ -275,15 +262,11 @@ export const getResponseSender = (endpointOption: t.TEndpointOption): string =>
275
262
  if (endpoint === EModelEndpoint.google) {
276
263
  if (modelLabel) {
277
264
  return modelLabel;
278
- } else if (model && (model.includes('gemini') || model.includes('learnlm'))) {
279
- return 'Gemini';
280
265
  } else if (model?.toLowerCase().includes('gemma') === true) {
281
266
  return 'Gemma';
282
- } else if (model && model.includes('code')) {
283
- return 'Codey';
284
267
  }
285
268
 
286
- return 'PaLM2';
269
+ return 'Gemini';
287
270
  }
288
271
 
289
272
  if (endpoint === EModelEndpoint.custom || endpointType === EModelEndpoint.custom) {
@@ -12,23 +12,6 @@ import { QueryKeys } from '../keys';
12
12
  import * as s from '../schemas';
13
13
  import * as t from '../types';
14
14
 
15
- export const useAbortRequestWithMessage = (): UseMutationResult<
16
- void,
17
- Error,
18
- { endpoint: string; abortKey: string; message: string }
19
- > => {
20
- const queryClient = useQueryClient();
21
- return useMutation(
22
- ({ endpoint, abortKey, message }) =>
23
- dataService.abortRequestWithMessage(endpoint, abortKey, message),
24
- {
25
- onSuccess: () => {
26
- queryClient.invalidateQueries([QueryKeys.balance]);
27
- },
28
- },
29
- );
30
- };
31
-
32
15
  export const useGetSharedMessages = (
33
16
  shareId: string,
34
17
  config?: UseQueryOptions<t.TSharedMessagesResponse>,