librechat-data-provider 0.7.85 → 0.7.87
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 +1 -1
- package/specs/actions.spec.ts +7 -9
- package/src/actions.ts +17 -8
- package/src/api-endpoints.ts +10 -0
- package/src/config.ts +70 -27
- package/src/createPayload.ts +3 -2
- package/src/data-service.ts +46 -1
- package/src/feedback.ts +141 -0
- package/src/file-config.ts +0 -1
- package/src/index.ts +4 -0
- package/src/keys.ts +3 -0
- package/src/mcp.ts +7 -0
- package/src/memory.ts +62 -0
- package/src/parameterSettings.ts +4 -4
- package/src/parsers.ts +3 -1
- package/src/permissions.ts +16 -0
- package/src/react-query/react-query-service.ts +16 -0
- package/src/roles.ts +16 -0
- package/src/schemas.ts +11 -0
- package/src/types/assistants.ts +1 -0
- package/src/types/mutations.ts +8 -1
- package/src/types/queries.ts +15 -0
- package/src/types.ts +96 -20
- package/src/web.ts +17 -11
- package/src/zod.spec.ts +59 -67
package/src/parameterSettings.ts
CHANGED
|
@@ -682,9 +682,9 @@ const bedrockGeneralColumns = {
|
|
|
682
682
|
export const presetSettings: Record<
|
|
683
683
|
string,
|
|
684
684
|
| {
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
}
|
|
685
|
+
col1: SettingsConfiguration;
|
|
686
|
+
col2: SettingsConfiguration;
|
|
687
|
+
}
|
|
688
688
|
| undefined
|
|
689
689
|
> = {
|
|
690
690
|
[EModelEndpoint.openAI]: openAIColumns,
|
|
@@ -723,4 +723,4 @@ export const agentParamSettings: Record<string, SettingsConfiguration | undefine
|
|
|
723
723
|
acc[key] = value.col2;
|
|
724
724
|
}
|
|
725
725
|
return acc;
|
|
726
|
-
}, {});
|
|
726
|
+
}, {});
|
package/src/parsers.ts
CHANGED
|
@@ -225,13 +225,15 @@ const extractOmniVersion = (modelStr: string): string => {
|
|
|
225
225
|
export const getResponseSender = (endpointOption: t.TEndpointOption): string => {
|
|
226
226
|
const {
|
|
227
227
|
model: _m,
|
|
228
|
-
endpoint,
|
|
228
|
+
endpoint: _e,
|
|
229
229
|
endpointType,
|
|
230
230
|
modelDisplayLabel: _mdl,
|
|
231
231
|
chatGptLabel: _cgl,
|
|
232
232
|
modelLabel: _ml,
|
|
233
233
|
} = endpointOption;
|
|
234
234
|
|
|
235
|
+
const endpoint = _e as EModelEndpoint;
|
|
236
|
+
|
|
235
237
|
const model = _m ?? '';
|
|
236
238
|
const modelDisplayLabel = _mdl ?? '';
|
|
237
239
|
const chatGptLabel = _cgl ?? '';
|
package/src/permissions.ts
CHANGED
|
@@ -16,6 +16,10 @@ export enum PermissionTypes {
|
|
|
16
16
|
* Type for Agent Permissions
|
|
17
17
|
*/
|
|
18
18
|
AGENTS = 'AGENTS',
|
|
19
|
+
/**
|
|
20
|
+
* Type for Memory Permissions
|
|
21
|
+
*/
|
|
22
|
+
MEMORIES = 'MEMORIES',
|
|
19
23
|
/**
|
|
20
24
|
* Type for Multi-Conversation Permissions
|
|
21
25
|
*/
|
|
@@ -45,6 +49,8 @@ export enum Permissions {
|
|
|
45
49
|
READ = 'READ',
|
|
46
50
|
READ_AUTHOR = 'READ_AUTHOR',
|
|
47
51
|
SHARE = 'SHARE',
|
|
52
|
+
/** Can disable if desired */
|
|
53
|
+
OPT_OUT = 'OPT_OUT',
|
|
48
54
|
}
|
|
49
55
|
|
|
50
56
|
export const promptPermissionsSchema = z.object({
|
|
@@ -60,6 +66,15 @@ export const bookmarkPermissionsSchema = z.object({
|
|
|
60
66
|
});
|
|
61
67
|
export type TBookmarkPermissions = z.infer<typeof bookmarkPermissionsSchema>;
|
|
62
68
|
|
|
69
|
+
export const memoryPermissionsSchema = z.object({
|
|
70
|
+
[Permissions.USE]: z.boolean().default(true),
|
|
71
|
+
[Permissions.CREATE]: z.boolean().default(true),
|
|
72
|
+
[Permissions.UPDATE]: z.boolean().default(true),
|
|
73
|
+
[Permissions.READ]: z.boolean().default(true),
|
|
74
|
+
[Permissions.OPT_OUT]: z.boolean().default(true),
|
|
75
|
+
});
|
|
76
|
+
export type TMemoryPermissions = z.infer<typeof memoryPermissionsSchema>;
|
|
77
|
+
|
|
63
78
|
export const agentPermissionsSchema = z.object({
|
|
64
79
|
[Permissions.SHARED_GLOBAL]: z.boolean().default(false),
|
|
65
80
|
[Permissions.USE]: z.boolean().default(true),
|
|
@@ -92,6 +107,7 @@ export type TWebSearchPermissions = z.infer<typeof webSearchPermissionsSchema>;
|
|
|
92
107
|
export const permissionsSchema = z.object({
|
|
93
108
|
[PermissionTypes.PROMPTS]: promptPermissionsSchema,
|
|
94
109
|
[PermissionTypes.BOOKMARKS]: bookmarkPermissionsSchema,
|
|
110
|
+
[PermissionTypes.MEMORIES]: memoryPermissionsSchema,
|
|
95
111
|
[PermissionTypes.AGENTS]: agentPermissionsSchema,
|
|
96
112
|
[PermissionTypes.MULTI_CONVO]: multiConvoPermissionsSchema,
|
|
97
113
|
[PermissionTypes.TEMPORARY_CHAT]: temporaryChatPermissionsSchema,
|
|
@@ -347,3 +347,19 @@ export const useGetCustomConfigSpeechQuery = (
|
|
|
347
347
|
},
|
|
348
348
|
);
|
|
349
349
|
};
|
|
350
|
+
|
|
351
|
+
export const useUpdateFeedbackMutation = (
|
|
352
|
+
conversationId: string,
|
|
353
|
+
messageId: string,
|
|
354
|
+
): UseMutationResult<t.TUpdateFeedbackResponse, Error, t.TUpdateFeedbackRequest> => {
|
|
355
|
+
const queryClient = useQueryClient();
|
|
356
|
+
return useMutation(
|
|
357
|
+
(payload: t.TUpdateFeedbackRequest) =>
|
|
358
|
+
dataService.updateFeedback(conversationId, messageId, payload),
|
|
359
|
+
{
|
|
360
|
+
onSuccess: () => {
|
|
361
|
+
queryClient.invalidateQueries([QueryKeys.messages, messageId]);
|
|
362
|
+
},
|
|
363
|
+
},
|
|
364
|
+
);
|
|
365
|
+
};
|
package/src/roles.ts
CHANGED
|
@@ -5,6 +5,7 @@ import {
|
|
|
5
5
|
permissionsSchema,
|
|
6
6
|
agentPermissionsSchema,
|
|
7
7
|
promptPermissionsSchema,
|
|
8
|
+
memoryPermissionsSchema,
|
|
8
9
|
runCodePermissionsSchema,
|
|
9
10
|
webSearchPermissionsSchema,
|
|
10
11
|
bookmarkPermissionsSchema,
|
|
@@ -48,6 +49,13 @@ const defaultRolesSchema = z.object({
|
|
|
48
49
|
[PermissionTypes.BOOKMARKS]: bookmarkPermissionsSchema.extend({
|
|
49
50
|
[Permissions.USE]: z.boolean().default(true),
|
|
50
51
|
}),
|
|
52
|
+
[PermissionTypes.MEMORIES]: memoryPermissionsSchema.extend({
|
|
53
|
+
[Permissions.USE]: z.boolean().default(true),
|
|
54
|
+
[Permissions.CREATE]: z.boolean().default(true),
|
|
55
|
+
[Permissions.UPDATE]: z.boolean().default(true),
|
|
56
|
+
[Permissions.READ]: z.boolean().default(true),
|
|
57
|
+
[Permissions.OPT_OUT]: z.boolean().default(true),
|
|
58
|
+
}),
|
|
51
59
|
[PermissionTypes.AGENTS]: agentPermissionsSchema.extend({
|
|
52
60
|
[Permissions.SHARED_GLOBAL]: z.boolean().default(true),
|
|
53
61
|
[Permissions.USE]: z.boolean().default(true),
|
|
@@ -86,6 +94,13 @@ export const roleDefaults = defaultRolesSchema.parse({
|
|
|
86
94
|
[PermissionTypes.BOOKMARKS]: {
|
|
87
95
|
[Permissions.USE]: true,
|
|
88
96
|
},
|
|
97
|
+
[PermissionTypes.MEMORIES]: {
|
|
98
|
+
[Permissions.USE]: true,
|
|
99
|
+
[Permissions.CREATE]: true,
|
|
100
|
+
[Permissions.UPDATE]: true,
|
|
101
|
+
[Permissions.READ]: true,
|
|
102
|
+
[Permissions.OPT_OUT]: true,
|
|
103
|
+
},
|
|
89
104
|
[PermissionTypes.AGENTS]: {
|
|
90
105
|
[Permissions.SHARED_GLOBAL]: true,
|
|
91
106
|
[Permissions.USE]: true,
|
|
@@ -110,6 +125,7 @@ export const roleDefaults = defaultRolesSchema.parse({
|
|
|
110
125
|
permissions: {
|
|
111
126
|
[PermissionTypes.PROMPTS]: {},
|
|
112
127
|
[PermissionTypes.BOOKMARKS]: {},
|
|
128
|
+
[PermissionTypes.MEMORIES]: {},
|
|
113
129
|
[PermissionTypes.AGENTS]: {},
|
|
114
130
|
[PermissionTypes.MULTI_CONVO]: {},
|
|
115
131
|
[PermissionTypes.TEMPORARY_CHAT]: {},
|
package/src/schemas.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
import { Tools } from './types/assistants';
|
|
3
3
|
import type { TMessageContentParts, FunctionTool, FunctionToolCall } from './types/assistants';
|
|
4
|
+
import { TFeedback, feedbackSchema } from './feedback';
|
|
4
5
|
import type { SearchResultData } from './types/web';
|
|
5
6
|
import type { TEphemeralAgent } from './types';
|
|
6
7
|
import type { TFile } from './types/files';
|
|
@@ -518,13 +519,22 @@ export const tMessageSchema = z.object({
|
|
|
518
519
|
thread_id: z.string().optional(),
|
|
519
520
|
/* frontend components */
|
|
520
521
|
iconURL: z.string().nullable().optional(),
|
|
522
|
+
feedback: feedbackSchema.optional(),
|
|
521
523
|
});
|
|
522
524
|
|
|
525
|
+
export type MemoryArtifact = {
|
|
526
|
+
key: string;
|
|
527
|
+
value?: string;
|
|
528
|
+
tokenCount?: number;
|
|
529
|
+
type: 'update' | 'delete';
|
|
530
|
+
};
|
|
531
|
+
|
|
523
532
|
export type TAttachmentMetadata = {
|
|
524
533
|
type?: Tools;
|
|
525
534
|
messageId: string;
|
|
526
535
|
toolCallId: string;
|
|
527
536
|
[Tools.web_search]?: SearchResultData;
|
|
537
|
+
[Tools.memory]?: MemoryArtifact;
|
|
528
538
|
};
|
|
529
539
|
|
|
530
540
|
export type TAttachment =
|
|
@@ -543,6 +553,7 @@ export type TMessage = z.input<typeof tMessageSchema> & {
|
|
|
543
553
|
siblingIndex?: number;
|
|
544
554
|
attachments?: TAttachment[];
|
|
545
555
|
clientTimestamp?: string;
|
|
556
|
+
feedback?: TFeedback;
|
|
546
557
|
};
|
|
547
558
|
|
|
548
559
|
export const coerceNumber = z.union([z.number(), z.string()]).transform((val) => {
|
package/src/types/assistants.ts
CHANGED
package/src/types/mutations.ts
CHANGED
|
@@ -278,7 +278,7 @@ export type UpdatePermVars<T> = {
|
|
|
278
278
|
};
|
|
279
279
|
|
|
280
280
|
export type UpdatePromptPermVars = UpdatePermVars<p.TPromptPermissions>;
|
|
281
|
-
|
|
281
|
+
export type UpdateMemoryPermVars = UpdatePermVars<p.TMemoryPermissions>;
|
|
282
282
|
export type UpdateAgentPermVars = UpdatePermVars<p.TAgentPermissions>;
|
|
283
283
|
|
|
284
284
|
export type UpdatePermResponse = r.TRole;
|
|
@@ -290,6 +290,13 @@ export type UpdatePromptPermOptions = MutationOptions<
|
|
|
290
290
|
types.TError | null | undefined
|
|
291
291
|
>;
|
|
292
292
|
|
|
293
|
+
export type UpdateMemoryPermOptions = MutationOptions<
|
|
294
|
+
UpdatePermResponse,
|
|
295
|
+
UpdateMemoryPermVars,
|
|
296
|
+
unknown,
|
|
297
|
+
types.TError | null | undefined
|
|
298
|
+
>;
|
|
299
|
+
|
|
293
300
|
export type UpdateAgentPermOptions = MutationOptions<
|
|
294
301
|
UpdatePermResponse,
|
|
295
302
|
UpdateAgentPermVars,
|
package/src/types/queries.ts
CHANGED
|
@@ -109,3 +109,18 @@ export type VerifyToolAuthResponse = {
|
|
|
109
109
|
|
|
110
110
|
export type GetToolCallParams = { conversationId: string };
|
|
111
111
|
export type ToolCallResults = a.ToolCallResult[];
|
|
112
|
+
|
|
113
|
+
/* Memories */
|
|
114
|
+
export type TUserMemory = {
|
|
115
|
+
key: string;
|
|
116
|
+
value: string;
|
|
117
|
+
updated_at: string;
|
|
118
|
+
tokenCount?: number;
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
export type MemoriesResponse = {
|
|
122
|
+
memories: TUserMemory[];
|
|
123
|
+
totalTokens: number;
|
|
124
|
+
tokenLimit: number | null;
|
|
125
|
+
usagePercentage: number | null;
|
|
126
|
+
};
|
package/src/types.ts
CHANGED
|
@@ -1,16 +1,19 @@
|
|
|
1
1
|
import type OpenAI from 'openai';
|
|
2
2
|
import type { InfiniteData } from '@tanstack/react-query';
|
|
3
3
|
import type {
|
|
4
|
+
TBanner,
|
|
4
5
|
TMessage,
|
|
5
6
|
TResPlugin,
|
|
6
|
-
ImageDetail,
|
|
7
7
|
TSharedLink,
|
|
8
8
|
TConversation,
|
|
9
9
|
EModelEndpoint,
|
|
10
10
|
TConversationTag,
|
|
11
|
-
|
|
11
|
+
TAttachment,
|
|
12
12
|
} from './schemas';
|
|
13
|
-
import { SettingDefinition } from './generate';
|
|
13
|
+
import type { SettingDefinition } from './generate';
|
|
14
|
+
import type { TMinimalFeedback } from './feedback';
|
|
15
|
+
import type { Agent } from './types/assistants';
|
|
16
|
+
|
|
14
17
|
export type TOpenAIMessage = OpenAI.Chat.ChatCompletionMessageParam;
|
|
15
18
|
|
|
16
19
|
export * from './schemas';
|
|
@@ -18,28 +21,78 @@ export * from './schemas';
|
|
|
18
21
|
export type TMessages = TMessage[];
|
|
19
22
|
|
|
20
23
|
/* TODO: Cleanup EndpointOption types */
|
|
21
|
-
export type TEndpointOption =
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
endpoint
|
|
25
|
-
endpointType
|
|
24
|
+
export type TEndpointOption = Pick<
|
|
25
|
+
TConversation,
|
|
26
|
+
// Core conversation fields
|
|
27
|
+
| 'endpoint'
|
|
28
|
+
| 'endpointType'
|
|
29
|
+
| 'model'
|
|
30
|
+
| 'modelLabel'
|
|
31
|
+
| 'chatGptLabel'
|
|
32
|
+
| 'promptPrefix'
|
|
33
|
+
| 'temperature'
|
|
34
|
+
| 'topP'
|
|
35
|
+
| 'topK'
|
|
36
|
+
| 'top_p'
|
|
37
|
+
| 'frequency_penalty'
|
|
38
|
+
| 'presence_penalty'
|
|
39
|
+
| 'maxOutputTokens'
|
|
40
|
+
| 'maxContextTokens'
|
|
41
|
+
| 'max_tokens'
|
|
42
|
+
| 'maxTokens'
|
|
43
|
+
| 'resendFiles'
|
|
44
|
+
| 'imageDetail'
|
|
45
|
+
| 'reasoning_effort'
|
|
46
|
+
| 'instructions'
|
|
47
|
+
| 'additional_instructions'
|
|
48
|
+
| 'append_current_datetime'
|
|
49
|
+
| 'tools'
|
|
50
|
+
| 'stop'
|
|
51
|
+
| 'region'
|
|
52
|
+
| 'additionalModelRequestFields'
|
|
53
|
+
// Anthropic-specific
|
|
54
|
+
| 'promptCache'
|
|
55
|
+
| 'thinking'
|
|
56
|
+
| 'thinkingBudget'
|
|
57
|
+
// Assistant/Agent fields
|
|
58
|
+
| 'assistant_id'
|
|
59
|
+
| 'agent_id'
|
|
60
|
+
// UI/Display fields
|
|
61
|
+
| 'iconURL'
|
|
62
|
+
| 'greeting'
|
|
63
|
+
| 'spec'
|
|
64
|
+
// Artifacts
|
|
65
|
+
| 'artifacts'
|
|
66
|
+
// Files
|
|
67
|
+
| 'file_ids'
|
|
68
|
+
// System field
|
|
69
|
+
| 'system'
|
|
70
|
+
// Google examples
|
|
71
|
+
| 'examples'
|
|
72
|
+
// Context
|
|
73
|
+
| 'context'
|
|
74
|
+
> & {
|
|
75
|
+
// Fields specific to endpoint options that don't exist on TConversation
|
|
26
76
|
modelDisplayLabel?: string;
|
|
27
|
-
resendFiles?: boolean;
|
|
28
|
-
promptCache?: boolean;
|
|
29
|
-
maxContextTokens?: number;
|
|
30
|
-
imageDetail?: ImageDetail;
|
|
31
|
-
model?: string | null;
|
|
32
|
-
promptPrefix?: string;
|
|
33
|
-
temperature?: number;
|
|
34
|
-
chatGptLabel?: string | null;
|
|
35
|
-
modelLabel?: string | null;
|
|
36
|
-
jailbreak?: boolean;
|
|
37
77
|
key?: string | null;
|
|
38
|
-
|
|
78
|
+
/** @deprecated Assistants API */
|
|
39
79
|
thread_id?: string;
|
|
40
|
-
|
|
80
|
+
// Conversation identifiers for multi-response streams
|
|
41
81
|
overrideConvoId?: string;
|
|
42
82
|
overrideUserMessageId?: string;
|
|
83
|
+
// Model parameters (used by different endpoints)
|
|
84
|
+
modelOptions?: Record<string, unknown>;
|
|
85
|
+
model_parameters?: Record<string, unknown>;
|
|
86
|
+
// Configuration data (added by middleware)
|
|
87
|
+
modelsConfig?: TModelsConfig;
|
|
88
|
+
// File attachments (processed by middleware)
|
|
89
|
+
attachments?: TAttachment[];
|
|
90
|
+
// Generated prompts
|
|
91
|
+
artifactsPrompt?: string;
|
|
92
|
+
// Agent-specific fields
|
|
93
|
+
agent?: Promise<Agent>;
|
|
94
|
+
// Client-specific options
|
|
95
|
+
clientOptions?: Record<string, unknown>;
|
|
43
96
|
};
|
|
44
97
|
|
|
45
98
|
export type TEphemeralAgent = {
|
|
@@ -128,6 +181,9 @@ export type TUser = {
|
|
|
128
181
|
plugins?: string[];
|
|
129
182
|
twoFactorEnabled?: boolean;
|
|
130
183
|
backupCodes?: TBackupCode[];
|
|
184
|
+
personalization?: {
|
|
185
|
+
memories?: boolean;
|
|
186
|
+
};
|
|
131
187
|
createdAt: string;
|
|
132
188
|
updatedAt: string;
|
|
133
189
|
};
|
|
@@ -546,3 +602,23 @@ export type TAcceptTermsResponse = {
|
|
|
546
602
|
};
|
|
547
603
|
|
|
548
604
|
export type TBannerResponse = TBanner | null;
|
|
605
|
+
|
|
606
|
+
export type TUpdateFeedbackRequest = {
|
|
607
|
+
feedback?: TMinimalFeedback;
|
|
608
|
+
};
|
|
609
|
+
|
|
610
|
+
export type TUpdateFeedbackResponse = {
|
|
611
|
+
messageId: string;
|
|
612
|
+
conversationId: string;
|
|
613
|
+
feedback?: TMinimalFeedback;
|
|
614
|
+
};
|
|
615
|
+
|
|
616
|
+
export type TBalanceResponse = {
|
|
617
|
+
tokenCredits: number;
|
|
618
|
+
// Automatic refill settings
|
|
619
|
+
autoRefillEnabled: boolean;
|
|
620
|
+
refillIntervalValue?: number;
|
|
621
|
+
refillIntervalUnit?: 'seconds' | 'minutes' | 'hours' | 'days' | 'weeks' | 'months';
|
|
622
|
+
lastRefill?: Date;
|
|
623
|
+
refillAmount?: number;
|
|
624
|
+
};
|
package/src/web.ts
CHANGED
|
@@ -5,8 +5,8 @@ import type {
|
|
|
5
5
|
SearchProviders,
|
|
6
6
|
TWebSearchConfig,
|
|
7
7
|
} from './config';
|
|
8
|
-
import { extractVariableName } from './utils';
|
|
9
8
|
import { SearchCategories, SafeSearchTypes } from './config';
|
|
9
|
+
import { extractVariableName } from './utils';
|
|
10
10
|
import { AuthType } from './schemas';
|
|
11
11
|
|
|
12
12
|
export function loadWebSearchConfig(
|
|
@@ -64,23 +64,29 @@ export const webSearchAuth = {
|
|
|
64
64
|
/**
|
|
65
65
|
* Extracts all API keys from the webSearchAuth configuration object
|
|
66
66
|
*/
|
|
67
|
-
export
|
|
67
|
+
export function getWebSearchKeys(): TWebSearchKeys[] {
|
|
68
|
+
const keys: TWebSearchKeys[] = [];
|
|
68
69
|
|
|
69
|
-
// Iterate through each category (providers, scrapers, rerankers)
|
|
70
|
-
for (const category of Object.keys(webSearchAuth)) {
|
|
71
|
-
|
|
70
|
+
// Iterate through each category (providers, scrapers, rerankers)
|
|
71
|
+
for (const category of Object.keys(webSearchAuth)) {
|
|
72
|
+
const categoryObj = webSearchAuth[category as TWebSearchCategories];
|
|
72
73
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
74
|
+
// Iterate through each service within the category
|
|
75
|
+
for (const service of Object.keys(categoryObj)) {
|
|
76
|
+
const serviceObj = categoryObj[service as keyof typeof categoryObj];
|
|
76
77
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
78
|
+
// Extract the API keys from the service
|
|
79
|
+
for (const key of Object.keys(serviceObj)) {
|
|
80
|
+
keys.push(key as TWebSearchKeys);
|
|
81
|
+
}
|
|
80
82
|
}
|
|
81
83
|
}
|
|
84
|
+
|
|
85
|
+
return keys;
|
|
82
86
|
}
|
|
83
87
|
|
|
88
|
+
export const webSearchKeys: TWebSearchKeys[] = getWebSearchKeys();
|
|
89
|
+
|
|
84
90
|
export function extractWebSearchEnvVars({
|
|
85
91
|
keys,
|
|
86
92
|
config,
|