librechat-data-provider 0.8.402 → 0.8.404
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/dist/types/accessPermissions.d.ts +744 -0
- package/dist/types/actions.d.ts +118 -0
- package/dist/types/api-endpoints.d.ts +150 -0
- package/dist/types/artifacts.d.ts +97 -0
- package/dist/types/azure.d.ts +22 -0
- package/dist/types/bedrock.d.ts +1220 -0
- package/dist/types/config.d.ts +14849 -0
- package/dist/types/config.spec.d.ts +1 -0
- package/dist/types/createPayload.d.ts +5 -0
- package/dist/types/data-service.d.ts +287 -0
- package/dist/types/feedback.d.ts +36 -0
- package/dist/types/file-config.d.ts +263 -0
- package/dist/types/file-config.spec.d.ts +1 -0
- package/dist/types/generate.d.ts +597 -0
- package/dist/types/headers-helpers.d.ts +2 -0
- package/{src/index.ts → dist/types/index.d.ts} +0 -15
- package/dist/types/keys.d.ts +92 -0
- package/dist/types/mcp.d.ts +2760 -0
- package/dist/types/messages.d.ts +10 -0
- package/dist/types/models.d.ts +1547 -0
- package/dist/types/parameterSettings.d.ts +69 -0
- package/dist/types/parsers.d.ts +110 -0
- package/dist/types/permissions.d.ts +522 -0
- package/dist/types/react-query/react-query-service.d.ts +85 -0
- package/dist/types/request.d.ts +25 -0
- package/dist/types/roles.d.ts +554 -0
- package/dist/types/roles.spec.d.ts +1 -0
- package/dist/types/schemas.d.ts +5110 -0
- package/dist/types/schemas.spec.d.ts +1 -0
- package/dist/types/types/agents.d.ts +433 -0
- package/dist/types/types/assistants.d.ts +547 -0
- package/dist/types/types/files.d.ts +172 -0
- package/dist/types/types/graph.d.ts +135 -0
- package/{src/types/mcpServers.ts → dist/types/types/mcpServers.d.ts} +12 -18
- package/dist/types/types/mutations.d.ts +209 -0
- package/dist/types/types/queries.d.ts +169 -0
- package/dist/types/types/runs.d.ts +36 -0
- package/dist/types/types/web.d.ts +520 -0
- package/dist/types/types.d.ts +503 -0
- package/dist/types/utils.d.ts +12 -0
- package/package.json +5 -1
- package/babel.config.js +0 -4
- package/check_updates.sh +0 -52
- package/jest.config.js +0 -19
- package/react-query/package-lock.json +0 -292
- package/react-query/package.json +0 -10
- package/rollup.config.js +0 -74
- package/server-rollup.config.js +0 -40
- package/specs/actions.spec.ts +0 -2533
- package/specs/api-endpoints-subdir.spec.ts +0 -140
- package/specs/api-endpoints.spec.ts +0 -74
- package/specs/azure.spec.ts +0 -844
- package/specs/bedrock.spec.ts +0 -862
- package/specs/filetypes.spec.ts +0 -175
- package/specs/generate.spec.ts +0 -770
- package/specs/headers-helpers.spec.ts +0 -24
- package/specs/mcp.spec.ts +0 -147
- package/specs/openapiSpecs.ts +0 -524
- package/specs/parsers.spec.ts +0 -601
- package/specs/request-interceptor.spec.ts +0 -304
- package/specs/utils.spec.ts +0 -196
- package/src/accessPermissions.ts +0 -346
- package/src/actions.ts +0 -813
- package/src/api-endpoints.ts +0 -440
- package/src/artifacts.ts +0 -3104
- package/src/azure.ts +0 -328
- package/src/bedrock.ts +0 -425
- package/src/config.spec.ts +0 -315
- package/src/config.ts +0 -2006
- package/src/createPayload.ts +0 -46
- package/src/data-service.ts +0 -1087
- package/src/feedback.ts +0 -141
- package/src/file-config.spec.ts +0 -1248
- package/src/file-config.ts +0 -764
- package/src/generate.ts +0 -634
- package/src/headers-helpers.ts +0 -13
- package/src/keys.ts +0 -99
- package/src/mcp.ts +0 -271
- package/src/messages.ts +0 -50
- package/src/models.ts +0 -69
- package/src/parameterSettings.ts +0 -1111
- package/src/parsers.ts +0 -563
- package/src/permissions.ts +0 -188
- package/src/react-query/react-query-service.ts +0 -566
- package/src/request.ts +0 -171
- package/src/roles.spec.ts +0 -132
- package/src/roles.ts +0 -225
- package/src/schemas.spec.ts +0 -355
- package/src/schemas.ts +0 -1234
- package/src/types/agents.ts +0 -470
- package/src/types/assistants.ts +0 -654
- package/src/types/files.ts +0 -191
- package/src/types/graph.ts +0 -145
- package/src/types/mutations.ts +0 -422
- package/src/types/queries.ts +0 -208
- package/src/types/runs.ts +0 -40
- package/src/types/web.ts +0 -588
- package/src/types.ts +0 -676
- package/src/utils.ts +0 -85
- package/tsconfig.json +0 -28
- package/tsconfig.spec.json +0 -10
- /package/{src/react-query/index.ts → dist/types/react-query/index.d.ts} +0 -0
- /package/{src/types/index.ts → dist/types/types/index.d.ts} +0 -0
package/src/parsers.ts
DELETED
|
@@ -1,563 +0,0 @@
|
|
|
1
|
-
import dayjs from 'dayjs';
|
|
2
|
-
import type { ZodIssue } from 'zod';
|
|
3
|
-
import type * as a from './types/assistants';
|
|
4
|
-
import type * as s from './schemas';
|
|
5
|
-
import type * as t from './types';
|
|
6
|
-
import { ContentTypes } from './types/runs';
|
|
7
|
-
import {
|
|
8
|
-
openAISchema,
|
|
9
|
-
googleSchema,
|
|
10
|
-
EModelEndpoint,
|
|
11
|
-
anthropicSchema,
|
|
12
|
-
assistantSchema,
|
|
13
|
-
// agentsSchema,
|
|
14
|
-
compactAgentsSchema,
|
|
15
|
-
compactGoogleSchema,
|
|
16
|
-
compactAssistantSchema,
|
|
17
|
-
} from './schemas';
|
|
18
|
-
import { bedrockInputSchema } from './bedrock';
|
|
19
|
-
import { alternateName } from './config';
|
|
20
|
-
|
|
21
|
-
type EndpointSchema =
|
|
22
|
-
| typeof openAISchema
|
|
23
|
-
| typeof googleSchema
|
|
24
|
-
| typeof anthropicSchema
|
|
25
|
-
| typeof assistantSchema
|
|
26
|
-
| typeof compactAgentsSchema
|
|
27
|
-
| typeof bedrockInputSchema;
|
|
28
|
-
|
|
29
|
-
export type EndpointSchemaKey = EModelEndpoint;
|
|
30
|
-
|
|
31
|
-
const endpointSchemas: Record<EndpointSchemaKey, EndpointSchema> = {
|
|
32
|
-
[EModelEndpoint.openAI]: openAISchema,
|
|
33
|
-
[EModelEndpoint.azureOpenAI]: openAISchema,
|
|
34
|
-
[EModelEndpoint.custom]: openAISchema,
|
|
35
|
-
[EModelEndpoint.google]: googleSchema,
|
|
36
|
-
[EModelEndpoint.anthropic]: anthropicSchema,
|
|
37
|
-
[EModelEndpoint.assistants]: assistantSchema,
|
|
38
|
-
[EModelEndpoint.azureAssistants]: assistantSchema,
|
|
39
|
-
[EModelEndpoint.agents]: compactAgentsSchema,
|
|
40
|
-
[EModelEndpoint.bedrock]: bedrockInputSchema,
|
|
41
|
-
};
|
|
42
|
-
|
|
43
|
-
// const schemaCreators: Record<EModelEndpoint, (customSchema: DefaultSchemaValues) => EndpointSchema> = {
|
|
44
|
-
// [EModelEndpoint.google]: createGoogleSchema,
|
|
45
|
-
// };
|
|
46
|
-
|
|
47
|
-
/** Get the enabled endpoints from the `ENDPOINTS` environment variable */
|
|
48
|
-
export function getEnabledEndpoints() {
|
|
49
|
-
const defaultEndpoints: string[] = [
|
|
50
|
-
EModelEndpoint.openAI,
|
|
51
|
-
EModelEndpoint.agents,
|
|
52
|
-
EModelEndpoint.assistants,
|
|
53
|
-
EModelEndpoint.azureAssistants,
|
|
54
|
-
EModelEndpoint.azureOpenAI,
|
|
55
|
-
EModelEndpoint.google,
|
|
56
|
-
EModelEndpoint.anthropic,
|
|
57
|
-
EModelEndpoint.bedrock,
|
|
58
|
-
];
|
|
59
|
-
|
|
60
|
-
const endpointsEnv = process.env.ENDPOINTS ?? '';
|
|
61
|
-
let enabledEndpoints = defaultEndpoints;
|
|
62
|
-
if (endpointsEnv) {
|
|
63
|
-
enabledEndpoints = endpointsEnv
|
|
64
|
-
.split(',')
|
|
65
|
-
.filter((endpoint) => endpoint.trim())
|
|
66
|
-
.map((endpoint) => endpoint.trim());
|
|
67
|
-
}
|
|
68
|
-
return enabledEndpoints;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
/** Orders an existing EndpointsConfig object based on enabled endpoint/custom ordering */
|
|
72
|
-
export function orderEndpointsConfig(endpointsConfig: t.TEndpointsConfig) {
|
|
73
|
-
if (!endpointsConfig) {
|
|
74
|
-
return {};
|
|
75
|
-
}
|
|
76
|
-
const enabledEndpoints = getEnabledEndpoints();
|
|
77
|
-
const endpointKeys = Object.keys(endpointsConfig);
|
|
78
|
-
const defaultCustomIndex = enabledEndpoints.indexOf(EModelEndpoint.custom);
|
|
79
|
-
return endpointKeys.reduce(
|
|
80
|
-
(accumulatedConfig: Record<string, t.TConfig | null | undefined>, currentEndpointKey) => {
|
|
81
|
-
const isCustom = !(currentEndpointKey in EModelEndpoint);
|
|
82
|
-
const isEnabled = enabledEndpoints.includes(currentEndpointKey);
|
|
83
|
-
if (!isEnabled && !isCustom) {
|
|
84
|
-
return accumulatedConfig;
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
const index = enabledEndpoints.indexOf(currentEndpointKey);
|
|
88
|
-
|
|
89
|
-
if (isCustom) {
|
|
90
|
-
accumulatedConfig[currentEndpointKey] = {
|
|
91
|
-
order: defaultCustomIndex >= 0 ? defaultCustomIndex : 9999,
|
|
92
|
-
...(endpointsConfig[currentEndpointKey] as Omit<t.TConfig, 'order'> & { order?: number }),
|
|
93
|
-
};
|
|
94
|
-
} else if (endpointsConfig[currentEndpointKey]) {
|
|
95
|
-
accumulatedConfig[currentEndpointKey] = {
|
|
96
|
-
...endpointsConfig[currentEndpointKey],
|
|
97
|
-
order: index,
|
|
98
|
-
};
|
|
99
|
-
}
|
|
100
|
-
return accumulatedConfig;
|
|
101
|
-
},
|
|
102
|
-
{},
|
|
103
|
-
);
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
/** Converts an array of Zod issues into a string. */
|
|
107
|
-
export function errorsToString(errors: ZodIssue[]) {
|
|
108
|
-
return errors
|
|
109
|
-
.map((error) => {
|
|
110
|
-
const field = error.path.join('.');
|
|
111
|
-
const message = error.message;
|
|
112
|
-
|
|
113
|
-
return `${field}: ${message}`;
|
|
114
|
-
})
|
|
115
|
-
.join(' ');
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
export function getFirstDefinedValue(possibleValues: string[]) {
|
|
119
|
-
let returnValue;
|
|
120
|
-
for (const value of possibleValues) {
|
|
121
|
-
if (value) {
|
|
122
|
-
returnValue = value;
|
|
123
|
-
break;
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
return returnValue;
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
export function getNonEmptyValue(possibleValues: string[]) {
|
|
130
|
-
for (const value of possibleValues) {
|
|
131
|
-
if (value && value.trim() !== '') {
|
|
132
|
-
return value;
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
return undefined;
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
export type TPossibleValues = {
|
|
139
|
-
models: string[];
|
|
140
|
-
};
|
|
141
|
-
|
|
142
|
-
export const parseConvo = ({
|
|
143
|
-
endpoint,
|
|
144
|
-
endpointType,
|
|
145
|
-
conversation,
|
|
146
|
-
possibleValues,
|
|
147
|
-
defaultParamsEndpoint,
|
|
148
|
-
}: {
|
|
149
|
-
endpoint: EndpointSchemaKey;
|
|
150
|
-
endpointType?: EndpointSchemaKey | null;
|
|
151
|
-
conversation: Partial<s.TConversation | s.TPreset> | null;
|
|
152
|
-
possibleValues?: TPossibleValues;
|
|
153
|
-
defaultParamsEndpoint?: string | null;
|
|
154
|
-
}) => {
|
|
155
|
-
let schema = endpointSchemas[endpoint] as EndpointSchema | undefined;
|
|
156
|
-
|
|
157
|
-
if (!schema && !endpointType) {
|
|
158
|
-
throw new Error(`Unknown endpoint: ${endpoint}`);
|
|
159
|
-
} else if (!schema) {
|
|
160
|
-
const overrideSchema = defaultParamsEndpoint
|
|
161
|
-
? endpointSchemas[defaultParamsEndpoint as EndpointSchemaKey]
|
|
162
|
-
: undefined;
|
|
163
|
-
schema = overrideSchema ?? (endpointType ? endpointSchemas[endpointType] : undefined);
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
const convo = schema?.parse(conversation) as s.TConversation | undefined;
|
|
167
|
-
const { models } = possibleValues ?? {};
|
|
168
|
-
|
|
169
|
-
if (models && convo) {
|
|
170
|
-
convo.model = getFirstDefinedValue(models) ?? convo.model;
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
return convo;
|
|
174
|
-
};
|
|
175
|
-
|
|
176
|
-
/** Match GPT followed by digit, optional decimal, and optional suffix
|
|
177
|
-
*
|
|
178
|
-
* Examples: gpt-4, gpt-4o, gpt-4.5, gpt-5a, etc. */
|
|
179
|
-
const extractGPTVersion = (modelStr: string): string => {
|
|
180
|
-
const gptMatch = modelStr.match(/gpt-(\d+(?:\.\d+)?)([a-z])?/i);
|
|
181
|
-
if (gptMatch) {
|
|
182
|
-
const version = gptMatch[1];
|
|
183
|
-
const suffix = gptMatch[2] || '';
|
|
184
|
-
return `GPT-${version}${suffix}`;
|
|
185
|
-
}
|
|
186
|
-
return '';
|
|
187
|
-
};
|
|
188
|
-
|
|
189
|
-
/** Match omni models (o1, o3, etc.), "o" followed by a digit, possibly with decimal */
|
|
190
|
-
const extractOmniVersion = (modelStr: string): string => {
|
|
191
|
-
const omniMatch = modelStr.match(/\bo(\d+(?:\.\d+)?)\b/i);
|
|
192
|
-
if (omniMatch) {
|
|
193
|
-
const version = omniMatch[1];
|
|
194
|
-
return `o${version}`;
|
|
195
|
-
}
|
|
196
|
-
return '';
|
|
197
|
-
};
|
|
198
|
-
|
|
199
|
-
export const getResponseSender = (endpointOption: Partial<t.TEndpointOption>): string => {
|
|
200
|
-
const {
|
|
201
|
-
model: _m,
|
|
202
|
-
endpoint: _e,
|
|
203
|
-
endpointType,
|
|
204
|
-
modelDisplayLabel: _mdl,
|
|
205
|
-
chatGptLabel: _cgl,
|
|
206
|
-
modelLabel: _ml,
|
|
207
|
-
} = endpointOption;
|
|
208
|
-
|
|
209
|
-
const endpoint = _e as EModelEndpoint;
|
|
210
|
-
|
|
211
|
-
const model = _m ?? '';
|
|
212
|
-
const modelDisplayLabel = _mdl ?? '';
|
|
213
|
-
const chatGptLabel = _cgl ?? '';
|
|
214
|
-
const modelLabel = _ml ?? '';
|
|
215
|
-
if (
|
|
216
|
-
[EModelEndpoint.openAI, EModelEndpoint.bedrock, EModelEndpoint.azureOpenAI].includes(endpoint)
|
|
217
|
-
) {
|
|
218
|
-
if (modelLabel) {
|
|
219
|
-
return modelLabel;
|
|
220
|
-
} else if (chatGptLabel) {
|
|
221
|
-
// @deprecated - prefer modelLabel
|
|
222
|
-
return chatGptLabel;
|
|
223
|
-
} else if (model && extractOmniVersion(model)) {
|
|
224
|
-
return extractOmniVersion(model);
|
|
225
|
-
} else if (model && (model.includes('mistral') || model.includes('codestral'))) {
|
|
226
|
-
return 'Mistral';
|
|
227
|
-
} else if (model && model.includes('deepseek')) {
|
|
228
|
-
return 'Deepseek';
|
|
229
|
-
} else if (model && model.includes('kimi')) {
|
|
230
|
-
return 'Kimi';
|
|
231
|
-
} else if (model && model.includes('moonshot')) {
|
|
232
|
-
return 'Moonshot';
|
|
233
|
-
} else if (model && model.includes('gpt-')) {
|
|
234
|
-
const gptVersion = extractGPTVersion(model);
|
|
235
|
-
return gptVersion || 'GPT';
|
|
236
|
-
}
|
|
237
|
-
return (alternateName[endpoint] as string | undefined) ?? 'AI';
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
if (endpoint === EModelEndpoint.anthropic) {
|
|
241
|
-
return modelLabel || 'Claude';
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
if (endpoint === EModelEndpoint.bedrock) {
|
|
245
|
-
return modelLabel || alternateName[endpoint];
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
if (endpoint === EModelEndpoint.google) {
|
|
249
|
-
if (modelLabel) {
|
|
250
|
-
return modelLabel;
|
|
251
|
-
} else if (model?.toLowerCase().includes('gemma') === true) {
|
|
252
|
-
return 'Gemma';
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
return 'Gemini';
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
if (endpoint === EModelEndpoint.custom || endpointType === EModelEndpoint.custom) {
|
|
259
|
-
if (modelLabel) {
|
|
260
|
-
return modelLabel;
|
|
261
|
-
} else if (chatGptLabel) {
|
|
262
|
-
// @deprecated - prefer modelLabel
|
|
263
|
-
return chatGptLabel;
|
|
264
|
-
} else if (model && extractOmniVersion(model)) {
|
|
265
|
-
return extractOmniVersion(model);
|
|
266
|
-
} else if (model && (model.includes('mistral') || model.includes('codestral'))) {
|
|
267
|
-
return 'Mistral';
|
|
268
|
-
} else if (model && model.includes('deepseek')) {
|
|
269
|
-
return 'Deepseek';
|
|
270
|
-
} else if (model && model.includes('kimi')) {
|
|
271
|
-
return 'Kimi';
|
|
272
|
-
} else if (model && model.includes('moonshot')) {
|
|
273
|
-
return 'Moonshot';
|
|
274
|
-
} else if (model && model.includes('gpt-')) {
|
|
275
|
-
const gptVersion = extractGPTVersion(model);
|
|
276
|
-
return gptVersion || 'GPT';
|
|
277
|
-
} else if (modelDisplayLabel) {
|
|
278
|
-
return modelDisplayLabel;
|
|
279
|
-
}
|
|
280
|
-
|
|
281
|
-
return 'AI';
|
|
282
|
-
}
|
|
283
|
-
|
|
284
|
-
return '';
|
|
285
|
-
};
|
|
286
|
-
|
|
287
|
-
type CompactEndpointSchema =
|
|
288
|
-
| typeof openAISchema
|
|
289
|
-
| typeof compactAssistantSchema
|
|
290
|
-
| typeof compactAgentsSchema
|
|
291
|
-
| typeof compactGoogleSchema
|
|
292
|
-
| typeof anthropicSchema
|
|
293
|
-
| typeof bedrockInputSchema;
|
|
294
|
-
|
|
295
|
-
const compactEndpointSchemas: Record<EndpointSchemaKey, CompactEndpointSchema> = {
|
|
296
|
-
[EModelEndpoint.openAI]: openAISchema,
|
|
297
|
-
[EModelEndpoint.azureOpenAI]: openAISchema,
|
|
298
|
-
[EModelEndpoint.custom]: openAISchema,
|
|
299
|
-
[EModelEndpoint.assistants]: compactAssistantSchema,
|
|
300
|
-
[EModelEndpoint.azureAssistants]: compactAssistantSchema,
|
|
301
|
-
[EModelEndpoint.agents]: compactAgentsSchema,
|
|
302
|
-
[EModelEndpoint.google]: compactGoogleSchema,
|
|
303
|
-
[EModelEndpoint.bedrock]: bedrockInputSchema,
|
|
304
|
-
[EModelEndpoint.anthropic]: anthropicSchema,
|
|
305
|
-
};
|
|
306
|
-
|
|
307
|
-
export const parseCompactConvo = ({
|
|
308
|
-
endpoint,
|
|
309
|
-
endpointType,
|
|
310
|
-
conversation,
|
|
311
|
-
possibleValues,
|
|
312
|
-
defaultParamsEndpoint,
|
|
313
|
-
}: {
|
|
314
|
-
endpoint?: EndpointSchemaKey;
|
|
315
|
-
endpointType?: EndpointSchemaKey | null;
|
|
316
|
-
conversation: Partial<s.TConversation | s.TPreset>;
|
|
317
|
-
possibleValues?: TPossibleValues;
|
|
318
|
-
defaultParamsEndpoint?: string | null;
|
|
319
|
-
}): Omit<s.TConversation, 'iconURL'> | null => {
|
|
320
|
-
if (!endpoint) {
|
|
321
|
-
throw new Error(`undefined endpoint: ${endpoint}`);
|
|
322
|
-
}
|
|
323
|
-
|
|
324
|
-
let schema = compactEndpointSchemas[endpoint] as CompactEndpointSchema | undefined;
|
|
325
|
-
|
|
326
|
-
if (!schema && !endpointType) {
|
|
327
|
-
throw new Error(`Unknown endpoint: ${endpoint}`);
|
|
328
|
-
} else if (!schema) {
|
|
329
|
-
const overrideSchema = defaultParamsEndpoint
|
|
330
|
-
? compactEndpointSchemas[defaultParamsEndpoint as EndpointSchemaKey]
|
|
331
|
-
: undefined;
|
|
332
|
-
schema = overrideSchema ?? (endpointType ? compactEndpointSchemas[endpointType] : undefined);
|
|
333
|
-
}
|
|
334
|
-
|
|
335
|
-
if (!schema) {
|
|
336
|
-
throw new Error(`Unknown endpointType: ${endpointType}`);
|
|
337
|
-
}
|
|
338
|
-
|
|
339
|
-
// Strip iconURL from input before parsing - it should only be derived server-side
|
|
340
|
-
// from model spec configuration, not accepted from client requests
|
|
341
|
-
const { iconURL: _clientIconURL, ...conversationWithoutIconURL } = conversation;
|
|
342
|
-
|
|
343
|
-
const convo = schema.parse(conversationWithoutIconURL) as s.TConversation | null;
|
|
344
|
-
const { models } = possibleValues ?? {};
|
|
345
|
-
|
|
346
|
-
if (models && convo) {
|
|
347
|
-
convo.model = getFirstDefinedValue(models) ?? convo.model;
|
|
348
|
-
}
|
|
349
|
-
|
|
350
|
-
return convo;
|
|
351
|
-
};
|
|
352
|
-
|
|
353
|
-
export function parseTextParts(
|
|
354
|
-
contentParts: Array<a.TMessageContentParts | undefined>,
|
|
355
|
-
skipReasoning: boolean = false,
|
|
356
|
-
): string {
|
|
357
|
-
let result = '';
|
|
358
|
-
|
|
359
|
-
for (const part of contentParts) {
|
|
360
|
-
if (!part?.type) {
|
|
361
|
-
continue;
|
|
362
|
-
}
|
|
363
|
-
if (part.type === ContentTypes.TEXT) {
|
|
364
|
-
const textValue = (typeof part.text === 'string' ? part.text : part.text?.value) || '';
|
|
365
|
-
|
|
366
|
-
if (
|
|
367
|
-
result.length > 0 &&
|
|
368
|
-
textValue.length > 0 &&
|
|
369
|
-
result[result.length - 1] !== ' ' &&
|
|
370
|
-
textValue[0] !== ' '
|
|
371
|
-
) {
|
|
372
|
-
result += ' ';
|
|
373
|
-
}
|
|
374
|
-
result += textValue;
|
|
375
|
-
} else if (part.type === ContentTypes.THINK && !skipReasoning) {
|
|
376
|
-
const textValue = typeof part.think === 'string' ? part.think : '';
|
|
377
|
-
if (
|
|
378
|
-
result.length > 0 &&
|
|
379
|
-
textValue.length > 0 &&
|
|
380
|
-
result[result.length - 1] !== ' ' &&
|
|
381
|
-
textValue[0] !== ' '
|
|
382
|
-
) {
|
|
383
|
-
result += ' ';
|
|
384
|
-
}
|
|
385
|
-
result += textValue;
|
|
386
|
-
}
|
|
387
|
-
}
|
|
388
|
-
|
|
389
|
-
return result;
|
|
390
|
-
}
|
|
391
|
-
|
|
392
|
-
export const SEPARATORS = ['.', '?', '!', '۔', '。', '‥', ';', '¡', '¿', '\n', '```'];
|
|
393
|
-
|
|
394
|
-
export function findLastSeparatorIndex(text: string, separators = SEPARATORS): number {
|
|
395
|
-
let lastIndex = -1;
|
|
396
|
-
for (const separator of separators) {
|
|
397
|
-
const index = text.lastIndexOf(separator);
|
|
398
|
-
if (index > lastIndex) {
|
|
399
|
-
lastIndex = index;
|
|
400
|
-
}
|
|
401
|
-
}
|
|
402
|
-
return lastIndex;
|
|
403
|
-
}
|
|
404
|
-
|
|
405
|
-
export function replaceSpecialVars({ text, user }: { text: string; user?: t.TUser | null }) {
|
|
406
|
-
let result = text;
|
|
407
|
-
if (!result) {
|
|
408
|
-
return result;
|
|
409
|
-
}
|
|
410
|
-
|
|
411
|
-
const now = dayjs();
|
|
412
|
-
const weekdayName = now.format('dddd');
|
|
413
|
-
|
|
414
|
-
const currentDate = now.format('YYYY-MM-DD');
|
|
415
|
-
result = result.replace(/{{current_date}}/gi, `${currentDate} (${weekdayName})`);
|
|
416
|
-
|
|
417
|
-
const currentDatetime = now.format('YYYY-MM-DD HH:mm:ss Z');
|
|
418
|
-
result = result.replace(/{{current_datetime}}/gi, `${currentDatetime} (${weekdayName})`);
|
|
419
|
-
|
|
420
|
-
const isoDatetime = now.toISOString();
|
|
421
|
-
result = result.replace(/{{iso_datetime}}/gi, isoDatetime);
|
|
422
|
-
|
|
423
|
-
if (user && user.name) {
|
|
424
|
-
result = result.replace(/{{current_user}}/gi, user.name);
|
|
425
|
-
}
|
|
426
|
-
|
|
427
|
-
return result;
|
|
428
|
-
}
|
|
429
|
-
|
|
430
|
-
/**
|
|
431
|
-
* Parsed ephemeral agent ID result
|
|
432
|
-
*/
|
|
433
|
-
export type ParsedEphemeralAgentId = {
|
|
434
|
-
endpoint: string;
|
|
435
|
-
model: string;
|
|
436
|
-
sender?: string;
|
|
437
|
-
index?: number;
|
|
438
|
-
};
|
|
439
|
-
|
|
440
|
-
/**
|
|
441
|
-
* Encodes an ephemeral agent ID from endpoint, model, optional sender, and optional index.
|
|
442
|
-
* Uses __ to replace : (reserved in graph node names) and ___ to separate sender.
|
|
443
|
-
*
|
|
444
|
-
* Format: endpoint__model___sender or endpoint__model___sender____index (if index provided)
|
|
445
|
-
*
|
|
446
|
-
* @example
|
|
447
|
-
* encodeEphemeralAgentId({ endpoint: 'openAI', model: 'gpt-4o', sender: 'GPT-4o' })
|
|
448
|
-
* // => 'openAI__gpt-4o___GPT-4o'
|
|
449
|
-
*
|
|
450
|
-
* @example
|
|
451
|
-
* encodeEphemeralAgentId({ endpoint: 'openAI', model: 'gpt-4o', sender: 'GPT-4o', index: 1 })
|
|
452
|
-
* // => 'openAI__gpt-4o___GPT-4o____1'
|
|
453
|
-
*/
|
|
454
|
-
export function encodeEphemeralAgentId({
|
|
455
|
-
endpoint,
|
|
456
|
-
model,
|
|
457
|
-
sender,
|
|
458
|
-
index,
|
|
459
|
-
}: {
|
|
460
|
-
endpoint: string;
|
|
461
|
-
model: string;
|
|
462
|
-
sender?: string;
|
|
463
|
-
index?: number;
|
|
464
|
-
}): string {
|
|
465
|
-
const base = `${endpoint}:${model}`.replace(/:/g, '__');
|
|
466
|
-
let result = base;
|
|
467
|
-
if (sender) {
|
|
468
|
-
// Use ___ as separator before sender to distinguish from __ in model names
|
|
469
|
-
result = `${base}___${sender.replace(/:/g, '__')}`;
|
|
470
|
-
}
|
|
471
|
-
if (index != null) {
|
|
472
|
-
// Use ____ (4 underscores) as separator for index
|
|
473
|
-
result = `${result}____${index}`;
|
|
474
|
-
}
|
|
475
|
-
return result;
|
|
476
|
-
}
|
|
477
|
-
|
|
478
|
-
/**
|
|
479
|
-
* Parses an ephemeral agent ID back into its components.
|
|
480
|
-
* Returns undefined if the ID doesn't match the expected format.
|
|
481
|
-
*
|
|
482
|
-
* Format: endpoint__model___sender or endpoint__model___sender____index
|
|
483
|
-
* - ____ (4 underscores) separates optional index suffix
|
|
484
|
-
* - ___ (triple underscore) separates model from optional sender
|
|
485
|
-
* - __ (double underscore) replaces : in endpoint/model names
|
|
486
|
-
*
|
|
487
|
-
* @example
|
|
488
|
-
* parseEphemeralAgentId('openAI__gpt-4o___GPT-4o')
|
|
489
|
-
* // => { endpoint: 'openAI', model: 'gpt-4o', sender: 'GPT-4o' }
|
|
490
|
-
*
|
|
491
|
-
* @example
|
|
492
|
-
* parseEphemeralAgentId('openAI__gpt-4o___GPT-4o____1')
|
|
493
|
-
* // => { endpoint: 'openAI', model: 'gpt-4o', sender: 'GPT-4o', index: 1 }
|
|
494
|
-
*/
|
|
495
|
-
export function parseEphemeralAgentId(agentId: string): ParsedEphemeralAgentId | undefined {
|
|
496
|
-
if (!agentId.includes('__')) {
|
|
497
|
-
return undefined;
|
|
498
|
-
}
|
|
499
|
-
|
|
500
|
-
// First check for index suffix (separated by ____)
|
|
501
|
-
let index: number | undefined;
|
|
502
|
-
let workingId = agentId;
|
|
503
|
-
if (agentId.includes('____')) {
|
|
504
|
-
const lastIndexSep = agentId.lastIndexOf('____');
|
|
505
|
-
const indexStr = agentId.slice(lastIndexSep + 4);
|
|
506
|
-
const parsedIndex = parseInt(indexStr, 10);
|
|
507
|
-
if (!isNaN(parsedIndex)) {
|
|
508
|
-
index = parsedIndex;
|
|
509
|
-
workingId = agentId.slice(0, lastIndexSep);
|
|
510
|
-
}
|
|
511
|
-
}
|
|
512
|
-
|
|
513
|
-
// Check for sender (separated by ___)
|
|
514
|
-
let sender: string | undefined;
|
|
515
|
-
let mainPart = workingId;
|
|
516
|
-
if (workingId.includes('___')) {
|
|
517
|
-
const [before, after] = workingId.split('___');
|
|
518
|
-
mainPart = before;
|
|
519
|
-
// Restore colons in sender if any
|
|
520
|
-
sender = after?.replace(/__/g, ':');
|
|
521
|
-
}
|
|
522
|
-
|
|
523
|
-
const [endpoint, ...modelParts] = mainPart.split('__');
|
|
524
|
-
if (!endpoint || modelParts.length === 0) {
|
|
525
|
-
return undefined;
|
|
526
|
-
}
|
|
527
|
-
// Restore colons in model name (model names can contain colons like claude-3:opus)
|
|
528
|
-
const model = modelParts.join(':');
|
|
529
|
-
return { endpoint, model, sender, index };
|
|
530
|
-
}
|
|
531
|
-
|
|
532
|
-
/**
|
|
533
|
-
* Checks if an agent ID represents an ephemeral (non-saved) agent.
|
|
534
|
-
* Real agent IDs always start with "agent_", so anything else is ephemeral.
|
|
535
|
-
*/
|
|
536
|
-
export function isEphemeralAgentId(agentId: string | null | undefined): boolean {
|
|
537
|
-
return !agentId?.startsWith('agent_');
|
|
538
|
-
}
|
|
539
|
-
|
|
540
|
-
/**
|
|
541
|
-
* Strips the index suffix (____N) from an agent ID if present.
|
|
542
|
-
* Works with both ephemeral and real agent IDs.
|
|
543
|
-
*
|
|
544
|
-
* @example
|
|
545
|
-
* stripAgentIdSuffix('agent_abc123____1') // => 'agent_abc123'
|
|
546
|
-
* stripAgentIdSuffix('openAI__gpt-4o___GPT-4o____1') // => 'openAI__gpt-4o___GPT-4o'
|
|
547
|
-
* stripAgentIdSuffix('agent_abc123') // => 'agent_abc123' (unchanged)
|
|
548
|
-
*/
|
|
549
|
-
export function stripAgentIdSuffix(agentId: string): string {
|
|
550
|
-
return agentId.replace(/____\d+$/, '');
|
|
551
|
-
}
|
|
552
|
-
|
|
553
|
-
/**
|
|
554
|
-
* Appends an index suffix (____N) to an agent ID.
|
|
555
|
-
* Used to distinguish parallel agents with the same base ID.
|
|
556
|
-
*
|
|
557
|
-
* @example
|
|
558
|
-
* appendAgentIdSuffix('agent_abc123', 1) // => 'agent_abc123____1'
|
|
559
|
-
* appendAgentIdSuffix('openAI__gpt-4o___GPT-4o', 1) // => 'openAI__gpt-4o___GPT-4o____1'
|
|
560
|
-
*/
|
|
561
|
-
export function appendAgentIdSuffix(agentId: string, index: number): string {
|
|
562
|
-
return `${agentId}____${index}`;
|
|
563
|
-
}
|