@librechat/data-schemas 0.0.22 → 0.0.30
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.cjs +2213 -1579
- package/dist/index.cjs.map +1 -1
- package/dist/index.es.js +2179 -1554
- package/dist/index.es.js.map +1 -1
- package/dist/types/app/agents.d.ts +10 -0
- package/dist/types/app/assistants.d.ts +19 -0
- package/dist/types/app/azure.d.ts +7 -0
- package/dist/types/app/endpoints.d.ts +16 -0
- package/dist/types/app/index.d.ts +6 -0
- package/dist/types/app/interface.d.ts +13 -0
- package/dist/types/app/memory.d.ts +3 -0
- package/dist/types/app/ocr.d.ts +2 -0
- package/dist/types/app/service.d.ts +23 -0
- package/dist/types/app/specs.d.ts +9 -0
- package/dist/types/app/turnstile.d.ts +17 -0
- package/dist/types/app/web.d.ts +41 -0
- package/dist/types/app/web.spec.d.ts +1 -0
- package/dist/types/index.d.ts +1 -0
- package/dist/types/methods/share.d.ts +2 -1
- package/dist/types/methods/token.d.ts +2 -2
- package/dist/types/models/plugins/mongoMeili.d.ts +2 -2
- package/dist/types/schema/share.d.ts +1 -0
- package/dist/types/types/agent.d.ts +3 -0
- package/dist/types/types/app.d.ts +98 -0
- package/dist/types/types/index.d.ts +2 -0
- package/dist/types/types/message.d.ts +1 -0
- package/dist/types/types/role.d.ts +1 -4
- package/dist/types/types/share.d.ts +1 -0
- package/dist/types/types/web.d.ts +3 -0
- package/package.json +4 -4
package/dist/index.es.js
CHANGED
|
@@ -1,1871 +1,2376 @@
|
|
|
1
|
-
import { PermissionBits, FileSources, Constants, PermissionTypes, Permissions, SystemRoles, ResourceType, PrincipalType, PrincipalModel, roleDefaults, AccessRoleIds } from 'librechat-data-provider';
|
|
2
|
-
import jwt from 'jsonwebtoken';
|
|
3
|
-
import { webcrypto } from 'node:crypto';
|
|
4
|
-
import mongoose, { Schema, Types } from 'mongoose';
|
|
1
|
+
import { EModelEndpoint, agentsEndpointSchema, memorySchema, removeNullishValues, SafeSearchTypes, normalizeEndpointName, defaultAssistantsVersion, Capabilities, assistantEndpointSchema, validateAzureGroups, mapModelToAzureConfig, OCRStrategy, getConfigDefaults, PermissionBits, FileSources, Constants, PermissionTypes, Permissions, SystemRoles, ResourceType, PrincipalType, PrincipalModel, roleDefaults, AccessRoleIds } from 'librechat-data-provider';
|
|
5
2
|
import winston from 'winston';
|
|
6
3
|
import 'winston-daily-rotate-file';
|
|
7
4
|
import { klona } from 'klona';
|
|
8
5
|
import path from 'path';
|
|
6
|
+
import jwt from 'jsonwebtoken';
|
|
7
|
+
import { webcrypto } from 'node:crypto';
|
|
8
|
+
import mongoose, { Schema, Types } from 'mongoose';
|
|
9
9
|
import _ from 'lodash';
|
|
10
10
|
import { MeiliSearch } from 'meilisearch';
|
|
11
11
|
import { nanoid } from 'nanoid';
|
|
12
12
|
|
|
13
13
|
/**
|
|
14
|
-
*
|
|
14
|
+
* Sets up the Agents configuration from the config (`librechat.yaml`) file.
|
|
15
|
+
* If no agents config is defined, uses the provided defaults or parses empty object.
|
|
16
|
+
*
|
|
17
|
+
* @param config - The loaded custom configuration.
|
|
18
|
+
* @param [defaultConfig] - Default configuration from getConfigDefaults.
|
|
19
|
+
* @returns The Agents endpoint configuration.
|
|
15
20
|
*/
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
RoleBits[RoleBits["OWNER"] = PermissionBits.VIEW | PermissionBits.EDIT | PermissionBits.DELETE | PermissionBits.SHARE] = "OWNER";
|
|
26
|
-
})(RoleBits || (RoleBits = {}));
|
|
21
|
+
function agentsConfigSetup(config, defaultConfig) {
|
|
22
|
+
var _a;
|
|
23
|
+
const agentsConfig = (_a = config === null || config === void 0 ? void 0 : config.endpoints) === null || _a === void 0 ? void 0 : _a[EModelEndpoint.agents];
|
|
24
|
+
if (!agentsConfig) {
|
|
25
|
+
return defaultConfig || agentsEndpointSchema.parse({});
|
|
26
|
+
}
|
|
27
|
+
const parsedConfig = agentsEndpointSchema.parse(agentsConfig);
|
|
28
|
+
return parsedConfig;
|
|
29
|
+
}
|
|
27
30
|
|
|
28
|
-
|
|
29
|
-
|
|
31
|
+
const hasValidAgent = (agent) => !!agent &&
|
|
32
|
+
(('id' in agent && !!agent.id) ||
|
|
33
|
+
('provider' in agent && 'model' in agent && !!agent.provider && !!agent.model));
|
|
34
|
+
const isDisabled = (config) => !config || config.disabled === true;
|
|
35
|
+
function loadMemoryConfig(config) {
|
|
36
|
+
var _a;
|
|
37
|
+
if (!config)
|
|
38
|
+
return undefined;
|
|
39
|
+
if (isDisabled(config))
|
|
40
|
+
return config;
|
|
41
|
+
if (!hasValidAgent(config.agent)) {
|
|
42
|
+
return { ...config, disabled: true };
|
|
43
|
+
}
|
|
44
|
+
const charLimit = (_a = memorySchema.shape.charLimit.safeParse(config.charLimit).data) !== null && _a !== void 0 ? _a : 10000;
|
|
45
|
+
return { ...config, charLimit };
|
|
30
46
|
}
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
return
|
|
47
|
+
function isMemoryEnabled(config) {
|
|
48
|
+
if (isDisabled(config))
|
|
49
|
+
return false;
|
|
50
|
+
return hasValidAgent(config.agent);
|
|
35
51
|
}
|
|
36
52
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
const
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
53
|
+
/**
|
|
54
|
+
* Loads the default interface object.
|
|
55
|
+
* @param params - The loaded custom configuration.
|
|
56
|
+
* @param params.config - The loaded custom configuration.
|
|
57
|
+
* @param params.configDefaults - The custom configuration default values.
|
|
58
|
+
* @returns default interface object.
|
|
59
|
+
*/
|
|
60
|
+
async function loadDefaultInterface({ config, configDefaults, }) {
|
|
61
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q;
|
|
62
|
+
const { interface: interfaceConfig } = config !== null && config !== void 0 ? config : {};
|
|
63
|
+
const { interface: defaults } = configDefaults;
|
|
64
|
+
const hasModelSpecs = ((_c = (_b = (_a = config === null || config === void 0 ? void 0 : config.modelSpecs) === null || _a === void 0 ? void 0 : _a.list) === null || _b === void 0 ? void 0 : _b.length) !== null && _c !== void 0 ? _c : 0) > 0;
|
|
65
|
+
const includesAddedEndpoints = ((_f = (_e = (_d = config === null || config === void 0 ? void 0 : config.modelSpecs) === null || _d === void 0 ? void 0 : _d.addedEndpoints) === null || _e === void 0 ? void 0 : _e.length) !== null && _f !== void 0 ? _f : 0) > 0;
|
|
66
|
+
const memoryConfig = config === null || config === void 0 ? void 0 : config.memory;
|
|
67
|
+
const memoryEnabled = isMemoryEnabled(memoryConfig);
|
|
68
|
+
/** Only disable memories if memory config is present but disabled/invalid */
|
|
69
|
+
const shouldDisableMemories = memoryConfig && !memoryEnabled;
|
|
70
|
+
const loadedInterface = removeNullishValues({
|
|
71
|
+
// UI elements - use schema defaults
|
|
72
|
+
endpointsMenu: (_g = interfaceConfig === null || interfaceConfig === void 0 ? void 0 : interfaceConfig.endpointsMenu) !== null && _g !== void 0 ? _g : (hasModelSpecs ? false : defaults.endpointsMenu),
|
|
73
|
+
modelSelect: (_h = interfaceConfig === null || interfaceConfig === void 0 ? void 0 : interfaceConfig.modelSelect) !== null && _h !== void 0 ? _h : (hasModelSpecs ? includesAddedEndpoints : defaults.modelSelect),
|
|
74
|
+
parameters: (_j = interfaceConfig === null || interfaceConfig === void 0 ? void 0 : interfaceConfig.parameters) !== null && _j !== void 0 ? _j : (hasModelSpecs ? false : defaults.parameters),
|
|
75
|
+
presets: (_k = interfaceConfig === null || interfaceConfig === void 0 ? void 0 : interfaceConfig.presets) !== null && _k !== void 0 ? _k : (hasModelSpecs ? false : defaults.presets),
|
|
76
|
+
sidePanel: (_l = interfaceConfig === null || interfaceConfig === void 0 ? void 0 : interfaceConfig.sidePanel) !== null && _l !== void 0 ? _l : defaults.sidePanel,
|
|
77
|
+
privacyPolicy: (_m = interfaceConfig === null || interfaceConfig === void 0 ? void 0 : interfaceConfig.privacyPolicy) !== null && _m !== void 0 ? _m : defaults.privacyPolicy,
|
|
78
|
+
termsOfService: (_o = interfaceConfig === null || interfaceConfig === void 0 ? void 0 : interfaceConfig.termsOfService) !== null && _o !== void 0 ? _o : defaults.termsOfService,
|
|
79
|
+
mcpServers: (_p = interfaceConfig === null || interfaceConfig === void 0 ? void 0 : interfaceConfig.mcpServers) !== null && _p !== void 0 ? _p : defaults.mcpServers,
|
|
80
|
+
customWelcome: (_q = interfaceConfig === null || interfaceConfig === void 0 ? void 0 : interfaceConfig.customWelcome) !== null && _q !== void 0 ? _q : defaults.customWelcome,
|
|
81
|
+
// Permissions - only include if explicitly configured
|
|
82
|
+
bookmarks: interfaceConfig === null || interfaceConfig === void 0 ? void 0 : interfaceConfig.bookmarks,
|
|
83
|
+
memories: shouldDisableMemories ? false : interfaceConfig === null || interfaceConfig === void 0 ? void 0 : interfaceConfig.memories,
|
|
84
|
+
prompts: interfaceConfig === null || interfaceConfig === void 0 ? void 0 : interfaceConfig.prompts,
|
|
85
|
+
multiConvo: interfaceConfig === null || interfaceConfig === void 0 ? void 0 : interfaceConfig.multiConvo,
|
|
86
|
+
agents: interfaceConfig === null || interfaceConfig === void 0 ? void 0 : interfaceConfig.agents,
|
|
87
|
+
temporaryChat: interfaceConfig === null || interfaceConfig === void 0 ? void 0 : interfaceConfig.temporaryChat,
|
|
88
|
+
runCode: interfaceConfig === null || interfaceConfig === void 0 ? void 0 : interfaceConfig.runCode,
|
|
89
|
+
webSearch: interfaceConfig === null || interfaceConfig === void 0 ? void 0 : interfaceConfig.webSearch,
|
|
90
|
+
fileSearch: interfaceConfig === null || interfaceConfig === void 0 ? void 0 : interfaceConfig.fileSearch,
|
|
91
|
+
fileCitations: interfaceConfig === null || interfaceConfig === void 0 ? void 0 : interfaceConfig.fileCitations,
|
|
92
|
+
peoplePicker: interfaceConfig === null || interfaceConfig === void 0 ? void 0 : interfaceConfig.peoplePicker,
|
|
93
|
+
marketplace: interfaceConfig === null || interfaceConfig === void 0 ? void 0 : interfaceConfig.marketplace,
|
|
94
|
+
});
|
|
95
|
+
return loadedInterface;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* ESM-native object traversal utility
|
|
100
|
+
* Simplified implementation focused on the forEach use case
|
|
101
|
+
*/
|
|
102
|
+
function isObject(value) {
|
|
103
|
+
if (value === null || typeof value !== 'object') {
|
|
104
|
+
return false;
|
|
105
|
+
}
|
|
106
|
+
// Treat these built-in types as leaf nodes, not objects to traverse
|
|
107
|
+
if (value instanceof Date)
|
|
108
|
+
return false;
|
|
109
|
+
if (value instanceof RegExp)
|
|
110
|
+
return false;
|
|
111
|
+
if (value instanceof Error)
|
|
112
|
+
return false;
|
|
113
|
+
if (value instanceof URL)
|
|
114
|
+
return false;
|
|
115
|
+
// Check for Buffer (Node.js)
|
|
116
|
+
if (typeof Buffer !== 'undefined' && Buffer.isBuffer(value))
|
|
117
|
+
return false;
|
|
118
|
+
// Check for TypedArrays and ArrayBuffer
|
|
119
|
+
if (ArrayBuffer.isView(value))
|
|
120
|
+
return false;
|
|
121
|
+
if (value instanceof ArrayBuffer)
|
|
122
|
+
return false;
|
|
123
|
+
if (value instanceof SharedArrayBuffer)
|
|
124
|
+
return false;
|
|
125
|
+
// Check for other built-in types that shouldn't be traversed
|
|
126
|
+
if (value instanceof Promise)
|
|
127
|
+
return false;
|
|
128
|
+
if (value instanceof WeakMap)
|
|
129
|
+
return false;
|
|
130
|
+
if (value instanceof WeakSet)
|
|
131
|
+
return false;
|
|
132
|
+
if (value instanceof Map)
|
|
133
|
+
return false;
|
|
134
|
+
if (value instanceof Set)
|
|
135
|
+
return false;
|
|
136
|
+
// Check if it's a primitive wrapper object
|
|
137
|
+
const stringTag = Object.prototype.toString.call(value);
|
|
138
|
+
if (stringTag === '[object Boolean]' ||
|
|
139
|
+
stringTag === '[object Number]' ||
|
|
140
|
+
stringTag === '[object String]') {
|
|
141
|
+
return false;
|
|
142
|
+
}
|
|
143
|
+
return true;
|
|
144
|
+
}
|
|
145
|
+
// Helper to safely set a property on an object or array
|
|
146
|
+
function setProperty(obj, key, value) {
|
|
147
|
+
if (Array.isArray(obj) && typeof key === 'number') {
|
|
148
|
+
obj[key] = value;
|
|
149
|
+
}
|
|
150
|
+
else if (!Array.isArray(obj) && typeof key === 'string') {
|
|
151
|
+
obj[key] = value;
|
|
152
|
+
}
|
|
153
|
+
else if (!Array.isArray(obj) && typeof key === 'number') {
|
|
154
|
+
// Handle numeric keys on objects
|
|
155
|
+
obj[key] = value;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
// Helper to safely delete a property from an object
|
|
159
|
+
function deleteProperty(obj, key) {
|
|
160
|
+
if (Array.isArray(obj) && typeof key === 'number') {
|
|
161
|
+
// For arrays, we should use splice, but this is handled in remove()
|
|
162
|
+
// This function is only called for non-array deletion
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
if (!Array.isArray(obj)) {
|
|
166
|
+
delete obj[key];
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
function forEach(obj, callback) {
|
|
170
|
+
const visited = new WeakSet();
|
|
171
|
+
function walk(node, path = [], parent) {
|
|
172
|
+
// Check for circular references
|
|
173
|
+
let circular = null;
|
|
174
|
+
if (isObject(node)) {
|
|
175
|
+
if (visited.has(node)) {
|
|
176
|
+
// Find the circular reference in the parent chain
|
|
177
|
+
let p = parent;
|
|
178
|
+
while (p) {
|
|
179
|
+
if (p.node === node) {
|
|
180
|
+
circular = p;
|
|
181
|
+
break;
|
|
182
|
+
}
|
|
183
|
+
p = p.parent;
|
|
184
|
+
}
|
|
185
|
+
return; // Skip circular references
|
|
186
|
+
}
|
|
187
|
+
visited.add(node);
|
|
188
|
+
}
|
|
189
|
+
const key = path.length > 0 ? path[path.length - 1] : undefined;
|
|
190
|
+
const isRoot = path.length === 0;
|
|
191
|
+
const level = path.length;
|
|
192
|
+
// Determine if this is a leaf node
|
|
193
|
+
const isLeaf = !isObject(node) ||
|
|
194
|
+
(Array.isArray(node) && node.length === 0) ||
|
|
195
|
+
Object.keys(node).length === 0;
|
|
196
|
+
// Create context
|
|
197
|
+
const context = {
|
|
198
|
+
node,
|
|
199
|
+
path: [...path],
|
|
200
|
+
parent,
|
|
201
|
+
key,
|
|
202
|
+
isLeaf,
|
|
203
|
+
notLeaf: !isLeaf,
|
|
204
|
+
isRoot,
|
|
205
|
+
notRoot: !isRoot,
|
|
206
|
+
level,
|
|
207
|
+
circular,
|
|
208
|
+
update(value) {
|
|
209
|
+
if (!isRoot && parent && key !== undefined && isObject(parent.node)) {
|
|
210
|
+
setProperty(parent.node, key, value);
|
|
211
|
+
}
|
|
212
|
+
this.node = value;
|
|
213
|
+
},
|
|
214
|
+
remove() {
|
|
215
|
+
if (!isRoot && parent && key !== undefined && isObject(parent.node)) {
|
|
216
|
+
if (Array.isArray(parent.node) && typeof key === 'number') {
|
|
217
|
+
parent.node.splice(key, 1);
|
|
218
|
+
}
|
|
219
|
+
else {
|
|
220
|
+
deleteProperty(parent.node, key);
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
},
|
|
224
|
+
};
|
|
225
|
+
// Call the callback with the context
|
|
226
|
+
callback.call(context, node);
|
|
227
|
+
// Traverse children if not circular and is an object
|
|
228
|
+
if (!circular && isObject(node) && !isLeaf) {
|
|
229
|
+
if (Array.isArray(node)) {
|
|
230
|
+
for (let i = 0; i < node.length; i++) {
|
|
231
|
+
walk(node[i], [...path, i], context);
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
else {
|
|
235
|
+
for (const [childKey, childValue] of Object.entries(node)) {
|
|
236
|
+
walk(childValue, [...path, childKey], context);
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
walk(obj);
|
|
242
|
+
}
|
|
243
|
+
// Main traverse function that returns an object with forEach method
|
|
244
|
+
function traverse(obj) {
|
|
245
|
+
return {
|
|
246
|
+
forEach(callback) {
|
|
247
|
+
forEach(obj, callback);
|
|
73
248
|
},
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
oauth_client_id: String,
|
|
77
|
-
oauth_client_secret: String,
|
|
78
|
-
},
|
|
79
|
-
});
|
|
249
|
+
};
|
|
250
|
+
}
|
|
80
251
|
|
|
81
|
-
const
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
default: undefined,
|
|
140
|
-
},
|
|
141
|
-
hide_sequential_outputs: {
|
|
142
|
-
type: Boolean,
|
|
143
|
-
},
|
|
144
|
-
end_after_tools: {
|
|
145
|
-
type: Boolean,
|
|
146
|
-
},
|
|
147
|
-
agent_ids: {
|
|
148
|
-
type: [String],
|
|
149
|
-
},
|
|
150
|
-
isCollaborative: {
|
|
151
|
-
type: Boolean,
|
|
152
|
-
default: undefined,
|
|
153
|
-
},
|
|
154
|
-
conversation_starters: {
|
|
155
|
-
type: [String],
|
|
156
|
-
default: [],
|
|
157
|
-
},
|
|
158
|
-
tool_resources: {
|
|
159
|
-
type: Schema.Types.Mixed,
|
|
160
|
-
default: {},
|
|
161
|
-
},
|
|
162
|
-
projectIds: {
|
|
163
|
-
type: [Schema.Types.ObjectId],
|
|
164
|
-
ref: 'Project',
|
|
165
|
-
index: true,
|
|
166
|
-
},
|
|
167
|
-
versions: {
|
|
168
|
-
type: [Schema.Types.Mixed],
|
|
169
|
-
default: [],
|
|
170
|
-
},
|
|
171
|
-
category: {
|
|
172
|
-
type: String,
|
|
173
|
-
trim: true,
|
|
174
|
-
index: true,
|
|
175
|
-
default: 'general',
|
|
176
|
-
},
|
|
177
|
-
support_contact: {
|
|
178
|
-
type: Schema.Types.Mixed,
|
|
179
|
-
default: undefined,
|
|
180
|
-
},
|
|
181
|
-
is_promoted: {
|
|
182
|
-
type: Boolean,
|
|
183
|
-
default: false,
|
|
184
|
-
index: true,
|
|
185
|
-
},
|
|
186
|
-
}, {
|
|
187
|
-
timestamps: true,
|
|
252
|
+
const SPLAT_SYMBOL = Symbol.for('splat');
|
|
253
|
+
const MESSAGE_SYMBOL = Symbol.for('message');
|
|
254
|
+
const CONSOLE_JSON_STRING_LENGTH = parseInt(process.env.CONSOLE_JSON_STRING_LENGTH || '', 10) || 255;
|
|
255
|
+
const DEBUG_MESSAGE_LENGTH = parseInt(process.env.DEBUG_MESSAGE_LENGTH || '', 10) || 150;
|
|
256
|
+
const sensitiveKeys = [
|
|
257
|
+
/^(sk-)[^\s]+/, // OpenAI API key pattern
|
|
258
|
+
/(Bearer )[^\s]+/, // Header: Bearer token pattern
|
|
259
|
+
/(api-key:? )[^\s]+/, // Header: API key pattern
|
|
260
|
+
/(key=)[^\s]+/, // URL query param: sensitive key pattern (Google)
|
|
261
|
+
];
|
|
262
|
+
/**
|
|
263
|
+
* Determines if a given value string is sensitive and returns matching regex patterns.
|
|
264
|
+
*
|
|
265
|
+
* @param valueStr - The value string to check.
|
|
266
|
+
* @returns An array of regex patterns that match the value string.
|
|
267
|
+
*/
|
|
268
|
+
function getMatchingSensitivePatterns(valueStr) {
|
|
269
|
+
if (valueStr) {
|
|
270
|
+
// Filter and return all regex patterns that match the value string
|
|
271
|
+
return sensitiveKeys.filter((regex) => regex.test(valueStr));
|
|
272
|
+
}
|
|
273
|
+
return [];
|
|
274
|
+
}
|
|
275
|
+
/**
|
|
276
|
+
* Redacts sensitive information from a console message and trims it to a specified length if provided.
|
|
277
|
+
* @param str - The console message to be redacted.
|
|
278
|
+
* @param trimLength - The optional length at which to trim the redacted message.
|
|
279
|
+
* @returns The redacted and optionally trimmed console message.
|
|
280
|
+
*/
|
|
281
|
+
function redactMessage(str, trimLength) {
|
|
282
|
+
if (!str) {
|
|
283
|
+
return '';
|
|
284
|
+
}
|
|
285
|
+
const patterns = getMatchingSensitivePatterns(str);
|
|
286
|
+
patterns.forEach((pattern) => {
|
|
287
|
+
str = str.replace(pattern, '$1[REDACTED]');
|
|
288
|
+
});
|
|
289
|
+
return str;
|
|
290
|
+
}
|
|
291
|
+
/**
|
|
292
|
+
* Redacts sensitive information from log messages if the log level is 'error'.
|
|
293
|
+
* Note: Intentionally mutates the object.
|
|
294
|
+
* @param info - The log information object.
|
|
295
|
+
* @returns The modified log information object.
|
|
296
|
+
*/
|
|
297
|
+
const redactFormat = winston.format((info) => {
|
|
298
|
+
if (info.level === 'error') {
|
|
299
|
+
// Type guard to ensure message is a string
|
|
300
|
+
if (typeof info.message === 'string') {
|
|
301
|
+
info.message = redactMessage(info.message);
|
|
302
|
+
}
|
|
303
|
+
// Handle MESSAGE_SYMBOL with type safety
|
|
304
|
+
const symbolValue = info[MESSAGE_SYMBOL];
|
|
305
|
+
if (typeof symbolValue === 'string') {
|
|
306
|
+
info[MESSAGE_SYMBOL] = redactMessage(symbolValue);
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
return info;
|
|
188
310
|
});
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
311
|
+
/**
|
|
312
|
+
* Truncates long strings, especially base64 image data, within log messages.
|
|
313
|
+
*
|
|
314
|
+
* @param value - The value to be inspected and potentially truncated.
|
|
315
|
+
* @param length - The length at which to truncate the value. Default: 100.
|
|
316
|
+
* @returns The truncated or original value.
|
|
317
|
+
*/
|
|
318
|
+
const truncateLongStrings = (value, length = 100) => {
|
|
319
|
+
if (typeof value === 'string') {
|
|
320
|
+
return value.length > length ? value.substring(0, length) + '... [truncated]' : value;
|
|
321
|
+
}
|
|
322
|
+
return value;
|
|
323
|
+
};
|
|
324
|
+
/**
|
|
325
|
+
* An array mapping function that truncates long strings (objects converted to JSON strings).
|
|
326
|
+
* @param item - The item to be condensed.
|
|
327
|
+
* @returns The condensed item.
|
|
328
|
+
*/
|
|
329
|
+
const condenseArray = (item) => {
|
|
330
|
+
if (typeof item === 'string') {
|
|
331
|
+
return truncateLongStrings(JSON.stringify(item));
|
|
332
|
+
}
|
|
333
|
+
else if (typeof item === 'object') {
|
|
334
|
+
return truncateLongStrings(JSON.stringify(item));
|
|
335
|
+
}
|
|
336
|
+
return item;
|
|
337
|
+
};
|
|
338
|
+
/**
|
|
339
|
+
* Formats log messages for debugging purposes.
|
|
340
|
+
* - Truncates long strings within log messages.
|
|
341
|
+
* - Condenses arrays by truncating long strings and objects as strings within array items.
|
|
342
|
+
* - Redacts sensitive information from log messages if the log level is 'error'.
|
|
343
|
+
* - Converts log information object to a formatted string.
|
|
344
|
+
*
|
|
345
|
+
* @param options - The options for formatting log messages.
|
|
346
|
+
* @returns The formatted log message.
|
|
347
|
+
*/
|
|
348
|
+
const debugTraverse = winston.format.printf(({ level, message, timestamp, ...metadata }) => {
|
|
349
|
+
if (!message) {
|
|
350
|
+
return `${timestamp} ${level}`;
|
|
351
|
+
}
|
|
352
|
+
// Type-safe version of the CJS logic: !message?.trim || typeof message !== 'string'
|
|
353
|
+
if (typeof message !== 'string' || !message.trim) {
|
|
354
|
+
return `${timestamp} ${level}: ${JSON.stringify(message)}`;
|
|
355
|
+
}
|
|
356
|
+
const msgParts = [
|
|
357
|
+
`${timestamp} ${level}: ${truncateLongStrings(message.trim(), DEBUG_MESSAGE_LENGTH)}`,
|
|
358
|
+
];
|
|
359
|
+
try {
|
|
360
|
+
if (level !== 'debug') {
|
|
361
|
+
return msgParts[0];
|
|
362
|
+
}
|
|
363
|
+
if (!metadata) {
|
|
364
|
+
return msgParts[0];
|
|
365
|
+
}
|
|
366
|
+
// Type-safe access to SPLAT_SYMBOL using bracket notation
|
|
367
|
+
const metadataRecord = metadata;
|
|
368
|
+
const splatArray = metadataRecord[SPLAT_SYMBOL];
|
|
369
|
+
const debugValue = Array.isArray(splatArray) ? splatArray[0] : undefined;
|
|
370
|
+
if (!debugValue) {
|
|
371
|
+
return msgParts[0];
|
|
372
|
+
}
|
|
373
|
+
if (debugValue && Array.isArray(debugValue)) {
|
|
374
|
+
msgParts.push(`\n${JSON.stringify(debugValue.map(condenseArray))}`);
|
|
375
|
+
return msgParts.join('');
|
|
376
|
+
}
|
|
377
|
+
if (typeof debugValue !== 'object') {
|
|
378
|
+
msgParts.push(` ${debugValue}`);
|
|
379
|
+
return msgParts.join('');
|
|
380
|
+
}
|
|
381
|
+
msgParts.push('\n{');
|
|
382
|
+
const copy = klona(metadata);
|
|
383
|
+
try {
|
|
384
|
+
const traversal = traverse(copy);
|
|
385
|
+
traversal.forEach(function (value) {
|
|
386
|
+
var _a;
|
|
387
|
+
if (typeof (this === null || this === void 0 ? void 0 : this.key) === 'symbol') {
|
|
388
|
+
return;
|
|
389
|
+
}
|
|
390
|
+
let _parentKey = '';
|
|
391
|
+
const parent = this.parent;
|
|
392
|
+
if (typeof (parent === null || parent === void 0 ? void 0 : parent.key) !== 'symbol' && (parent === null || parent === void 0 ? void 0 : parent.key) !== undefined) {
|
|
393
|
+
_parentKey = String(parent.key);
|
|
394
|
+
}
|
|
395
|
+
const parentKey = `${parent && parent.notRoot ? _parentKey + '.' : ''}`;
|
|
396
|
+
const tabs = `${parent && parent.notRoot ? ' ' : ' '}`;
|
|
397
|
+
const currentKey = (_a = this === null || this === void 0 ? void 0 : this.key) !== null && _a !== void 0 ? _a : 'unknown';
|
|
398
|
+
if (this.isLeaf && typeof value === 'string') {
|
|
399
|
+
const truncatedText = truncateLongStrings(value);
|
|
400
|
+
msgParts.push(`\n${tabs}${parentKey}${currentKey}: ${JSON.stringify(truncatedText)},`);
|
|
401
|
+
}
|
|
402
|
+
else if (this.notLeaf && Array.isArray(value) && value.length > 0) {
|
|
403
|
+
const currentMessage = `\n${tabs}// ${value.length} ${String(currentKey).replace(/s$/, '')}(s)`;
|
|
404
|
+
this.update(currentMessage);
|
|
405
|
+
msgParts.push(currentMessage);
|
|
406
|
+
const stringifiedArray = value.map(condenseArray);
|
|
407
|
+
msgParts.push(`\n${tabs}${parentKey}${currentKey}: [${stringifiedArray}],`);
|
|
408
|
+
}
|
|
409
|
+
else if (this.isLeaf && typeof value === 'function') {
|
|
410
|
+
msgParts.push(`\n${tabs}${parentKey}${currentKey}: function,`);
|
|
411
|
+
}
|
|
412
|
+
else if (this.isLeaf) {
|
|
413
|
+
msgParts.push(`\n${tabs}${parentKey}${currentKey}: ${value},`);
|
|
414
|
+
}
|
|
415
|
+
});
|
|
416
|
+
}
|
|
417
|
+
catch (e) {
|
|
418
|
+
const errorMessage = e instanceof Error ? e.message : 'Unknown error';
|
|
419
|
+
msgParts.push(`\n[LOGGER TRAVERSAL ERROR] ${errorMessage}`);
|
|
420
|
+
}
|
|
421
|
+
msgParts.push('\n}');
|
|
422
|
+
return msgParts.join('');
|
|
423
|
+
}
|
|
424
|
+
catch (e) {
|
|
425
|
+
const errorMessage = e instanceof Error ? e.message : 'Unknown error';
|
|
426
|
+
msgParts.push(`\n[LOGGER PARSING ERROR] ${errorMessage}`);
|
|
427
|
+
return msgParts.join('');
|
|
428
|
+
}
|
|
429
|
+
});
|
|
430
|
+
/**
|
|
431
|
+
* Truncates long string values in JSON log objects.
|
|
432
|
+
* Prevents outputting extremely long values (e.g., base64, blobs).
|
|
433
|
+
*/
|
|
434
|
+
const jsonTruncateFormat = winston.format((info) => {
|
|
435
|
+
const truncateLongStrings = (str, maxLength) => str.length > maxLength ? str.substring(0, maxLength) + '...' : str;
|
|
436
|
+
const seen = new WeakSet();
|
|
437
|
+
const truncateObject = (obj) => {
|
|
438
|
+
if (typeof obj !== 'object' || obj === null) {
|
|
439
|
+
return obj;
|
|
440
|
+
}
|
|
441
|
+
// Handle circular references - now with proper object type
|
|
442
|
+
if (seen.has(obj)) {
|
|
443
|
+
return '[Circular]';
|
|
444
|
+
}
|
|
445
|
+
seen.add(obj);
|
|
446
|
+
if (Array.isArray(obj)) {
|
|
447
|
+
return obj.map((item) => truncateObject(item));
|
|
448
|
+
}
|
|
449
|
+
// We know this is an object at this point
|
|
450
|
+
const objectRecord = obj;
|
|
451
|
+
const newObj = {};
|
|
452
|
+
Object.entries(objectRecord).forEach(([key, value]) => {
|
|
453
|
+
if (typeof value === 'string') {
|
|
454
|
+
newObj[key] = truncateLongStrings(value, CONSOLE_JSON_STRING_LENGTH);
|
|
455
|
+
}
|
|
456
|
+
else {
|
|
457
|
+
newObj[key] = truncateObject(value);
|
|
458
|
+
}
|
|
459
|
+
});
|
|
460
|
+
return newObj;
|
|
461
|
+
};
|
|
462
|
+
return truncateObject(info);
|
|
226
463
|
});
|
|
227
|
-
agentCategorySchema.index({ isActive: 1, order: 1 });
|
|
228
|
-
agentCategorySchema.index({ order: 1, label: 1 });
|
|
229
464
|
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
465
|
+
/**
|
|
466
|
+
* Determine the log directory in a cross-compatible way.
|
|
467
|
+
* Priority:
|
|
468
|
+
* 1. LIBRECHAT_LOG_DIR environment variable
|
|
469
|
+
* 2. If running within LibreChat monorepo (when cwd ends with /api), use api/logs
|
|
470
|
+
* 3. If api/logs exists relative to cwd, use that (for running from project root)
|
|
471
|
+
* 4. Otherwise, use logs directory relative to process.cwd()
|
|
472
|
+
*
|
|
473
|
+
* This avoids using __dirname which is not available in ESM modules
|
|
474
|
+
*/
|
|
475
|
+
const getLogDirectory = () => {
|
|
476
|
+
if (process.env.LIBRECHAT_LOG_DIR) {
|
|
477
|
+
return process.env.LIBRECHAT_LOG_DIR;
|
|
478
|
+
}
|
|
479
|
+
const cwd = process.cwd();
|
|
480
|
+
// Check if we're running from within the api directory
|
|
481
|
+
if (cwd.endsWith('/api') || cwd.endsWith('\\api')) {
|
|
482
|
+
return path.join(cwd, 'logs');
|
|
483
|
+
}
|
|
484
|
+
// Check if api/logs exists relative to current directory (running from project root)
|
|
485
|
+
// We'll just use the path and let the file system create it if needed
|
|
486
|
+
const apiLogsPath = path.join(cwd, 'api', 'logs');
|
|
487
|
+
// For LibreChat project structure, use api/logs
|
|
488
|
+
// For external consumers, they should set LIBRECHAT_LOG_DIR
|
|
489
|
+
if (cwd.includes('LibreChat')) {
|
|
490
|
+
return apiLogsPath;
|
|
491
|
+
}
|
|
492
|
+
// Default to logs directory relative to current working directory
|
|
493
|
+
return path.join(cwd, 'logs');
|
|
494
|
+
};
|
|
495
|
+
|
|
496
|
+
const logDir$1 = getLogDirectory();
|
|
497
|
+
const { NODE_ENV: NODE_ENV$1, DEBUG_LOGGING: DEBUG_LOGGING$1, CONSOLE_JSON, DEBUG_CONSOLE } = process.env;
|
|
498
|
+
const useConsoleJson = typeof CONSOLE_JSON === 'string' && CONSOLE_JSON.toLowerCase() === 'true';
|
|
499
|
+
const useDebugConsole = typeof DEBUG_CONSOLE === 'string' && DEBUG_CONSOLE.toLowerCase() === 'true';
|
|
500
|
+
const useDebugLogging$1 = typeof DEBUG_LOGGING$1 === 'string' && DEBUG_LOGGING$1.toLowerCase() === 'true';
|
|
501
|
+
const levels$1 = {
|
|
502
|
+
error: 0,
|
|
503
|
+
warn: 1,
|
|
504
|
+
info: 2,
|
|
505
|
+
http: 3,
|
|
506
|
+
verbose: 4,
|
|
507
|
+
debug: 5,
|
|
508
|
+
activity: 6,
|
|
509
|
+
silly: 7,
|
|
510
|
+
};
|
|
511
|
+
winston.addColors({
|
|
512
|
+
info: 'green',
|
|
513
|
+
warn: 'italic yellow',
|
|
514
|
+
error: 'red',
|
|
515
|
+
debug: 'blue',
|
|
516
|
+
});
|
|
517
|
+
const level$1 = () => {
|
|
518
|
+
const env = NODE_ENV$1 || 'development';
|
|
519
|
+
return env === 'development' ? 'debug' : 'warn';
|
|
520
|
+
};
|
|
521
|
+
const fileFormat$1 = winston.format.combine(redactFormat(), winston.format.timestamp({ format: () => new Date().toISOString() }), winston.format.errors({ stack: true }), winston.format.splat());
|
|
522
|
+
const transports$1 = [
|
|
523
|
+
new winston.transports.DailyRotateFile({
|
|
524
|
+
level: 'error',
|
|
525
|
+
filename: `${logDir$1}/error-%DATE%.log`,
|
|
526
|
+
datePattern: 'YYYY-MM-DD',
|
|
527
|
+
zippedArchive: true,
|
|
528
|
+
maxSize: '20m',
|
|
529
|
+
maxFiles: '14d',
|
|
530
|
+
format: winston.format.combine(fileFormat$1, winston.format.json()),
|
|
531
|
+
}),
|
|
532
|
+
];
|
|
533
|
+
if (useDebugLogging$1) {
|
|
534
|
+
transports$1.push(new winston.transports.DailyRotateFile({
|
|
535
|
+
level: 'debug',
|
|
536
|
+
filename: `${logDir$1}/debug-%DATE%.log`,
|
|
537
|
+
datePattern: 'YYYY-MM-DD',
|
|
538
|
+
zippedArchive: true,
|
|
539
|
+
maxSize: '20m',
|
|
540
|
+
maxFiles: '14d',
|
|
541
|
+
format: winston.format.combine(fileFormat$1, debugTraverse),
|
|
542
|
+
}));
|
|
543
|
+
}
|
|
544
|
+
const consoleFormat$1 = winston.format.combine(redactFormat(), winston.format.colorize({ all: true }), winston.format.timestamp({ format: 'YYYY-MM-DD HH:mm:ss' }), winston.format.printf((info) => {
|
|
545
|
+
const message = `${info.timestamp} ${info.level}: ${info.message}`;
|
|
546
|
+
return info.level.includes('error') ? redactMessage(message) : message;
|
|
547
|
+
}));
|
|
548
|
+
let consoleLogLevel = 'info';
|
|
549
|
+
if (useDebugConsole) {
|
|
550
|
+
consoleLogLevel = 'debug';
|
|
551
|
+
}
|
|
552
|
+
// Add console transport
|
|
553
|
+
if (useDebugConsole) {
|
|
554
|
+
transports$1.push(new winston.transports.Console({
|
|
555
|
+
level: consoleLogLevel,
|
|
556
|
+
format: useConsoleJson
|
|
557
|
+
? winston.format.combine(fileFormat$1, jsonTruncateFormat(), winston.format.json())
|
|
558
|
+
: winston.format.combine(fileFormat$1, debugTraverse),
|
|
559
|
+
}));
|
|
560
|
+
}
|
|
561
|
+
else if (useConsoleJson) {
|
|
562
|
+
transports$1.push(new winston.transports.Console({
|
|
563
|
+
level: consoleLogLevel,
|
|
564
|
+
format: winston.format.combine(fileFormat$1, jsonTruncateFormat(), winston.format.json()),
|
|
565
|
+
}));
|
|
566
|
+
}
|
|
567
|
+
else {
|
|
568
|
+
transports$1.push(new winston.transports.Console({
|
|
569
|
+
level: consoleLogLevel,
|
|
570
|
+
format: consoleFormat$1,
|
|
571
|
+
}));
|
|
572
|
+
}
|
|
573
|
+
// Create logger
|
|
574
|
+
const logger$1 = winston.createLogger({
|
|
575
|
+
level: level$1(),
|
|
576
|
+
levels: levels$1,
|
|
577
|
+
transports: transports$1,
|
|
260
578
|
});
|
|
261
579
|
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
type: Number,
|
|
295
|
-
default: 0,
|
|
296
|
-
},
|
|
297
|
-
});
|
|
580
|
+
/**
|
|
581
|
+
* Loads and maps the Cloudflare Turnstile configuration.
|
|
582
|
+
*
|
|
583
|
+
* Expected config structure:
|
|
584
|
+
*
|
|
585
|
+
* turnstile:
|
|
586
|
+
* siteKey: "your-site-key-here"
|
|
587
|
+
* options:
|
|
588
|
+
* language: "auto" // "auto" or an ISO 639-1 language code (e.g. en)
|
|
589
|
+
* size: "normal" // Options: "normal", "compact", "flexible", or "invisible"
|
|
590
|
+
*
|
|
591
|
+
* @param config - The loaded custom configuration.
|
|
592
|
+
* @param configDefaults - The custom configuration default values.
|
|
593
|
+
* @returns The mapped Turnstile configuration.
|
|
594
|
+
*/
|
|
595
|
+
function loadTurnstileConfig(config, configDefaults) {
|
|
596
|
+
var _a, _b;
|
|
597
|
+
const { turnstile: customTurnstile } = config !== null && config !== void 0 ? config : {};
|
|
598
|
+
const { turnstile: defaults } = configDefaults;
|
|
599
|
+
const loadedTurnstile = removeNullishValues({
|
|
600
|
+
siteKey: (_a = customTurnstile === null || customTurnstile === void 0 ? void 0 : customTurnstile.siteKey) !== null && _a !== void 0 ? _a : defaults === null || defaults === void 0 ? void 0 : defaults.siteKey,
|
|
601
|
+
options: (_b = customTurnstile === null || customTurnstile === void 0 ? void 0 : customTurnstile.options) !== null && _b !== void 0 ? _b : defaults === null || defaults === void 0 ? void 0 : defaults.options,
|
|
602
|
+
});
|
|
603
|
+
const enabled = Boolean(loadedTurnstile.siteKey);
|
|
604
|
+
if (enabled) {
|
|
605
|
+
logger$1.debug('Turnstile is ENABLED with configuration:\n' + JSON.stringify(loadedTurnstile, null, 2));
|
|
606
|
+
}
|
|
607
|
+
else {
|
|
608
|
+
logger$1.debug('Turnstile is DISABLED (no siteKey provided).');
|
|
609
|
+
}
|
|
610
|
+
return loadedTurnstile;
|
|
611
|
+
}
|
|
298
612
|
|
|
299
|
-
const
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
type: Date,
|
|
310
|
-
required: true,
|
|
311
|
-
default: Date.now,
|
|
312
|
-
},
|
|
313
|
-
displayTo: {
|
|
314
|
-
type: Date,
|
|
613
|
+
const webSearchAuth = {
|
|
614
|
+
providers: {
|
|
615
|
+
serper: {
|
|
616
|
+
serperApiKey: 1,
|
|
617
|
+
},
|
|
618
|
+
searxng: {
|
|
619
|
+
searxngInstanceUrl: 1,
|
|
620
|
+
/** Optional (0) */
|
|
621
|
+
searxngApiKey: 0,
|
|
622
|
+
},
|
|
315
623
|
},
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
624
|
+
scrapers: {
|
|
625
|
+
firecrawl: {
|
|
626
|
+
firecrawlApiKey: 1,
|
|
627
|
+
/** Optional (0) */
|
|
628
|
+
firecrawlApiUrl: 0,
|
|
629
|
+
firecrawlVersion: 0,
|
|
630
|
+
},
|
|
631
|
+
serper: {
|
|
632
|
+
serperApiKey: 1,
|
|
633
|
+
},
|
|
320
634
|
},
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
635
|
+
rerankers: {
|
|
636
|
+
jina: {
|
|
637
|
+
jinaApiKey: 1,
|
|
638
|
+
/** Optional (0) */
|
|
639
|
+
jinaApiUrl: 0,
|
|
640
|
+
},
|
|
641
|
+
cohere: { cohereApiKey: 1 },
|
|
324
642
|
},
|
|
325
|
-
}
|
|
643
|
+
};
|
|
644
|
+
/**
|
|
645
|
+
* Extracts all unique API keys from the webSearchAuth configuration object
|
|
646
|
+
*/
|
|
647
|
+
function getWebSearchKeys() {
|
|
648
|
+
const keysSet = new Set();
|
|
649
|
+
// Iterate through each category (providers, scrapers, rerankers)
|
|
650
|
+
for (const category of Object.keys(webSearchAuth)) {
|
|
651
|
+
const categoryObj = webSearchAuth[category];
|
|
652
|
+
// Iterate through each service within the category
|
|
653
|
+
for (const service of Object.keys(categoryObj)) {
|
|
654
|
+
const serviceObj = categoryObj[service];
|
|
655
|
+
// Extract the API keys from the service and add to set for deduplication
|
|
656
|
+
for (const key of Object.keys(serviceObj)) {
|
|
657
|
+
keysSet.add(key);
|
|
658
|
+
}
|
|
659
|
+
}
|
|
660
|
+
}
|
|
661
|
+
return Array.from(keysSet);
|
|
662
|
+
}
|
|
663
|
+
const webSearchKeys = getWebSearchKeys();
|
|
664
|
+
function loadWebSearchConfig(config) {
|
|
665
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
|
|
666
|
+
const serperApiKey = (_a = config === null || config === void 0 ? void 0 : config.serperApiKey) !== null && _a !== void 0 ? _a : '${SERPER_API_KEY}';
|
|
667
|
+
const searxngInstanceUrl = (_b = config === null || config === void 0 ? void 0 : config.searxngInstanceUrl) !== null && _b !== void 0 ? _b : '${SEARXNG_INSTANCE_URL}';
|
|
668
|
+
const searxngApiKey = (_c = config === null || config === void 0 ? void 0 : config.searxngApiKey) !== null && _c !== void 0 ? _c : '${SEARXNG_API_KEY}';
|
|
669
|
+
const firecrawlApiKey = (_d = config === null || config === void 0 ? void 0 : config.firecrawlApiKey) !== null && _d !== void 0 ? _d : '${FIRECRAWL_API_KEY}';
|
|
670
|
+
const firecrawlApiUrl = (_e = config === null || config === void 0 ? void 0 : config.firecrawlApiUrl) !== null && _e !== void 0 ? _e : '${FIRECRAWL_API_URL}';
|
|
671
|
+
const firecrawlVersion = (_f = config === null || config === void 0 ? void 0 : config.firecrawlVersion) !== null && _f !== void 0 ? _f : '${FIRECRAWL_VERSION}';
|
|
672
|
+
const jinaApiKey = (_g = config === null || config === void 0 ? void 0 : config.jinaApiKey) !== null && _g !== void 0 ? _g : '${JINA_API_KEY}';
|
|
673
|
+
const jinaApiUrl = (_h = config === null || config === void 0 ? void 0 : config.jinaApiUrl) !== null && _h !== void 0 ? _h : '${JINA_API_URL}';
|
|
674
|
+
const cohereApiKey = (_j = config === null || config === void 0 ? void 0 : config.cohereApiKey) !== null && _j !== void 0 ? _j : '${COHERE_API_KEY}';
|
|
675
|
+
const safeSearch = (_k = config === null || config === void 0 ? void 0 : config.safeSearch) !== null && _k !== void 0 ? _k : SafeSearchTypes.MODERATE;
|
|
676
|
+
return {
|
|
677
|
+
...config,
|
|
678
|
+
safeSearch,
|
|
679
|
+
jinaApiKey,
|
|
680
|
+
jinaApiUrl,
|
|
681
|
+
cohereApiKey,
|
|
682
|
+
serperApiKey,
|
|
683
|
+
searxngApiKey,
|
|
684
|
+
firecrawlApiKey,
|
|
685
|
+
firecrawlApiUrl,
|
|
686
|
+
firecrawlVersion,
|
|
687
|
+
searxngInstanceUrl,
|
|
688
|
+
};
|
|
689
|
+
}
|
|
326
690
|
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
}
|
|
691
|
+
/**
|
|
692
|
+
* Sets up Model Specs from the config (`librechat.yaml`) file.
|
|
693
|
+
* @param [endpoints] - The loaded custom configuration for endpoints.
|
|
694
|
+
* @param [modelSpecs] - The loaded custom configuration for model specs.
|
|
695
|
+
* @param [interfaceConfig] - The loaded interface configuration.
|
|
696
|
+
* @returns The processed model specs, if any.
|
|
697
|
+
*/
|
|
698
|
+
function processModelSpecs(endpoints, _modelSpecs, interfaceConfig) {
|
|
699
|
+
var _a, _b, _c, _d;
|
|
700
|
+
if (!_modelSpecs) {
|
|
701
|
+
return undefined;
|
|
702
|
+
}
|
|
703
|
+
const list = _modelSpecs.list;
|
|
704
|
+
const modelSpecs = [];
|
|
705
|
+
const customEndpoints = (_a = endpoints === null || endpoints === void 0 ? void 0 : endpoints[EModelEndpoint.custom]) !== null && _a !== void 0 ? _a : [];
|
|
706
|
+
if ((interfaceConfig === null || interfaceConfig === void 0 ? void 0 : interfaceConfig.modelSelect) !== true && ((_c = (_b = _modelSpecs.addedEndpoints) === null || _b === void 0 ? void 0 : _b.length) !== null && _c !== void 0 ? _c : 0) > 0) {
|
|
707
|
+
logger$1.warn(`To utilize \`addedEndpoints\`, which allows provider/model selections alongside model specs, set \`modelSelect: true\` in the interface configuration.
|
|
339
708
|
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
709
|
+
Example:
|
|
710
|
+
\`\`\`yaml
|
|
711
|
+
interface:
|
|
712
|
+
modelSelect: true
|
|
713
|
+
\`\`\`
|
|
714
|
+
`);
|
|
715
|
+
}
|
|
716
|
+
if (!list || list.length === 0) {
|
|
717
|
+
return undefined;
|
|
718
|
+
}
|
|
719
|
+
for (const spec of list) {
|
|
720
|
+
const currentEndpoint = (_d = spec.preset) === null || _d === void 0 ? void 0 : _d.endpoint;
|
|
721
|
+
if (!currentEndpoint) {
|
|
722
|
+
logger$1.warn('A model spec is missing the `endpoint` field within its `preset`. Skipping model spec...');
|
|
723
|
+
continue;
|
|
724
|
+
}
|
|
725
|
+
if (EModelEndpoint[currentEndpoint] && currentEndpoint !== EModelEndpoint.custom) {
|
|
726
|
+
modelSpecs.push(spec);
|
|
727
|
+
continue;
|
|
728
|
+
}
|
|
729
|
+
else if (currentEndpoint === EModelEndpoint.custom) {
|
|
730
|
+
logger$1.warn(`Model Spec with endpoint "${currentEndpoint}" is not supported. You must specify the name of the custom endpoint (case-sensitive, as defined in your config). Skipping model spec...`);
|
|
731
|
+
continue;
|
|
732
|
+
}
|
|
733
|
+
const normalizedName = normalizeEndpointName(currentEndpoint);
|
|
734
|
+
const endpoint = customEndpoints.find((customEndpoint) => normalizedName === normalizeEndpointName(customEndpoint.name));
|
|
735
|
+
if (!endpoint) {
|
|
736
|
+
logger$1.warn(`Model spec with endpoint "${currentEndpoint}" was skipped: Endpoint not found in configuration. The \`endpoint\` value must exactly match either a system-defined endpoint or a custom endpoint defined by the user.
|
|
365
737
|
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
738
|
+
For more information, see the documentation at https://www.librechat.ai/docs/configuration/librechat_yaml/object_structure/model_specs#endpoint`);
|
|
739
|
+
continue;
|
|
740
|
+
}
|
|
741
|
+
modelSpecs.push({
|
|
742
|
+
...spec,
|
|
743
|
+
preset: {
|
|
744
|
+
...spec.preset,
|
|
745
|
+
endpoint: normalizedName,
|
|
746
|
+
},
|
|
747
|
+
});
|
|
748
|
+
}
|
|
749
|
+
return {
|
|
750
|
+
..._modelSpecs,
|
|
751
|
+
list: modelSpecs,
|
|
752
|
+
};
|
|
753
|
+
}
|
|
754
|
+
|
|
755
|
+
/**
|
|
756
|
+
* Sets up the minimum, default Assistants configuration if Azure OpenAI Assistants option is enabled.
|
|
757
|
+
* @returns The Assistants endpoint configuration.
|
|
758
|
+
*/
|
|
759
|
+
function azureAssistantsDefaults() {
|
|
760
|
+
return {
|
|
761
|
+
capabilities: [Capabilities.tools, Capabilities.actions, Capabilities.code_interpreter],
|
|
762
|
+
version: defaultAssistantsVersion.azureAssistants,
|
|
763
|
+
};
|
|
764
|
+
}
|
|
765
|
+
/**
|
|
766
|
+
* Sets up the Assistants configuration from the config (`librechat.yaml`) file.
|
|
767
|
+
* @param config - The loaded custom configuration.
|
|
768
|
+
* @param assistantsEndpoint - The Assistants endpoint name.
|
|
769
|
+
* - The previously loaded assistants configuration from Azure OpenAI Assistants option.
|
|
770
|
+
* @param [prevConfig]
|
|
771
|
+
* @returns The Assistants endpoint configuration.
|
|
772
|
+
*/
|
|
773
|
+
function assistantsConfigSetup(config, assistantsEndpoint, prevConfig = {}) {
|
|
774
|
+
var _a, _b, _c, _d, _e;
|
|
775
|
+
const assistantsConfig = (_a = config.endpoints) === null || _a === void 0 ? void 0 : _a[assistantsEndpoint];
|
|
776
|
+
const parsedConfig = assistantEndpointSchema.parse(assistantsConfig);
|
|
777
|
+
if (((_b = assistantsConfig === null || assistantsConfig === void 0 ? void 0 : assistantsConfig.supportedIds) === null || _b === void 0 ? void 0 : _b.length) && ((_c = assistantsConfig.excludedIds) === null || _c === void 0 ? void 0 : _c.length)) {
|
|
778
|
+
logger$1.warn(`Configuration conflict: The '${assistantsEndpoint}' endpoint has both 'supportedIds' and 'excludedIds' defined. The 'excludedIds' will be ignored.`);
|
|
779
|
+
}
|
|
780
|
+
if ((assistantsConfig === null || assistantsConfig === void 0 ? void 0 : assistantsConfig.privateAssistants) &&
|
|
781
|
+
(((_d = assistantsConfig.supportedIds) === null || _d === void 0 ? void 0 : _d.length) || ((_e = assistantsConfig.excludedIds) === null || _e === void 0 ? void 0 : _e.length))) {
|
|
782
|
+
logger$1.warn(`Configuration conflict: The '${assistantsEndpoint}' endpoint has both 'privateAssistants' and 'supportedIds' or 'excludedIds' defined. The 'supportedIds' and 'excludedIds' will be ignored.`);
|
|
783
|
+
}
|
|
784
|
+
return {
|
|
785
|
+
...prevConfig,
|
|
786
|
+
retrievalModels: parsedConfig.retrievalModels,
|
|
787
|
+
disableBuilder: parsedConfig.disableBuilder,
|
|
788
|
+
pollIntervalMs: parsedConfig.pollIntervalMs,
|
|
789
|
+
supportedIds: parsedConfig.supportedIds,
|
|
790
|
+
capabilities: parsedConfig.capabilities,
|
|
791
|
+
excludedIds: parsedConfig.excludedIds,
|
|
792
|
+
privateAssistants: parsedConfig.privateAssistants,
|
|
793
|
+
timeoutMs: parsedConfig.timeoutMs,
|
|
794
|
+
streamRate: parsedConfig.streamRate,
|
|
795
|
+
titlePrompt: parsedConfig.titlePrompt,
|
|
796
|
+
titleMethod: parsedConfig.titleMethod,
|
|
797
|
+
titleModel: parsedConfig.titleModel,
|
|
798
|
+
titleEndpoint: parsedConfig.titleEndpoint,
|
|
799
|
+
titlePromptTemplate: parsedConfig.titlePromptTemplate,
|
|
800
|
+
};
|
|
801
|
+
}
|
|
802
|
+
|
|
803
|
+
/**
|
|
804
|
+
* Sets up the Azure OpenAI configuration from the config (`librechat.yaml`) file.
|
|
805
|
+
* @param config - The loaded custom configuration.
|
|
806
|
+
* @returns The Azure OpenAI configuration.
|
|
807
|
+
*/
|
|
808
|
+
function azureConfigSetup(config) {
|
|
809
|
+
var _a, _b, _c;
|
|
810
|
+
const azureConfig = (_a = config.endpoints) === null || _a === void 0 ? void 0 : _a[EModelEndpoint.azureOpenAI];
|
|
811
|
+
if (!azureConfig) {
|
|
812
|
+
throw new Error('Azure OpenAI configuration is missing.');
|
|
813
|
+
}
|
|
814
|
+
const { groups, ...azureConfiguration } = azureConfig;
|
|
815
|
+
const { isValid, modelNames, modelGroupMap, groupMap, errors } = validateAzureGroups(groups);
|
|
816
|
+
if (!isValid) {
|
|
817
|
+
const errorString = errors.join('\n');
|
|
818
|
+
const errorMessage = 'Invalid Azure OpenAI configuration:\n' + errorString;
|
|
819
|
+
logger$1.error(errorMessage);
|
|
820
|
+
throw new Error(errorMessage);
|
|
821
|
+
}
|
|
822
|
+
const assistantModels = [];
|
|
823
|
+
const assistantGroups = new Set();
|
|
824
|
+
for (const modelName of modelNames) {
|
|
825
|
+
mapModelToAzureConfig({ modelName, modelGroupMap, groupMap });
|
|
826
|
+
const groupName = (_b = modelGroupMap === null || modelGroupMap === void 0 ? void 0 : modelGroupMap[modelName]) === null || _b === void 0 ? void 0 : _b.group;
|
|
827
|
+
const modelGroup = groupMap === null || groupMap === void 0 ? void 0 : groupMap[groupName];
|
|
828
|
+
const supportsAssistants = (modelGroup === null || modelGroup === void 0 ? void 0 : modelGroup.assistants) || ((_c = modelGroup === null || modelGroup === void 0 ? void 0 : modelGroup[modelName]) === null || _c === void 0 ? void 0 : _c.assistants);
|
|
829
|
+
if (supportsAssistants) {
|
|
830
|
+
assistantModels.push(modelName);
|
|
831
|
+
if (!assistantGroups.has(groupName)) {
|
|
832
|
+
assistantGroups.add(groupName);
|
|
833
|
+
}
|
|
834
|
+
}
|
|
835
|
+
}
|
|
836
|
+
if (azureConfiguration.assistants && assistantModels.length === 0) {
|
|
837
|
+
throw new Error('No Azure models are configured to support assistants. Please remove the `assistants` field or configure at least one model to support assistants.');
|
|
838
|
+
}
|
|
839
|
+
if (azureConfiguration.assistants &&
|
|
840
|
+
process.env.ENDPOINTS &&
|
|
841
|
+
!process.env.ENDPOINTS.includes(EModelEndpoint.azureAssistants)) {
|
|
842
|
+
logger$1.warn(`Azure Assistants are configured, but the endpoint will not be accessible as it's not included in the ENDPOINTS environment variable.
|
|
843
|
+
Please add the value "${EModelEndpoint.azureAssistants}" to the ENDPOINTS list if expected.`);
|
|
844
|
+
}
|
|
845
|
+
return {
|
|
846
|
+
errors,
|
|
847
|
+
isValid,
|
|
848
|
+
groupMap,
|
|
849
|
+
modelNames,
|
|
850
|
+
modelGroupMap,
|
|
851
|
+
assistantModels,
|
|
852
|
+
assistantGroups: Array.from(assistantGroups),
|
|
853
|
+
...azureConfiguration,
|
|
854
|
+
};
|
|
855
|
+
}
|
|
856
|
+
|
|
857
|
+
/**
|
|
858
|
+
* Loads custom config endpoints
|
|
859
|
+
* @param [config]
|
|
860
|
+
* @param [agentsDefaults]
|
|
861
|
+
*/
|
|
862
|
+
const loadEndpoints = (config, agentsDefaults) => {
|
|
863
|
+
var _a;
|
|
864
|
+
const loadedEndpoints = {};
|
|
865
|
+
const endpoints = config === null || config === void 0 ? void 0 : config.endpoints;
|
|
866
|
+
if (endpoints === null || endpoints === void 0 ? void 0 : endpoints[EModelEndpoint.azureOpenAI]) {
|
|
867
|
+
loadedEndpoints[EModelEndpoint.azureOpenAI] = azureConfigSetup(config);
|
|
868
|
+
}
|
|
869
|
+
if ((_a = endpoints === null || endpoints === void 0 ? void 0 : endpoints[EModelEndpoint.azureOpenAI]) === null || _a === void 0 ? void 0 : _a.assistants) {
|
|
870
|
+
loadedEndpoints[EModelEndpoint.azureAssistants] = azureAssistantsDefaults();
|
|
871
|
+
}
|
|
872
|
+
if (endpoints === null || endpoints === void 0 ? void 0 : endpoints[EModelEndpoint.azureAssistants]) {
|
|
873
|
+
loadedEndpoints[EModelEndpoint.azureAssistants] = assistantsConfigSetup(config, EModelEndpoint.azureAssistants, loadedEndpoints[EModelEndpoint.azureAssistants]);
|
|
874
|
+
}
|
|
875
|
+
if (endpoints === null || endpoints === void 0 ? void 0 : endpoints[EModelEndpoint.assistants]) {
|
|
876
|
+
loadedEndpoints[EModelEndpoint.assistants] = assistantsConfigSetup(config, EModelEndpoint.assistants, loadedEndpoints[EModelEndpoint.assistants]);
|
|
877
|
+
}
|
|
878
|
+
loadedEndpoints[EModelEndpoint.agents] = agentsConfigSetup(config, agentsDefaults);
|
|
879
|
+
const endpointKeys = [
|
|
880
|
+
EModelEndpoint.openAI,
|
|
881
|
+
EModelEndpoint.google,
|
|
882
|
+
EModelEndpoint.custom,
|
|
883
|
+
EModelEndpoint.bedrock,
|
|
884
|
+
EModelEndpoint.anthropic,
|
|
885
|
+
];
|
|
886
|
+
endpointKeys.forEach((key) => {
|
|
887
|
+
const currentKey = key;
|
|
888
|
+
if (endpoints === null || endpoints === void 0 ? void 0 : endpoints[currentKey]) {
|
|
889
|
+
loadedEndpoints[currentKey] = endpoints[currentKey];
|
|
890
|
+
}
|
|
891
|
+
});
|
|
892
|
+
if (endpoints === null || endpoints === void 0 ? void 0 : endpoints.all) {
|
|
893
|
+
loadedEndpoints.all = endpoints.all;
|
|
894
|
+
}
|
|
895
|
+
return loadedEndpoints;
|
|
896
|
+
};
|
|
897
|
+
|
|
898
|
+
function loadOCRConfig(config) {
|
|
899
|
+
var _a, _b, _c, _d;
|
|
900
|
+
if (!config)
|
|
901
|
+
return;
|
|
902
|
+
const baseURL = (_a = config === null || config === void 0 ? void 0 : config.baseURL) !== null && _a !== void 0 ? _a : '';
|
|
903
|
+
const apiKey = (_b = config === null || config === void 0 ? void 0 : config.apiKey) !== null && _b !== void 0 ? _b : '';
|
|
904
|
+
const mistralModel = (_c = config === null || config === void 0 ? void 0 : config.mistralModel) !== null && _c !== void 0 ? _c : '';
|
|
905
|
+
return {
|
|
906
|
+
apiKey,
|
|
907
|
+
baseURL,
|
|
908
|
+
mistralModel,
|
|
909
|
+
strategy: (_d = config === null || config === void 0 ? void 0 : config.strategy) !== null && _d !== void 0 ? _d : OCRStrategy.MISTRAL_OCR,
|
|
910
|
+
};
|
|
911
|
+
}
|
|
912
|
+
|
|
913
|
+
/**
|
|
914
|
+
* Loads custom config and initializes app-wide variables.
|
|
915
|
+
* @function AppService
|
|
916
|
+
*/
|
|
917
|
+
const AppService = async (params) => {
|
|
918
|
+
var _a, _b, _c, _d, _e, _f;
|
|
919
|
+
const { config, paths, systemTools } = params || {};
|
|
920
|
+
if (!config) {
|
|
921
|
+
throw new Error('Config is required');
|
|
922
|
+
}
|
|
923
|
+
const configDefaults = getConfigDefaults();
|
|
924
|
+
const ocr = loadOCRConfig(config.ocr);
|
|
925
|
+
const webSearch = loadWebSearchConfig(config.webSearch);
|
|
926
|
+
const memory = loadMemoryConfig(config.memory);
|
|
927
|
+
const filteredTools = config.filteredTools;
|
|
928
|
+
const includedTools = config.includedTools;
|
|
929
|
+
const fileStrategy = ((_a = config.fileStrategy) !== null && _a !== void 0 ? _a : configDefaults.fileStrategy);
|
|
930
|
+
const startBalance = process.env.START_BALANCE;
|
|
931
|
+
const balance = (_b = config.balance) !== null && _b !== void 0 ? _b : {
|
|
932
|
+
enabled: ((_c = process.env.CHECK_BALANCE) === null || _c === void 0 ? void 0 : _c.toLowerCase().trim()) === 'true',
|
|
933
|
+
startBalance: startBalance ? parseInt(startBalance, 10) : undefined,
|
|
934
|
+
};
|
|
935
|
+
const transactions = (_d = config.transactions) !== null && _d !== void 0 ? _d : configDefaults.transactions;
|
|
936
|
+
const imageOutputType = (_e = config === null || config === void 0 ? void 0 : config.imageOutputType) !== null && _e !== void 0 ? _e : configDefaults.imageOutputType;
|
|
937
|
+
process.env.CDN_PROVIDER = fileStrategy;
|
|
938
|
+
const availableTools = systemTools;
|
|
939
|
+
const mcpConfig = config.mcpServers || null;
|
|
940
|
+
const registration = (_f = config.registration) !== null && _f !== void 0 ? _f : configDefaults.registration;
|
|
941
|
+
const interfaceConfig = await loadDefaultInterface({ config, configDefaults });
|
|
942
|
+
const turnstileConfig = loadTurnstileConfig(config, configDefaults);
|
|
943
|
+
const speech = config.speech;
|
|
944
|
+
const defaultConfig = {
|
|
945
|
+
ocr,
|
|
946
|
+
paths,
|
|
947
|
+
config,
|
|
948
|
+
memory,
|
|
949
|
+
speech,
|
|
950
|
+
balance,
|
|
951
|
+
transactions,
|
|
952
|
+
mcpConfig,
|
|
953
|
+
webSearch,
|
|
954
|
+
fileStrategy,
|
|
955
|
+
registration,
|
|
956
|
+
filteredTools,
|
|
957
|
+
includedTools,
|
|
958
|
+
availableTools,
|
|
959
|
+
imageOutputType,
|
|
960
|
+
interfaceConfig,
|
|
961
|
+
turnstileConfig,
|
|
962
|
+
fileStrategies: config.fileStrategies,
|
|
963
|
+
};
|
|
964
|
+
const agentsDefaults = agentsConfigSetup(config);
|
|
965
|
+
if (!Object.keys(config).length) {
|
|
966
|
+
const appConfig = {
|
|
967
|
+
...defaultConfig,
|
|
968
|
+
endpoints: {
|
|
969
|
+
[EModelEndpoint.agents]: agentsDefaults,
|
|
970
|
+
},
|
|
971
|
+
};
|
|
972
|
+
return appConfig;
|
|
973
|
+
}
|
|
974
|
+
const loadedEndpoints = loadEndpoints(config, agentsDefaults);
|
|
975
|
+
const appConfig = {
|
|
976
|
+
...defaultConfig,
|
|
977
|
+
fileConfig: config === null || config === void 0 ? void 0 : config.fileConfig,
|
|
978
|
+
secureImageLinks: config === null || config === void 0 ? void 0 : config.secureImageLinks,
|
|
979
|
+
modelSpecs: processModelSpecs(config === null || config === void 0 ? void 0 : config.endpoints, config.modelSpecs, interfaceConfig),
|
|
980
|
+
endpoints: loadedEndpoints,
|
|
981
|
+
};
|
|
982
|
+
return appConfig;
|
|
983
|
+
};
|
|
984
|
+
|
|
985
|
+
/**
|
|
986
|
+
* Common role combinations
|
|
987
|
+
*/
|
|
988
|
+
var RoleBits;
|
|
989
|
+
(function (RoleBits) {
|
|
990
|
+
/** 0001 = 1 */
|
|
991
|
+
RoleBits[RoleBits["VIEWER"] = PermissionBits.VIEW] = "VIEWER";
|
|
992
|
+
/** 0011 = 3 */
|
|
993
|
+
RoleBits[RoleBits["EDITOR"] = PermissionBits.VIEW | PermissionBits.EDIT] = "EDITOR";
|
|
994
|
+
/** 0111 = 7 */
|
|
995
|
+
RoleBits[RoleBits["MANAGER"] = PermissionBits.VIEW | PermissionBits.EDIT | PermissionBits.DELETE] = "MANAGER";
|
|
996
|
+
/** 1111 = 15 */
|
|
997
|
+
RoleBits[RoleBits["OWNER"] = PermissionBits.VIEW | PermissionBits.EDIT | PermissionBits.DELETE | PermissionBits.SHARE] = "OWNER";
|
|
998
|
+
})(RoleBits || (RoleBits = {}));
|
|
999
|
+
|
|
1000
|
+
async function signPayload({ payload, secret, expirationTime, }) {
|
|
1001
|
+
return jwt.sign(payload, secret, { expiresIn: expirationTime });
|
|
1002
|
+
}
|
|
1003
|
+
async function hashToken(str) {
|
|
1004
|
+
const data = new TextEncoder().encode(str);
|
|
1005
|
+
const hashBuffer = await webcrypto.subtle.digest('SHA-256', data);
|
|
1006
|
+
return Buffer.from(hashBuffer).toString('hex');
|
|
1007
|
+
}
|
|
1008
|
+
|
|
1009
|
+
// Define the Auth sub-schema with type-safety.
|
|
1010
|
+
const AuthSchema = new Schema({
|
|
1011
|
+
authorization_type: { type: String },
|
|
1012
|
+
custom_auth_header: { type: String },
|
|
1013
|
+
type: { type: String, enum: ['service_http', 'oauth', 'none'] },
|
|
1014
|
+
authorization_content_type: { type: String },
|
|
1015
|
+
authorization_url: { type: String },
|
|
1016
|
+
client_url: { type: String },
|
|
1017
|
+
scope: { type: String },
|
|
1018
|
+
token_exchange_method: { type: String, enum: ['default_post', 'basic_auth_header', null] },
|
|
1019
|
+
}, { _id: false });
|
|
1020
|
+
const Action = new Schema({
|
|
1021
|
+
user: {
|
|
1022
|
+
type: mongoose.Schema.Types.ObjectId,
|
|
1023
|
+
ref: 'User',
|
|
1024
|
+
index: true,
|
|
372
1025
|
required: true,
|
|
373
1026
|
},
|
|
374
|
-
|
|
375
|
-
type: String,
|
|
376
|
-
},
|
|
377
|
-
// for azureOpenAI, openAI, chatGPTBrowser only
|
|
378
|
-
model: {
|
|
379
|
-
type: String,
|
|
380
|
-
required: false,
|
|
381
|
-
},
|
|
382
|
-
// for bedrock only
|
|
383
|
-
region: {
|
|
384
|
-
type: String,
|
|
385
|
-
required: false,
|
|
386
|
-
},
|
|
387
|
-
// for azureOpenAI, openAI only
|
|
388
|
-
chatGptLabel: {
|
|
389
|
-
type: String,
|
|
390
|
-
required: false,
|
|
391
|
-
},
|
|
392
|
-
// for google only
|
|
393
|
-
examples: { type: [{ type: Schema.Types.Mixed }], default: undefined },
|
|
394
|
-
modelLabel: {
|
|
395
|
-
type: String,
|
|
396
|
-
required: false,
|
|
397
|
-
},
|
|
398
|
-
promptPrefix: {
|
|
1027
|
+
action_id: {
|
|
399
1028
|
type: String,
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
temperature: {
|
|
403
|
-
type: Number,
|
|
404
|
-
required: false,
|
|
405
|
-
},
|
|
406
|
-
top_p: {
|
|
407
|
-
type: Number,
|
|
408
|
-
required: false,
|
|
409
|
-
},
|
|
410
|
-
// for google only
|
|
411
|
-
topP: {
|
|
412
|
-
type: Number,
|
|
413
|
-
required: false,
|
|
414
|
-
},
|
|
415
|
-
topK: {
|
|
416
|
-
type: Number,
|
|
417
|
-
required: false,
|
|
418
|
-
},
|
|
419
|
-
maxOutputTokens: {
|
|
420
|
-
type: Number,
|
|
421
|
-
required: false,
|
|
422
|
-
},
|
|
423
|
-
maxTokens: {
|
|
424
|
-
type: Number,
|
|
425
|
-
required: false,
|
|
426
|
-
},
|
|
427
|
-
presence_penalty: {
|
|
428
|
-
type: Number,
|
|
429
|
-
required: false,
|
|
430
|
-
},
|
|
431
|
-
frequency_penalty: {
|
|
432
|
-
type: Number,
|
|
433
|
-
required: false,
|
|
434
|
-
},
|
|
435
|
-
file_ids: { type: [{ type: String }], default: undefined },
|
|
436
|
-
// deprecated
|
|
437
|
-
resendImages: {
|
|
438
|
-
type: Boolean,
|
|
439
|
-
},
|
|
440
|
-
/* Anthropic only */
|
|
441
|
-
promptCache: {
|
|
442
|
-
type: Boolean,
|
|
443
|
-
},
|
|
444
|
-
thinking: {
|
|
445
|
-
type: Boolean,
|
|
446
|
-
},
|
|
447
|
-
thinkingBudget: {
|
|
448
|
-
type: Number,
|
|
1029
|
+
index: true,
|
|
1030
|
+
required: true,
|
|
449
1031
|
},
|
|
450
|
-
|
|
1032
|
+
type: {
|
|
451
1033
|
type: String,
|
|
1034
|
+
default: 'action_prototype',
|
|
452
1035
|
},
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
1036
|
+
settings: Schema.Types.Mixed,
|
|
1037
|
+
agent_id: String,
|
|
1038
|
+
assistant_id: String,
|
|
1039
|
+
metadata: {
|
|
1040
|
+
api_key: String,
|
|
1041
|
+
auth: AuthSchema,
|
|
1042
|
+
domain: {
|
|
1043
|
+
type: String,
|
|
1044
|
+
required: true,
|
|
1045
|
+
},
|
|
1046
|
+
privacy_policy_url: String,
|
|
1047
|
+
raw_spec: String,
|
|
1048
|
+
oauth_client_id: String,
|
|
1049
|
+
oauth_client_secret: String,
|
|
456
1050
|
},
|
|
457
|
-
|
|
1051
|
+
});
|
|
1052
|
+
|
|
1053
|
+
const agentSchema = new Schema({
|
|
1054
|
+
id: {
|
|
458
1055
|
type: String,
|
|
1056
|
+
index: true,
|
|
1057
|
+
unique: true,
|
|
1058
|
+
required: true,
|
|
459
1059
|
},
|
|
460
|
-
|
|
461
|
-
agent_id: {
|
|
1060
|
+
name: {
|
|
462
1061
|
type: String,
|
|
463
1062
|
},
|
|
464
|
-
|
|
465
|
-
assistant_id: {
|
|
1063
|
+
description: {
|
|
466
1064
|
type: String,
|
|
467
1065
|
},
|
|
468
1066
|
instructions: {
|
|
469
1067
|
type: String,
|
|
470
1068
|
},
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
default: false,
|
|
475
|
-
},
|
|
476
|
-
/* UI Components */
|
|
477
|
-
iconURL: {
|
|
478
|
-
type: String,
|
|
479
|
-
},
|
|
480
|
-
greeting: {
|
|
481
|
-
type: String,
|
|
482
|
-
},
|
|
483
|
-
spec: {
|
|
484
|
-
type: String,
|
|
485
|
-
},
|
|
486
|
-
tags: {
|
|
487
|
-
type: [String],
|
|
488
|
-
default: [],
|
|
489
|
-
},
|
|
490
|
-
tools: { type: [{ type: String }], default: undefined },
|
|
491
|
-
maxContextTokens: {
|
|
492
|
-
type: Number,
|
|
493
|
-
},
|
|
494
|
-
max_tokens: {
|
|
495
|
-
type: Number,
|
|
496
|
-
},
|
|
497
|
-
useResponsesApi: {
|
|
498
|
-
type: Boolean,
|
|
499
|
-
},
|
|
500
|
-
/** OpenAI Responses API / Anthropic API / Google API */
|
|
501
|
-
web_search: {
|
|
502
|
-
type: Boolean,
|
|
503
|
-
},
|
|
504
|
-
disableStreaming: {
|
|
505
|
-
type: Boolean,
|
|
506
|
-
},
|
|
507
|
-
fileTokenLimit: {
|
|
508
|
-
type: Number,
|
|
509
|
-
},
|
|
510
|
-
/** Reasoning models only */
|
|
511
|
-
reasoning_effort: {
|
|
512
|
-
type: String,
|
|
513
|
-
},
|
|
514
|
-
reasoning_summary: {
|
|
515
|
-
type: String,
|
|
1069
|
+
avatar: {
|
|
1070
|
+
type: Schema.Types.Mixed,
|
|
1071
|
+
default: undefined,
|
|
516
1072
|
},
|
|
517
|
-
|
|
518
|
-
verbosity: {
|
|
1073
|
+
provider: {
|
|
519
1074
|
type: String,
|
|
1075
|
+
required: true,
|
|
520
1076
|
},
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
const convoSchema = new Schema({
|
|
524
|
-
conversationId: {
|
|
1077
|
+
model: {
|
|
525
1078
|
type: String,
|
|
526
|
-
unique: true,
|
|
527
1079
|
required: true,
|
|
528
|
-
index: true,
|
|
529
|
-
meiliIndex: true,
|
|
530
1080
|
},
|
|
531
|
-
|
|
532
|
-
type:
|
|
533
|
-
default: 'New Chat',
|
|
534
|
-
meiliIndex: true,
|
|
1081
|
+
model_parameters: {
|
|
1082
|
+
type: Object,
|
|
535
1083
|
},
|
|
536
|
-
|
|
1084
|
+
artifacts: {
|
|
537
1085
|
type: String,
|
|
538
|
-
index: true,
|
|
539
1086
|
},
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
type: Schema.Types.Mixed,
|
|
1087
|
+
access_level: {
|
|
1088
|
+
type: Number,
|
|
543
1089
|
},
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
type: String,
|
|
1090
|
+
recursion_limit: {
|
|
1091
|
+
type: Number,
|
|
547
1092
|
},
|
|
548
|
-
|
|
1093
|
+
tools: {
|
|
549
1094
|
type: [String],
|
|
550
|
-
default:
|
|
551
|
-
meiliIndex: true,
|
|
1095
|
+
default: undefined,
|
|
552
1096
|
},
|
|
553
|
-
|
|
554
|
-
type: [
|
|
1097
|
+
tool_kwargs: {
|
|
1098
|
+
type: [{ type: Schema.Types.Mixed }],
|
|
555
1099
|
},
|
|
556
|
-
|
|
557
|
-
type:
|
|
1100
|
+
actions: {
|
|
1101
|
+
type: [String],
|
|
1102
|
+
default: undefined,
|
|
558
1103
|
},
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
convoSchema.index({ createdAt: 1, updatedAt: 1 });
|
|
562
|
-
convoSchema.index({ conversationId: 1, user: 1 }, { unique: true });
|
|
563
|
-
|
|
564
|
-
const file = new Schema({
|
|
565
|
-
user: {
|
|
566
|
-
type: mongoose.Schema.Types.ObjectId,
|
|
1104
|
+
author: {
|
|
1105
|
+
type: Schema.Types.ObjectId,
|
|
567
1106
|
ref: 'User',
|
|
568
|
-
index: true,
|
|
569
1107
|
required: true,
|
|
570
1108
|
},
|
|
571
|
-
|
|
572
|
-
type: String,
|
|
573
|
-
ref: 'Conversation',
|
|
574
|
-
index: true,
|
|
575
|
-
},
|
|
576
|
-
file_id: {
|
|
577
|
-
type: String,
|
|
578
|
-
index: true,
|
|
579
|
-
required: true,
|
|
580
|
-
},
|
|
581
|
-
temp_file_id: {
|
|
1109
|
+
authorName: {
|
|
582
1110
|
type: String,
|
|
1111
|
+
default: undefined,
|
|
583
1112
|
},
|
|
584
|
-
|
|
585
|
-
type:
|
|
586
|
-
required: true,
|
|
1113
|
+
hide_sequential_outputs: {
|
|
1114
|
+
type: Boolean,
|
|
587
1115
|
},
|
|
588
|
-
|
|
589
|
-
type:
|
|
590
|
-
required: true,
|
|
1116
|
+
end_after_tools: {
|
|
1117
|
+
type: Boolean,
|
|
591
1118
|
},
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
1119
|
+
/** @deprecated Use edges instead */
|
|
1120
|
+
agent_ids: {
|
|
1121
|
+
type: [String],
|
|
595
1122
|
},
|
|
596
|
-
|
|
597
|
-
type:
|
|
598
|
-
|
|
599
|
-
default: 'file',
|
|
1123
|
+
edges: {
|
|
1124
|
+
type: [{ type: Schema.Types.Mixed }],
|
|
1125
|
+
default: [],
|
|
600
1126
|
},
|
|
601
|
-
|
|
1127
|
+
isCollaborative: {
|
|
602
1128
|
type: Boolean,
|
|
1129
|
+
default: undefined,
|
|
603
1130
|
},
|
|
604
|
-
|
|
605
|
-
type: String,
|
|
606
|
-
|
|
607
|
-
},
|
|
608
|
-
text: {
|
|
609
|
-
type: String,
|
|
1131
|
+
conversation_starters: {
|
|
1132
|
+
type: [String],
|
|
1133
|
+
default: [],
|
|
610
1134
|
},
|
|
611
|
-
|
|
612
|
-
type:
|
|
1135
|
+
tool_resources: {
|
|
1136
|
+
type: Schema.Types.Mixed,
|
|
1137
|
+
default: {},
|
|
613
1138
|
},
|
|
614
|
-
|
|
615
|
-
type:
|
|
616
|
-
|
|
617
|
-
|
|
1139
|
+
projectIds: {
|
|
1140
|
+
type: [Schema.Types.ObjectId],
|
|
1141
|
+
ref: 'Project',
|
|
1142
|
+
index: true,
|
|
618
1143
|
},
|
|
619
|
-
|
|
620
|
-
type:
|
|
621
|
-
default:
|
|
1144
|
+
versions: {
|
|
1145
|
+
type: [Schema.Types.Mixed],
|
|
1146
|
+
default: [],
|
|
622
1147
|
},
|
|
623
|
-
|
|
1148
|
+
category: {
|
|
624
1149
|
type: String,
|
|
1150
|
+
trim: true,
|
|
1151
|
+
index: true,
|
|
1152
|
+
default: 'general',
|
|
625
1153
|
},
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
fileIdentifier: String,
|
|
1154
|
+
support_contact: {
|
|
1155
|
+
type: Schema.Types.Mixed,
|
|
1156
|
+
default: undefined,
|
|
630
1157
|
},
|
|
631
|
-
|
|
632
|
-
type:
|
|
633
|
-
|
|
1158
|
+
is_promoted: {
|
|
1159
|
+
type: Boolean,
|
|
1160
|
+
default: false,
|
|
1161
|
+
index: true,
|
|
634
1162
|
},
|
|
635
1163
|
}, {
|
|
636
1164
|
timestamps: true,
|
|
637
1165
|
});
|
|
638
|
-
|
|
1166
|
+
agentSchema.index({ updatedAt: -1, _id: 1 });
|
|
639
1167
|
|
|
640
|
-
const
|
|
641
|
-
userId: {
|
|
642
|
-
type: mongoose.Schema.Types.ObjectId,
|
|
643
|
-
ref: 'User',
|
|
644
|
-
required: true,
|
|
645
|
-
},
|
|
646
|
-
name: {
|
|
647
|
-
type: String,
|
|
648
|
-
required: true,
|
|
649
|
-
},
|
|
1168
|
+
const agentCategorySchema = new Schema({
|
|
650
1169
|
value: {
|
|
651
1170
|
type: String,
|
|
652
1171
|
required: true,
|
|
653
|
-
},
|
|
654
|
-
expiresAt: {
|
|
655
|
-
type: Date,
|
|
656
|
-
},
|
|
657
|
-
});
|
|
658
|
-
keySchema.index({ expiresAt: 1 }, { expireAfterSeconds: 0 });
|
|
659
|
-
|
|
660
|
-
const messageSchema = new Schema({
|
|
661
|
-
messageId: {
|
|
662
|
-
type: String,
|
|
663
1172
|
unique: true,
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
meiliIndex: true,
|
|
667
|
-
},
|
|
668
|
-
conversationId: {
|
|
669
|
-
type: String,
|
|
1173
|
+
trim: true,
|
|
1174
|
+
lowercase: true,
|
|
670
1175
|
index: true,
|
|
671
|
-
required: true,
|
|
672
|
-
meiliIndex: true,
|
|
673
1176
|
},
|
|
674
|
-
|
|
1177
|
+
label: {
|
|
675
1178
|
type: String,
|
|
676
|
-
index: true,
|
|
677
1179
|
required: true,
|
|
678
|
-
|
|
679
|
-
},
|
|
680
|
-
model: {
|
|
681
|
-
type: String,
|
|
682
|
-
default: null,
|
|
683
|
-
},
|
|
684
|
-
endpoint: {
|
|
685
|
-
type: String,
|
|
686
|
-
},
|
|
687
|
-
conversationSignature: {
|
|
688
|
-
type: String,
|
|
1180
|
+
trim: true,
|
|
689
1181
|
},
|
|
690
|
-
|
|
1182
|
+
description: {
|
|
691
1183
|
type: String,
|
|
1184
|
+
trim: true,
|
|
1185
|
+
default: '',
|
|
692
1186
|
},
|
|
693
|
-
|
|
1187
|
+
order: {
|
|
694
1188
|
type: Number,
|
|
1189
|
+
default: 0,
|
|
1190
|
+
index: true,
|
|
695
1191
|
},
|
|
696
|
-
|
|
697
|
-
type:
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
type: Number,
|
|
1192
|
+
isActive: {
|
|
1193
|
+
type: Boolean,
|
|
1194
|
+
default: true,
|
|
1195
|
+
index: true,
|
|
701
1196
|
},
|
|
702
|
-
|
|
703
|
-
type:
|
|
1197
|
+
custom: {
|
|
1198
|
+
type: Boolean,
|
|
1199
|
+
default: false,
|
|
704
1200
|
},
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
1201
|
+
}, {
|
|
1202
|
+
timestamps: true,
|
|
1203
|
+
});
|
|
1204
|
+
agentCategorySchema.index({ isActive: 1, order: 1 });
|
|
1205
|
+
agentCategorySchema.index({ order: 1, label: 1 });
|
|
1206
|
+
|
|
1207
|
+
const assistantSchema = new Schema({
|
|
1208
|
+
user: {
|
|
1209
|
+
type: Schema.Types.ObjectId,
|
|
1210
|
+
ref: 'User',
|
|
1211
|
+
required: true,
|
|
708
1212
|
},
|
|
709
|
-
|
|
1213
|
+
assistant_id: {
|
|
710
1214
|
type: String,
|
|
711
|
-
|
|
1215
|
+
index: true,
|
|
1216
|
+
required: true,
|
|
712
1217
|
},
|
|
713
|
-
|
|
714
|
-
type:
|
|
1218
|
+
avatar: {
|
|
1219
|
+
type: Schema.Types.Mixed,
|
|
1220
|
+
default: undefined,
|
|
715
1221
|
},
|
|
716
|
-
|
|
717
|
-
type:
|
|
718
|
-
|
|
719
|
-
default: false,
|
|
1222
|
+
conversation_starters: {
|
|
1223
|
+
type: [String],
|
|
1224
|
+
default: [],
|
|
720
1225
|
},
|
|
721
|
-
|
|
722
|
-
type:
|
|
723
|
-
default: false,
|
|
1226
|
+
access_level: {
|
|
1227
|
+
type: Number,
|
|
724
1228
|
},
|
|
725
|
-
|
|
1229
|
+
file_ids: { type: [String], default: undefined },
|
|
1230
|
+
actions: { type: [String], default: undefined },
|
|
1231
|
+
append_current_datetime: {
|
|
726
1232
|
type: Boolean,
|
|
727
1233
|
default: false,
|
|
728
1234
|
},
|
|
729
|
-
|
|
730
|
-
|
|
1235
|
+
}, {
|
|
1236
|
+
timestamps: true,
|
|
1237
|
+
});
|
|
1238
|
+
|
|
1239
|
+
const balanceSchema = new Schema({
|
|
1240
|
+
user: {
|
|
1241
|
+
type: Schema.Types.ObjectId,
|
|
1242
|
+
ref: 'User',
|
|
1243
|
+
index: true,
|
|
1244
|
+
required: true,
|
|
731
1245
|
},
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
enum: ['thumbsUp', 'thumbsDown'],
|
|
737
|
-
required: true,
|
|
738
|
-
},
|
|
739
|
-
tag: {
|
|
740
|
-
type: mongoose.Schema.Types.Mixed,
|
|
741
|
-
required: false,
|
|
742
|
-
},
|
|
743
|
-
text: {
|
|
744
|
-
type: String,
|
|
745
|
-
required: false,
|
|
746
|
-
},
|
|
747
|
-
},
|
|
748
|
-
default: undefined,
|
|
749
|
-
required: false,
|
|
1246
|
+
// 1000 tokenCredits = 1 mill ($0.001 USD)
|
|
1247
|
+
tokenCredits: {
|
|
1248
|
+
type: Number,
|
|
1249
|
+
default: 0,
|
|
750
1250
|
},
|
|
751
|
-
|
|
1251
|
+
// Automatic refill settings
|
|
1252
|
+
autoRefillEnabled: {
|
|
752
1253
|
type: Boolean,
|
|
753
|
-
required: false,
|
|
754
|
-
select: false,
|
|
755
1254
|
default: false,
|
|
756
1255
|
},
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
latest: {
|
|
761
|
-
type: String,
|
|
762
|
-
required: false,
|
|
763
|
-
},
|
|
764
|
-
inputs: {
|
|
765
|
-
type: [mongoose.Schema.Types.Mixed],
|
|
766
|
-
required: false,
|
|
767
|
-
default: undefined,
|
|
768
|
-
},
|
|
769
|
-
outputs: {
|
|
770
|
-
type: String,
|
|
771
|
-
required: false,
|
|
772
|
-
},
|
|
773
|
-
},
|
|
774
|
-
default: undefined,
|
|
775
|
-
},
|
|
776
|
-
plugins: { type: [{ type: mongoose.Schema.Types.Mixed }], default: undefined },
|
|
777
|
-
content: {
|
|
778
|
-
type: [{ type: mongoose.Schema.Types.Mixed }],
|
|
779
|
-
default: undefined,
|
|
780
|
-
meiliIndex: true,
|
|
781
|
-
},
|
|
782
|
-
thread_id: {
|
|
783
|
-
type: String,
|
|
1256
|
+
refillIntervalValue: {
|
|
1257
|
+
type: Number,
|
|
1258
|
+
default: 30,
|
|
784
1259
|
},
|
|
785
|
-
|
|
786
|
-
iconURL: {
|
|
1260
|
+
refillIntervalUnit: {
|
|
787
1261
|
type: String,
|
|
1262
|
+
enum: ['seconds', 'minutes', 'hours', 'days', 'weeks', 'months'],
|
|
1263
|
+
default: 'days',
|
|
788
1264
|
},
|
|
789
|
-
|
|
790
|
-
/*
|
|
791
|
-
attachments: {
|
|
792
|
-
type: [
|
|
793
|
-
{
|
|
794
|
-
file_id: String,
|
|
795
|
-
filename: String,
|
|
796
|
-
filepath: String,
|
|
797
|
-
expiresAt: Date,
|
|
798
|
-
width: Number,
|
|
799
|
-
height: Number,
|
|
800
|
-
type: String,
|
|
801
|
-
conversationId: String,
|
|
802
|
-
messageId: {
|
|
803
|
-
type: String,
|
|
804
|
-
required: true,
|
|
805
|
-
},
|
|
806
|
-
toolCallId: String,
|
|
807
|
-
},
|
|
808
|
-
],
|
|
809
|
-
default: undefined,
|
|
810
|
-
},
|
|
811
|
-
*/
|
|
812
|
-
expiredAt: {
|
|
1265
|
+
lastRefill: {
|
|
813
1266
|
type: Date,
|
|
1267
|
+
default: Date.now,
|
|
814
1268
|
},
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
1269
|
+
// amount to add on each refill
|
|
1270
|
+
refillAmount: {
|
|
1271
|
+
type: Number,
|
|
1272
|
+
default: 0,
|
|
1273
|
+
},
|
|
1274
|
+
});
|
|
819
1275
|
|
|
820
|
-
const
|
|
821
|
-
|
|
1276
|
+
const bannerSchema = new Schema({
|
|
1277
|
+
bannerId: {
|
|
822
1278
|
type: String,
|
|
823
1279
|
required: true,
|
|
824
1280
|
},
|
|
825
|
-
|
|
1281
|
+
message: {
|
|
826
1282
|
type: String,
|
|
827
1283
|
required: true,
|
|
828
1284
|
},
|
|
829
|
-
|
|
830
|
-
type:
|
|
1285
|
+
displayFrom: {
|
|
1286
|
+
type: Date,
|
|
831
1287
|
required: true,
|
|
1288
|
+
default: Date.now,
|
|
832
1289
|
},
|
|
833
|
-
|
|
1290
|
+
displayTo: {
|
|
1291
|
+
type: Date,
|
|
1292
|
+
},
|
|
1293
|
+
type: {
|
|
834
1294
|
type: String,
|
|
1295
|
+
enum: ['banner', 'popup'],
|
|
1296
|
+
default: 'banner',
|
|
1297
|
+
},
|
|
1298
|
+
isPublic: {
|
|
1299
|
+
type: Boolean,
|
|
1300
|
+
default: false,
|
|
835
1301
|
},
|
|
836
1302
|
}, { timestamps: true });
|
|
837
1303
|
|
|
838
|
-
const
|
|
839
|
-
|
|
1304
|
+
const categoriesSchema = new Schema({
|
|
1305
|
+
label: {
|
|
840
1306
|
type: String,
|
|
1307
|
+
required: true,
|
|
841
1308
|
unique: true,
|
|
1309
|
+
},
|
|
1310
|
+
value: {
|
|
1311
|
+
type: String,
|
|
842
1312
|
required: true,
|
|
843
|
-
|
|
1313
|
+
unique: true,
|
|
844
1314
|
},
|
|
845
|
-
|
|
1315
|
+
});
|
|
1316
|
+
|
|
1317
|
+
const conversationTag = new Schema({
|
|
1318
|
+
tag: {
|
|
846
1319
|
type: String,
|
|
847
|
-
|
|
848
|
-
meiliIndex: true,
|
|
1320
|
+
index: true,
|
|
849
1321
|
},
|
|
850
1322
|
user: {
|
|
851
1323
|
type: String,
|
|
852
|
-
|
|
1324
|
+
index: true,
|
|
853
1325
|
},
|
|
854
|
-
|
|
855
|
-
type:
|
|
1326
|
+
description: {
|
|
1327
|
+
type: String,
|
|
1328
|
+
index: true,
|
|
856
1329
|
},
|
|
857
|
-
|
|
1330
|
+
count: {
|
|
858
1331
|
type: Number,
|
|
1332
|
+
default: 0,
|
|
859
1333
|
},
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
1334
|
+
position: {
|
|
1335
|
+
type: Number,
|
|
1336
|
+
default: 0,
|
|
1337
|
+
index: true,
|
|
864
1338
|
},
|
|
865
1339
|
}, { timestamps: true });
|
|
1340
|
+
// Create a compound index on tag and user with unique constraint.
|
|
1341
|
+
conversationTag.index({ tag: 1, user: 1 }, { unique: true });
|
|
866
1342
|
|
|
867
|
-
|
|
868
|
-
|
|
1343
|
+
// @ts-ignore
|
|
1344
|
+
const conversationPreset = {
|
|
1345
|
+
// endpoint: [azureOpenAI, openAI, anthropic, chatGPTBrowser]
|
|
1346
|
+
endpoint: {
|
|
869
1347
|
type: String,
|
|
1348
|
+
default: null,
|
|
870
1349
|
required: true,
|
|
871
|
-
index: true,
|
|
872
|
-
},
|
|
873
|
-
promptGroupIds: {
|
|
874
|
-
type: [Schema.Types.ObjectId],
|
|
875
|
-
ref: 'PromptGroup',
|
|
876
|
-
default: [],
|
|
877
1350
|
},
|
|
878
|
-
|
|
879
|
-
type:
|
|
880
|
-
ref: 'Agent',
|
|
881
|
-
default: [],
|
|
1351
|
+
endpointType: {
|
|
1352
|
+
type: String,
|
|
882
1353
|
},
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
const promptSchema = new Schema({
|
|
888
|
-
groupId: {
|
|
889
|
-
type: Schema.Types.ObjectId,
|
|
890
|
-
ref: 'PromptGroup',
|
|
891
|
-
required: true,
|
|
892
|
-
index: true,
|
|
1354
|
+
// for azureOpenAI, openAI, chatGPTBrowser only
|
|
1355
|
+
model: {
|
|
1356
|
+
type: String,
|
|
1357
|
+
required: false,
|
|
893
1358
|
},
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
required:
|
|
1359
|
+
// for bedrock only
|
|
1360
|
+
region: {
|
|
1361
|
+
type: String,
|
|
1362
|
+
required: false,
|
|
898
1363
|
},
|
|
899
|
-
|
|
1364
|
+
// for azureOpenAI, openAI only
|
|
1365
|
+
chatGptLabel: {
|
|
900
1366
|
type: String,
|
|
901
|
-
required:
|
|
1367
|
+
required: false,
|
|
902
1368
|
},
|
|
903
|
-
|
|
1369
|
+
// for google only
|
|
1370
|
+
examples: { type: [{ type: Schema.Types.Mixed }], default: undefined },
|
|
1371
|
+
modelLabel: {
|
|
904
1372
|
type: String,
|
|
905
|
-
|
|
906
|
-
required: true,
|
|
1373
|
+
required: false,
|
|
907
1374
|
},
|
|
908
|
-
|
|
909
|
-
timestamps: true,
|
|
910
|
-
});
|
|
911
|
-
promptSchema.index({ createdAt: 1, updatedAt: 1 });
|
|
912
|
-
|
|
913
|
-
const promptGroupSchema = new Schema({
|
|
914
|
-
name: {
|
|
1375
|
+
promptPrefix: {
|
|
915
1376
|
type: String,
|
|
916
|
-
required:
|
|
917
|
-
index: true,
|
|
1377
|
+
required: false,
|
|
918
1378
|
},
|
|
919
|
-
|
|
1379
|
+
temperature: {
|
|
920
1380
|
type: Number,
|
|
921
|
-
|
|
1381
|
+
required: false,
|
|
922
1382
|
},
|
|
923
|
-
|
|
924
|
-
type:
|
|
925
|
-
|
|
1383
|
+
top_p: {
|
|
1384
|
+
type: Number,
|
|
1385
|
+
required: false,
|
|
926
1386
|
},
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
1387
|
+
// for google only
|
|
1388
|
+
topP: {
|
|
1389
|
+
type: Number,
|
|
1390
|
+
required: false,
|
|
931
1391
|
},
|
|
932
|
-
|
|
933
|
-
type:
|
|
934
|
-
|
|
935
|
-
index: true,
|
|
936
|
-
default: [],
|
|
1392
|
+
topK: {
|
|
1393
|
+
type: Number,
|
|
1394
|
+
required: false,
|
|
937
1395
|
},
|
|
938
|
-
|
|
939
|
-
type:
|
|
940
|
-
|
|
941
|
-
required: true,
|
|
942
|
-
index: true,
|
|
1396
|
+
maxOutputTokens: {
|
|
1397
|
+
type: Number,
|
|
1398
|
+
required: false,
|
|
943
1399
|
},
|
|
944
|
-
|
|
945
|
-
type:
|
|
946
|
-
|
|
947
|
-
required: true,
|
|
948
|
-
index: true,
|
|
1400
|
+
maxTokens: {
|
|
1401
|
+
type: Number,
|
|
1402
|
+
required: false,
|
|
949
1403
|
},
|
|
950
|
-
|
|
1404
|
+
presence_penalty: {
|
|
1405
|
+
type: Number,
|
|
1406
|
+
required: false,
|
|
1407
|
+
},
|
|
1408
|
+
frequency_penalty: {
|
|
1409
|
+
type: Number,
|
|
1410
|
+
required: false,
|
|
1411
|
+
},
|
|
1412
|
+
file_ids: { type: [{ type: String }], default: undefined },
|
|
1413
|
+
// deprecated
|
|
1414
|
+
resendImages: {
|
|
1415
|
+
type: Boolean,
|
|
1416
|
+
},
|
|
1417
|
+
/* Anthropic only */
|
|
1418
|
+
promptCache: {
|
|
1419
|
+
type: Boolean,
|
|
1420
|
+
},
|
|
1421
|
+
thinking: {
|
|
1422
|
+
type: Boolean,
|
|
1423
|
+
},
|
|
1424
|
+
thinkingBudget: {
|
|
1425
|
+
type: Number,
|
|
1426
|
+
},
|
|
1427
|
+
system: {
|
|
951
1428
|
type: String,
|
|
952
|
-
required: true,
|
|
953
1429
|
},
|
|
954
|
-
|
|
1430
|
+
// files
|
|
1431
|
+
resendFiles: {
|
|
1432
|
+
type: Boolean,
|
|
1433
|
+
},
|
|
1434
|
+
imageDetail: {
|
|
955
1435
|
type: String,
|
|
956
|
-
index: true,
|
|
957
|
-
validate: {
|
|
958
|
-
validator: function (v) {
|
|
959
|
-
return v === undefined || v === null || v === '' || /^[a-z0-9-]+$/.test(v);
|
|
960
|
-
},
|
|
961
|
-
message: (props) => { var _a; return `${(_a = props === null || props === void 0 ? void 0 : props.value) !== null && _a !== void 0 ? _a : 'Value'} is not a valid command. Only lowercase alphanumeric characters and hyphens are allowed.`; },
|
|
962
|
-
},
|
|
963
|
-
maxlength: [
|
|
964
|
-
Constants.COMMANDS_MAX_LENGTH,
|
|
965
|
-
`Command cannot be longer than ${Constants.COMMANDS_MAX_LENGTH} characters`,
|
|
966
|
-
],
|
|
967
|
-
}, // Casting here bypasses the type error for the command field.
|
|
968
|
-
}, {
|
|
969
|
-
timestamps: true,
|
|
970
|
-
});
|
|
971
|
-
promptGroupSchema.index({ createdAt: 1, updatedAt: 1 });
|
|
972
|
-
|
|
973
|
-
/**
|
|
974
|
-
* Uses a sub-schema for permissions. Notice we disable `_id` for this subdocument.
|
|
975
|
-
*/
|
|
976
|
-
const rolePermissionsSchema = new Schema({
|
|
977
|
-
[PermissionTypes.BOOKMARKS]: {
|
|
978
|
-
[Permissions.USE]: { type: Boolean },
|
|
979
1436
|
},
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
[Permissions.CREATE]: { type: Boolean },
|
|
1437
|
+
/* agents */
|
|
1438
|
+
agent_id: {
|
|
1439
|
+
type: String,
|
|
984
1440
|
},
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
1441
|
+
/* assistants */
|
|
1442
|
+
assistant_id: {
|
|
1443
|
+
type: String,
|
|
1444
|
+
},
|
|
1445
|
+
instructions: {
|
|
1446
|
+
type: String,
|
|
991
1447
|
},
|
|
992
|
-
[
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
1448
|
+
stop: { type: [{ type: String }], default: undefined },
|
|
1449
|
+
isArchived: {
|
|
1450
|
+
type: Boolean,
|
|
1451
|
+
default: false,
|
|
996
1452
|
},
|
|
997
|
-
|
|
998
|
-
|
|
1453
|
+
/* UI Components */
|
|
1454
|
+
iconURL: {
|
|
1455
|
+
type: String,
|
|
999
1456
|
},
|
|
1000
|
-
|
|
1001
|
-
|
|
1457
|
+
greeting: {
|
|
1458
|
+
type: String,
|
|
1002
1459
|
},
|
|
1003
|
-
|
|
1004
|
-
|
|
1460
|
+
spec: {
|
|
1461
|
+
type: String,
|
|
1005
1462
|
},
|
|
1006
|
-
|
|
1007
|
-
|
|
1463
|
+
tags: {
|
|
1464
|
+
type: [String],
|
|
1465
|
+
default: [],
|
|
1008
1466
|
},
|
|
1009
|
-
[
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
[Permissions.VIEW_ROLES]: { type: Boolean },
|
|
1467
|
+
tools: { type: [{ type: String }], default: undefined },
|
|
1468
|
+
maxContextTokens: {
|
|
1469
|
+
type: Number,
|
|
1013
1470
|
},
|
|
1014
|
-
|
|
1015
|
-
|
|
1471
|
+
max_tokens: {
|
|
1472
|
+
type: Number,
|
|
1016
1473
|
},
|
|
1017
|
-
|
|
1018
|
-
|
|
1474
|
+
useResponsesApi: {
|
|
1475
|
+
type: Boolean,
|
|
1019
1476
|
},
|
|
1020
|
-
|
|
1021
|
-
|
|
1477
|
+
/** OpenAI Responses API / Anthropic API / Google API */
|
|
1478
|
+
web_search: {
|
|
1479
|
+
type: Boolean,
|
|
1022
1480
|
},
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
name: { type: String, required: true, unique: true, index: true },
|
|
1026
|
-
permissions: {
|
|
1027
|
-
type: rolePermissionsSchema,
|
|
1481
|
+
disableStreaming: {
|
|
1482
|
+
type: Boolean,
|
|
1028
1483
|
},
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1484
|
+
fileTokenLimit: {
|
|
1485
|
+
type: Number,
|
|
1486
|
+
},
|
|
1487
|
+
/** Reasoning models only */
|
|
1488
|
+
reasoning_effort: {
|
|
1033
1489
|
type: String,
|
|
1034
|
-
required: true,
|
|
1035
1490
|
},
|
|
1036
|
-
|
|
1037
|
-
type:
|
|
1038
|
-
required: true,
|
|
1039
|
-
expires: 0,
|
|
1491
|
+
reasoning_summary: {
|
|
1492
|
+
type: String,
|
|
1040
1493
|
},
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
required: true,
|
|
1494
|
+
/** Verbosity control */
|
|
1495
|
+
verbosity: {
|
|
1496
|
+
type: String,
|
|
1045
1497
|
},
|
|
1046
|
-
}
|
|
1498
|
+
};
|
|
1047
1499
|
|
|
1048
|
-
const
|
|
1500
|
+
const convoSchema = new Schema({
|
|
1049
1501
|
conversationId: {
|
|
1050
1502
|
type: String,
|
|
1503
|
+
unique: true,
|
|
1051
1504
|
required: true,
|
|
1505
|
+
index: true,
|
|
1506
|
+
meiliIndex: true,
|
|
1052
1507
|
},
|
|
1053
1508
|
title: {
|
|
1054
1509
|
type: String,
|
|
1055
|
-
|
|
1510
|
+
default: 'New Chat',
|
|
1511
|
+
meiliIndex: true,
|
|
1056
1512
|
},
|
|
1057
1513
|
user: {
|
|
1058
1514
|
type: String,
|
|
1059
1515
|
index: true,
|
|
1516
|
+
meiliIndex: true,
|
|
1060
1517
|
},
|
|
1061
|
-
messages: [{ type:
|
|
1062
|
-
|
|
1518
|
+
messages: [{ type: Schema.Types.ObjectId, ref: 'Message' }],
|
|
1519
|
+
agentOptions: {
|
|
1520
|
+
type: Schema.Types.Mixed,
|
|
1521
|
+
},
|
|
1522
|
+
...conversationPreset,
|
|
1523
|
+
agent_id: {
|
|
1063
1524
|
type: String,
|
|
1064
|
-
index: true,
|
|
1065
1525
|
},
|
|
1066
|
-
|
|
1067
|
-
type:
|
|
1068
|
-
default:
|
|
1526
|
+
tags: {
|
|
1527
|
+
type: [String],
|
|
1528
|
+
default: [],
|
|
1529
|
+
meiliIndex: true,
|
|
1530
|
+
},
|
|
1531
|
+
files: {
|
|
1532
|
+
type: [String],
|
|
1533
|
+
},
|
|
1534
|
+
expiredAt: {
|
|
1535
|
+
type: Date,
|
|
1069
1536
|
},
|
|
1070
1537
|
}, { timestamps: true });
|
|
1538
|
+
convoSchema.index({ expiredAt: 1 }, { expireAfterSeconds: 0 });
|
|
1539
|
+
convoSchema.index({ createdAt: 1, updatedAt: 1 });
|
|
1540
|
+
convoSchema.index({ conversationId: 1, user: 1 }, { unique: true });
|
|
1071
1541
|
|
|
1072
|
-
const
|
|
1073
|
-
|
|
1074
|
-
type: Schema.Types.ObjectId,
|
|
1542
|
+
const file = new Schema({
|
|
1543
|
+
user: {
|
|
1544
|
+
type: mongoose.Schema.Types.ObjectId,
|
|
1545
|
+
ref: 'User',
|
|
1546
|
+
index: true,
|
|
1075
1547
|
required: true,
|
|
1076
|
-
ref: 'user',
|
|
1077
|
-
},
|
|
1078
|
-
email: {
|
|
1079
|
-
type: String,
|
|
1080
1548
|
},
|
|
1081
|
-
|
|
1082
|
-
type: String,
|
|
1083
|
-
},
|
|
1084
|
-
identifier: {
|
|
1549
|
+
conversationId: {
|
|
1085
1550
|
type: String,
|
|
1551
|
+
ref: 'Conversation',
|
|
1552
|
+
index: true,
|
|
1086
1553
|
},
|
|
1087
|
-
|
|
1554
|
+
file_id: {
|
|
1088
1555
|
type: String,
|
|
1556
|
+
index: true,
|
|
1089
1557
|
required: true,
|
|
1090
1558
|
},
|
|
1091
|
-
|
|
1092
|
-
type:
|
|
1093
|
-
required: true,
|
|
1094
|
-
default: Date.now,
|
|
1559
|
+
temp_file_id: {
|
|
1560
|
+
type: String,
|
|
1095
1561
|
},
|
|
1096
|
-
|
|
1097
|
-
type:
|
|
1562
|
+
bytes: {
|
|
1563
|
+
type: Number,
|
|
1098
1564
|
required: true,
|
|
1099
1565
|
},
|
|
1100
|
-
|
|
1101
|
-
type: Map,
|
|
1102
|
-
of: Schema.Types.Mixed,
|
|
1103
|
-
},
|
|
1104
|
-
});
|
|
1105
|
-
tokenSchema.index({ expiresAt: 1 }, { expireAfterSeconds: 0 });
|
|
1106
|
-
|
|
1107
|
-
const toolCallSchema = new Schema({
|
|
1108
|
-
conversationId: {
|
|
1566
|
+
filename: {
|
|
1109
1567
|
type: String,
|
|
1110
1568
|
required: true,
|
|
1111
1569
|
},
|
|
1112
|
-
|
|
1570
|
+
filepath: {
|
|
1113
1571
|
type: String,
|
|
1114
1572
|
required: true,
|
|
1115
1573
|
},
|
|
1116
|
-
|
|
1574
|
+
object: {
|
|
1117
1575
|
type: String,
|
|
1118
1576
|
required: true,
|
|
1577
|
+
default: 'file',
|
|
1119
1578
|
},
|
|
1120
|
-
|
|
1121
|
-
type:
|
|
1122
|
-
ref: 'User',
|
|
1123
|
-
required: true,
|
|
1579
|
+
embedded: {
|
|
1580
|
+
type: Boolean,
|
|
1124
1581
|
},
|
|
1125
|
-
|
|
1126
|
-
type:
|
|
1582
|
+
type: {
|
|
1583
|
+
type: String,
|
|
1584
|
+
required: true,
|
|
1127
1585
|
},
|
|
1128
|
-
|
|
1129
|
-
type:
|
|
1586
|
+
text: {
|
|
1587
|
+
type: String,
|
|
1130
1588
|
},
|
|
1131
|
-
|
|
1132
|
-
type:
|
|
1589
|
+
context: {
|
|
1590
|
+
type: String,
|
|
1133
1591
|
},
|
|
1134
|
-
|
|
1592
|
+
usage: {
|
|
1135
1593
|
type: Number,
|
|
1136
|
-
},
|
|
1137
|
-
}, { timestamps: true });
|
|
1138
|
-
toolCallSchema.index({ messageId: 1, user: 1 });
|
|
1139
|
-
toolCallSchema.index({ conversationId: 1, user: 1 });
|
|
1140
|
-
|
|
1141
|
-
const transactionSchema = new Schema({
|
|
1142
|
-
user: {
|
|
1143
|
-
type: mongoose.Schema.Types.ObjectId,
|
|
1144
|
-
ref: 'User',
|
|
1145
|
-
index: true,
|
|
1146
1594
|
required: true,
|
|
1595
|
+
default: 0,
|
|
1147
1596
|
},
|
|
1148
|
-
|
|
1149
|
-
type: String,
|
|
1150
|
-
ref: 'Conversation',
|
|
1151
|
-
index: true,
|
|
1152
|
-
},
|
|
1153
|
-
tokenType: {
|
|
1597
|
+
source: {
|
|
1154
1598
|
type: String,
|
|
1155
|
-
|
|
1156
|
-
required: true,
|
|
1599
|
+
default: FileSources.local,
|
|
1157
1600
|
},
|
|
1158
1601
|
model: {
|
|
1159
1602
|
type: String,
|
|
1160
1603
|
},
|
|
1161
|
-
|
|
1162
|
-
|
|
1604
|
+
width: Number,
|
|
1605
|
+
height: Number,
|
|
1606
|
+
metadata: {
|
|
1607
|
+
fileIdentifier: String,
|
|
1163
1608
|
},
|
|
1164
|
-
|
|
1165
|
-
type:
|
|
1609
|
+
expiresAt: {
|
|
1610
|
+
type: Date,
|
|
1611
|
+
expires: 3600, // 1 hour in seconds
|
|
1166
1612
|
},
|
|
1167
|
-
rate: Number,
|
|
1168
|
-
rawAmount: Number,
|
|
1169
|
-
tokenValue: Number,
|
|
1170
|
-
inputTokens: { type: Number },
|
|
1171
|
-
writeTokens: { type: Number },
|
|
1172
|
-
readTokens: { type: Number },
|
|
1173
1613
|
}, {
|
|
1174
1614
|
timestamps: true,
|
|
1175
1615
|
});
|
|
1616
|
+
file.index({ createdAt: 1, updatedAt: 1 });
|
|
1176
1617
|
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1618
|
+
const keySchema = new Schema({
|
|
1619
|
+
userId: {
|
|
1620
|
+
type: mongoose.Schema.Types.ObjectId,
|
|
1621
|
+
ref: 'User',
|
|
1622
|
+
required: true,
|
|
1182
1623
|
},
|
|
1183
|
-
}, { _id: false });
|
|
1184
|
-
// Backup code sub-schema
|
|
1185
|
-
const BackupCodeSchema = new Schema({
|
|
1186
|
-
codeHash: { type: String, required: true },
|
|
1187
|
-
used: { type: Boolean, default: false },
|
|
1188
|
-
usedAt: { type: Date, default: null },
|
|
1189
|
-
}, { _id: false });
|
|
1190
|
-
const userSchema = new Schema({
|
|
1191
1624
|
name: {
|
|
1192
1625
|
type: String,
|
|
1626
|
+
required: true,
|
|
1193
1627
|
},
|
|
1194
|
-
|
|
1628
|
+
value: {
|
|
1195
1629
|
type: String,
|
|
1196
|
-
|
|
1197
|
-
default: '',
|
|
1630
|
+
required: true,
|
|
1198
1631
|
},
|
|
1199
|
-
|
|
1632
|
+
expiresAt: {
|
|
1633
|
+
type: Date,
|
|
1634
|
+
},
|
|
1635
|
+
});
|
|
1636
|
+
keySchema.index({ expiresAt: 1 }, { expireAfterSeconds: 0 });
|
|
1637
|
+
|
|
1638
|
+
const messageSchema = new Schema({
|
|
1639
|
+
messageId: {
|
|
1200
1640
|
type: String,
|
|
1201
|
-
required: [true, "can't be blank"],
|
|
1202
|
-
lowercase: true,
|
|
1203
1641
|
unique: true,
|
|
1204
|
-
|
|
1642
|
+
required: true,
|
|
1205
1643
|
index: true,
|
|
1644
|
+
meiliIndex: true,
|
|
1206
1645
|
},
|
|
1207
|
-
|
|
1208
|
-
type:
|
|
1646
|
+
conversationId: {
|
|
1647
|
+
type: String,
|
|
1648
|
+
index: true,
|
|
1209
1649
|
required: true,
|
|
1210
|
-
|
|
1650
|
+
meiliIndex: true,
|
|
1211
1651
|
},
|
|
1212
|
-
|
|
1652
|
+
user: {
|
|
1213
1653
|
type: String,
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1654
|
+
index: true,
|
|
1655
|
+
required: true,
|
|
1656
|
+
default: null,
|
|
1657
|
+
meiliIndex: true,
|
|
1218
1658
|
},
|
|
1219
|
-
|
|
1659
|
+
model: {
|
|
1220
1660
|
type: String,
|
|
1221
|
-
|
|
1661
|
+
default: null,
|
|
1222
1662
|
},
|
|
1223
|
-
|
|
1663
|
+
endpoint: {
|
|
1224
1664
|
type: String,
|
|
1225
|
-
required: true,
|
|
1226
|
-
default: 'local',
|
|
1227
1665
|
},
|
|
1228
|
-
|
|
1666
|
+
conversationSignature: {
|
|
1229
1667
|
type: String,
|
|
1230
|
-
default: SystemRoles.USER,
|
|
1231
1668
|
},
|
|
1232
|
-
|
|
1669
|
+
clientId: {
|
|
1233
1670
|
type: String,
|
|
1234
|
-
unique: true,
|
|
1235
|
-
sparse: true,
|
|
1236
1671
|
},
|
|
1237
|
-
|
|
1238
|
-
type:
|
|
1239
|
-
unique: true,
|
|
1240
|
-
sparse: true,
|
|
1672
|
+
invocationId: {
|
|
1673
|
+
type: Number,
|
|
1241
1674
|
},
|
|
1242
|
-
|
|
1675
|
+
parentMessageId: {
|
|
1243
1676
|
type: String,
|
|
1244
|
-
unique: true,
|
|
1245
|
-
sparse: true,
|
|
1246
1677
|
},
|
|
1247
|
-
|
|
1248
|
-
type:
|
|
1249
|
-
unique: true,
|
|
1250
|
-
sparse: true,
|
|
1678
|
+
tokenCount: {
|
|
1679
|
+
type: Number,
|
|
1251
1680
|
},
|
|
1252
|
-
|
|
1253
|
-
type:
|
|
1254
|
-
unique: true,
|
|
1255
|
-
sparse: true,
|
|
1681
|
+
summaryTokenCount: {
|
|
1682
|
+
type: Number,
|
|
1256
1683
|
},
|
|
1257
|
-
|
|
1684
|
+
sender: {
|
|
1258
1685
|
type: String,
|
|
1259
|
-
|
|
1260
|
-
sparse: true,
|
|
1686
|
+
meiliIndex: true,
|
|
1261
1687
|
},
|
|
1262
|
-
|
|
1688
|
+
text: {
|
|
1263
1689
|
type: String,
|
|
1264
|
-
|
|
1265
|
-
sparse: true,
|
|
1690
|
+
meiliIndex: true,
|
|
1266
1691
|
},
|
|
1267
|
-
|
|
1692
|
+
summary: {
|
|
1268
1693
|
type: String,
|
|
1269
|
-
unique: true,
|
|
1270
|
-
sparse: true,
|
|
1271
|
-
},
|
|
1272
|
-
plugins: {
|
|
1273
|
-
type: Array,
|
|
1274
1694
|
},
|
|
1275
|
-
|
|
1695
|
+
isCreatedByUser: {
|
|
1276
1696
|
type: Boolean,
|
|
1697
|
+
required: true,
|
|
1277
1698
|
default: false,
|
|
1278
1699
|
},
|
|
1279
|
-
|
|
1280
|
-
type:
|
|
1281
|
-
|
|
1700
|
+
unfinished: {
|
|
1701
|
+
type: Boolean,
|
|
1702
|
+
default: false,
|
|
1282
1703
|
},
|
|
1283
|
-
|
|
1284
|
-
type:
|
|
1285
|
-
|
|
1704
|
+
error: {
|
|
1705
|
+
type: Boolean,
|
|
1706
|
+
default: false,
|
|
1286
1707
|
},
|
|
1287
|
-
|
|
1288
|
-
type:
|
|
1708
|
+
finish_reason: {
|
|
1709
|
+
type: String,
|
|
1289
1710
|
},
|
|
1290
|
-
|
|
1291
|
-
type:
|
|
1292
|
-
|
|
1711
|
+
feedback: {
|
|
1712
|
+
type: {
|
|
1713
|
+
rating: {
|
|
1714
|
+
type: String,
|
|
1715
|
+
enum: ['thumbsUp', 'thumbsDown'],
|
|
1716
|
+
required: true,
|
|
1717
|
+
},
|
|
1718
|
+
tag: {
|
|
1719
|
+
type: mongoose.Schema.Types.Mixed,
|
|
1720
|
+
required: false,
|
|
1721
|
+
},
|
|
1722
|
+
text: {
|
|
1723
|
+
type: String,
|
|
1724
|
+
required: false,
|
|
1725
|
+
},
|
|
1726
|
+
},
|
|
1727
|
+
default: undefined,
|
|
1728
|
+
required: false,
|
|
1293
1729
|
},
|
|
1294
|
-
|
|
1730
|
+
_meiliIndex: {
|
|
1295
1731
|
type: Boolean,
|
|
1732
|
+
required: false,
|
|
1733
|
+
select: false,
|
|
1296
1734
|
default: false,
|
|
1297
1735
|
},
|
|
1298
|
-
|
|
1736
|
+
files: { type: [{ type: mongoose.Schema.Types.Mixed }], default: undefined },
|
|
1737
|
+
plugin: {
|
|
1299
1738
|
type: {
|
|
1300
|
-
|
|
1301
|
-
type:
|
|
1302
|
-
|
|
1739
|
+
latest: {
|
|
1740
|
+
type: String,
|
|
1741
|
+
required: false,
|
|
1742
|
+
},
|
|
1743
|
+
inputs: {
|
|
1744
|
+
type: [mongoose.Schema.Types.Mixed],
|
|
1745
|
+
required: false,
|
|
1746
|
+
default: undefined,
|
|
1747
|
+
},
|
|
1748
|
+
outputs: {
|
|
1749
|
+
type: String,
|
|
1750
|
+
required: false,
|
|
1303
1751
|
},
|
|
1304
1752
|
},
|
|
1305
|
-
default:
|
|
1753
|
+
default: undefined,
|
|
1306
1754
|
},
|
|
1307
|
-
|
|
1308
|
-
|
|
1755
|
+
plugins: { type: [{ type: mongoose.Schema.Types.Mixed }], default: undefined },
|
|
1756
|
+
content: {
|
|
1757
|
+
type: [{ type: mongoose.Schema.Types.Mixed }],
|
|
1758
|
+
default: undefined,
|
|
1759
|
+
meiliIndex: true,
|
|
1760
|
+
},
|
|
1761
|
+
thread_id: {
|
|
1309
1762
|
type: String,
|
|
1310
|
-
|
|
1763
|
+
},
|
|
1764
|
+
/* frontend components */
|
|
1765
|
+
iconURL: {
|
|
1766
|
+
type: String,
|
|
1767
|
+
},
|
|
1768
|
+
metadata: { type: mongoose.Schema.Types.Mixed },
|
|
1769
|
+
attachments: { type: [{ type: mongoose.Schema.Types.Mixed }], default: undefined },
|
|
1770
|
+
/*
|
|
1771
|
+
attachments: {
|
|
1772
|
+
type: [
|
|
1773
|
+
{
|
|
1774
|
+
file_id: String,
|
|
1775
|
+
filename: String,
|
|
1776
|
+
filepath: String,
|
|
1777
|
+
expiresAt: Date,
|
|
1778
|
+
width: Number,
|
|
1779
|
+
height: Number,
|
|
1780
|
+
type: String,
|
|
1781
|
+
conversationId: String,
|
|
1782
|
+
messageId: {
|
|
1783
|
+
type: String,
|
|
1784
|
+
required: true,
|
|
1785
|
+
},
|
|
1786
|
+
toolCallId: String,
|
|
1787
|
+
},
|
|
1788
|
+
],
|
|
1789
|
+
default: undefined,
|
|
1790
|
+
},
|
|
1791
|
+
*/
|
|
1792
|
+
expiredAt: {
|
|
1793
|
+
type: Date,
|
|
1311
1794
|
},
|
|
1312
1795
|
}, { timestamps: true });
|
|
1796
|
+
messageSchema.index({ expiredAt: 1 }, { expireAfterSeconds: 0 });
|
|
1797
|
+
messageSchema.index({ createdAt: 1 });
|
|
1798
|
+
messageSchema.index({ messageId: 1, user: 1 }, { unique: true });
|
|
1313
1799
|
|
|
1314
|
-
const
|
|
1315
|
-
|
|
1316
|
-
type:
|
|
1317
|
-
ref: 'User',
|
|
1318
|
-
index: true,
|
|
1800
|
+
const pluginAuthSchema = new Schema({
|
|
1801
|
+
authField: {
|
|
1802
|
+
type: String,
|
|
1319
1803
|
required: true,
|
|
1320
1804
|
},
|
|
1321
|
-
|
|
1805
|
+
value: {
|
|
1322
1806
|
type: String,
|
|
1323
1807
|
required: true,
|
|
1324
|
-
validate: {
|
|
1325
|
-
validator: (v) => /^[a-z_]+$/.test(v),
|
|
1326
|
-
message: 'Key must only contain lowercase letters and underscores',
|
|
1327
|
-
},
|
|
1328
1808
|
},
|
|
1329
|
-
|
|
1809
|
+
userId: {
|
|
1330
1810
|
type: String,
|
|
1331
1811
|
required: true,
|
|
1332
1812
|
},
|
|
1333
|
-
|
|
1813
|
+
pluginKey: {
|
|
1814
|
+
type: String,
|
|
1815
|
+
},
|
|
1816
|
+
}, { timestamps: true });
|
|
1817
|
+
|
|
1818
|
+
const presetSchema = new Schema({
|
|
1819
|
+
presetId: {
|
|
1820
|
+
type: String,
|
|
1821
|
+
unique: true,
|
|
1822
|
+
required: true,
|
|
1823
|
+
index: true,
|
|
1824
|
+
},
|
|
1825
|
+
title: {
|
|
1826
|
+
type: String,
|
|
1827
|
+
default: 'New Chat',
|
|
1828
|
+
meiliIndex: true,
|
|
1829
|
+
},
|
|
1830
|
+
user: {
|
|
1831
|
+
type: String,
|
|
1832
|
+
default: null,
|
|
1833
|
+
},
|
|
1834
|
+
defaultPreset: {
|
|
1835
|
+
type: Boolean,
|
|
1836
|
+
},
|
|
1837
|
+
order: {
|
|
1334
1838
|
type: Number,
|
|
1335
|
-
default: 0,
|
|
1336
1839
|
},
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1840
|
+
...conversationPreset,
|
|
1841
|
+
agentOptions: {
|
|
1842
|
+
type: mongoose.Schema.Types.Mixed,
|
|
1843
|
+
default: null,
|
|
1340
1844
|
},
|
|
1341
|
-
});
|
|
1845
|
+
}, { timestamps: true });
|
|
1342
1846
|
|
|
1343
|
-
const
|
|
1847
|
+
const projectSchema = new Schema({
|
|
1344
1848
|
name: {
|
|
1345
1849
|
type: String,
|
|
1346
1850
|
required: true,
|
|
1347
1851
|
index: true,
|
|
1348
1852
|
},
|
|
1349
|
-
|
|
1350
|
-
type:
|
|
1351
|
-
|
|
1853
|
+
promptGroupIds: {
|
|
1854
|
+
type: [Schema.Types.ObjectId],
|
|
1855
|
+
ref: 'PromptGroup',
|
|
1856
|
+
default: [],
|
|
1352
1857
|
},
|
|
1353
|
-
|
|
1354
|
-
type: String,
|
|
1355
|
-
|
|
1858
|
+
agentIds: {
|
|
1859
|
+
type: [String],
|
|
1860
|
+
ref: 'Agent',
|
|
1861
|
+
default: [],
|
|
1862
|
+
},
|
|
1863
|
+
}, {
|
|
1864
|
+
timestamps: true,
|
|
1865
|
+
});
|
|
1866
|
+
|
|
1867
|
+
const promptSchema = new Schema({
|
|
1868
|
+
groupId: {
|
|
1869
|
+
type: Schema.Types.ObjectId,
|
|
1870
|
+
ref: 'PromptGroup',
|
|
1871
|
+
required: true,
|
|
1356
1872
|
index: true,
|
|
1357
1873
|
},
|
|
1358
|
-
|
|
1359
|
-
type:
|
|
1360
|
-
|
|
1874
|
+
author: {
|
|
1875
|
+
type: Schema.Types.ObjectId,
|
|
1876
|
+
ref: 'User',
|
|
1877
|
+
required: true,
|
|
1361
1878
|
},
|
|
1362
|
-
|
|
1363
|
-
{
|
|
1364
|
-
type: String,
|
|
1365
|
-
required: false,
|
|
1366
|
-
},
|
|
1367
|
-
],
|
|
1368
|
-
source: {
|
|
1879
|
+
prompt: {
|
|
1369
1880
|
type: String,
|
|
1370
|
-
|
|
1371
|
-
default: 'local',
|
|
1881
|
+
required: true,
|
|
1372
1882
|
},
|
|
1373
|
-
|
|
1374
|
-
idOnTheSource: {
|
|
1883
|
+
type: {
|
|
1375
1884
|
type: String,
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
required: function () {
|
|
1379
|
-
return this.source !== 'local';
|
|
1380
|
-
},
|
|
1885
|
+
enum: ['text', 'chat'],
|
|
1886
|
+
required: true,
|
|
1381
1887
|
},
|
|
1382
|
-
}, {
|
|
1383
|
-
|
|
1384
|
-
unique: true,
|
|
1385
|
-
partialFilterExpression: { idOnTheSource: { $exists: true } },
|
|
1888
|
+
}, {
|
|
1889
|
+
timestamps: true,
|
|
1386
1890
|
});
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
/**
|
|
1390
|
-
* ESM-native object traversal utility
|
|
1391
|
-
* Simplified implementation focused on the forEach use case
|
|
1392
|
-
*/
|
|
1393
|
-
function isObject(value) {
|
|
1394
|
-
if (value === null || typeof value !== 'object') {
|
|
1395
|
-
return false;
|
|
1396
|
-
}
|
|
1397
|
-
// Treat these built-in types as leaf nodes, not objects to traverse
|
|
1398
|
-
if (value instanceof Date)
|
|
1399
|
-
return false;
|
|
1400
|
-
if (value instanceof RegExp)
|
|
1401
|
-
return false;
|
|
1402
|
-
if (value instanceof Error)
|
|
1403
|
-
return false;
|
|
1404
|
-
if (value instanceof URL)
|
|
1405
|
-
return false;
|
|
1406
|
-
// Check for Buffer (Node.js)
|
|
1407
|
-
if (typeof Buffer !== 'undefined' && Buffer.isBuffer(value))
|
|
1408
|
-
return false;
|
|
1409
|
-
// Check for TypedArrays and ArrayBuffer
|
|
1410
|
-
if (ArrayBuffer.isView(value))
|
|
1411
|
-
return false;
|
|
1412
|
-
if (value instanceof ArrayBuffer)
|
|
1413
|
-
return false;
|
|
1414
|
-
if (value instanceof SharedArrayBuffer)
|
|
1415
|
-
return false;
|
|
1416
|
-
// Check for other built-in types that shouldn't be traversed
|
|
1417
|
-
if (value instanceof Promise)
|
|
1418
|
-
return false;
|
|
1419
|
-
if (value instanceof WeakMap)
|
|
1420
|
-
return false;
|
|
1421
|
-
if (value instanceof WeakSet)
|
|
1422
|
-
return false;
|
|
1423
|
-
if (value instanceof Map)
|
|
1424
|
-
return false;
|
|
1425
|
-
if (value instanceof Set)
|
|
1426
|
-
return false;
|
|
1427
|
-
// Check if it's a primitive wrapper object
|
|
1428
|
-
const stringTag = Object.prototype.toString.call(value);
|
|
1429
|
-
if (stringTag === '[object Boolean]' ||
|
|
1430
|
-
stringTag === '[object Number]' ||
|
|
1431
|
-
stringTag === '[object String]') {
|
|
1432
|
-
return false;
|
|
1433
|
-
}
|
|
1434
|
-
return true;
|
|
1435
|
-
}
|
|
1436
|
-
// Helper to safely set a property on an object or array
|
|
1437
|
-
function setProperty(obj, key, value) {
|
|
1438
|
-
if (Array.isArray(obj) && typeof key === 'number') {
|
|
1439
|
-
obj[key] = value;
|
|
1440
|
-
}
|
|
1441
|
-
else if (!Array.isArray(obj) && typeof key === 'string') {
|
|
1442
|
-
obj[key] = value;
|
|
1443
|
-
}
|
|
1444
|
-
else if (!Array.isArray(obj) && typeof key === 'number') {
|
|
1445
|
-
// Handle numeric keys on objects
|
|
1446
|
-
obj[key] = value;
|
|
1447
|
-
}
|
|
1448
|
-
}
|
|
1449
|
-
// Helper to safely delete a property from an object
|
|
1450
|
-
function deleteProperty(obj, key) {
|
|
1451
|
-
if (Array.isArray(obj) && typeof key === 'number') {
|
|
1452
|
-
// For arrays, we should use splice, but this is handled in remove()
|
|
1453
|
-
// This function is only called for non-array deletion
|
|
1454
|
-
return;
|
|
1455
|
-
}
|
|
1456
|
-
if (!Array.isArray(obj)) {
|
|
1457
|
-
delete obj[key];
|
|
1458
|
-
}
|
|
1459
|
-
}
|
|
1460
|
-
function forEach(obj, callback) {
|
|
1461
|
-
const visited = new WeakSet();
|
|
1462
|
-
function walk(node, path = [], parent) {
|
|
1463
|
-
// Check for circular references
|
|
1464
|
-
let circular = null;
|
|
1465
|
-
if (isObject(node)) {
|
|
1466
|
-
if (visited.has(node)) {
|
|
1467
|
-
// Find the circular reference in the parent chain
|
|
1468
|
-
let p = parent;
|
|
1469
|
-
while (p) {
|
|
1470
|
-
if (p.node === node) {
|
|
1471
|
-
circular = p;
|
|
1472
|
-
break;
|
|
1473
|
-
}
|
|
1474
|
-
p = p.parent;
|
|
1475
|
-
}
|
|
1476
|
-
return; // Skip circular references
|
|
1477
|
-
}
|
|
1478
|
-
visited.add(node);
|
|
1479
|
-
}
|
|
1480
|
-
const key = path.length > 0 ? path[path.length - 1] : undefined;
|
|
1481
|
-
const isRoot = path.length === 0;
|
|
1482
|
-
const level = path.length;
|
|
1483
|
-
// Determine if this is a leaf node
|
|
1484
|
-
const isLeaf = !isObject(node) ||
|
|
1485
|
-
(Array.isArray(node) && node.length === 0) ||
|
|
1486
|
-
Object.keys(node).length === 0;
|
|
1487
|
-
// Create context
|
|
1488
|
-
const context = {
|
|
1489
|
-
node,
|
|
1490
|
-
path: [...path],
|
|
1491
|
-
parent,
|
|
1492
|
-
key,
|
|
1493
|
-
isLeaf,
|
|
1494
|
-
notLeaf: !isLeaf,
|
|
1495
|
-
isRoot,
|
|
1496
|
-
notRoot: !isRoot,
|
|
1497
|
-
level,
|
|
1498
|
-
circular,
|
|
1499
|
-
update(value) {
|
|
1500
|
-
if (!isRoot && parent && key !== undefined && isObject(parent.node)) {
|
|
1501
|
-
setProperty(parent.node, key, value);
|
|
1502
|
-
}
|
|
1503
|
-
this.node = value;
|
|
1504
|
-
},
|
|
1505
|
-
remove() {
|
|
1506
|
-
if (!isRoot && parent && key !== undefined && isObject(parent.node)) {
|
|
1507
|
-
if (Array.isArray(parent.node) && typeof key === 'number') {
|
|
1508
|
-
parent.node.splice(key, 1);
|
|
1509
|
-
}
|
|
1510
|
-
else {
|
|
1511
|
-
deleteProperty(parent.node, key);
|
|
1512
|
-
}
|
|
1513
|
-
}
|
|
1514
|
-
},
|
|
1515
|
-
};
|
|
1516
|
-
// Call the callback with the context
|
|
1517
|
-
callback.call(context, node);
|
|
1518
|
-
// Traverse children if not circular and is an object
|
|
1519
|
-
if (!circular && isObject(node) && !isLeaf) {
|
|
1520
|
-
if (Array.isArray(node)) {
|
|
1521
|
-
for (let i = 0; i < node.length; i++) {
|
|
1522
|
-
walk(node[i], [...path, i], context);
|
|
1523
|
-
}
|
|
1524
|
-
}
|
|
1525
|
-
else {
|
|
1526
|
-
for (const [childKey, childValue] of Object.entries(node)) {
|
|
1527
|
-
walk(childValue, [...path, childKey], context);
|
|
1528
|
-
}
|
|
1529
|
-
}
|
|
1530
|
-
}
|
|
1531
|
-
}
|
|
1532
|
-
walk(obj);
|
|
1533
|
-
}
|
|
1534
|
-
// Main traverse function that returns an object with forEach method
|
|
1535
|
-
function traverse(obj) {
|
|
1536
|
-
return {
|
|
1537
|
-
forEach(callback) {
|
|
1538
|
-
forEach(obj, callback);
|
|
1539
|
-
},
|
|
1540
|
-
};
|
|
1541
|
-
}
|
|
1891
|
+
promptSchema.index({ createdAt: 1, updatedAt: 1 });
|
|
1542
1892
|
|
|
1543
|
-
const
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
}
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1893
|
+
const promptGroupSchema = new Schema({
|
|
1894
|
+
name: {
|
|
1895
|
+
type: String,
|
|
1896
|
+
required: true,
|
|
1897
|
+
index: true,
|
|
1898
|
+
},
|
|
1899
|
+
numberOfGenerations: {
|
|
1900
|
+
type: Number,
|
|
1901
|
+
default: 0,
|
|
1902
|
+
},
|
|
1903
|
+
oneliner: {
|
|
1904
|
+
type: String,
|
|
1905
|
+
default: '',
|
|
1906
|
+
},
|
|
1907
|
+
category: {
|
|
1908
|
+
type: String,
|
|
1909
|
+
default: '',
|
|
1910
|
+
index: true,
|
|
1911
|
+
},
|
|
1912
|
+
projectIds: {
|
|
1913
|
+
type: [Schema.Types.ObjectId],
|
|
1914
|
+
ref: 'Project',
|
|
1915
|
+
index: true,
|
|
1916
|
+
default: [],
|
|
1917
|
+
},
|
|
1918
|
+
productionId: {
|
|
1919
|
+
type: Schema.Types.ObjectId,
|
|
1920
|
+
ref: 'Prompt',
|
|
1921
|
+
required: true,
|
|
1922
|
+
index: true,
|
|
1923
|
+
},
|
|
1924
|
+
author: {
|
|
1925
|
+
type: Schema.Types.ObjectId,
|
|
1926
|
+
ref: 'User',
|
|
1927
|
+
required: true,
|
|
1928
|
+
index: true,
|
|
1929
|
+
},
|
|
1930
|
+
authorName: {
|
|
1931
|
+
type: String,
|
|
1932
|
+
required: true,
|
|
1933
|
+
},
|
|
1934
|
+
command: {
|
|
1935
|
+
type: String,
|
|
1936
|
+
index: true,
|
|
1937
|
+
validate: {
|
|
1938
|
+
validator: function (v) {
|
|
1939
|
+
return v === undefined || v === null || v === '' || /^[a-z0-9-]+$/.test(v);
|
|
1940
|
+
},
|
|
1941
|
+
message: (props) => { var _a; return `${(_a = props === null || props === void 0 ? void 0 : props.value) !== null && _a !== void 0 ? _a : 'Value'} is not a valid command. Only lowercase alphanumeric characters and hyphens are allowed.`; },
|
|
1942
|
+
},
|
|
1943
|
+
maxlength: [
|
|
1944
|
+
Constants.COMMANDS_MAX_LENGTH,
|
|
1945
|
+
`Command cannot be longer than ${Constants.COMMANDS_MAX_LENGTH} characters`,
|
|
1946
|
+
],
|
|
1947
|
+
}, // Casting here bypasses the type error for the command field.
|
|
1948
|
+
}, {
|
|
1949
|
+
timestamps: true,
|
|
1600
1950
|
});
|
|
1951
|
+
promptGroupSchema.index({ createdAt: 1, updatedAt: 1 });
|
|
1952
|
+
|
|
1601
1953
|
/**
|
|
1602
|
-
*
|
|
1603
|
-
*
|
|
1604
|
-
* @param value - The value to be inspected and potentially truncated.
|
|
1605
|
-
* @param length - The length at which to truncate the value. Default: 100.
|
|
1606
|
-
* @returns The truncated or original value.
|
|
1607
|
-
*/
|
|
1608
|
-
const truncateLongStrings = (value, length = 100) => {
|
|
1609
|
-
if (typeof value === 'string') {
|
|
1610
|
-
return value.length > length ? value.substring(0, length) + '... [truncated]' : value;
|
|
1611
|
-
}
|
|
1612
|
-
return value;
|
|
1613
|
-
};
|
|
1614
|
-
/**
|
|
1615
|
-
* An array mapping function that truncates long strings (objects converted to JSON strings).
|
|
1616
|
-
* @param item - The item to be condensed.
|
|
1617
|
-
* @returns The condensed item.
|
|
1618
|
-
*/
|
|
1619
|
-
const condenseArray = (item) => {
|
|
1620
|
-
if (typeof item === 'string') {
|
|
1621
|
-
return truncateLongStrings(JSON.stringify(item));
|
|
1622
|
-
}
|
|
1623
|
-
else if (typeof item === 'object') {
|
|
1624
|
-
return truncateLongStrings(JSON.stringify(item));
|
|
1625
|
-
}
|
|
1626
|
-
return item;
|
|
1627
|
-
};
|
|
1628
|
-
/**
|
|
1629
|
-
* Formats log messages for debugging purposes.
|
|
1630
|
-
* - Truncates long strings within log messages.
|
|
1631
|
-
* - Condenses arrays by truncating long strings and objects as strings within array items.
|
|
1632
|
-
* - Redacts sensitive information from log messages if the log level is 'error'.
|
|
1633
|
-
* - Converts log information object to a formatted string.
|
|
1634
|
-
*
|
|
1635
|
-
* @param options - The options for formatting log messages.
|
|
1636
|
-
* @returns The formatted log message.
|
|
1954
|
+
* Uses a sub-schema for permissions. Notice we disable `_id` for this subdocument.
|
|
1637
1955
|
*/
|
|
1638
|
-
const
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
}
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
}
|
|
1653
|
-
|
|
1654
|
-
|
|
1655
|
-
}
|
|
1656
|
-
|
|
1657
|
-
|
|
1658
|
-
|
|
1659
|
-
|
|
1660
|
-
|
|
1661
|
-
|
|
1662
|
-
|
|
1663
|
-
|
|
1664
|
-
|
|
1665
|
-
|
|
1666
|
-
}
|
|
1667
|
-
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
|
|
1675
|
-
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
|
|
1685
|
-
|
|
1686
|
-
|
|
1687
|
-
|
|
1688
|
-
|
|
1689
|
-
|
|
1690
|
-
|
|
1691
|
-
|
|
1692
|
-
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
|
|
1696
|
-
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
|
|
1702
|
-
|
|
1703
|
-
|
|
1704
|
-
|
|
1705
|
-
|
|
1706
|
-
|
|
1707
|
-
|
|
1708
|
-
|
|
1709
|
-
|
|
1710
|
-
|
|
1711
|
-
|
|
1712
|
-
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
|
|
1718
|
-
}
|
|
1956
|
+
const rolePermissionsSchema = new Schema({
|
|
1957
|
+
[PermissionTypes.BOOKMARKS]: {
|
|
1958
|
+
[Permissions.USE]: { type: Boolean },
|
|
1959
|
+
},
|
|
1960
|
+
[PermissionTypes.PROMPTS]: {
|
|
1961
|
+
[Permissions.SHARED_GLOBAL]: { type: Boolean },
|
|
1962
|
+
[Permissions.USE]: { type: Boolean },
|
|
1963
|
+
[Permissions.CREATE]: { type: Boolean },
|
|
1964
|
+
},
|
|
1965
|
+
[PermissionTypes.MEMORIES]: {
|
|
1966
|
+
[Permissions.USE]: { type: Boolean },
|
|
1967
|
+
[Permissions.CREATE]: { type: Boolean },
|
|
1968
|
+
[Permissions.UPDATE]: { type: Boolean },
|
|
1969
|
+
[Permissions.READ]: { type: Boolean },
|
|
1970
|
+
[Permissions.OPT_OUT]: { type: Boolean },
|
|
1971
|
+
},
|
|
1972
|
+
[PermissionTypes.AGENTS]: {
|
|
1973
|
+
[Permissions.SHARED_GLOBAL]: { type: Boolean },
|
|
1974
|
+
[Permissions.USE]: { type: Boolean },
|
|
1975
|
+
[Permissions.CREATE]: { type: Boolean },
|
|
1976
|
+
},
|
|
1977
|
+
[PermissionTypes.MULTI_CONVO]: {
|
|
1978
|
+
[Permissions.USE]: { type: Boolean },
|
|
1979
|
+
},
|
|
1980
|
+
[PermissionTypes.TEMPORARY_CHAT]: {
|
|
1981
|
+
[Permissions.USE]: { type: Boolean },
|
|
1982
|
+
},
|
|
1983
|
+
[PermissionTypes.RUN_CODE]: {
|
|
1984
|
+
[Permissions.USE]: { type: Boolean },
|
|
1985
|
+
},
|
|
1986
|
+
[PermissionTypes.WEB_SEARCH]: {
|
|
1987
|
+
[Permissions.USE]: { type: Boolean },
|
|
1988
|
+
},
|
|
1989
|
+
[PermissionTypes.PEOPLE_PICKER]: {
|
|
1990
|
+
[Permissions.VIEW_USERS]: { type: Boolean },
|
|
1991
|
+
[Permissions.VIEW_GROUPS]: { type: Boolean },
|
|
1992
|
+
[Permissions.VIEW_ROLES]: { type: Boolean },
|
|
1993
|
+
},
|
|
1994
|
+
[PermissionTypes.MARKETPLACE]: {
|
|
1995
|
+
[Permissions.USE]: { type: Boolean },
|
|
1996
|
+
},
|
|
1997
|
+
[PermissionTypes.FILE_SEARCH]: {
|
|
1998
|
+
[Permissions.USE]: { type: Boolean },
|
|
1999
|
+
},
|
|
2000
|
+
[PermissionTypes.FILE_CITATIONS]: {
|
|
2001
|
+
[Permissions.USE]: { type: Boolean },
|
|
2002
|
+
},
|
|
2003
|
+
}, { _id: false });
|
|
2004
|
+
const roleSchema = new Schema({
|
|
2005
|
+
name: { type: String, required: true, unique: true, index: true },
|
|
2006
|
+
permissions: {
|
|
2007
|
+
type: rolePermissionsSchema,
|
|
2008
|
+
},
|
|
2009
|
+
});
|
|
2010
|
+
|
|
2011
|
+
const sessionSchema = new Schema({
|
|
2012
|
+
refreshTokenHash: {
|
|
2013
|
+
type: String,
|
|
2014
|
+
required: true,
|
|
2015
|
+
},
|
|
2016
|
+
expiration: {
|
|
2017
|
+
type: Date,
|
|
2018
|
+
required: true,
|
|
2019
|
+
expires: 0,
|
|
2020
|
+
},
|
|
2021
|
+
user: {
|
|
2022
|
+
type: mongoose.Schema.Types.ObjectId,
|
|
2023
|
+
ref: 'User',
|
|
2024
|
+
required: true,
|
|
2025
|
+
},
|
|
2026
|
+
});
|
|
2027
|
+
|
|
2028
|
+
const shareSchema = new Schema({
|
|
2029
|
+
conversationId: {
|
|
2030
|
+
type: String,
|
|
2031
|
+
required: true,
|
|
2032
|
+
},
|
|
2033
|
+
title: {
|
|
2034
|
+
type: String,
|
|
2035
|
+
index: true,
|
|
2036
|
+
},
|
|
2037
|
+
user: {
|
|
2038
|
+
type: String,
|
|
2039
|
+
index: true,
|
|
2040
|
+
},
|
|
2041
|
+
messages: [{ type: mongoose.Schema.Types.ObjectId, ref: 'Message' }],
|
|
2042
|
+
shareId: {
|
|
2043
|
+
type: String,
|
|
2044
|
+
index: true,
|
|
2045
|
+
},
|
|
2046
|
+
targetMessageId: {
|
|
2047
|
+
type: String,
|
|
2048
|
+
required: false,
|
|
2049
|
+
index: true,
|
|
2050
|
+
},
|
|
2051
|
+
isPublic: {
|
|
2052
|
+
type: Boolean,
|
|
2053
|
+
default: true,
|
|
2054
|
+
},
|
|
2055
|
+
}, { timestamps: true });
|
|
2056
|
+
shareSchema.index({ conversationId: 1, user: 1, targetMessageId: 1 });
|
|
2057
|
+
|
|
2058
|
+
const tokenSchema = new Schema({
|
|
2059
|
+
userId: {
|
|
2060
|
+
type: Schema.Types.ObjectId,
|
|
2061
|
+
required: true,
|
|
2062
|
+
ref: 'user',
|
|
2063
|
+
},
|
|
2064
|
+
email: {
|
|
2065
|
+
type: String,
|
|
2066
|
+
},
|
|
2067
|
+
type: {
|
|
2068
|
+
type: String,
|
|
2069
|
+
},
|
|
2070
|
+
identifier: {
|
|
2071
|
+
type: String,
|
|
2072
|
+
},
|
|
2073
|
+
token: {
|
|
2074
|
+
type: String,
|
|
2075
|
+
required: true,
|
|
2076
|
+
},
|
|
2077
|
+
createdAt: {
|
|
2078
|
+
type: Date,
|
|
2079
|
+
required: true,
|
|
2080
|
+
default: Date.now,
|
|
2081
|
+
},
|
|
2082
|
+
expiresAt: {
|
|
2083
|
+
type: Date,
|
|
2084
|
+
required: true,
|
|
2085
|
+
},
|
|
2086
|
+
metadata: {
|
|
2087
|
+
type: Map,
|
|
2088
|
+
of: Schema.Types.Mixed,
|
|
2089
|
+
},
|
|
1719
2090
|
});
|
|
1720
|
-
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
|
|
1724
|
-
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
|
|
1732
|
-
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
}
|
|
1752
|
-
|
|
2091
|
+
tokenSchema.index({ expiresAt: 1 }, { expireAfterSeconds: 0 });
|
|
2092
|
+
|
|
2093
|
+
const toolCallSchema = new Schema({
|
|
2094
|
+
conversationId: {
|
|
2095
|
+
type: String,
|
|
2096
|
+
required: true,
|
|
2097
|
+
},
|
|
2098
|
+
messageId: {
|
|
2099
|
+
type: String,
|
|
2100
|
+
required: true,
|
|
2101
|
+
},
|
|
2102
|
+
toolId: {
|
|
2103
|
+
type: String,
|
|
2104
|
+
required: true,
|
|
2105
|
+
},
|
|
2106
|
+
user: {
|
|
2107
|
+
type: mongoose.Schema.Types.ObjectId,
|
|
2108
|
+
ref: 'User',
|
|
2109
|
+
required: true,
|
|
2110
|
+
},
|
|
2111
|
+
result: {
|
|
2112
|
+
type: mongoose.Schema.Types.Mixed,
|
|
2113
|
+
},
|
|
2114
|
+
attachments: {
|
|
2115
|
+
type: mongoose.Schema.Types.Mixed,
|
|
2116
|
+
},
|
|
2117
|
+
blockIndex: {
|
|
2118
|
+
type: Number,
|
|
2119
|
+
},
|
|
2120
|
+
partIndex: {
|
|
2121
|
+
type: Number,
|
|
2122
|
+
},
|
|
2123
|
+
}, { timestamps: true });
|
|
2124
|
+
toolCallSchema.index({ messageId: 1, user: 1 });
|
|
2125
|
+
toolCallSchema.index({ conversationId: 1, user: 1 });
|
|
2126
|
+
|
|
2127
|
+
const transactionSchema = new Schema({
|
|
2128
|
+
user: {
|
|
2129
|
+
type: mongoose.Schema.Types.ObjectId,
|
|
2130
|
+
ref: 'User',
|
|
2131
|
+
index: true,
|
|
2132
|
+
required: true,
|
|
2133
|
+
},
|
|
2134
|
+
conversationId: {
|
|
2135
|
+
type: String,
|
|
2136
|
+
ref: 'Conversation',
|
|
2137
|
+
index: true,
|
|
2138
|
+
},
|
|
2139
|
+
tokenType: {
|
|
2140
|
+
type: String,
|
|
2141
|
+
enum: ['prompt', 'completion', 'credits'],
|
|
2142
|
+
required: true,
|
|
2143
|
+
},
|
|
2144
|
+
model: {
|
|
2145
|
+
type: String,
|
|
2146
|
+
},
|
|
2147
|
+
context: {
|
|
2148
|
+
type: String,
|
|
2149
|
+
},
|
|
2150
|
+
valueKey: {
|
|
2151
|
+
type: String,
|
|
2152
|
+
},
|
|
2153
|
+
rate: Number,
|
|
2154
|
+
rawAmount: Number,
|
|
2155
|
+
tokenValue: Number,
|
|
2156
|
+
inputTokens: { type: Number },
|
|
2157
|
+
writeTokens: { type: Number },
|
|
2158
|
+
readTokens: { type: Number },
|
|
2159
|
+
}, {
|
|
2160
|
+
timestamps: true,
|
|
1753
2161
|
});
|
|
1754
2162
|
|
|
1755
|
-
|
|
1756
|
-
|
|
1757
|
-
|
|
1758
|
-
|
|
1759
|
-
|
|
1760
|
-
|
|
1761
|
-
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
|
|
1765
|
-
|
|
1766
|
-
|
|
1767
|
-
|
|
1768
|
-
|
|
1769
|
-
|
|
1770
|
-
|
|
1771
|
-
|
|
1772
|
-
|
|
1773
|
-
|
|
1774
|
-
|
|
1775
|
-
|
|
1776
|
-
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
|
|
1780
|
-
|
|
1781
|
-
|
|
1782
|
-
|
|
1783
|
-
|
|
1784
|
-
}
|
|
2163
|
+
// Session sub-schema
|
|
2164
|
+
const SessionSchema = new Schema({
|
|
2165
|
+
refreshToken: {
|
|
2166
|
+
type: String,
|
|
2167
|
+
default: '',
|
|
2168
|
+
},
|
|
2169
|
+
}, { _id: false });
|
|
2170
|
+
// Backup code sub-schema
|
|
2171
|
+
const BackupCodeSchema = new Schema({
|
|
2172
|
+
codeHash: { type: String, required: true },
|
|
2173
|
+
used: { type: Boolean, default: false },
|
|
2174
|
+
usedAt: { type: Date, default: null },
|
|
2175
|
+
}, { _id: false });
|
|
2176
|
+
const userSchema = new Schema({
|
|
2177
|
+
name: {
|
|
2178
|
+
type: String,
|
|
2179
|
+
},
|
|
2180
|
+
username: {
|
|
2181
|
+
type: String,
|
|
2182
|
+
lowercase: true,
|
|
2183
|
+
default: '',
|
|
2184
|
+
},
|
|
2185
|
+
email: {
|
|
2186
|
+
type: String,
|
|
2187
|
+
required: [true, "can't be blank"],
|
|
2188
|
+
lowercase: true,
|
|
2189
|
+
unique: true,
|
|
2190
|
+
match: [/\S+@\S+\.\S+/, 'is invalid'],
|
|
2191
|
+
index: true,
|
|
2192
|
+
},
|
|
2193
|
+
emailVerified: {
|
|
2194
|
+
type: Boolean,
|
|
2195
|
+
required: true,
|
|
2196
|
+
default: false,
|
|
2197
|
+
},
|
|
2198
|
+
password: {
|
|
2199
|
+
type: String,
|
|
2200
|
+
trim: true,
|
|
2201
|
+
minlength: 8,
|
|
2202
|
+
maxlength: 128,
|
|
2203
|
+
select: false,
|
|
2204
|
+
},
|
|
2205
|
+
avatar: {
|
|
2206
|
+
type: String,
|
|
2207
|
+
required: false,
|
|
2208
|
+
},
|
|
2209
|
+
provider: {
|
|
2210
|
+
type: String,
|
|
2211
|
+
required: true,
|
|
2212
|
+
default: 'local',
|
|
2213
|
+
},
|
|
2214
|
+
role: {
|
|
2215
|
+
type: String,
|
|
2216
|
+
default: SystemRoles.USER,
|
|
2217
|
+
},
|
|
2218
|
+
googleId: {
|
|
2219
|
+
type: String,
|
|
2220
|
+
unique: true,
|
|
2221
|
+
sparse: true,
|
|
2222
|
+
},
|
|
2223
|
+
facebookId: {
|
|
2224
|
+
type: String,
|
|
2225
|
+
unique: true,
|
|
2226
|
+
sparse: true,
|
|
2227
|
+
},
|
|
2228
|
+
openidId: {
|
|
2229
|
+
type: String,
|
|
2230
|
+
unique: true,
|
|
2231
|
+
sparse: true,
|
|
2232
|
+
},
|
|
2233
|
+
samlId: {
|
|
2234
|
+
type: String,
|
|
2235
|
+
unique: true,
|
|
2236
|
+
sparse: true,
|
|
2237
|
+
},
|
|
2238
|
+
ldapId: {
|
|
2239
|
+
type: String,
|
|
2240
|
+
unique: true,
|
|
2241
|
+
sparse: true,
|
|
2242
|
+
},
|
|
2243
|
+
githubId: {
|
|
2244
|
+
type: String,
|
|
2245
|
+
unique: true,
|
|
2246
|
+
sparse: true,
|
|
2247
|
+
},
|
|
2248
|
+
discordId: {
|
|
2249
|
+
type: String,
|
|
2250
|
+
unique: true,
|
|
2251
|
+
sparse: true,
|
|
2252
|
+
},
|
|
2253
|
+
appleId: {
|
|
2254
|
+
type: String,
|
|
2255
|
+
unique: true,
|
|
2256
|
+
sparse: true,
|
|
2257
|
+
},
|
|
2258
|
+
plugins: {
|
|
2259
|
+
type: Array,
|
|
2260
|
+
},
|
|
2261
|
+
twoFactorEnabled: {
|
|
2262
|
+
type: Boolean,
|
|
2263
|
+
default: false,
|
|
2264
|
+
},
|
|
2265
|
+
totpSecret: {
|
|
2266
|
+
type: String,
|
|
2267
|
+
select: false,
|
|
2268
|
+
},
|
|
2269
|
+
backupCodes: {
|
|
2270
|
+
type: [BackupCodeSchema],
|
|
2271
|
+
select: false,
|
|
2272
|
+
},
|
|
2273
|
+
refreshToken: {
|
|
2274
|
+
type: [SessionSchema],
|
|
2275
|
+
},
|
|
2276
|
+
expiresAt: {
|
|
2277
|
+
type: Date,
|
|
2278
|
+
expires: 604800, // 7 days in seconds
|
|
2279
|
+
},
|
|
2280
|
+
termsAccepted: {
|
|
2281
|
+
type: Boolean,
|
|
2282
|
+
default: false,
|
|
2283
|
+
},
|
|
2284
|
+
personalization: {
|
|
2285
|
+
type: {
|
|
2286
|
+
memories: {
|
|
2287
|
+
type: Boolean,
|
|
2288
|
+
default: true,
|
|
2289
|
+
},
|
|
2290
|
+
},
|
|
2291
|
+
default: {},
|
|
2292
|
+
},
|
|
2293
|
+
/** Field for external source identification (for consistency with TPrincipal schema) */
|
|
2294
|
+
idOnTheSource: {
|
|
2295
|
+
type: String,
|
|
2296
|
+
sparse: true,
|
|
2297
|
+
},
|
|
2298
|
+
}, { timestamps: true });
|
|
1785
2299
|
|
|
1786
|
-
const
|
|
1787
|
-
|
|
1788
|
-
|
|
1789
|
-
|
|
1790
|
-
|
|
1791
|
-
|
|
1792
|
-
|
|
1793
|
-
|
|
1794
|
-
|
|
1795
|
-
|
|
1796
|
-
|
|
1797
|
-
|
|
1798
|
-
|
|
1799
|
-
|
|
1800
|
-
}
|
|
1801
|
-
|
|
1802
|
-
|
|
1803
|
-
|
|
1804
|
-
|
|
1805
|
-
|
|
2300
|
+
const MemoryEntrySchema = new Schema({
|
|
2301
|
+
userId: {
|
|
2302
|
+
type: Schema.Types.ObjectId,
|
|
2303
|
+
ref: 'User',
|
|
2304
|
+
index: true,
|
|
2305
|
+
required: true,
|
|
2306
|
+
},
|
|
2307
|
+
key: {
|
|
2308
|
+
type: String,
|
|
2309
|
+
required: true,
|
|
2310
|
+
validate: {
|
|
2311
|
+
validator: (v) => /^[a-z_]+$/.test(v),
|
|
2312
|
+
message: 'Key must only contain lowercase letters and underscores',
|
|
2313
|
+
},
|
|
2314
|
+
},
|
|
2315
|
+
value: {
|
|
2316
|
+
type: String,
|
|
2317
|
+
required: true,
|
|
2318
|
+
},
|
|
2319
|
+
tokenCount: {
|
|
2320
|
+
type: Number,
|
|
2321
|
+
default: 0,
|
|
2322
|
+
},
|
|
2323
|
+
updated_at: {
|
|
2324
|
+
type: Date,
|
|
2325
|
+
default: Date.now,
|
|
2326
|
+
},
|
|
1806
2327
|
});
|
|
1807
|
-
|
|
1808
|
-
|
|
1809
|
-
|
|
1810
|
-
|
|
1811
|
-
|
|
1812
|
-
|
|
1813
|
-
|
|
1814
|
-
|
|
1815
|
-
|
|
1816
|
-
|
|
1817
|
-
|
|
1818
|
-
|
|
1819
|
-
|
|
1820
|
-
|
|
1821
|
-
|
|
1822
|
-
|
|
1823
|
-
|
|
1824
|
-
|
|
1825
|
-
|
|
1826
|
-
|
|
1827
|
-
|
|
1828
|
-
|
|
1829
|
-
|
|
1830
|
-
|
|
1831
|
-
|
|
1832
|
-
|
|
1833
|
-
|
|
1834
|
-
|
|
1835
|
-
|
|
1836
|
-
|
|
1837
|
-
}
|
|
1838
|
-
|
|
1839
|
-
|
|
1840
|
-
|
|
1841
|
-
|
|
1842
|
-
|
|
1843
|
-
|
|
1844
|
-
|
|
1845
|
-
|
|
1846
|
-
|
|
1847
|
-
|
|
1848
|
-
|
|
1849
|
-
|
|
1850
|
-
}
|
|
1851
|
-
else if (useConsoleJson) {
|
|
1852
|
-
transports$1.push(new winston.transports.Console({
|
|
1853
|
-
level: consoleLogLevel,
|
|
1854
|
-
format: winston.format.combine(fileFormat$1, jsonTruncateFormat(), winston.format.json()),
|
|
1855
|
-
}));
|
|
1856
|
-
}
|
|
1857
|
-
else {
|
|
1858
|
-
transports$1.push(new winston.transports.Console({
|
|
1859
|
-
level: consoleLogLevel,
|
|
1860
|
-
format: consoleFormat$1,
|
|
1861
|
-
}));
|
|
1862
|
-
}
|
|
1863
|
-
// Create logger
|
|
1864
|
-
const logger$1 = winston.createLogger({
|
|
1865
|
-
level: level$1(),
|
|
1866
|
-
levels: levels$1,
|
|
1867
|
-
transports: transports$1,
|
|
2328
|
+
|
|
2329
|
+
const groupSchema = new Schema({
|
|
2330
|
+
name: {
|
|
2331
|
+
type: String,
|
|
2332
|
+
required: true,
|
|
2333
|
+
index: true,
|
|
2334
|
+
},
|
|
2335
|
+
description: {
|
|
2336
|
+
type: String,
|
|
2337
|
+
required: false,
|
|
2338
|
+
},
|
|
2339
|
+
email: {
|
|
2340
|
+
type: String,
|
|
2341
|
+
required: false,
|
|
2342
|
+
index: true,
|
|
2343
|
+
},
|
|
2344
|
+
avatar: {
|
|
2345
|
+
type: String,
|
|
2346
|
+
required: false,
|
|
2347
|
+
},
|
|
2348
|
+
memberIds: [
|
|
2349
|
+
{
|
|
2350
|
+
type: String,
|
|
2351
|
+
required: false,
|
|
2352
|
+
},
|
|
2353
|
+
],
|
|
2354
|
+
source: {
|
|
2355
|
+
type: String,
|
|
2356
|
+
enum: ['local', 'entra'],
|
|
2357
|
+
default: 'local',
|
|
2358
|
+
},
|
|
2359
|
+
/** External ID (e.g., Entra ID) */
|
|
2360
|
+
idOnTheSource: {
|
|
2361
|
+
type: String,
|
|
2362
|
+
sparse: true,
|
|
2363
|
+
index: true,
|
|
2364
|
+
required: function () {
|
|
2365
|
+
return this.source !== 'local';
|
|
2366
|
+
},
|
|
2367
|
+
},
|
|
2368
|
+
}, { timestamps: true });
|
|
2369
|
+
groupSchema.index({ idOnTheSource: 1, source: 1 }, {
|
|
2370
|
+
unique: true,
|
|
2371
|
+
partialFilterExpression: { idOnTheSource: { $exists: true } },
|
|
1868
2372
|
});
|
|
2373
|
+
groupSchema.index({ memberIds: 1 });
|
|
1869
2374
|
|
|
1870
2375
|
/**
|
|
1871
2376
|
* Checks if the connected MongoDB deployment supports transactions
|
|
@@ -2419,6 +2924,16 @@ function mongoMeili(schema, options) {
|
|
|
2419
2924
|
logger.error(`[mongoMeili] Error checking index ${indexName}:`, error);
|
|
2420
2925
|
}
|
|
2421
2926
|
}
|
|
2927
|
+
// Configure index settings to make 'user' field filterable
|
|
2928
|
+
try {
|
|
2929
|
+
await index.updateSettings({
|
|
2930
|
+
filterableAttributes: ['user'],
|
|
2931
|
+
});
|
|
2932
|
+
logger.debug(`[mongoMeili] Updated index ${indexName} settings to make 'user' filterable`);
|
|
2933
|
+
}
|
|
2934
|
+
catch (settingsError) {
|
|
2935
|
+
logger.error(`[mongoMeili] Error updating index settings for ${indexName}:`, settingsError);
|
|
2936
|
+
}
|
|
2422
2937
|
})();
|
|
2423
2938
|
// Collect attributes from the schema that should be indexed
|
|
2424
2939
|
const attributesToIndex = [
|
|
@@ -2427,6 +2942,12 @@ function mongoMeili(schema, options) {
|
|
|
2427
2942
|
return schemaValue.meiliIndex ? [...results, key] : results;
|
|
2428
2943
|
}, []),
|
|
2429
2944
|
];
|
|
2945
|
+
// CRITICAL: Always include 'user' field for proper filtering
|
|
2946
|
+
// This ensures existing deployments can filter by user after migration
|
|
2947
|
+
if (schema.obj.user && !attributesToIndex.includes('user')) {
|
|
2948
|
+
attributesToIndex.push('user');
|
|
2949
|
+
logger.debug(`[mongoMeili] Added 'user' field to ${indexName} index attributes`);
|
|
2950
|
+
}
|
|
2430
2951
|
schema.loadClass(createMeiliMongooseModel({ index, attributesToIndex, syncOptions }));
|
|
2431
2952
|
// Register Mongoose hooks
|
|
2432
2953
|
schema.post('save', function (doc, next) {
|
|
@@ -3084,7 +3605,7 @@ function createTokenMethods(mongoose) {
|
|
|
3084
3605
|
/**
|
|
3085
3606
|
* Finds a Token document that matches the provided query.
|
|
3086
3607
|
*/
|
|
3087
|
-
async function findToken(query) {
|
|
3608
|
+
async function findToken(query, options) {
|
|
3088
3609
|
try {
|
|
3089
3610
|
const Token = mongoose.models.Token;
|
|
3090
3611
|
const conditions = [];
|
|
@@ -3100,9 +3621,7 @@ function createTokenMethods(mongoose) {
|
|
|
3100
3621
|
if (query.identifier) {
|
|
3101
3622
|
conditions.push({ identifier: query.identifier });
|
|
3102
3623
|
}
|
|
3103
|
-
const token = await Token.findOne({
|
|
3104
|
-
$and: conditions,
|
|
3105
|
-
}).lean();
|
|
3624
|
+
const token = await Token.findOne({ $and: conditions }, null, options).lean();
|
|
3106
3625
|
return token;
|
|
3107
3626
|
}
|
|
3108
3627
|
catch (error) {
|
|
@@ -4748,6 +5267,68 @@ function anonymizeMessages(messages, newConvoId) {
|
|
|
4748
5267
|
};
|
|
4749
5268
|
});
|
|
4750
5269
|
}
|
|
5270
|
+
/**
|
|
5271
|
+
* Filter messages up to and including the target message (branch-specific)
|
|
5272
|
+
* Similar to getMessagesUpToTargetLevel from fork utilities
|
|
5273
|
+
*/
|
|
5274
|
+
function getMessagesUpToTarget(messages, targetMessageId) {
|
|
5275
|
+
var _a, _b;
|
|
5276
|
+
if (!messages || messages.length === 0) {
|
|
5277
|
+
return [];
|
|
5278
|
+
}
|
|
5279
|
+
// If only one message and it's the target, return it
|
|
5280
|
+
if (messages.length === 1 && ((_a = messages[0]) === null || _a === void 0 ? void 0 : _a.messageId) === targetMessageId) {
|
|
5281
|
+
return messages;
|
|
5282
|
+
}
|
|
5283
|
+
// Create a map of parentMessageId to children messages
|
|
5284
|
+
const parentToChildrenMap = new Map();
|
|
5285
|
+
for (const message of messages) {
|
|
5286
|
+
const parentId = message.parentMessageId || Constants.NO_PARENT;
|
|
5287
|
+
if (!parentToChildrenMap.has(parentId)) {
|
|
5288
|
+
parentToChildrenMap.set(parentId, []);
|
|
5289
|
+
}
|
|
5290
|
+
(_b = parentToChildrenMap.get(parentId)) === null || _b === void 0 ? void 0 : _b.push(message);
|
|
5291
|
+
}
|
|
5292
|
+
// Find the target message
|
|
5293
|
+
const targetMessage = messages.find((msg) => msg.messageId === targetMessageId);
|
|
5294
|
+
if (!targetMessage) {
|
|
5295
|
+
// If target not found, return all messages for backwards compatibility
|
|
5296
|
+
return messages;
|
|
5297
|
+
}
|
|
5298
|
+
const visited = new Set();
|
|
5299
|
+
const rootMessages = parentToChildrenMap.get(Constants.NO_PARENT) || [];
|
|
5300
|
+
let currentLevel = rootMessages.length > 0 ? [...rootMessages] : [targetMessage];
|
|
5301
|
+
const results = new Set(currentLevel);
|
|
5302
|
+
// Check if the target message is at the root level
|
|
5303
|
+
if (currentLevel.some((msg) => msg.messageId === targetMessageId) &&
|
|
5304
|
+
targetMessage.parentMessageId === Constants.NO_PARENT) {
|
|
5305
|
+
return Array.from(results);
|
|
5306
|
+
}
|
|
5307
|
+
// Iterate level by level until the target is found
|
|
5308
|
+
let targetFound = false;
|
|
5309
|
+
while (!targetFound && currentLevel.length > 0) {
|
|
5310
|
+
const nextLevel = [];
|
|
5311
|
+
for (const node of currentLevel) {
|
|
5312
|
+
if (visited.has(node.messageId)) {
|
|
5313
|
+
continue;
|
|
5314
|
+
}
|
|
5315
|
+
visited.add(node.messageId);
|
|
5316
|
+
const children = parentToChildrenMap.get(node.messageId) || [];
|
|
5317
|
+
for (const child of children) {
|
|
5318
|
+
if (visited.has(child.messageId)) {
|
|
5319
|
+
continue;
|
|
5320
|
+
}
|
|
5321
|
+
nextLevel.push(child);
|
|
5322
|
+
results.add(child);
|
|
5323
|
+
if (child.messageId === targetMessageId) {
|
|
5324
|
+
targetFound = true;
|
|
5325
|
+
}
|
|
5326
|
+
}
|
|
5327
|
+
}
|
|
5328
|
+
currentLevel = nextLevel;
|
|
5329
|
+
}
|
|
5330
|
+
return Array.from(results);
|
|
5331
|
+
}
|
|
4751
5332
|
/** Factory function that takes mongoose instance and returns the methods */
|
|
4752
5333
|
function createShareMethods(mongoose) {
|
|
4753
5334
|
/**
|
|
@@ -4766,6 +5347,11 @@ function createShareMethods(mongoose) {
|
|
|
4766
5347
|
if (!(share === null || share === void 0 ? void 0 : share.conversationId) || !share.isPublic) {
|
|
4767
5348
|
return null;
|
|
4768
5349
|
}
|
|
5350
|
+
/** Filtered messages based on targetMessageId if present (branch-specific sharing) */
|
|
5351
|
+
let messagesToShare = share.messages;
|
|
5352
|
+
if (share.targetMessageId) {
|
|
5353
|
+
messagesToShare = getMessagesUpToTarget(share.messages, share.targetMessageId);
|
|
5354
|
+
}
|
|
4769
5355
|
const newConvoId = anonymizeConvoId(share.conversationId);
|
|
4770
5356
|
const result = {
|
|
4771
5357
|
shareId: share.shareId || shareId,
|
|
@@ -4774,7 +5360,7 @@ function createShareMethods(mongoose) {
|
|
|
4774
5360
|
createdAt: share.createdAt,
|
|
4775
5361
|
updatedAt: share.updatedAt,
|
|
4776
5362
|
conversationId: newConvoId,
|
|
4777
|
-
messages: anonymizeMessages(
|
|
5363
|
+
messages: anonymizeMessages(messagesToShare, newConvoId),
|
|
4778
5364
|
};
|
|
4779
5365
|
return result;
|
|
4780
5366
|
}
|
|
@@ -4805,7 +5391,9 @@ function createShareMethods(mongoose) {
|
|
|
4805
5391
|
}
|
|
4806
5392
|
if (search && search.trim()) {
|
|
4807
5393
|
try {
|
|
4808
|
-
const searchResults = await Conversation.meiliSearch(search
|
|
5394
|
+
const searchResults = await Conversation.meiliSearch(search, {
|
|
5395
|
+
filter: `user = "${user}"`,
|
|
5396
|
+
});
|
|
4809
5397
|
if (!((_a = searchResults === null || searchResults === void 0 ? void 0 : searchResults.hits) === null || _a === void 0 ? void 0 : _a.length)) {
|
|
4810
5398
|
return {
|
|
4811
5399
|
links: [],
|
|
@@ -4880,10 +5468,34 @@ function createShareMethods(mongoose) {
|
|
|
4880
5468
|
throw new ShareServiceError('Error deleting shared links', 'BULK_DELETE_ERROR');
|
|
4881
5469
|
}
|
|
4882
5470
|
}
|
|
5471
|
+
/**
|
|
5472
|
+
* Delete shared links by conversation ID
|
|
5473
|
+
*/
|
|
5474
|
+
async function deleteConvoSharedLink(user, conversationId) {
|
|
5475
|
+
if (!user || !conversationId) {
|
|
5476
|
+
throw new ShareServiceError('Missing required parameters', 'INVALID_PARAMS');
|
|
5477
|
+
}
|
|
5478
|
+
try {
|
|
5479
|
+
const SharedLink = mongoose.models.SharedLink;
|
|
5480
|
+
const result = await SharedLink.deleteMany({ user, conversationId });
|
|
5481
|
+
return {
|
|
5482
|
+
message: 'Shared links deleted successfully',
|
|
5483
|
+
deletedCount: result.deletedCount,
|
|
5484
|
+
};
|
|
5485
|
+
}
|
|
5486
|
+
catch (error) {
|
|
5487
|
+
logger$1.error('[deleteConvoSharedLink] Error deleting shared links', {
|
|
5488
|
+
error: error instanceof Error ? error.message : 'Unknown error',
|
|
5489
|
+
user,
|
|
5490
|
+
conversationId,
|
|
5491
|
+
});
|
|
5492
|
+
throw new ShareServiceError('Error deleting shared links', 'SHARE_DELETE_ERROR');
|
|
5493
|
+
}
|
|
5494
|
+
}
|
|
4883
5495
|
/**
|
|
4884
5496
|
* Create a new shared link for a conversation
|
|
4885
5497
|
*/
|
|
4886
|
-
async function createSharedLink(user, conversationId) {
|
|
5498
|
+
async function createSharedLink(user, conversationId, targetMessageId) {
|
|
4887
5499
|
if (!user || !conversationId) {
|
|
4888
5500
|
throw new ShareServiceError('Missing required parameters', 'INVALID_PARAMS');
|
|
4889
5501
|
}
|
|
@@ -4892,7 +5504,12 @@ function createShareMethods(mongoose) {
|
|
|
4892
5504
|
const SharedLink = mongoose.models.SharedLink;
|
|
4893
5505
|
const Conversation = mongoose.models.Conversation;
|
|
4894
5506
|
const [existingShare, conversationMessages] = await Promise.all([
|
|
4895
|
-
SharedLink.findOne({
|
|
5507
|
+
SharedLink.findOne({
|
|
5508
|
+
conversationId,
|
|
5509
|
+
user,
|
|
5510
|
+
isPublic: true,
|
|
5511
|
+
...(targetMessageId && { targetMessageId }),
|
|
5512
|
+
})
|
|
4896
5513
|
.select('-_id -__v -user')
|
|
4897
5514
|
.lean(),
|
|
4898
5515
|
Message.find({ conversationId, user }).sort({ createdAt: 1 }).lean(),
|
|
@@ -4901,11 +5518,16 @@ function createShareMethods(mongoose) {
|
|
|
4901
5518
|
logger$1.error('[createSharedLink] Share already exists', {
|
|
4902
5519
|
user,
|
|
4903
5520
|
conversationId,
|
|
5521
|
+
targetMessageId,
|
|
4904
5522
|
});
|
|
4905
5523
|
throw new ShareServiceError('Share already exists', 'SHARE_EXISTS');
|
|
4906
5524
|
}
|
|
4907
5525
|
else if (existingShare) {
|
|
4908
|
-
await SharedLink.deleteOne({
|
|
5526
|
+
await SharedLink.deleteOne({
|
|
5527
|
+
conversationId,
|
|
5528
|
+
user,
|
|
5529
|
+
...(targetMessageId && { targetMessageId }),
|
|
5530
|
+
});
|
|
4909
5531
|
}
|
|
4910
5532
|
const conversation = (await Conversation.findOne({ conversationId, user }).lean());
|
|
4911
5533
|
// Check if user owns the conversation
|
|
@@ -4924,6 +5546,7 @@ function createShareMethods(mongoose) {
|
|
|
4924
5546
|
messages: conversationMessages,
|
|
4925
5547
|
title,
|
|
4926
5548
|
user,
|
|
5549
|
+
...(targetMessageId && { targetMessageId }),
|
|
4927
5550
|
});
|
|
4928
5551
|
return { shareId, conversationId };
|
|
4929
5552
|
}
|
|
@@ -4935,6 +5558,7 @@ function createShareMethods(mongoose) {
|
|
|
4935
5558
|
error: error instanceof Error ? error.message : 'Unknown error',
|
|
4936
5559
|
user,
|
|
4937
5560
|
conversationId,
|
|
5561
|
+
targetMessageId,
|
|
4938
5562
|
});
|
|
4939
5563
|
throw new ShareServiceError('Error creating shared link', 'SHARE_CREATE_ERROR');
|
|
4940
5564
|
}
|
|
@@ -5047,6 +5671,7 @@ function createShareMethods(mongoose) {
|
|
|
5047
5671
|
deleteSharedLink,
|
|
5048
5672
|
getSharedMessages,
|
|
5049
5673
|
deleteAllSharedLinks,
|
|
5674
|
+
deleteConvoSharedLink,
|
|
5050
5675
|
};
|
|
5051
5676
|
}
|
|
5052
5677
|
|
|
@@ -5069,5 +5694,5 @@ function createMethods(mongoose) {
|
|
|
5069
5694
|
};
|
|
5070
5695
|
}
|
|
5071
5696
|
|
|
5072
|
-
export { RoleBits, Action as actionSchema, agentCategorySchema, agentSchema, assistantSchema, balanceSchema, bannerSchema, categoriesSchema, conversationTag as conversationTagSchema, convoSchema, createMethods, createModels, file as fileSchema, getTransactionSupport, groupSchema, hashToken, keySchema, logger$1 as logger, logger as meiliLogger, MemoryEntrySchema as memorySchema, messageSchema, pluginAuthSchema, presetSchema, projectSchema, promptGroupSchema, promptSchema, roleSchema, sessionSchema, shareSchema, signPayload, supportsTransactions, tokenSchema, toolCallSchema, transactionSchema, userSchema };
|
|
5697
|
+
export { AppService, RoleBits, Action as actionSchema, agentCategorySchema, agentSchema, agentsConfigSetup, assistantSchema, balanceSchema, bannerSchema, categoriesSchema, conversationTag as conversationTagSchema, convoSchema, createMethods, createModels, file as fileSchema, getTransactionSupport, getWebSearchKeys, groupSchema, hashToken, keySchema, loadDefaultInterface, loadTurnstileConfig, loadWebSearchConfig, logger$1 as logger, logger as meiliLogger, MemoryEntrySchema as memorySchema, messageSchema, pluginAuthSchema, presetSchema, processModelSpecs, projectSchema, promptGroupSchema, promptSchema, roleSchema, sessionSchema, shareSchema, signPayload, supportsTransactions, tokenSchema, toolCallSchema, transactionSchema, userSchema, webSearchAuth, webSearchKeys };
|
|
5073
5698
|
//# sourceMappingURL=index.es.js.map
|