@librechat/data-schemas 0.0.34 → 0.0.36
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 +330 -15
- package/dist/index.cjs.map +1 -1
- package/dist/index.es.js +331 -17
- package/dist/index.es.js.map +1 -1
- package/dist/types/methods/agentApiKey.d.ts +39 -0
- package/dist/types/methods/file.d.ts +8 -0
- package/dist/types/methods/index.d.ts +3 -2
- package/dist/types/models/agentApiKey.d.ts +27 -0
- package/dist/types/models/index.d.ts +1 -0
- package/dist/types/schema/agentApiKey.d.ts +38 -0
- package/dist/types/schema/defaults.d.ts +3 -0
- package/dist/types/schema/index.d.ts +1 -0
- package/dist/types/schema/preset.d.ts +1 -0
- package/dist/types/types/agent.d.ts +3 -1
- package/dist/types/types/agentApiKey.d.ts +65 -0
- package/dist/types/types/convo.d.ts +1 -0
- package/dist/types/types/file.d.ts +1 -0
- package/dist/types/types/index.d.ts +1 -0
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -1462,12 +1462,57 @@ const agentSchema = new mongoose.Schema({
|
|
|
1462
1462
|
default: [],
|
|
1463
1463
|
index: true,
|
|
1464
1464
|
},
|
|
1465
|
+
/** Per-tool configuration (defer_loading, allowed_callers) */
|
|
1466
|
+
tool_options: {
|
|
1467
|
+
type: mongoose.Schema.Types.Mixed,
|
|
1468
|
+
default: undefined,
|
|
1469
|
+
},
|
|
1465
1470
|
}, {
|
|
1466
1471
|
timestamps: true,
|
|
1467
1472
|
});
|
|
1468
1473
|
agentSchema.index({ updatedAt: -1, _id: 1 });
|
|
1469
1474
|
agentSchema.index({ 'edges.to': 1 });
|
|
1470
1475
|
|
|
1476
|
+
const agentApiKeySchema = new mongoose.Schema({
|
|
1477
|
+
userId: {
|
|
1478
|
+
type: mongoose.Schema.Types.ObjectId,
|
|
1479
|
+
ref: 'User',
|
|
1480
|
+
required: true,
|
|
1481
|
+
index: true,
|
|
1482
|
+
},
|
|
1483
|
+
name: {
|
|
1484
|
+
type: String,
|
|
1485
|
+
required: true,
|
|
1486
|
+
trim: true,
|
|
1487
|
+
maxlength: 100,
|
|
1488
|
+
},
|
|
1489
|
+
keyHash: {
|
|
1490
|
+
type: String,
|
|
1491
|
+
required: true,
|
|
1492
|
+
select: false,
|
|
1493
|
+
index: true,
|
|
1494
|
+
},
|
|
1495
|
+
keyPrefix: {
|
|
1496
|
+
type: String,
|
|
1497
|
+
required: true,
|
|
1498
|
+
index: true,
|
|
1499
|
+
},
|
|
1500
|
+
lastUsedAt: {
|
|
1501
|
+
type: Date,
|
|
1502
|
+
},
|
|
1503
|
+
expiresAt: {
|
|
1504
|
+
type: Date,
|
|
1505
|
+
},
|
|
1506
|
+
}, { timestamps: true });
|
|
1507
|
+
agentApiKeySchema.index({ userId: 1, name: 1 });
|
|
1508
|
+
/**
|
|
1509
|
+
* TTL index for automatic cleanup of expired keys.
|
|
1510
|
+
* MongoDB deletes documents when expiresAt passes (expireAfterSeconds: 0 means immediate).
|
|
1511
|
+
* Note: Expired keys are permanently removed, not soft-deleted.
|
|
1512
|
+
* If audit trails are needed, remove this index and check expiration programmatically.
|
|
1513
|
+
*/
|
|
1514
|
+
agentApiKeySchema.index({ expiresAt: 1 }, { expireAfterSeconds: 0 });
|
|
1515
|
+
|
|
1471
1516
|
const agentCategorySchema = new mongoose.Schema({
|
|
1472
1517
|
value: {
|
|
1473
1518
|
type: String,
|
|
@@ -1730,6 +1775,9 @@ const conversationPreset = {
|
|
|
1730
1775
|
thinkingBudget: {
|
|
1731
1776
|
type: Number,
|
|
1732
1777
|
},
|
|
1778
|
+
effort: {
|
|
1779
|
+
type: String,
|
|
1780
|
+
},
|
|
1733
1781
|
system: {
|
|
1734
1782
|
type: String,
|
|
1735
1783
|
},
|
|
@@ -1856,6 +1904,10 @@ const file = new mongoose.Schema({
|
|
|
1856
1904
|
ref: 'Conversation',
|
|
1857
1905
|
index: true,
|
|
1858
1906
|
},
|
|
1907
|
+
messageId: {
|
|
1908
|
+
type: String,
|
|
1909
|
+
index: true,
|
|
1910
|
+
},
|
|
1859
1911
|
file_id: {
|
|
1860
1912
|
type: String,
|
|
1861
1913
|
index: true,
|
|
@@ -1919,6 +1971,7 @@ const file = new mongoose.Schema({
|
|
|
1919
1971
|
timestamps: true,
|
|
1920
1972
|
});
|
|
1921
1973
|
file.index({ createdAt: 1, updatedAt: 1 });
|
|
1974
|
+
file.index({ filename: 1, conversationId: 1, context: 1 }, { unique: true, partialFilterExpression: { context: librechatDataProvider.FileContext.execute_code } });
|
|
1922
1975
|
|
|
1923
1976
|
const keySchema = new mongoose.Schema({
|
|
1924
1977
|
userId: {
|
|
@@ -2296,6 +2349,12 @@ const rolePermissionsSchema = new mongoose.Schema({
|
|
|
2296
2349
|
[librechatDataProvider.Permissions.SHARE]: { type: Boolean },
|
|
2297
2350
|
[librechatDataProvider.Permissions.SHARE_PUBLIC]: { type: Boolean },
|
|
2298
2351
|
},
|
|
2352
|
+
[librechatDataProvider.PermissionTypes.REMOTE_AGENTS]: {
|
|
2353
|
+
[librechatDataProvider.Permissions.USE]: { type: Boolean },
|
|
2354
|
+
[librechatDataProvider.Permissions.CREATE]: { type: Boolean },
|
|
2355
|
+
[librechatDataProvider.Permissions.SHARE]: { type: Boolean },
|
|
2356
|
+
[librechatDataProvider.Permissions.SHARE_PUBLIC]: { type: Boolean },
|
|
2357
|
+
},
|
|
2299
2358
|
}, { _id: false });
|
|
2300
2359
|
const roleSchema = new mongoose.Schema({
|
|
2301
2360
|
name: { type: String, required: true, unique: true, index: true },
|
|
@@ -2870,8 +2929,8 @@ const createMeiliMongooseModel = ({ index, attributesToIndex, syncOptions, }) =>
|
|
|
2870
2929
|
}
|
|
2871
2930
|
/**
|
|
2872
2931
|
* Synchronizes data between the MongoDB collection and the MeiliSearch index by
|
|
2873
|
-
* incrementally indexing only documents where `expiredAt` is `null` and `_meiliIndex` is `
|
|
2874
|
-
* (i.e., non-expired documents that have not yet been indexed).
|
|
2932
|
+
* incrementally indexing only documents where `expiredAt` is `null` and `_meiliIndex` is not `true`
|
|
2933
|
+
* (i.e., non-expired documents that have not yet been indexed, including those with missing or null `_meiliIndex`).
|
|
2875
2934
|
* */
|
|
2876
2935
|
static async syncWithMeili() {
|
|
2877
2936
|
const startTime = Date.now();
|
|
@@ -2896,7 +2955,7 @@ const createMeiliMongooseModel = ({ index, attributesToIndex, syncOptions, }) =>
|
|
|
2896
2955
|
while (hasMore) {
|
|
2897
2956
|
const query = {
|
|
2898
2957
|
expiredAt: null,
|
|
2899
|
-
_meiliIndex:
|
|
2958
|
+
_meiliIndex: { $ne: true },
|
|
2900
2959
|
};
|
|
2901
2960
|
try {
|
|
2902
2961
|
const documents = await this.find(query)
|
|
@@ -2974,7 +3033,11 @@ const createMeiliMongooseModel = ({ index, attributesToIndex, syncOptions, }) =>
|
|
|
2974
3033
|
await index.deleteDocuments(toDelete.map(String));
|
|
2975
3034
|
logger.debug(`[cleanupMeiliIndex] Deleted ${toDelete.length} orphaned documents`);
|
|
2976
3035
|
}
|
|
2977
|
-
|
|
3036
|
+
// if fetch documents request returns less documents than limit, all documents are processed
|
|
3037
|
+
if (batch.results.length < batchSize) {
|
|
3038
|
+
break;
|
|
3039
|
+
}
|
|
3040
|
+
offset += batchSize - toDelete.length;
|
|
2978
3041
|
// Add delay between batches
|
|
2979
3042
|
if (delayMs > 0) {
|
|
2980
3043
|
await new Promise((resolve) => setTimeout(resolve, delayMs));
|
|
@@ -3355,6 +3418,10 @@ function createAgentModel(mongoose) {
|
|
|
3355
3418
|
return mongoose.models.Agent || mongoose.model('Agent', agentSchema);
|
|
3356
3419
|
}
|
|
3357
3420
|
|
|
3421
|
+
function createAgentApiKeyModel(mongoose) {
|
|
3422
|
+
return (mongoose.models.AgentApiKey || mongoose.model('AgentApiKey', agentApiKeySchema));
|
|
3423
|
+
}
|
|
3424
|
+
|
|
3358
3425
|
/**
|
|
3359
3426
|
* Creates or returns the AgentCategory model using the provided mongoose instance and schema
|
|
3360
3427
|
*/
|
|
@@ -3518,7 +3585,7 @@ const accessRoleSchema = new mongoose.Schema({
|
|
|
3518
3585
|
description: String,
|
|
3519
3586
|
resourceType: {
|
|
3520
3587
|
type: String,
|
|
3521
|
-
enum: ['agent', 'project', 'file', 'promptGroup', 'mcpServer'],
|
|
3588
|
+
enum: ['agent', 'project', 'file', 'promptGroup', 'mcpServer', 'remoteAgent'],
|
|
3522
3589
|
required: true,
|
|
3523
3590
|
default: 'agent',
|
|
3524
3591
|
},
|
|
@@ -3618,6 +3685,7 @@ function createModels(mongoose) {
|
|
|
3618
3685
|
Conversation: createConversationModel(mongoose),
|
|
3619
3686
|
Message: createMessageModel(mongoose),
|
|
3620
3687
|
Agent: createAgentModel(mongoose),
|
|
3688
|
+
AgentApiKey: createAgentApiKeyModel(mongoose),
|
|
3621
3689
|
AgentCategory: createAgentCategoryModel(mongoose),
|
|
3622
3690
|
MCPServer: createMCPServerModel(mongoose),
|
|
3623
3691
|
Role: createRoleModel(mongoose),
|
|
@@ -4431,30 +4499,33 @@ function createFileMethods(mongoose) {
|
|
|
4431
4499
|
return await query.sort(sortOptions).lean();
|
|
4432
4500
|
}
|
|
4433
4501
|
/**
|
|
4434
|
-
* Retrieves tool files (files that are embedded or have a fileIdentifier) from an array of file IDs
|
|
4502
|
+
* Retrieves tool files (files that are embedded or have a fileIdentifier) from an array of file IDs.
|
|
4503
|
+
* Note: execute_code files are handled separately by getCodeGeneratedFiles.
|
|
4435
4504
|
* @param fileIds - Array of file_id strings to search for
|
|
4436
4505
|
* @param toolResourceSet - Optional filter for tool resources
|
|
4437
4506
|
* @returns Files that match the criteria
|
|
4438
4507
|
*/
|
|
4439
4508
|
async function getToolFilesByIds(fileIds, toolResourceSet) {
|
|
4440
|
-
var _a, _b, _c;
|
|
4441
4509
|
if (!fileIds || !fileIds.length || !(toolResourceSet === null || toolResourceSet === void 0 ? void 0 : toolResourceSet.size)) {
|
|
4442
4510
|
return [];
|
|
4443
4511
|
}
|
|
4444
4512
|
try {
|
|
4445
|
-
const
|
|
4446
|
-
file_id: { $in: fileIds },
|
|
4447
|
-
$or: [],
|
|
4448
|
-
};
|
|
4513
|
+
const orConditions = [];
|
|
4449
4514
|
if (toolResourceSet.has(librechatDataProvider.EToolResources.context)) {
|
|
4450
|
-
|
|
4515
|
+
orConditions.push({ text: { $exists: true, $ne: null }, context: librechatDataProvider.FileContext.agents });
|
|
4451
4516
|
}
|
|
4452
4517
|
if (toolResourceSet.has(librechatDataProvider.EToolResources.file_search)) {
|
|
4453
|
-
|
|
4518
|
+
orConditions.push({ embedded: true });
|
|
4454
4519
|
}
|
|
4455
|
-
|
|
4456
|
-
|
|
4520
|
+
// If no conditions to match, return empty
|
|
4521
|
+
if (orConditions.length === 0) {
|
|
4522
|
+
return [];
|
|
4457
4523
|
}
|
|
4524
|
+
const filter = {
|
|
4525
|
+
file_id: { $in: fileIds },
|
|
4526
|
+
context: { $ne: librechatDataProvider.FileContext.execute_code },
|
|
4527
|
+
$or: orConditions,
|
|
4528
|
+
};
|
|
4458
4529
|
const selectFields = { text: 0 };
|
|
4459
4530
|
const sortOptions = { updatedAt: -1 };
|
|
4460
4531
|
const results = await getFiles(filter, sortOptions, selectFields);
|
|
@@ -4465,6 +4536,91 @@ function createFileMethods(mongoose) {
|
|
|
4465
4536
|
throw new Error('Error retrieving tool files');
|
|
4466
4537
|
}
|
|
4467
4538
|
}
|
|
4539
|
+
/**
|
|
4540
|
+
* Retrieves files generated by code execution for a given conversation.
|
|
4541
|
+
* These files are stored locally with fileIdentifier metadata for code env re-upload.
|
|
4542
|
+
*
|
|
4543
|
+
* @param conversationId - The conversation ID to search for
|
|
4544
|
+
* @param messageIds - Array of messageIds to filter by (for linear thread filtering).
|
|
4545
|
+
* While technically optional, this function returns empty if not provided.
|
|
4546
|
+
* This is intentional: code-generated files must be filtered by thread to avoid
|
|
4547
|
+
* including files from other branches of a conversation.
|
|
4548
|
+
* @returns Files generated by code execution in the conversation, filtered by messageIds
|
|
4549
|
+
*/
|
|
4550
|
+
async function getCodeGeneratedFiles(conversationId, messageIds) {
|
|
4551
|
+
if (!conversationId) {
|
|
4552
|
+
return [];
|
|
4553
|
+
}
|
|
4554
|
+
/**
|
|
4555
|
+
* Return early if messageIds not provided - this is intentional behavior.
|
|
4556
|
+
* Code-generated files must be filtered by thread messageIds to ensure we only
|
|
4557
|
+
* return files relevant to the current conversation branch, not orphaned files
|
|
4558
|
+
* from other branches or deleted messages.
|
|
4559
|
+
*/
|
|
4560
|
+
if (!messageIds || messageIds.length === 0) {
|
|
4561
|
+
return [];
|
|
4562
|
+
}
|
|
4563
|
+
try {
|
|
4564
|
+
const filter = {
|
|
4565
|
+
conversationId,
|
|
4566
|
+
context: librechatDataProvider.FileContext.execute_code,
|
|
4567
|
+
messageId: { $exists: true, $in: messageIds },
|
|
4568
|
+
'metadata.fileIdentifier': { $exists: true },
|
|
4569
|
+
};
|
|
4570
|
+
const selectFields = { text: 0 };
|
|
4571
|
+
const sortOptions = { createdAt: 1 };
|
|
4572
|
+
const results = await getFiles(filter, sortOptions, selectFields);
|
|
4573
|
+
return results !== null && results !== void 0 ? results : [];
|
|
4574
|
+
}
|
|
4575
|
+
catch (error) {
|
|
4576
|
+
logger$1.error('[getCodeGeneratedFiles] Error retrieving code generated files:', error);
|
|
4577
|
+
return [];
|
|
4578
|
+
}
|
|
4579
|
+
}
|
|
4580
|
+
/**
|
|
4581
|
+
* Retrieves user-uploaded execute_code files (not code-generated) by their file IDs.
|
|
4582
|
+
* These are files with fileIdentifier metadata but context is NOT execute_code (e.g., agents or message_attachment).
|
|
4583
|
+
* File IDs should be collected from message.files arrays in the current thread.
|
|
4584
|
+
* @param fileIds - Array of file IDs to fetch (from message.files in the thread)
|
|
4585
|
+
* @returns User-uploaded execute_code files
|
|
4586
|
+
*/
|
|
4587
|
+
async function getUserCodeFiles(fileIds) {
|
|
4588
|
+
if (!fileIds || fileIds.length === 0) {
|
|
4589
|
+
return [];
|
|
4590
|
+
}
|
|
4591
|
+
try {
|
|
4592
|
+
const filter = {
|
|
4593
|
+
file_id: { $in: fileIds },
|
|
4594
|
+
context: { $ne: librechatDataProvider.FileContext.execute_code },
|
|
4595
|
+
'metadata.fileIdentifier': { $exists: true },
|
|
4596
|
+
};
|
|
4597
|
+
const selectFields = { text: 0 };
|
|
4598
|
+
const sortOptions = { createdAt: 1 };
|
|
4599
|
+
const results = await getFiles(filter, sortOptions, selectFields);
|
|
4600
|
+
return results !== null && results !== void 0 ? results : [];
|
|
4601
|
+
}
|
|
4602
|
+
catch (error) {
|
|
4603
|
+
logger$1.error('[getUserCodeFiles] Error retrieving user code files:', error);
|
|
4604
|
+
return [];
|
|
4605
|
+
}
|
|
4606
|
+
}
|
|
4607
|
+
/**
|
|
4608
|
+
* Atomically claims a file_id for a code-execution output by compound key.
|
|
4609
|
+
* Uses $setOnInsert so concurrent calls for the same (filename, conversationId)
|
|
4610
|
+
* converge on a single record instead of creating duplicates.
|
|
4611
|
+
*/
|
|
4612
|
+
async function claimCodeFile(data) {
|
|
4613
|
+
const File = mongoose.models.File;
|
|
4614
|
+
const result = await File.findOneAndUpdate({
|
|
4615
|
+
filename: data.filename,
|
|
4616
|
+
conversationId: data.conversationId,
|
|
4617
|
+
context: librechatDataProvider.FileContext.execute_code,
|
|
4618
|
+
}, { $setOnInsert: { file_id: data.file_id, user: data.user } }, { upsert: true, new: true }).lean();
|
|
4619
|
+
if (!result) {
|
|
4620
|
+
throw new Error(`[claimCodeFile] Failed to claim file "${data.filename}" for conversation ${data.conversationId}`);
|
|
4621
|
+
}
|
|
4622
|
+
return result;
|
|
4623
|
+
}
|
|
4468
4624
|
/**
|
|
4469
4625
|
* Creates a new file with a TTL of 1 hour.
|
|
4470
4626
|
* @param data - The file data to be created, must contain file_id
|
|
@@ -4604,6 +4760,9 @@ function createFileMethods(mongoose) {
|
|
|
4604
4760
|
findFileById,
|
|
4605
4761
|
getFiles,
|
|
4606
4762
|
getToolFilesByIds,
|
|
4763
|
+
getCodeGeneratedFiles,
|
|
4764
|
+
getUserCodeFiles,
|
|
4765
|
+
claimCodeFile,
|
|
4607
4766
|
createFile,
|
|
4608
4767
|
updateFile,
|
|
4609
4768
|
updateFileUsage,
|
|
@@ -4962,6 +5121,139 @@ function createAgentCategoryMethods(mongoose) {
|
|
|
4962
5121
|
};
|
|
4963
5122
|
}
|
|
4964
5123
|
|
|
5124
|
+
const API_KEY_PREFIX = 'sk-';
|
|
5125
|
+
const API_KEY_LENGTH = 32;
|
|
5126
|
+
function createAgentApiKeyMethods(mongoose) {
|
|
5127
|
+
async function generateApiKey() {
|
|
5128
|
+
const randomPart = await getRandomValues(API_KEY_LENGTH);
|
|
5129
|
+
const key = `${API_KEY_PREFIX}${randomPart}`;
|
|
5130
|
+
const keyHash = await hashToken(key);
|
|
5131
|
+
const keyPrefix = key.slice(0, 8);
|
|
5132
|
+
return { key, keyHash, keyPrefix };
|
|
5133
|
+
}
|
|
5134
|
+
async function createAgentApiKey(data) {
|
|
5135
|
+
try {
|
|
5136
|
+
const AgentApiKey = mongoose.models.AgentApiKey;
|
|
5137
|
+
const { key, keyHash, keyPrefix } = await generateApiKey();
|
|
5138
|
+
const apiKeyDoc = await AgentApiKey.create({
|
|
5139
|
+
userId: data.userId,
|
|
5140
|
+
name: data.name,
|
|
5141
|
+
keyHash,
|
|
5142
|
+
keyPrefix,
|
|
5143
|
+
expiresAt: data.expiresAt || undefined,
|
|
5144
|
+
});
|
|
5145
|
+
return {
|
|
5146
|
+
id: apiKeyDoc._id.toString(),
|
|
5147
|
+
name: apiKeyDoc.name,
|
|
5148
|
+
keyPrefix,
|
|
5149
|
+
key,
|
|
5150
|
+
createdAt: apiKeyDoc.createdAt,
|
|
5151
|
+
expiresAt: apiKeyDoc.expiresAt,
|
|
5152
|
+
};
|
|
5153
|
+
}
|
|
5154
|
+
catch (error) {
|
|
5155
|
+
logger$1.error('[createAgentApiKey] Error creating API key:', error);
|
|
5156
|
+
throw error;
|
|
5157
|
+
}
|
|
5158
|
+
}
|
|
5159
|
+
async function validateAgentApiKey(apiKey) {
|
|
5160
|
+
try {
|
|
5161
|
+
const AgentApiKey = mongoose.models.AgentApiKey;
|
|
5162
|
+
const keyHash = await hashToken(apiKey);
|
|
5163
|
+
const keyDoc = (await AgentApiKey.findOne({ keyHash }).lean());
|
|
5164
|
+
if (!keyDoc) {
|
|
5165
|
+
return null;
|
|
5166
|
+
}
|
|
5167
|
+
if (keyDoc.expiresAt && new Date(keyDoc.expiresAt) < new Date()) {
|
|
5168
|
+
return null;
|
|
5169
|
+
}
|
|
5170
|
+
await AgentApiKey.updateOne({ _id: keyDoc._id }, { $set: { lastUsedAt: new Date() } });
|
|
5171
|
+
return {
|
|
5172
|
+
userId: keyDoc.userId,
|
|
5173
|
+
keyId: keyDoc._id,
|
|
5174
|
+
};
|
|
5175
|
+
}
|
|
5176
|
+
catch (error) {
|
|
5177
|
+
logger$1.error('[validateAgentApiKey] Error validating API key:', error);
|
|
5178
|
+
return null;
|
|
5179
|
+
}
|
|
5180
|
+
}
|
|
5181
|
+
async function listAgentApiKeys(userId) {
|
|
5182
|
+
try {
|
|
5183
|
+
const AgentApiKey = mongoose.models.AgentApiKey;
|
|
5184
|
+
const keys = (await AgentApiKey.find({ userId })
|
|
5185
|
+
.sort({ createdAt: -1 })
|
|
5186
|
+
.lean());
|
|
5187
|
+
return keys.map((key) => ({
|
|
5188
|
+
id: key._id.toString(),
|
|
5189
|
+
name: key.name,
|
|
5190
|
+
keyPrefix: key.keyPrefix,
|
|
5191
|
+
lastUsedAt: key.lastUsedAt,
|
|
5192
|
+
expiresAt: key.expiresAt,
|
|
5193
|
+
createdAt: key.createdAt,
|
|
5194
|
+
}));
|
|
5195
|
+
}
|
|
5196
|
+
catch (error) {
|
|
5197
|
+
logger$1.error('[listAgentApiKeys] Error listing API keys:', error);
|
|
5198
|
+
throw error;
|
|
5199
|
+
}
|
|
5200
|
+
}
|
|
5201
|
+
async function deleteAgentApiKey(keyId, userId) {
|
|
5202
|
+
try {
|
|
5203
|
+
const AgentApiKey = mongoose.models.AgentApiKey;
|
|
5204
|
+
const result = await AgentApiKey.deleteOne({ _id: keyId, userId });
|
|
5205
|
+
return result.deletedCount > 0;
|
|
5206
|
+
}
|
|
5207
|
+
catch (error) {
|
|
5208
|
+
logger$1.error('[deleteAgentApiKey] Error deleting API key:', error);
|
|
5209
|
+
throw error;
|
|
5210
|
+
}
|
|
5211
|
+
}
|
|
5212
|
+
async function deleteAllAgentApiKeys(userId) {
|
|
5213
|
+
try {
|
|
5214
|
+
const AgentApiKey = mongoose.models.AgentApiKey;
|
|
5215
|
+
const result = await AgentApiKey.deleteMany({ userId });
|
|
5216
|
+
return result.deletedCount;
|
|
5217
|
+
}
|
|
5218
|
+
catch (error) {
|
|
5219
|
+
logger$1.error('[deleteAllAgentApiKeys] Error deleting all API keys:', error);
|
|
5220
|
+
throw error;
|
|
5221
|
+
}
|
|
5222
|
+
}
|
|
5223
|
+
async function getAgentApiKeyById(keyId, userId) {
|
|
5224
|
+
try {
|
|
5225
|
+
const AgentApiKey = mongoose.models.AgentApiKey;
|
|
5226
|
+
const keyDoc = (await AgentApiKey.findOne({
|
|
5227
|
+
_id: keyId,
|
|
5228
|
+
userId,
|
|
5229
|
+
}).lean());
|
|
5230
|
+
if (!keyDoc) {
|
|
5231
|
+
return null;
|
|
5232
|
+
}
|
|
5233
|
+
return {
|
|
5234
|
+
id: keyDoc._id.toString(),
|
|
5235
|
+
name: keyDoc.name,
|
|
5236
|
+
keyPrefix: keyDoc.keyPrefix,
|
|
5237
|
+
lastUsedAt: keyDoc.lastUsedAt,
|
|
5238
|
+
expiresAt: keyDoc.expiresAt,
|
|
5239
|
+
createdAt: keyDoc.createdAt,
|
|
5240
|
+
};
|
|
5241
|
+
}
|
|
5242
|
+
catch (error) {
|
|
5243
|
+
logger$1.error('[getAgentApiKeyById] Error getting API key:', error);
|
|
5244
|
+
throw error;
|
|
5245
|
+
}
|
|
5246
|
+
}
|
|
5247
|
+
return {
|
|
5248
|
+
createAgentApiKey,
|
|
5249
|
+
validateAgentApiKey,
|
|
5250
|
+
listAgentApiKeys,
|
|
5251
|
+
deleteAgentApiKey,
|
|
5252
|
+
deleteAllAgentApiKeys,
|
|
5253
|
+
getAgentApiKeyById,
|
|
5254
|
+
};
|
|
5255
|
+
}
|
|
5256
|
+
|
|
4965
5257
|
const NORMALIZED_LIMIT_DEFAULT = 20;
|
|
4966
5258
|
const MAX_CREATE_RETRIES = 5;
|
|
4967
5259
|
const RETRY_BASE_DELAY_MS = 25;
|
|
@@ -5462,6 +5754,27 @@ function createAccessRoleMethods(mongoose) {
|
|
|
5462
5754
|
resourceType: librechatDataProvider.ResourceType.MCPSERVER,
|
|
5463
5755
|
permBits: exports.RoleBits.OWNER,
|
|
5464
5756
|
},
|
|
5757
|
+
{
|
|
5758
|
+
accessRoleId: librechatDataProvider.AccessRoleIds.REMOTE_AGENT_VIEWER,
|
|
5759
|
+
name: 'com_ui_remote_agent_role_viewer',
|
|
5760
|
+
description: 'com_ui_remote_agent_role_viewer_desc',
|
|
5761
|
+
resourceType: librechatDataProvider.ResourceType.REMOTE_AGENT,
|
|
5762
|
+
permBits: exports.RoleBits.VIEWER,
|
|
5763
|
+
},
|
|
5764
|
+
{
|
|
5765
|
+
accessRoleId: librechatDataProvider.AccessRoleIds.REMOTE_AGENT_EDITOR,
|
|
5766
|
+
name: 'com_ui_remote_agent_role_editor',
|
|
5767
|
+
description: 'com_ui_remote_agent_role_editor_desc',
|
|
5768
|
+
resourceType: librechatDataProvider.ResourceType.REMOTE_AGENT,
|
|
5769
|
+
permBits: exports.RoleBits.EDITOR,
|
|
5770
|
+
},
|
|
5771
|
+
{
|
|
5772
|
+
accessRoleId: librechatDataProvider.AccessRoleIds.REMOTE_AGENT_OWNER,
|
|
5773
|
+
name: 'com_ui_remote_agent_role_owner',
|
|
5774
|
+
description: 'com_ui_remote_agent_role_owner_desc',
|
|
5775
|
+
resourceType: librechatDataProvider.ResourceType.REMOTE_AGENT,
|
|
5776
|
+
permBits: exports.RoleBits.OWNER,
|
|
5777
|
+
},
|
|
5465
5778
|
];
|
|
5466
5779
|
const result = {};
|
|
5467
5780
|
for (const role of defaultRoles) {
|
|
@@ -6713,6 +7026,7 @@ function createMethods(mongoose) {
|
|
|
6713
7026
|
...createFileMethods(mongoose),
|
|
6714
7027
|
...createMemoryMethods(mongoose),
|
|
6715
7028
|
...createAgentCategoryMethods(mongoose),
|
|
7029
|
+
...createAgentApiKeyMethods(mongoose),
|
|
6716
7030
|
...createMCPServerMethods(mongoose),
|
|
6717
7031
|
...createAccessRoleMethods(mongoose),
|
|
6718
7032
|
...createUserGroupMethods(mongoose),
|
|
@@ -6726,6 +7040,7 @@ exports.AppService = AppService;
|
|
|
6726
7040
|
exports.DEFAULT_REFRESH_TOKEN_EXPIRY = DEFAULT_REFRESH_TOKEN_EXPIRY;
|
|
6727
7041
|
exports.DEFAULT_SESSION_EXPIRY = DEFAULT_SESSION_EXPIRY;
|
|
6728
7042
|
exports.actionSchema = Action;
|
|
7043
|
+
exports.agentApiKeySchema = agentApiKeySchema;
|
|
6729
7044
|
exports.agentCategorySchema = agentCategorySchema;
|
|
6730
7045
|
exports.agentSchema = agentSchema;
|
|
6731
7046
|
exports.agentsConfigSetup = agentsConfigSetup;
|