librechat-data-provider 0.7.4 → 0.7.7

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.
Files changed (49) hide show
  1. package/check_updates.sh +1 -0
  2. package/dist/index.es.js +1 -1
  3. package/dist/index.es.js.map +1 -1
  4. package/dist/index.js +1 -1
  5. package/dist/index.js.map +1 -1
  6. package/dist/react-query/index.es.js +1 -1
  7. package/dist/react-query/index.es.js.map +1 -1
  8. package/dist/react-query/package.json +1 -1
  9. package/package.json +6 -6
  10. package/react-query/package.json +1 -1
  11. package/server-rollup.config.js +3 -3
  12. package/specs/actions.spec.ts +700 -36
  13. package/specs/azure.spec.ts +8 -5
  14. package/specs/filetypes.spec.ts +1 -7
  15. package/specs/mcp.spec.ts +52 -0
  16. package/specs/openapiSpecs.ts +127 -0
  17. package/specs/utils.spec.ts +129 -0
  18. package/src/actions.ts +311 -101
  19. package/src/api-endpoints.ts +70 -13
  20. package/src/artifacts.ts +3104 -0
  21. package/src/azure.ts +40 -33
  22. package/src/bedrock.ts +227 -0
  23. package/src/config.ts +344 -78
  24. package/src/createPayload.ts +3 -1
  25. package/src/data-service.ts +353 -90
  26. package/src/file-config.ts +13 -2
  27. package/src/generate.ts +31 -2
  28. package/src/index.ts +12 -4
  29. package/src/keys.ts +17 -0
  30. package/src/mcp.ts +87 -0
  31. package/src/models.ts +1 -1
  32. package/src/parsers.ts +118 -60
  33. package/src/react-query/react-query-service.ts +54 -115
  34. package/src/request.ts +31 -7
  35. package/src/roles.ts +91 -2
  36. package/src/schemas.ts +513 -340
  37. package/src/types/agents.ts +276 -0
  38. package/src/types/assistants.ts +181 -27
  39. package/src/types/files.ts +6 -0
  40. package/src/types/mutations.ts +170 -7
  41. package/src/types/queries.ts +43 -21
  42. package/src/types/runs.ts +23 -0
  43. package/src/types.ts +132 -67
  44. package/src/utils.ts +44 -0
  45. package/src/zod.spec.ts +526 -0
  46. package/src/zod.ts +86 -0
  47. package/tsconfig.json +1 -2
  48. package/specs/parsers.spec.ts +0 -48
  49. package/src/sse.js +0 -242
package/src/generate.ts CHANGED
@@ -13,10 +13,18 @@ export type ComponentType =
13
13
  | 'checkbox'
14
14
  | 'switch'
15
15
  | 'dropdown'
16
+ | 'combobox'
16
17
  | 'tags';
17
18
 
18
19
  export type OptionType = 'conversation' | 'model' | 'custom';
19
20
 
21
+ export type Option = Record<string, unknown> & {
22
+ label?: string;
23
+ value: string | number | null;
24
+ };
25
+
26
+ export type OptionWithIcon = Option & { icon?: React.ReactNode };
27
+
20
28
  export enum ComponentTypes {
21
29
  Input = 'input',
22
30
  Textarea = 'textarea',
@@ -24,6 +32,7 @@ export enum ComponentTypes {
24
32
  Checkbox = 'checkbox',
25
33
  Switch = 'switch',
26
34
  Dropdown = 'dropdown',
35
+ Combobox = 'combobox',
27
36
  Tags = 'tags',
28
37
  }
29
38
 
@@ -45,6 +54,7 @@ export interface SettingDefinition {
45
54
  description?: string;
46
55
  type: 'number' | 'boolean' | 'string' | 'enum' | 'array';
47
56
  default?: number | boolean | string | string[];
57
+ showLabel?: boolean;
48
58
  showDefault?: boolean;
49
59
  options?: string[];
50
60
  range?: SettingRange;
@@ -64,13 +74,18 @@ export interface SettingDefinition {
64
74
  maxTags?: number; // Specific to tags component
65
75
  includeInput?: boolean; // Specific to slider component
66
76
  descriptionSide?: 'top' | 'right' | 'bottom' | 'left';
77
+ items?: OptionWithIcon[]; // Specific to combobox component
78
+ searchPlaceholder?: string; // Specific to combobox component
79
+ selectPlaceholder?: string; // Specific to combobox component
80
+ searchPlaceholderCode?: boolean; // Specific to combobox component
81
+ selectPlaceholderCode?: boolean; // Specific to combobox component
67
82
  }
68
83
 
69
84
  export type DynamicSettingProps = Partial<SettingDefinition> & {
70
85
  readonly?: boolean;
71
86
  settingKey: string;
72
87
  setOption: TSetOption;
73
- conversation: TConversation | TPreset | null;
88
+ conversation: Partial<TConversation> | Partial<TPreset> | null;
74
89
  defaultValue?: number | boolean | string | string[];
75
90
  className?: string;
76
91
  inputClassName?: string;
@@ -190,6 +205,7 @@ const minColumns = 1;
190
205
  const maxColumns = 4;
191
206
  const minSliderOptions = 2;
192
207
  const minDropdownOptions = 2;
208
+ const minComboboxOptions = 2;
193
209
 
194
210
  /**
195
211
  * Validates the provided setting using the constraints unique to each component type.
@@ -383,9 +399,22 @@ export function validateSettingDefinitions(settings: SettingsConfiguration): voi
383
399
  }
384
400
  }
385
401
 
402
+ if (setting.component === ComponentTypes.Combobox) {
403
+ if (!setting.options || setting.options.length < minComboboxOptions) {
404
+ errors.push({
405
+ code: ZodIssueCode.custom,
406
+ message: `Combobox component for setting ${setting.key} requires at least ${minComboboxOptions} options.`,
407
+ path: ['options'],
408
+ });
409
+ }
410
+ if (!setting.default && setting.options && setting.options.length > 0) {
411
+ setting.default = setting.options[0];
412
+ }
413
+ }
414
+
386
415
  // Default columnSpan
387
416
  if (!setting.columnSpan) {
388
- setting.columnSpan = Math.floor(columns / 2);
417
+ setting.columnSpan = Math.floor((columns ?? 0) / 2);
389
418
  }
390
419
 
391
420
  // Default label to key
package/src/index.ts CHANGED
@@ -1,28 +1,36 @@
1
1
  /* config */
2
2
  export * from './azure';
3
+ export * from './bedrock';
3
4
  export * from './config';
4
5
  export * from './file-config';
6
+ /* artifacts */
7
+ export * from './artifacts';
5
8
  /* schema helpers */
6
9
  export * from './parsers';
10
+ export * from './zod';
7
11
  /* custom/dynamic configurations */
8
- export * from './models';
9
12
  export * from './generate';
13
+ export * from './models';
14
+ /* mcp */
15
+ export * from './mcp';
10
16
  /* RBAC */
11
17
  export * from './roles';
12
18
  /* types (exports schemas from `./types` as they contain needed in other defs) */
13
19
  export * from './types';
20
+ export * from './types/agents';
14
21
  export * from './types/assistants';
15
- export * from './types/queries';
16
22
  export * from './types/files';
17
23
  export * from './types/mutations';
24
+ export * from './types/queries';
25
+ export * from './types/runs';
18
26
  /* query/mutation keys */
19
27
  export * from './keys';
20
28
  /* api call helpers */
21
29
  export * from './headers-helpers';
22
30
  export { default as request } from './request';
23
- import * as dataService from './data-service';
24
31
  export { dataService };
32
+ import * as dataService from './data-service';
25
33
  /* general helpers */
26
- export * from './sse';
34
+ export * from './utils';
27
35
  export * from './actions';
28
36
  export { default as createPayload } from './createPayload';
package/src/keys.ts CHANGED
@@ -19,12 +19,18 @@ export enum QueryKeys {
19
19
  startupConfig = 'startupConfig',
20
20
  assistants = 'assistants',
21
21
  assistant = 'assistant',
22
+ agents = 'agents',
23
+ agent = 'agent',
22
24
  endpointsConfigOverride = 'endpointsConfigOverride',
23
25
  files = 'files',
24
26
  fileConfig = 'fileConfig',
25
27
  tools = 'tools',
28
+ toolAuth = 'toolAuth',
29
+ toolCalls = 'toolCalls',
30
+ agentTools = 'agentTools',
26
31
  actions = 'actions',
27
32
  assistantDocs = 'assistantDocs',
33
+ agentDocs = 'agentDocs',
28
34
  fileDownload = 'fileDownload',
29
35
  voices = 'voices',
30
36
  customConfigSpeech = 'customConfigSpeech',
@@ -36,6 +42,10 @@ export enum QueryKeys {
36
42
  categories = 'categories',
37
43
  randomPrompts = 'randomPrompts',
38
44
  roles = 'roles',
45
+ conversationTags = 'conversationTags',
46
+ health = 'health',
47
+ userTerms = 'userTerms',
48
+ banner = 'banner',
39
49
  }
40
50
 
41
51
  export enum MutationKeys {
@@ -43,13 +53,20 @@ export enum MutationKeys {
43
53
  fileDelete = 'fileDelete',
44
54
  updatePreset = 'updatePreset',
45
55
  deletePreset = 'deletePreset',
56
+ loginUser = 'loginUser',
46
57
  logoutUser = 'logoutUser',
58
+ refreshToken = 'refreshToken',
47
59
  avatarUpload = 'avatarUpload',
48
60
  speechToText = 'speechToText',
49
61
  textToSpeech = 'textToSpeech',
50
62
  assistantAvatarUpload = 'assistantAvatarUpload',
63
+ agentAvatarUpload = 'agentAvatarUpload',
51
64
  updateAction = 'updateAction',
65
+ updateAgentAction = 'updateAgentAction',
52
66
  deleteAction = 'deleteAction',
67
+ deleteAgentAction = 'deleteAgentAction',
53
68
  deleteUser = 'deleteUser',
54
69
  updateRole = 'updateRole',
70
+ enableTwoFactor = 'enableTwoFactor',
71
+ verifyTwoFactor = 'verifyTwoFactor',
55
72
  }
package/src/mcp.ts ADDED
@@ -0,0 +1,87 @@
1
+ import { z } from 'zod';
2
+ import { extractEnvVariable } from './utils';
3
+
4
+ const BaseOptionsSchema = z.object({
5
+ iconPath: z.string().optional(),
6
+ timeout: z.number().optional(),
7
+ });
8
+
9
+ export const StdioOptionsSchema = BaseOptionsSchema.extend({
10
+ type: z.literal('stdio').optional(),
11
+ /**
12
+ * The executable to run to start the server.
13
+ */
14
+ command: z.string(),
15
+ /**
16
+ * Command line arguments to pass to the executable.
17
+ */
18
+ args: z.array(z.string()),
19
+ /**
20
+ * The environment to use when spawning the process.
21
+ *
22
+ * If not specified, the result of getDefaultEnvironment() will be used.
23
+ * Environment variables can be referenced using ${VAR_NAME} syntax.
24
+ */
25
+ env: z
26
+ .record(z.string(), z.string())
27
+ .optional()
28
+ .transform((env) => {
29
+ if (!env) {
30
+ return env;
31
+ }
32
+
33
+ const processedEnv: Record<string, string> = {};
34
+ for (const [key, value] of Object.entries(env)) {
35
+ processedEnv[key] = extractEnvVariable(value);
36
+ }
37
+ return processedEnv;
38
+ }),
39
+ /**
40
+ * How to handle stderr of the child process. This matches the semantics of Node's `child_process.spawn`.
41
+ *
42
+ * @type {import('node:child_process').IOType | import('node:stream').Stream | number}
43
+ *
44
+ * The default is "inherit", meaning messages to stderr will be printed to the parent process's stderr.
45
+ */
46
+ stderr: z.any().optional(),
47
+ });
48
+
49
+ export const WebSocketOptionsSchema = BaseOptionsSchema.extend({
50
+ type: z.literal('websocket').optional(),
51
+ url: z
52
+ .string()
53
+ .url()
54
+ .refine(
55
+ (val) => {
56
+ const protocol = new URL(val).protocol;
57
+ return protocol === 'ws:' || protocol === 'wss:';
58
+ },
59
+ {
60
+ message: 'WebSocket URL must start with ws:// or wss://',
61
+ },
62
+ ),
63
+ });
64
+
65
+ export const SSEOptionsSchema = BaseOptionsSchema.extend({
66
+ type: z.literal('sse').optional(),
67
+ url: z
68
+ .string()
69
+ .url()
70
+ .refine(
71
+ (val) => {
72
+ const protocol = new URL(val).protocol;
73
+ return protocol !== 'ws:' && protocol !== 'wss:';
74
+ },
75
+ {
76
+ message: 'SSE URL must not start with ws:// or wss://',
77
+ },
78
+ ),
79
+ });
80
+
81
+ export const MCPOptionsSchema = z.union([
82
+ StdioOptionsSchema,
83
+ WebSocketOptionsSchema,
84
+ SSEOptionsSchema,
85
+ ]);
86
+
87
+ export const MCPServersSchema = z.record(z.string(), MCPOptionsSchema);
package/src/models.ts CHANGED
@@ -37,7 +37,7 @@ export const tModelSpecSchema = z.object({
37
37
  export const specsConfigSchema = z.object({
38
38
  enforce: z.boolean().default(false),
39
39
  prioritize: z.boolean().default(true),
40
- list: z.array(tModelSpecSchema).optional(),
40
+ list: z.array(tModelSpecSchema).min(1),
41
41
  });
42
42
 
43
43
  export type TSpecsConfig = z.infer<typeof specsConfigSchema>;
package/src/parsers.ts CHANGED
@@ -2,45 +2,48 @@ import type { ZodIssue } from 'zod';
2
2
  import type * as a from './types/assistants';
3
3
  import type * as s from './schemas';
4
4
  import type * as t from './types';
5
- import { ContentTypes } from './types/assistants';
5
+ import { ContentTypes } from './types/runs';
6
6
  import {
7
- EModelEndpoint,
8
7
  openAISchema,
9
8
  googleSchema,
10
- bingAISchema,
9
+ EModelEndpoint,
11
10
  anthropicSchema,
12
- chatGPTBrowserSchema,
13
- gptPluginsSchema,
14
11
  assistantSchema,
15
- compactOpenAISchema,
12
+ gptPluginsSchema,
13
+ // agentsSchema,
14
+ compactAgentsSchema,
16
15
  compactGoogleSchema,
17
- compactAnthropicSchema,
18
16
  compactChatGPTSchema,
17
+ chatGPTBrowserSchema,
19
18
  compactPluginsSchema,
20
19
  compactAssistantSchema,
21
20
  } from './schemas';
21
+ import { bedrockInputSchema } from './bedrock';
22
+ import { extractEnvVariable } from './utils';
22
23
  import { alternateName } from './config';
23
24
 
24
25
  type EndpointSchema =
25
26
  | typeof openAISchema
26
27
  | typeof googleSchema
27
- | typeof bingAISchema
28
28
  | typeof anthropicSchema
29
29
  | typeof chatGPTBrowserSchema
30
30
  | typeof gptPluginsSchema
31
- | typeof assistantSchema;
31
+ | typeof assistantSchema
32
+ | typeof compactAgentsSchema
33
+ | typeof bedrockInputSchema;
32
34
 
33
35
  const endpointSchemas: Record<EModelEndpoint, EndpointSchema> = {
34
36
  [EModelEndpoint.openAI]: openAISchema,
35
37
  [EModelEndpoint.azureOpenAI]: openAISchema,
36
38
  [EModelEndpoint.custom]: openAISchema,
37
39
  [EModelEndpoint.google]: googleSchema,
38
- [EModelEndpoint.bingAI]: bingAISchema,
39
40
  [EModelEndpoint.anthropic]: anthropicSchema,
40
41
  [EModelEndpoint.chatGPTBrowser]: chatGPTBrowserSchema,
41
42
  [EModelEndpoint.gptPlugins]: gptPluginsSchema,
42
43
  [EModelEndpoint.assistants]: assistantSchema,
43
44
  [EModelEndpoint.azureAssistants]: assistantSchema,
45
+ [EModelEndpoint.agents]: compactAgentsSchema,
46
+ [EModelEndpoint.bedrock]: bedrockInputSchema,
44
47
  };
45
48
 
46
49
  // const schemaCreators: Record<EModelEndpoint, (customSchema: DefaultSchemaValues) => EndpointSchema> = {
@@ -51,22 +54,23 @@ const endpointSchemas: Record<EModelEndpoint, EndpointSchema> = {
51
54
  export function getEnabledEndpoints() {
52
55
  const defaultEndpoints: string[] = [
53
56
  EModelEndpoint.openAI,
57
+ EModelEndpoint.agents,
54
58
  EModelEndpoint.assistants,
55
59
  EModelEndpoint.azureAssistants,
56
60
  EModelEndpoint.azureOpenAI,
57
61
  EModelEndpoint.google,
58
- EModelEndpoint.bingAI,
59
62
  EModelEndpoint.chatGPTBrowser,
60
63
  EModelEndpoint.gptPlugins,
61
64
  EModelEndpoint.anthropic,
65
+ EModelEndpoint.bedrock,
62
66
  ];
63
67
 
64
- const endpointsEnv = process.env.ENDPOINTS || '';
68
+ const endpointsEnv = process.env.ENDPOINTS ?? '';
65
69
  let enabledEndpoints = defaultEndpoints;
66
70
  if (endpointsEnv) {
67
71
  enabledEndpoints = endpointsEnv
68
72
  .split(',')
69
- .filter((endpoint) => endpoint?.trim())
73
+ .filter((endpoint) => endpoint.trim())
70
74
  .map((endpoint) => endpoint.trim());
71
75
  }
72
76
  return enabledEndpoints;
@@ -119,17 +123,6 @@ export function errorsToString(errors: ZodIssue[]) {
119
123
  .join(' ');
120
124
  }
121
125
 
122
- export const envVarRegex = /^\${(.+)}$/;
123
-
124
- /** Extracts the value of an environment variable from a string. */
125
- export function extractEnvVariable(value: string) {
126
- const envVarMatch = value.match(envVarRegex);
127
- if (envVarMatch) {
128
- return process.env[envVarMatch[1]] || value;
129
- }
130
- return value;
131
- }
132
-
133
126
  /** Resolves header values to env variables if detected */
134
127
  export function resolveHeaders(headers: Record<string, string> | undefined) {
135
128
  const resolvedHeaders = { ...(headers ?? {}) };
@@ -154,6 +147,15 @@ export function getFirstDefinedValue(possibleValues: string[]) {
154
147
  return returnValue;
155
148
  }
156
149
 
150
+ export function getNonEmptyValue(possibleValues: string[]) {
151
+ for (const value of possibleValues) {
152
+ if (value && value.trim() !== '') {
153
+ return value;
154
+ }
155
+ }
156
+ return undefined;
157
+ }
158
+
157
159
  export type TPossibleValues = {
158
160
  models: string[];
159
161
  secondaryModels?: string[];
@@ -166,13 +168,13 @@ export const parseConvo = ({
166
168
  possibleValues,
167
169
  }: {
168
170
  endpoint: EModelEndpoint;
169
- endpointType?: EModelEndpoint;
170
- conversation: Partial<s.TConversation | s.TPreset>;
171
+ endpointType?: EModelEndpoint | null;
172
+ conversation: Partial<s.TConversation | s.TPreset> | null;
171
173
  possibleValues?: TPossibleValues;
172
174
  // TODO: POC for default schema
173
175
  // defaultSchema?: Partial<EndpointSchema>,
174
176
  }) => {
175
- let schema = endpointSchemas[endpoint];
177
+ let schema = endpointSchemas[endpoint] as EndpointSchema | undefined;
176
178
 
177
179
  if (!schema && !endpointType) {
178
180
  throw new Error(`Unknown endpoint: ${endpoint}`);
@@ -184,56 +186,93 @@ export const parseConvo = ({
184
186
  // schema = schemaCreators[endpoint](defaultSchema);
185
187
  // }
186
188
 
187
- const convo = schema.parse(conversation) as s.TConversation;
189
+ const convo = schema?.parse(conversation) as s.TConversation | undefined;
188
190
  const { models, secondaryModels } = possibleValues ?? {};
189
191
 
190
192
  if (models && convo) {
191
193
  convo.model = getFirstDefinedValue(models) ?? convo.model;
192
194
  }
193
195
 
194
- if (secondaryModels && convo.agentOptions) {
196
+ if (secondaryModels && convo?.agentOptions) {
195
197
  convo.agentOptions.model = getFirstDefinedValue(secondaryModels) ?? convo.agentOptions.model;
196
198
  }
197
199
 
198
200
  return convo;
199
201
  };
200
202
 
201
- export const getResponseSender = (endpointOption: t.TEndpointOption): string => {
202
- const { model, endpoint, endpointType, modelDisplayLabel, chatGptLabel, modelLabel, jailbreak } =
203
- endpointOption;
203
+ /** Match GPT followed by digit, optional decimal, and optional suffix
204
+ *
205
+ * Examples: gpt-4, gpt-4o, gpt-4.5, gpt-5a, etc. */
206
+ const extractGPTVersion = (modelStr: string): string => {
207
+ const gptMatch = modelStr.match(/gpt-(\d+(?:\.\d+)?)([a-z])?/i);
208
+ if (gptMatch) {
209
+ const version = gptMatch[1];
210
+ const suffix = gptMatch[2] || '';
211
+ return `GPT-${version}${suffix}`;
212
+ }
213
+ return '';
214
+ };
204
215
 
216
+ /** Match omni models (o1, o3, etc.), "o" followed by a digit, possibly with decimal */
217
+ const extractOmniVersion = (modelStr: string): string => {
218
+ const omniMatch = modelStr.match(/\bo(\d+(?:\.\d+)?)\b/i);
219
+ if (omniMatch) {
220
+ const version = omniMatch[1];
221
+ return `o${version}`;
222
+ }
223
+ return '';
224
+ };
225
+
226
+ export const getResponseSender = (endpointOption: t.TEndpointOption): string => {
227
+ const {
228
+ model: _m,
229
+ endpoint,
230
+ endpointType,
231
+ modelDisplayLabel: _mdl,
232
+ chatGptLabel: _cgl,
233
+ modelLabel: _ml,
234
+ } = endpointOption;
235
+
236
+ const model = _m ?? '';
237
+ const modelDisplayLabel = _mdl ?? '';
238
+ const chatGptLabel = _cgl ?? '';
239
+ const modelLabel = _ml ?? '';
205
240
  if (
206
241
  [
207
242
  EModelEndpoint.openAI,
208
- EModelEndpoint.azureOpenAI,
243
+ EModelEndpoint.bedrock,
209
244
  EModelEndpoint.gptPlugins,
245
+ EModelEndpoint.azureOpenAI,
210
246
  EModelEndpoint.chatGPTBrowser,
211
247
  ].includes(endpoint)
212
248
  ) {
213
249
  if (chatGptLabel) {
214
250
  return chatGptLabel;
215
- } else if (model && model.includes('gpt-3')) {
216
- return 'GPT-3.5';
217
- } else if (model && model.includes('gpt-4')) {
218
- return 'GPT-4';
251
+ } else if (modelLabel) {
252
+ return modelLabel;
253
+ } else if (model && extractOmniVersion(model)) {
254
+ return extractOmniVersion(model);
219
255
  } else if (model && model.includes('mistral')) {
220
256
  return 'Mistral';
257
+ } else if (model && model.includes('gpt-')) {
258
+ const gptVersion = extractGPTVersion(model);
259
+ return gptVersion || 'GPT';
221
260
  }
222
- return alternateName[endpoint] ?? 'ChatGPT';
261
+ return (alternateName[endpoint] as string | undefined) ?? 'ChatGPT';
223
262
  }
224
263
 
225
- if (endpoint === EModelEndpoint.bingAI) {
226
- return jailbreak ? 'Sydney' : 'BingAI';
264
+ if (endpoint === EModelEndpoint.anthropic) {
265
+ return modelLabel || 'Claude';
227
266
  }
228
267
 
229
- if (endpoint === EModelEndpoint.anthropic) {
230
- return modelLabel ?? 'Claude';
268
+ if (endpoint === EModelEndpoint.bedrock) {
269
+ return modelLabel || alternateName[endpoint];
231
270
  }
232
271
 
233
272
  if (endpoint === EModelEndpoint.google) {
234
273
  if (modelLabel) {
235
274
  return modelLabel;
236
- } else if (model && model.includes('gemini')) {
275
+ } else if (model && (model.includes('gemini') || model.includes('learnlm'))) {
237
276
  return 'Gemini';
238
277
  } else if (model && model.includes('code')) {
239
278
  return 'Codey';
@@ -247,12 +286,13 @@ export const getResponseSender = (endpointOption: t.TEndpointOption): string =>
247
286
  return modelLabel;
248
287
  } else if (chatGptLabel) {
249
288
  return chatGptLabel;
289
+ } else if (model && extractOmniVersion(model)) {
290
+ return extractOmniVersion(model);
250
291
  } else if (model && model.includes('mistral')) {
251
292
  return 'Mistral';
252
- } else if (model && model.includes('gpt-3')) {
253
- return 'GPT-3.5';
254
- } else if (model && model.includes('gpt-4')) {
255
- return 'GPT-4';
293
+ } else if (model && model.includes('gpt-')) {
294
+ const gptVersion = extractGPTVersion(model);
295
+ return gptVersion || 'GPT';
256
296
  } else if (modelDisplayLabel) {
257
297
  return modelDisplayLabel;
258
298
  }
@@ -264,24 +304,25 @@ export const getResponseSender = (endpointOption: t.TEndpointOption): string =>
264
304
  };
265
305
 
266
306
  type CompactEndpointSchema =
267
- | typeof compactOpenAISchema
307
+ | typeof openAISchema
268
308
  | typeof compactAssistantSchema
309
+ | typeof compactAgentsSchema
269
310
  | typeof compactGoogleSchema
270
- | typeof bingAISchema
271
- | typeof compactAnthropicSchema
311
+ | typeof anthropicSchema
272
312
  | typeof compactChatGPTSchema
313
+ | typeof bedrockInputSchema
273
314
  | typeof compactPluginsSchema;
274
315
 
275
316
  const compactEndpointSchemas: Record<string, CompactEndpointSchema> = {
276
- [EModelEndpoint.openAI]: compactOpenAISchema,
277
- [EModelEndpoint.azureOpenAI]: compactOpenAISchema,
278
- [EModelEndpoint.custom]: compactOpenAISchema,
317
+ [EModelEndpoint.openAI]: openAISchema,
318
+ [EModelEndpoint.azureOpenAI]: openAISchema,
319
+ [EModelEndpoint.custom]: openAISchema,
279
320
  [EModelEndpoint.assistants]: compactAssistantSchema,
280
321
  [EModelEndpoint.azureAssistants]: compactAssistantSchema,
322
+ [EModelEndpoint.agents]: compactAgentsSchema,
281
323
  [EModelEndpoint.google]: compactGoogleSchema,
282
- /* BingAI needs all fields */
283
- [EModelEndpoint.bingAI]: bingAISchema,
284
- [EModelEndpoint.anthropic]: compactAnthropicSchema,
324
+ [EModelEndpoint.bedrock]: bedrockInputSchema,
325
+ [EModelEndpoint.anthropic]: anthropicSchema,
285
326
  [EModelEndpoint.chatGPTBrowser]: compactChatGPTSchema,
286
327
  [EModelEndpoint.gptPlugins]: compactPluginsSchema,
287
328
  };
@@ -293,7 +334,7 @@ export const parseCompactConvo = ({
293
334
  possibleValues,
294
335
  }: {
295
336
  endpoint?: EModelEndpoint;
296
- endpointType?: EModelEndpoint;
337
+ endpointType?: EModelEndpoint | null;
297
338
  conversation: Partial<s.TConversation | s.TPreset>;
298
339
  possibleValues?: TPossibleValues;
299
340
  // TODO: POC for default schema
@@ -303,7 +344,7 @@ export const parseCompactConvo = ({
303
344
  throw new Error(`undefined endpoint: ${endpoint}`);
304
345
  }
305
346
 
306
- let schema = compactEndpointSchemas[endpoint];
347
+ let schema = compactEndpointSchemas[endpoint] as CompactEndpointSchema | undefined;
307
348
 
308
349
  if (!schema && !endpointType) {
309
350
  throw new Error(`Unknown endpoint: ${endpoint}`);
@@ -311,7 +352,11 @@ export const parseCompactConvo = ({
311
352
  schema = compactEndpointSchemas[endpointType];
312
353
  }
313
354
 
314
- const convo = schema.parse(conversation) as s.TConversation;
355
+ if (!schema) {
356
+ throw new Error(`Unknown endpointType: ${endpointType}`);
357
+ }
358
+
359
+ const convo = schema.parse(conversation) as s.TConversation | null;
315
360
  // const { models, secondaryModels } = possibleValues ?? {};
316
361
  const { models } = possibleValues ?? {};
317
362
 
@@ -331,7 +376,7 @@ export function parseTextParts(contentParts: a.TMessageContentParts[]): string {
331
376
 
332
377
  for (const part of contentParts) {
333
378
  if (part.type === ContentTypes.TEXT) {
334
- const textValue = part.text.value;
379
+ const textValue = typeof part.text === 'string' ? part.text : part.text.value;
335
380
 
336
381
  if (
337
382
  result.length > 0 &&
@@ -347,3 +392,16 @@ export function parseTextParts(contentParts: a.TMessageContentParts[]): string {
347
392
 
348
393
  return result;
349
394
  }
395
+
396
+ export const SEPARATORS = ['.', '?', '!', '۔', '。', '‥', ';', '¡', '¿', '\n', '```'];
397
+
398
+ export function findLastSeparatorIndex(text: string, separators = SEPARATORS): number {
399
+ let lastIndex = -1;
400
+ for (const separator of separators) {
401
+ const index = text.lastIndexOf(separator);
402
+ if (index > lastIndex) {
403
+ lastIndex = index;
404
+ }
405
+ }
406
+ return lastIndex;
407
+ }