librechat-data-provider 0.7.78 → 0.7.82
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/dist/index.es.js +1 -1
- package/dist/index.es.js.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/react-query/index.es.js +1 -1
- package/dist/react-query/index.es.js.map +1 -1
- package/package.json +2 -1
- package/specs/actions.spec.ts +238 -0
- package/specs/mcp.spec.ts +126 -1
- package/specs/parsers.spec.ts +125 -0
- package/src/actions.ts +73 -19
- package/src/api-endpoints.ts +42 -10
- package/src/config.ts +30 -2
- package/src/createPayload.ts +13 -2
- package/src/data-service.ts +47 -69
- package/src/file-config.ts +3 -2
- package/src/index.ts +1 -0
- package/src/mcp.ts +12 -8
- package/src/parsers.ts +47 -16
- package/src/permissions.ts +90 -0
- package/src/react-query/react-query-service.ts +5 -34
- package/src/roles.ts +72 -126
- package/src/schemas.ts +152 -178
- package/src/types/assistants.ts +16 -18
- package/src/types/mutations.ts +8 -2
- package/src/types/queries.ts +28 -13
- package/src/types.ts +10 -0
- package/src/zod.spec.ts +569 -1
- package/src/zod.ts +318 -9
package/src/api-endpoints.ts
CHANGED
|
@@ -1,4 +1,24 @@
|
|
|
1
1
|
import type { AssistantsEndpoint } from './schemas';
|
|
2
|
+
import * as q from './types/queries';
|
|
3
|
+
|
|
4
|
+
// Testing this buildQuery function
|
|
5
|
+
const buildQuery = (params: Record<string, unknown>): string => {
|
|
6
|
+
const query = Object.entries(params)
|
|
7
|
+
.filter(([, value]) => {
|
|
8
|
+
if (Array.isArray(value)) {
|
|
9
|
+
return value.length > 0;
|
|
10
|
+
}
|
|
11
|
+
return value !== undefined && value !== null && value !== '';
|
|
12
|
+
})
|
|
13
|
+
.map(([key, value]) => {
|
|
14
|
+
if (Array.isArray(value)) {
|
|
15
|
+
return value.map((v) => `${key}=${encodeURIComponent(v)}`).join('&');
|
|
16
|
+
}
|
|
17
|
+
return `${key}=${encodeURIComponent(String(value))}`;
|
|
18
|
+
})
|
|
19
|
+
.join('&');
|
|
20
|
+
return query ? `?${query}` : '';
|
|
21
|
+
};
|
|
2
22
|
|
|
3
23
|
export const health = () => '/health';
|
|
4
24
|
export const user = () => '/api/user';
|
|
@@ -9,8 +29,19 @@ export const userPlugins = () => '/api/user/plugins';
|
|
|
9
29
|
|
|
10
30
|
export const deleteUser = () => '/api/user/delete';
|
|
11
31
|
|
|
12
|
-
export const messages = (
|
|
13
|
-
|
|
32
|
+
export const messages = (params: q.MessagesListParams) => {
|
|
33
|
+
const { conversationId, messageId, ...rest } = params;
|
|
34
|
+
|
|
35
|
+
if (conversationId && messageId) {
|
|
36
|
+
return `/api/messages/${conversationId}/${messageId}`;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
if (conversationId) {
|
|
40
|
+
return `/api/messages/${conversationId}`;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
return `/api/messages${buildQuery(rest)}`;
|
|
44
|
+
};
|
|
14
45
|
|
|
15
46
|
const shareRoot = '/api/share';
|
|
16
47
|
export const shareMessages = (shareId: string) => `${shareRoot}/${shareId}`;
|
|
@@ -43,10 +74,9 @@ export const abortRequest = (endpoint: string) => `/api/ask/${endpoint}/abort`;
|
|
|
43
74
|
|
|
44
75
|
export const conversationsRoot = '/api/convos';
|
|
45
76
|
|
|
46
|
-
export const conversations = (
|
|
47
|
-
`${conversationsRoot}
|
|
48
|
-
|
|
49
|
-
}${tags?.map((tag) => `&tags=${tag}`).join('')}`;
|
|
77
|
+
export const conversations = (params: q.ConversationListParams) => {
|
|
78
|
+
return `${conversationsRoot}${buildQuery(params)}`;
|
|
79
|
+
};
|
|
50
80
|
|
|
51
81
|
export const conversationById = (id: string) => `${conversationsRoot}/${id}`;
|
|
52
82
|
|
|
@@ -54,7 +84,9 @@ export const genTitle = () => `${conversationsRoot}/gen_title`;
|
|
|
54
84
|
|
|
55
85
|
export const updateConversation = () => `${conversationsRoot}/update`;
|
|
56
86
|
|
|
57
|
-
export const deleteConversation = () => `${conversationsRoot}
|
|
87
|
+
export const deleteConversation = () => `${conversationsRoot}`;
|
|
88
|
+
|
|
89
|
+
export const deleteAllConversation = () => `${conversationsRoot}/all`;
|
|
58
90
|
|
|
59
91
|
export const importConversation = () => `${conversationsRoot}/import`;
|
|
60
92
|
|
|
@@ -62,8 +94,8 @@ export const forkConversation = () => `${conversationsRoot}/fork`;
|
|
|
62
94
|
|
|
63
95
|
export const duplicateConversation = () => `${conversationsRoot}/duplicate`;
|
|
64
96
|
|
|
65
|
-
export const search = (q: string,
|
|
66
|
-
`/api/search?q=${q}
|
|
97
|
+
export const search = (q: string, cursor?: string | null) =>
|
|
98
|
+
`/api/search?q=${q}${cursor ? `&cursor=${cursor}` : ''}`;
|
|
67
99
|
|
|
68
100
|
export const searchEnabled = () => '/api/search/enable';
|
|
69
101
|
|
|
@@ -244,4 +276,4 @@ export const verifyTwoFactor = () => '/api/auth/2fa/verify';
|
|
|
244
276
|
export const confirmTwoFactor = () => '/api/auth/2fa/confirm';
|
|
245
277
|
export const disableTwoFactor = () => '/api/auth/2fa/disable';
|
|
246
278
|
export const regenerateBackupCodes = () => '/api/auth/2fa/backup/regenerate';
|
|
247
|
-
export const verifyTwoFactorTemp = () => '/api/auth/2fa/verify-temp';
|
|
279
|
+
export const verifyTwoFactorTemp = () => '/api/auth/2fa/verify-temp';
|
package/src/config.ts
CHANGED
|
@@ -541,6 +541,7 @@ export type TStartupConfig = {
|
|
|
541
541
|
analyticsGtmId?: string;
|
|
542
542
|
instanceProjectId: string;
|
|
543
543
|
bundlerURL?: string;
|
|
544
|
+
staticBundlerURL?: string;
|
|
544
545
|
};
|
|
545
546
|
|
|
546
547
|
export enum OCRStrategy {
|
|
@@ -855,15 +856,21 @@ export const visionModels = [
|
|
|
855
856
|
'gpt-4o',
|
|
856
857
|
'gpt-4-turbo',
|
|
857
858
|
'gpt-4-vision',
|
|
859
|
+
'o4-mini',
|
|
860
|
+
'o3',
|
|
858
861
|
'o1',
|
|
862
|
+
'gpt-4.1',
|
|
859
863
|
'gpt-4.5',
|
|
860
864
|
'llava',
|
|
861
865
|
'llava-13b',
|
|
862
866
|
'gemini-pro-vision',
|
|
863
867
|
'claude-3',
|
|
868
|
+
'gemma',
|
|
864
869
|
'gemini-exp',
|
|
865
870
|
'gemini-1.5',
|
|
866
871
|
'gemini-2.0',
|
|
872
|
+
'gemini-2.5',
|
|
873
|
+
'gemini-3',
|
|
867
874
|
'moondream',
|
|
868
875
|
'llama3.2-vision',
|
|
869
876
|
'llama-3.2-11b-vision',
|
|
@@ -1007,6 +1014,10 @@ export enum CacheKeys {
|
|
|
1007
1014
|
* Key for in-progress flow states.
|
|
1008
1015
|
*/
|
|
1009
1016
|
FLOWS = 'flows',
|
|
1017
|
+
/**
|
|
1018
|
+
* Key for pending chat requests (concurrency check)
|
|
1019
|
+
*/
|
|
1020
|
+
PENDING_REQ = 'pending_req',
|
|
1010
1021
|
/**
|
|
1011
1022
|
* Key for s3 check intervals per user
|
|
1012
1023
|
*/
|
|
@@ -1217,13 +1228,15 @@ export enum TTSProviders {
|
|
|
1217
1228
|
/** Enum for app-wide constants */
|
|
1218
1229
|
export enum Constants {
|
|
1219
1230
|
/** Key for the app's version. */
|
|
1220
|
-
VERSION = 'v0.7.
|
|
1231
|
+
VERSION = 'v0.7.8',
|
|
1221
1232
|
/** Key for the Custom Config's version (librechat.yaml). */
|
|
1222
|
-
CONFIG_VERSION = '1.2.
|
|
1233
|
+
CONFIG_VERSION = '1.2.5',
|
|
1223
1234
|
/** Standard value for the first message's `parentMessageId` value, to indicate no parent exists. */
|
|
1224
1235
|
NO_PARENT = '00000000-0000-0000-0000-000000000000',
|
|
1225
1236
|
/** Standard value for the initial conversationId before a request is sent */
|
|
1226
1237
|
NEW_CONVO = 'new',
|
|
1238
|
+
/** Standard value for the temporary conversationId after a request is sent and before the server responds */
|
|
1239
|
+
PENDING_CONVO = 'PENDING',
|
|
1227
1240
|
/** Standard value for the conversationId used for search queries */
|
|
1228
1241
|
SEARCH = 'search',
|
|
1229
1242
|
/** Fixed, encoded domain length for Azure OpenAI Assistants Function name parsing. */
|
|
@@ -1244,6 +1257,8 @@ export enum Constants {
|
|
|
1244
1257
|
GLOBAL_PROJECT_NAME = 'instance',
|
|
1245
1258
|
/** Delimiter for MCP tools */
|
|
1246
1259
|
mcp_delimiter = '_mcp_',
|
|
1260
|
+
/** Placeholder Agent ID for Ephemeral Agents */
|
|
1261
|
+
EPHEMERAL_AGENT_ID = 'ephemeral',
|
|
1247
1262
|
}
|
|
1248
1263
|
|
|
1249
1264
|
export enum LocalStorageKeys {
|
|
@@ -1279,6 +1294,10 @@ export enum LocalStorageKeys {
|
|
|
1279
1294
|
ENABLE_USER_MSG_MARKDOWN = 'enableUserMsgMarkdown',
|
|
1280
1295
|
/** Key for displaying analysis tool code input */
|
|
1281
1296
|
SHOW_ANALYSIS_CODE = 'showAnalysisCode',
|
|
1297
|
+
/** Last selected MCP values per conversation ID */
|
|
1298
|
+
LAST_MCP_ = 'LAST_MCP_',
|
|
1299
|
+
/** Last checked toggle for Code Interpreter API per conversation ID */
|
|
1300
|
+
LAST_CODE_TOGGLE_ = 'LAST_CODE_TOGGLE_',
|
|
1282
1301
|
}
|
|
1283
1302
|
|
|
1284
1303
|
export enum ForkOptions {
|
|
@@ -1331,3 +1350,12 @@ export const providerEndpointMap = {
|
|
|
1331
1350
|
[EModelEndpoint.anthropic]: EModelEndpoint.anthropic,
|
|
1332
1351
|
[EModelEndpoint.azureOpenAI]: EModelEndpoint.azureOpenAI,
|
|
1333
1352
|
};
|
|
1353
|
+
|
|
1354
|
+
export const specialVariables = {
|
|
1355
|
+
current_date: true,
|
|
1356
|
+
current_user: true,
|
|
1357
|
+
iso_datetime: true,
|
|
1358
|
+
current_datetime: true,
|
|
1359
|
+
};
|
|
1360
|
+
|
|
1361
|
+
export type TSpecialVarLabel = `com_ui_special_var_${keyof typeof specialVariables}`;
|
package/src/createPayload.ts
CHANGED
|
@@ -3,8 +3,15 @@ import { EndpointURLs } from './config';
|
|
|
3
3
|
import * as s from './schemas';
|
|
4
4
|
|
|
5
5
|
export default function createPayload(submission: t.TSubmission) {
|
|
6
|
-
const {
|
|
7
|
-
|
|
6
|
+
const {
|
|
7
|
+
conversation,
|
|
8
|
+
userMessage,
|
|
9
|
+
endpointOption,
|
|
10
|
+
isEdited,
|
|
11
|
+
isContinued,
|
|
12
|
+
isTemporary,
|
|
13
|
+
ephemeralAgent,
|
|
14
|
+
} = submission;
|
|
8
15
|
const { conversationId } = s.tConvoUpdateSchema.parse(conversation);
|
|
9
16
|
const { endpoint, endpointType } = endpointOption as {
|
|
10
17
|
endpoint: s.EModelEndpoint;
|
|
@@ -12,16 +19,20 @@ export default function createPayload(submission: t.TSubmission) {
|
|
|
12
19
|
};
|
|
13
20
|
|
|
14
21
|
let server = EndpointURLs[endpointType ?? endpoint];
|
|
22
|
+
const isEphemeral = s.isEphemeralAgent(endpoint, ephemeralAgent);
|
|
15
23
|
|
|
16
24
|
if (isEdited && s.isAssistantsEndpoint(endpoint)) {
|
|
17
25
|
server += '/modify';
|
|
18
26
|
} else if (isEdited) {
|
|
19
27
|
server = server.replace('/ask/', '/edit/');
|
|
28
|
+
} else if (isEphemeral) {
|
|
29
|
+
server = `${EndpointURLs[s.EModelEndpoint.agents]}/${endpoint}`;
|
|
20
30
|
}
|
|
21
31
|
|
|
22
32
|
const payload: t.TPayload = {
|
|
23
33
|
...userMessage,
|
|
24
34
|
...endpointOption,
|
|
35
|
+
ephemeralAgent: isEphemeral ? ephemeralAgent : undefined,
|
|
25
36
|
isContinued: !!(isEdited && isContinued),
|
|
26
37
|
conversationId,
|
|
27
38
|
isTemporary,
|
package/src/data-service.ts
CHANGED
|
@@ -30,13 +30,6 @@ export function deleteUser(): Promise<s.TPreset> {
|
|
|
30
30
|
return request.delete(endpoints.deleteUser());
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
-
export function getMessagesByConvoId(conversationId: string): Promise<s.TMessage[]> {
|
|
34
|
-
if (conversationId === 'new') {
|
|
35
|
-
return Promise.resolve([]);
|
|
36
|
-
}
|
|
37
|
-
return request.get(endpoints.messages(conversationId));
|
|
38
|
-
}
|
|
39
|
-
|
|
40
33
|
export function getSharedMessages(shareId: string): Promise<t.TSharedMessagesResponse> {
|
|
41
34
|
return request.get(endpoints.shareMessages(shareId));
|
|
42
35
|
}
|
|
@@ -67,31 +60,6 @@ export function deleteSharedLink(shareId: string): Promise<m.TDeleteSharedLinkRe
|
|
|
67
60
|
return request.delete(endpoints.shareMessages(shareId));
|
|
68
61
|
}
|
|
69
62
|
|
|
70
|
-
export function updateMessage(payload: t.TUpdateMessageRequest): Promise<unknown> {
|
|
71
|
-
const { conversationId, messageId, text } = payload;
|
|
72
|
-
if (!conversationId) {
|
|
73
|
-
throw new Error('conversationId is required');
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
return request.put(endpoints.messages(conversationId, messageId), { text });
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
export const editArtifact = async ({
|
|
80
|
-
messageId,
|
|
81
|
-
...params
|
|
82
|
-
}: m.TEditArtifactRequest): Promise<m.TEditArtifactResponse> => {
|
|
83
|
-
return request.post(`/api/messages/artifact/${messageId}`, params);
|
|
84
|
-
};
|
|
85
|
-
|
|
86
|
-
export function updateMessageContent(payload: t.TUpdateMessageContent): Promise<unknown> {
|
|
87
|
-
const { conversationId, messageId, index, text } = payload;
|
|
88
|
-
if (!conversationId) {
|
|
89
|
-
throw new Error('conversationId is required');
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
return request.put(endpoints.messages(conversationId, messageId), { text, index });
|
|
93
|
-
}
|
|
94
|
-
|
|
95
63
|
export function updateUserKey(payload: t.TUpdateUserKeyRequest) {
|
|
96
64
|
const { value } = payload;
|
|
97
65
|
if (!value) {
|
|
@@ -589,46 +557,21 @@ export function forkConversation(payload: t.TForkConvoRequest): Promise<t.TForkC
|
|
|
589
557
|
}
|
|
590
558
|
|
|
591
559
|
export function deleteConversation(payload: t.TDeleteConversationRequest) {
|
|
592
|
-
|
|
593
|
-
return request.post(endpoints.deleteConversation(), { arg: payload });
|
|
560
|
+
return request.deleteWithOptions(endpoints.deleteConversation(), { data: { arg: payload } });
|
|
594
561
|
}
|
|
595
562
|
|
|
596
563
|
export function clearAllConversations(): Promise<unknown> {
|
|
597
|
-
return request.
|
|
564
|
+
return request.delete(endpoints.deleteAllConversation());
|
|
598
565
|
}
|
|
599
566
|
|
|
600
567
|
export const listConversations = (
|
|
601
568
|
params?: q.ConversationListParams,
|
|
602
569
|
): Promise<q.ConversationListResponse> => {
|
|
603
|
-
|
|
604
|
-
const pageNumber = (params?.pageNumber ?? '1') || '1'; // Default to page 1 if not provided
|
|
605
|
-
const isArchived = params?.isArchived ?? false; // Default to false if not provided
|
|
606
|
-
const tags = params?.tags || []; // Default to an empty array if not provided
|
|
607
|
-
return request.get(endpoints.conversations(pageNumber, isArchived, tags));
|
|
608
|
-
};
|
|
609
|
-
|
|
610
|
-
export const listConversationsByQuery = (
|
|
611
|
-
params?: q.ConversationListParams & { searchQuery?: string },
|
|
612
|
-
): Promise<q.ConversationListResponse> => {
|
|
613
|
-
const pageNumber = (params?.pageNumber ?? '1') || '1'; // Default to page 1 if not provided
|
|
614
|
-
const searchQuery = params?.searchQuery ?? ''; // If no search query is provided, default to an empty string
|
|
615
|
-
// Update the endpoint to handle a search query
|
|
616
|
-
if (searchQuery !== '') {
|
|
617
|
-
return request.get(endpoints.search(searchQuery, pageNumber));
|
|
618
|
-
} else {
|
|
619
|
-
return request.get(endpoints.conversations(pageNumber));
|
|
620
|
-
}
|
|
570
|
+
return request.get(endpoints.conversations(params ?? {}));
|
|
621
571
|
};
|
|
622
572
|
|
|
623
|
-
export
|
|
624
|
-
|
|
625
|
-
pageNumber: string,
|
|
626
|
-
): Promise<t.TSearchResults> => {
|
|
627
|
-
return request.get(endpoints.search(q, pageNumber));
|
|
628
|
-
};
|
|
629
|
-
|
|
630
|
-
export function getConversations(pageNumber: string): Promise<t.TGetConversationsResponse> {
|
|
631
|
-
return request.get(endpoints.conversations(pageNumber));
|
|
573
|
+
export function getConversations(cursor: string): Promise<t.TGetConversationsResponse> {
|
|
574
|
+
return request.get(endpoints.conversations({ cursor }));
|
|
632
575
|
}
|
|
633
576
|
|
|
634
577
|
export function getConversationById(id: string): Promise<s.TConversation> {
|
|
@@ -651,6 +594,45 @@ export function genTitle(payload: m.TGenTitleRequest): Promise<m.TGenTitleRespon
|
|
|
651
594
|
return request.post(endpoints.genTitle(), payload);
|
|
652
595
|
}
|
|
653
596
|
|
|
597
|
+
export const listMessages = (params?: q.MessagesListParams): Promise<q.MessagesListResponse> => {
|
|
598
|
+
return request.get(endpoints.messages(params ?? {}));
|
|
599
|
+
};
|
|
600
|
+
|
|
601
|
+
export function updateMessage(payload: t.TUpdateMessageRequest): Promise<unknown> {
|
|
602
|
+
const { conversationId, messageId, text } = payload;
|
|
603
|
+
if (!conversationId) {
|
|
604
|
+
throw new Error('conversationId is required');
|
|
605
|
+
}
|
|
606
|
+
|
|
607
|
+
return request.put(endpoints.messages({ conversationId, messageId }), { text });
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
export function updateMessageContent(payload: t.TUpdateMessageContent): Promise<unknown> {
|
|
611
|
+
const { conversationId, messageId, index, text } = payload;
|
|
612
|
+
if (!conversationId) {
|
|
613
|
+
throw new Error('conversationId is required');
|
|
614
|
+
}
|
|
615
|
+
|
|
616
|
+
return request.put(endpoints.messages({ conversationId, messageId }), { text, index });
|
|
617
|
+
}
|
|
618
|
+
|
|
619
|
+
export const editArtifact = async ({
|
|
620
|
+
messageId,
|
|
621
|
+
...params
|
|
622
|
+
}: m.TEditArtifactRequest): Promise<m.TEditArtifactResponse> => {
|
|
623
|
+
return request.post(`/api/messages/artifact/${messageId}`, params);
|
|
624
|
+
};
|
|
625
|
+
|
|
626
|
+
export function getMessagesByConvoId(conversationId: string): Promise<s.TMessage[]> {
|
|
627
|
+
if (
|
|
628
|
+
conversationId === config.Constants.NEW_CONVO ||
|
|
629
|
+
conversationId === config.Constants.PENDING_CONVO
|
|
630
|
+
) {
|
|
631
|
+
return Promise.resolve([]);
|
|
632
|
+
}
|
|
633
|
+
return request.get(endpoints.messages({ conversationId }));
|
|
634
|
+
}
|
|
635
|
+
|
|
654
636
|
export function getPrompt(id: string): Promise<{ prompt: t.TPrompt }> {
|
|
655
637
|
return request.get(endpoints.getPrompt(id));
|
|
656
638
|
}
|
|
@@ -779,15 +761,11 @@ export function enableTwoFactor(): Promise<t.TEnable2FAResponse> {
|
|
|
779
761
|
return request.get(endpoints.enableTwoFactor());
|
|
780
762
|
}
|
|
781
763
|
|
|
782
|
-
export function verifyTwoFactor(
|
|
783
|
-
payload: t.TVerify2FARequest,
|
|
784
|
-
): Promise<t.TVerify2FAResponse> {
|
|
764
|
+
export function verifyTwoFactor(payload: t.TVerify2FARequest): Promise<t.TVerify2FAResponse> {
|
|
785
765
|
return request.post(endpoints.verifyTwoFactor(), payload);
|
|
786
766
|
}
|
|
787
767
|
|
|
788
|
-
export function confirmTwoFactor(
|
|
789
|
-
payload: t.TVerify2FARequest,
|
|
790
|
-
): Promise<t.TVerify2FAResponse> {
|
|
768
|
+
export function confirmTwoFactor(payload: t.TVerify2FARequest): Promise<t.TVerify2FAResponse> {
|
|
791
769
|
return request.post(endpoints.confirmTwoFactor(), payload);
|
|
792
770
|
}
|
|
793
771
|
|
|
@@ -803,4 +781,4 @@ export function verifyTwoFactorTemp(
|
|
|
803
781
|
payload: t.TVerify2FATempRequest,
|
|
804
782
|
): Promise<t.TVerify2FATempResponse> {
|
|
805
783
|
return request.post(endpoints.verifyTwoFactorTemp(), payload);
|
|
806
|
-
}
|
|
784
|
+
}
|
package/src/file-config.ts
CHANGED
|
@@ -112,7 +112,7 @@ export const excelMimeTypes =
|
|
|
112
112
|
/^application\/(vnd\.ms-excel|msexcel|x-msexcel|x-ms-excel|x-excel|x-dos_ms_excel|xls|x-xls|vnd\.openxmlformats-officedocument\.spreadsheetml\.sheet)$/;
|
|
113
113
|
|
|
114
114
|
export const textMimeTypes =
|
|
115
|
-
/^(text\/(x-c|x-csharp|x-c\+\+|x-java|html|markdown|x-php|x-python|x-script\.python|x-ruby|x-tex|plain|css|vtt|javascript|csv))$/;
|
|
115
|
+
/^(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))$/;
|
|
116
116
|
|
|
117
117
|
export const applicationMimeTypes =
|
|
118
118
|
/^(application\/(epub\+zip|csv|json|pdf|x-tar|typescript|vnd\.openxmlformats-officedocument\.(wordprocessingml\.document|presentationml\.presentation|spreadsheetml\.sheet)|xml|zip))$/;
|
|
@@ -152,6 +152,7 @@ export const codeTypeMapping: { [key: string]: string } = {
|
|
|
152
152
|
yml: 'application/x-yaml',
|
|
153
153
|
yaml: 'application/x-yaml',
|
|
154
154
|
log: 'text/plain',
|
|
155
|
+
tsv: 'text/tab-separated-values',
|
|
155
156
|
};
|
|
156
157
|
|
|
157
158
|
export const retrievalMimeTypes = [
|
|
@@ -230,7 +231,7 @@ export const convertStringsToRegex = (patterns: string[]): RegExp[] =>
|
|
|
230
231
|
const regex = new RegExp(pattern);
|
|
231
232
|
acc.push(regex);
|
|
232
233
|
} catch (error) {
|
|
233
|
-
console.error(`Invalid regex pattern "${pattern}" skipped
|
|
234
|
+
console.error(`Invalid regex pattern "${pattern}" skipped.`, error);
|
|
234
235
|
}
|
|
235
236
|
return acc;
|
|
236
237
|
}, []);
|
package/src/index.ts
CHANGED
package/src/mcp.ts
CHANGED
|
@@ -5,6 +5,8 @@ const BaseOptionsSchema = z.object({
|
|
|
5
5
|
iconPath: z.string().optional(),
|
|
6
6
|
timeout: z.number().optional(),
|
|
7
7
|
initTimeout: z.number().optional(),
|
|
8
|
+
/** Controls visibility in chat dropdown menu (MCPSelect) */
|
|
9
|
+
chatMenu: z.boolean().optional(),
|
|
8
10
|
});
|
|
9
11
|
|
|
10
12
|
export const StdioOptionsSchema = BaseOptionsSchema.extend({
|
|
@@ -96,28 +98,30 @@ export type MCPOptions = z.infer<typeof MCPOptionsSchema>;
|
|
|
96
98
|
* @param {string} [userId] - The user ID
|
|
97
99
|
* @returns {MCPOptions} - The processed object with environment variables replaced
|
|
98
100
|
*/
|
|
99
|
-
export function processMCPEnv(obj: MCPOptions
|
|
101
|
+
export function processMCPEnv(obj: Readonly<MCPOptions>, userId?: string): MCPOptions {
|
|
100
102
|
if (obj === null || obj === undefined) {
|
|
101
103
|
return obj;
|
|
102
104
|
}
|
|
103
105
|
|
|
104
|
-
|
|
106
|
+
const newObj: MCPOptions = structuredClone(obj);
|
|
107
|
+
|
|
108
|
+
if ('env' in newObj && newObj.env) {
|
|
105
109
|
const processedEnv: Record<string, string> = {};
|
|
106
|
-
for (const [key, value] of Object.entries(
|
|
110
|
+
for (const [key, value] of Object.entries(newObj.env)) {
|
|
107
111
|
processedEnv[key] = extractEnvVariable(value);
|
|
108
112
|
}
|
|
109
|
-
|
|
110
|
-
} else if ('headers' in
|
|
113
|
+
newObj.env = processedEnv;
|
|
114
|
+
} else if ('headers' in newObj && newObj.headers) {
|
|
111
115
|
const processedHeaders: Record<string, string> = {};
|
|
112
|
-
for (const [key, value] of Object.entries(
|
|
116
|
+
for (const [key, value] of Object.entries(newObj.headers)) {
|
|
113
117
|
if (value === '{{LIBRECHAT_USER_ID}}' && userId != null && userId) {
|
|
114
118
|
processedHeaders[key] = userId;
|
|
115
119
|
continue;
|
|
116
120
|
}
|
|
117
121
|
processedHeaders[key] = extractEnvVariable(value);
|
|
118
122
|
}
|
|
119
|
-
|
|
123
|
+
newObj.headers = processedHeaders;
|
|
120
124
|
}
|
|
121
125
|
|
|
122
|
-
return
|
|
126
|
+
return newObj;
|
|
123
127
|
}
|
package/src/parsers.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import dayjs from 'dayjs';
|
|
1
2
|
import type { ZodIssue } from 'zod';
|
|
2
3
|
import type * as a from './types/assistants';
|
|
3
4
|
import type * as s from './schemas';
|
|
@@ -13,8 +14,6 @@ import {
|
|
|
13
14
|
// agentsSchema,
|
|
14
15
|
compactAgentsSchema,
|
|
15
16
|
compactGoogleSchema,
|
|
16
|
-
compactChatGPTSchema,
|
|
17
|
-
chatGPTBrowserSchema,
|
|
18
17
|
compactPluginsSchema,
|
|
19
18
|
compactAssistantSchema,
|
|
20
19
|
} from './schemas';
|
|
@@ -26,19 +25,19 @@ type EndpointSchema =
|
|
|
26
25
|
| typeof openAISchema
|
|
27
26
|
| typeof googleSchema
|
|
28
27
|
| typeof anthropicSchema
|
|
29
|
-
| typeof chatGPTBrowserSchema
|
|
30
28
|
| typeof gptPluginsSchema
|
|
31
29
|
| typeof assistantSchema
|
|
32
30
|
| typeof compactAgentsSchema
|
|
33
31
|
| typeof bedrockInputSchema;
|
|
34
32
|
|
|
35
|
-
|
|
33
|
+
export type EndpointSchemaKey = Exclude<EModelEndpoint, EModelEndpoint.chatGPTBrowser>;
|
|
34
|
+
|
|
35
|
+
const endpointSchemas: Record<EndpointSchemaKey, EndpointSchema> = {
|
|
36
36
|
[EModelEndpoint.openAI]: openAISchema,
|
|
37
37
|
[EModelEndpoint.azureOpenAI]: openAISchema,
|
|
38
38
|
[EModelEndpoint.custom]: openAISchema,
|
|
39
39
|
[EModelEndpoint.google]: googleSchema,
|
|
40
40
|
[EModelEndpoint.anthropic]: anthropicSchema,
|
|
41
|
-
[EModelEndpoint.chatGPTBrowser]: chatGPTBrowserSchema,
|
|
42
41
|
[EModelEndpoint.gptPlugins]: gptPluginsSchema,
|
|
43
42
|
[EModelEndpoint.assistants]: assistantSchema,
|
|
44
43
|
[EModelEndpoint.azureAssistants]: assistantSchema,
|
|
@@ -167,8 +166,8 @@ export const parseConvo = ({
|
|
|
167
166
|
conversation,
|
|
168
167
|
possibleValues,
|
|
169
168
|
}: {
|
|
170
|
-
endpoint:
|
|
171
|
-
endpointType?:
|
|
169
|
+
endpoint: EndpointSchemaKey;
|
|
170
|
+
endpointType?: EndpointSchemaKey | null;
|
|
172
171
|
conversation: Partial<s.TConversation | s.TPreset> | null;
|
|
173
172
|
possibleValues?: TPossibleValues;
|
|
174
173
|
// TODO: POC for default schema
|
|
@@ -252,8 +251,10 @@ export const getResponseSender = (endpointOption: t.TEndpointOption): string =>
|
|
|
252
251
|
return modelLabel;
|
|
253
252
|
} else if (model && extractOmniVersion(model)) {
|
|
254
253
|
return extractOmniVersion(model);
|
|
255
|
-
} else if (model && model.includes('mistral')) {
|
|
254
|
+
} else if (model && (model.includes('mistral') || model.includes('codestral'))) {
|
|
256
255
|
return 'Mistral';
|
|
256
|
+
} else if (model && model.includes('deepseek')) {
|
|
257
|
+
return 'Deepseek';
|
|
257
258
|
} else if (model && model.includes('gpt-')) {
|
|
258
259
|
const gptVersion = extractGPTVersion(model);
|
|
259
260
|
return gptVersion || 'GPT';
|
|
@@ -274,6 +275,8 @@ export const getResponseSender = (endpointOption: t.TEndpointOption): string =>
|
|
|
274
275
|
return modelLabel;
|
|
275
276
|
} else if (model && (model.includes('gemini') || model.includes('learnlm'))) {
|
|
276
277
|
return 'Gemini';
|
|
278
|
+
} else if (model?.toLowerCase().includes('gemma') === true) {
|
|
279
|
+
return 'Gemma';
|
|
277
280
|
} else if (model && model.includes('code')) {
|
|
278
281
|
return 'Codey';
|
|
279
282
|
}
|
|
@@ -288,8 +291,10 @@ export const getResponseSender = (endpointOption: t.TEndpointOption): string =>
|
|
|
288
291
|
return chatGptLabel;
|
|
289
292
|
} else if (model && extractOmniVersion(model)) {
|
|
290
293
|
return extractOmniVersion(model);
|
|
291
|
-
} else if (model && model.includes('mistral')) {
|
|
294
|
+
} else if (model && (model.includes('mistral') || model.includes('codestral'))) {
|
|
292
295
|
return 'Mistral';
|
|
296
|
+
} else if (model && model.includes('deepseek')) {
|
|
297
|
+
return 'Deepseek';
|
|
293
298
|
} else if (model && model.includes('gpt-')) {
|
|
294
299
|
const gptVersion = extractGPTVersion(model);
|
|
295
300
|
return gptVersion || 'GPT';
|
|
@@ -309,11 +314,10 @@ type CompactEndpointSchema =
|
|
|
309
314
|
| typeof compactAgentsSchema
|
|
310
315
|
| typeof compactGoogleSchema
|
|
311
316
|
| typeof anthropicSchema
|
|
312
|
-
| typeof compactChatGPTSchema
|
|
313
317
|
| typeof bedrockInputSchema
|
|
314
318
|
| typeof compactPluginsSchema;
|
|
315
319
|
|
|
316
|
-
const compactEndpointSchemas: Record<
|
|
320
|
+
const compactEndpointSchemas: Record<EndpointSchemaKey, CompactEndpointSchema> = {
|
|
317
321
|
[EModelEndpoint.openAI]: openAISchema,
|
|
318
322
|
[EModelEndpoint.azureOpenAI]: openAISchema,
|
|
319
323
|
[EModelEndpoint.custom]: openAISchema,
|
|
@@ -323,7 +327,6 @@ const compactEndpointSchemas: Record<string, CompactEndpointSchema> = {
|
|
|
323
327
|
[EModelEndpoint.google]: compactGoogleSchema,
|
|
324
328
|
[EModelEndpoint.bedrock]: bedrockInputSchema,
|
|
325
329
|
[EModelEndpoint.anthropic]: anthropicSchema,
|
|
326
|
-
[EModelEndpoint.chatGPTBrowser]: compactChatGPTSchema,
|
|
327
330
|
[EModelEndpoint.gptPlugins]: compactPluginsSchema,
|
|
328
331
|
};
|
|
329
332
|
|
|
@@ -333,8 +336,8 @@ export const parseCompactConvo = ({
|
|
|
333
336
|
conversation,
|
|
334
337
|
possibleValues,
|
|
335
338
|
}: {
|
|
336
|
-
endpoint?:
|
|
337
|
-
endpointType?:
|
|
339
|
+
endpoint?: EndpointSchemaKey;
|
|
340
|
+
endpointType?: EndpointSchemaKey | null;
|
|
338
341
|
conversation: Partial<s.TConversation | s.TPreset>;
|
|
339
342
|
possibleValues?: TPossibleValues;
|
|
340
343
|
// TODO: POC for default schema
|
|
@@ -371,7 +374,10 @@ export const parseCompactConvo = ({
|
|
|
371
374
|
return convo;
|
|
372
375
|
};
|
|
373
376
|
|
|
374
|
-
export function parseTextParts(
|
|
377
|
+
export function parseTextParts(
|
|
378
|
+
contentParts: a.TMessageContentParts[],
|
|
379
|
+
skipReasoning: boolean = false,
|
|
380
|
+
): string {
|
|
375
381
|
let result = '';
|
|
376
382
|
|
|
377
383
|
for (const part of contentParts) {
|
|
@@ -390,7 +396,7 @@ export function parseTextParts(contentParts: a.TMessageContentParts[]): string {
|
|
|
390
396
|
result += ' ';
|
|
391
397
|
}
|
|
392
398
|
result += textValue;
|
|
393
|
-
} else if (part.type === ContentTypes.THINK) {
|
|
399
|
+
} else if (part.type === ContentTypes.THINK && !skipReasoning) {
|
|
394
400
|
const textValue = typeof part.think === 'string' ? part.think : '';
|
|
395
401
|
if (
|
|
396
402
|
result.length > 0 &&
|
|
@@ -419,3 +425,28 @@ export function findLastSeparatorIndex(text: string, separators = SEPARATORS): n
|
|
|
419
425
|
}
|
|
420
426
|
return lastIndex;
|
|
421
427
|
}
|
|
428
|
+
|
|
429
|
+
export function replaceSpecialVars({ text, user }: { text: string; user?: t.TUser | null }) {
|
|
430
|
+
let result = text;
|
|
431
|
+
if (!result) {
|
|
432
|
+
return result;
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
// e.g., "2024-04-29 (1)" (1=Monday)
|
|
436
|
+
const currentDate = dayjs().format('YYYY-MM-DD');
|
|
437
|
+
const dayNumber = dayjs().day();
|
|
438
|
+
const combinedDate = `${currentDate} (${dayNumber})`;
|
|
439
|
+
result = result.replace(/{{current_date}}/gi, combinedDate);
|
|
440
|
+
|
|
441
|
+
const currentDatetime = dayjs().format('YYYY-MM-DD HH:mm:ss');
|
|
442
|
+
result = result.replace(/{{current_datetime}}/gi, `${currentDatetime} (${dayNumber})`);
|
|
443
|
+
|
|
444
|
+
const isoDatetime = dayjs().toISOString();
|
|
445
|
+
result = result.replace(/{{iso_datetime}}/gi, isoDatetime);
|
|
446
|
+
|
|
447
|
+
if (user && user.name) {
|
|
448
|
+
result = result.replace(/{{current_user}}/gi, user.name);
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
return result;
|
|
452
|
+
}
|