mirror of
https://github.com/danny-avila/LibreChat.git
synced 2025-12-17 00:40:14 +01:00
🔧 fix: Keyv and Proxy Issues, and More Memory Optimizations (#6867)
* chore: update @librechat/agents dependency to version 2.4.15
* refactor: Prevent memory leaks by nullifying boundModel.client in disposeClient function
* fix: use of proxy, use undici
* chore: update @librechat/agents dependency to version 2.4.16
* Revert "fix: use of proxy, use undici"
This reverts commit 83153cd582.
* fix: ensure fetch is imported for HTTP requests
* fix: replace direct OpenAI import with CustomOpenAIClient from @librechat/agents
* fix: update keyv peer dependency to version 5.3.2
* fix: update keyv dependency to version 5.3.2
* refactor: replace KeyvMongo with custom implementation and update flow state manager usage
* fix: update @librechat/agents dependency to version 2.4.17
* ci: update OpenAIClient tests to use CustomOpenAIClient from @librechat/agents
* refactor: remove KeyvMongo mock and related dependencies
This commit is contained in:
parent
339882eea4
commit
64bd373bc8
18 changed files with 375 additions and 743 deletions
|
|
@ -1,7 +1,6 @@
|
|||
const OpenAI = require('openai');
|
||||
const { OllamaClient } = require('./OllamaClient');
|
||||
const { HttpsProxyAgent } = require('https-proxy-agent');
|
||||
const { SplitStreamHandler } = require('@librechat/agents');
|
||||
const { SplitStreamHandler, CustomOpenAIClient: OpenAI } = require('@librechat/agents');
|
||||
const {
|
||||
Constants,
|
||||
ImageDetail,
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
const fetch = require('node-fetch');
|
||||
const { GraphEvents } = require('@librechat/agents');
|
||||
const { logger, sendEvent } = require('~/config');
|
||||
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ jest.mock('~/models', () => ({
|
|||
|
||||
const { getConvo, saveConvo } = require('~/models');
|
||||
|
||||
jest.mock('@langchain/openai', () => {
|
||||
jest.mock('@librechat/agents', () => {
|
||||
return {
|
||||
ChatOpenAI: jest.fn().mockImplementation(() => {
|
||||
return {};
|
||||
|
|
|
|||
|
|
@ -1,9 +1,7 @@
|
|||
jest.mock('~/cache/getLogStores');
|
||||
require('dotenv').config();
|
||||
const OpenAI = require('openai');
|
||||
const getLogStores = require('~/cache/getLogStores');
|
||||
const { fetchEventSource } = require('@waylaidwanderer/fetch-event-source');
|
||||
const { genAzureChatCompletion } = require('~/utils/azureUtils');
|
||||
const getLogStores = require('~/cache/getLogStores');
|
||||
const OpenAIClient = require('../OpenAIClient');
|
||||
jest.mock('meilisearch');
|
||||
|
||||
|
|
@ -36,19 +34,21 @@ jest.mock('~/models', () => ({
|
|||
updateFileUsage: jest.fn(),
|
||||
}));
|
||||
|
||||
jest.mock('@langchain/openai', () => {
|
||||
return {
|
||||
ChatOpenAI: jest.fn().mockImplementation(() => {
|
||||
return {};
|
||||
}),
|
||||
};
|
||||
// Import the actual module but mock specific parts
|
||||
const agents = jest.requireActual('@librechat/agents');
|
||||
const { CustomOpenAIClient } = agents;
|
||||
|
||||
// Also mock ChatOpenAI to prevent real API calls
|
||||
agents.ChatOpenAI = jest.fn().mockImplementation(() => {
|
||||
return {};
|
||||
});
|
||||
agents.AzureChatOpenAI = jest.fn().mockImplementation(() => {
|
||||
return {};
|
||||
});
|
||||
|
||||
jest.mock('openai');
|
||||
|
||||
jest.spyOn(OpenAI, 'constructor').mockImplementation(function (...options) {
|
||||
// We can add additional logic here if needed
|
||||
return new OpenAI(...options);
|
||||
// Mock only the CustomOpenAIClient constructor
|
||||
jest.spyOn(CustomOpenAIClient, 'constructor').mockImplementation(function (...options) {
|
||||
return new CustomOpenAIClient(...options);
|
||||
});
|
||||
|
||||
const finalChatCompletion = jest.fn().mockResolvedValue({
|
||||
|
|
@ -120,7 +120,13 @@ const create = jest.fn().mockResolvedValue({
|
|||
],
|
||||
});
|
||||
|
||||
OpenAI.mockImplementation(() => ({
|
||||
// Mock the implementation of CustomOpenAIClient instances
|
||||
jest.spyOn(CustomOpenAIClient.prototype, 'constructor').mockImplementation(function () {
|
||||
return this;
|
||||
});
|
||||
|
||||
// Create a mock for the CustomOpenAIClient class
|
||||
const mockCustomOpenAIClient = jest.fn().mockImplementation(() => ({
|
||||
beta: {
|
||||
chat: {
|
||||
completions: {
|
||||
|
|
@ -135,6 +141,8 @@ OpenAI.mockImplementation(() => ({
|
|||
},
|
||||
}));
|
||||
|
||||
CustomOpenAIClient.mockImplementation = mockCustomOpenAIClient;
|
||||
|
||||
describe('OpenAIClient', () => {
|
||||
beforeEach(() => {
|
||||
const mockCache = {
|
||||
|
|
@ -559,41 +567,6 @@ describe('OpenAIClient', () => {
|
|||
expect(requestBody).toHaveProperty('model');
|
||||
expect(requestBody.model).toBe(model);
|
||||
});
|
||||
|
||||
it('[Azure OpenAI] should call chatCompletion and OpenAI.stream with correct args', async () => {
|
||||
// Set a default model
|
||||
process.env.AZURE_OPENAI_DEFAULT_MODEL = 'gpt4-turbo';
|
||||
|
||||
const onProgress = jest.fn().mockImplementation(() => ({}));
|
||||
client.azure = defaultAzureOptions;
|
||||
const chatCompletion = jest.spyOn(client, 'chatCompletion');
|
||||
await client.sendMessage('Hi mom!', {
|
||||
replaceOptions: true,
|
||||
...defaultOptions,
|
||||
modelOptions: { model: 'gpt4-turbo', stream: true },
|
||||
onProgress,
|
||||
azure: defaultAzureOptions,
|
||||
});
|
||||
|
||||
expect(chatCompletion).toHaveBeenCalled();
|
||||
expect(chatCompletion.mock.calls.length).toBe(1);
|
||||
|
||||
const chatCompletionArgs = chatCompletion.mock.calls[0][0];
|
||||
const { payload } = chatCompletionArgs;
|
||||
|
||||
expect(payload[0].role).toBe('user');
|
||||
expect(payload[0].content).toBe('Hi mom!');
|
||||
|
||||
// Azure OpenAI does not use the model property, and will error if it's passed
|
||||
// This check ensures the model property is not present
|
||||
const streamArgs = stream.mock.calls[0][0];
|
||||
expect(streamArgs).not.toHaveProperty('model');
|
||||
|
||||
// Check if the baseURL is correct
|
||||
const constructorArgs = OpenAI.mock.calls[0][0];
|
||||
const expectedURL = genAzureChatCompletion(defaultAzureOptions).split('/chat')[0];
|
||||
expect(constructorArgs.baseURL).toBe(expectedURL);
|
||||
});
|
||||
});
|
||||
|
||||
describe('checkVisionRequest functionality', () => {
|
||||
|
|
|
|||
269
api/cache/keyvMongo.js
vendored
269
api/cache/keyvMongo.js
vendored
|
|
@ -1,9 +1,272 @@
|
|||
const { KeyvMongo } = require('@keyv/mongo');
|
||||
// api/cache/keyvMongo.js
|
||||
const mongoose = require('mongoose');
|
||||
const EventEmitter = require('events');
|
||||
const { GridFSBucket } = require('mongodb');
|
||||
const { logger } = require('~/config');
|
||||
|
||||
const { MONGO_URI } = process.env ?? {};
|
||||
const storeMap = new Map();
|
||||
|
||||
class KeyvMongoCustom extends EventEmitter {
|
||||
constructor(url, options = {}) {
|
||||
super();
|
||||
|
||||
url = url || {};
|
||||
if (typeof url === 'string') {
|
||||
url = { url };
|
||||
}
|
||||
if (url.uri) {
|
||||
url = { url: url.uri, ...url };
|
||||
}
|
||||
|
||||
this.opts = {
|
||||
url: 'mongodb://127.0.0.1:27017',
|
||||
collection: 'keyv',
|
||||
...url,
|
||||
...options,
|
||||
};
|
||||
|
||||
this.ttlSupport = false;
|
||||
|
||||
// Filter valid options
|
||||
const keyvMongoKeys = new Set([
|
||||
'url',
|
||||
'collection',
|
||||
'namespace',
|
||||
'serialize',
|
||||
'deserialize',
|
||||
'uri',
|
||||
'useGridFS',
|
||||
'dialect',
|
||||
]);
|
||||
this.opts = Object.fromEntries(Object.entries(this.opts).filter(([k]) => keyvMongoKeys.has(k)));
|
||||
}
|
||||
|
||||
// Helper to access the store WITHOUT storing a promise on the instance
|
||||
_getClient() {
|
||||
const storeKey = `${this.opts.collection}:${this.opts.useGridFS ? 'gridfs' : 'collection'}`;
|
||||
|
||||
// If we already have the store initialized, return it directly
|
||||
if (storeMap.has(storeKey)) {
|
||||
return Promise.resolve(storeMap.get(storeKey));
|
||||
}
|
||||
|
||||
// Check mongoose connection state
|
||||
if (mongoose.connection.readyState !== 1) {
|
||||
return Promise.reject(
|
||||
new Error('Mongoose connection not ready. Ensure connectDb() is called first.'),
|
||||
);
|
||||
}
|
||||
|
||||
try {
|
||||
const db = mongoose.connection.db;
|
||||
let client;
|
||||
|
||||
if (this.opts.useGridFS) {
|
||||
const bucket = new GridFSBucket(db, {
|
||||
readPreference: this.opts.readPreference,
|
||||
bucketName: this.opts.collection,
|
||||
});
|
||||
const store = db.collection(`${this.opts.collection}.files`);
|
||||
client = { bucket, store, db };
|
||||
} else {
|
||||
const collection = this.opts.collection || 'keyv';
|
||||
const store = db.collection(collection);
|
||||
client = { store, db };
|
||||
}
|
||||
|
||||
storeMap.set(storeKey, client);
|
||||
return Promise.resolve(client);
|
||||
} catch (error) {
|
||||
this.emit('error', error);
|
||||
return Promise.reject(error);
|
||||
}
|
||||
}
|
||||
|
||||
async get(key) {
|
||||
const client = await this._getClient();
|
||||
|
||||
if (this.opts.useGridFS) {
|
||||
await client.store.updateOne(
|
||||
{
|
||||
filename: key,
|
||||
},
|
||||
{
|
||||
$set: {
|
||||
'metadata.lastAccessed': new Date(),
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
const stream = client.bucket.openDownloadStreamByName(key);
|
||||
|
||||
return new Promise((resolve) => {
|
||||
const resp = [];
|
||||
stream.on('error', () => {
|
||||
resolve(undefined);
|
||||
});
|
||||
|
||||
stream.on('end', () => {
|
||||
const data = Buffer.concat(resp).toString('utf8');
|
||||
resolve(data);
|
||||
});
|
||||
|
||||
stream.on('data', (chunk) => {
|
||||
resp.push(chunk);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
const document = await client.store.findOne({ key: { $eq: key } });
|
||||
|
||||
if (!document) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return document.value;
|
||||
}
|
||||
|
||||
async getMany(keys) {
|
||||
const client = await this._getClient();
|
||||
|
||||
if (this.opts.useGridFS) {
|
||||
const promises = [];
|
||||
for (const key of keys) {
|
||||
promises.push(this.get(key));
|
||||
}
|
||||
|
||||
const values = await Promise.allSettled(promises);
|
||||
const data = [];
|
||||
for (const value of values) {
|
||||
data.push(value.value);
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
const values = await client.store
|
||||
.find({ key: { $in: keys } })
|
||||
.project({ _id: 0, value: 1, key: 1 })
|
||||
.toArray();
|
||||
|
||||
const results = [...keys];
|
||||
let i = 0;
|
||||
for (const key of keys) {
|
||||
const rowIndex = values.findIndex((row) => row.key === key);
|
||||
results[i] = rowIndex > -1 ? values[rowIndex].value : undefined;
|
||||
i++;
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
async set(key, value, ttl) {
|
||||
const client = await this._getClient();
|
||||
const expiresAt = typeof ttl === 'number' ? new Date(Date.now() + ttl) : null;
|
||||
|
||||
if (this.opts.useGridFS) {
|
||||
const stream = client.bucket.openUploadStream(key, {
|
||||
metadata: {
|
||||
expiresAt,
|
||||
lastAccessed: new Date(),
|
||||
},
|
||||
});
|
||||
|
||||
return new Promise((resolve) => {
|
||||
stream.on('finish', () => {
|
||||
resolve(stream);
|
||||
});
|
||||
stream.end(value);
|
||||
});
|
||||
}
|
||||
|
||||
await client.store.updateOne(
|
||||
{ key: { $eq: key } },
|
||||
{ $set: { key, value, expiresAt } },
|
||||
{ upsert: true },
|
||||
);
|
||||
}
|
||||
|
||||
async delete(key) {
|
||||
if (typeof key !== 'string') {
|
||||
return false;
|
||||
}
|
||||
|
||||
const client = await this._getClient();
|
||||
|
||||
if (this.opts.useGridFS) {
|
||||
try {
|
||||
const bucket = new GridFSBucket(client.db, {
|
||||
bucketName: this.opts.collection,
|
||||
});
|
||||
const files = await bucket.find({ filename: key }).toArray();
|
||||
await client.bucket.delete(files[0]._id);
|
||||
return true;
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
const object = await client.store.deleteOne({ key: { $eq: key } });
|
||||
return object.deletedCount > 0;
|
||||
}
|
||||
|
||||
async deleteMany(keys) {
|
||||
const client = await this._getClient();
|
||||
|
||||
if (this.opts.useGridFS) {
|
||||
const bucket = new GridFSBucket(client.db, {
|
||||
bucketName: this.opts.collection,
|
||||
});
|
||||
const files = await bucket.find({ filename: { $in: keys } }).toArray();
|
||||
if (files.length === 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
await Promise.all(files.map(async (file) => client.bucket.delete(file._id)));
|
||||
return true;
|
||||
}
|
||||
|
||||
const object = await client.store.deleteMany({ key: { $in: keys } });
|
||||
return object.deletedCount > 0;
|
||||
}
|
||||
|
||||
async clear() {
|
||||
const client = await this._getClient();
|
||||
|
||||
if (this.opts.useGridFS) {
|
||||
try {
|
||||
await client.bucket.drop();
|
||||
} catch (error) {
|
||||
// Throw error if not "namespace not found" error
|
||||
if (!(error.code === 26)) {
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
await client.store.deleteMany({
|
||||
key: { $regex: this.namespace ? `^${this.namespace}:*` : '' },
|
||||
});
|
||||
}
|
||||
|
||||
async has(key) {
|
||||
const client = await this._getClient();
|
||||
const filter = { [this.opts.useGridFS ? 'filename' : 'key']: { $eq: key } };
|
||||
const document = await client.store.countDocuments(filter, { limit: 1 });
|
||||
return document !== 0;
|
||||
}
|
||||
|
||||
// No-op disconnect
|
||||
async disconnect() {
|
||||
// This is a no-op since we don't want to close the shared mongoose connection
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
const keyvMongo = new KeyvMongoCustom({
|
||||
collection: 'logs',
|
||||
});
|
||||
|
||||
const keyvMongo = new KeyvMongo(MONGO_URI, { collection: 'logs' });
|
||||
keyvMongo.on('error', (err) => logger.error('KeyvMongo connection error:', err));
|
||||
|
||||
module.exports = keyvMongo;
|
||||
|
|
|
|||
|
|
@ -24,12 +24,12 @@ function getMCPManager(userId) {
|
|||
}
|
||||
|
||||
/**
|
||||
* @param {(key: string) => Keyv} getLogStores
|
||||
* @param {Keyv} flowsCache
|
||||
* @returns {FlowStateManager}
|
||||
*/
|
||||
function getFlowStateManager(getLogStores) {
|
||||
function getFlowStateManager(flowsCache) {
|
||||
if (!flowManager) {
|
||||
flowManager = new FlowStateManager(getLogStores(CacheKeys.FLOWS), {
|
||||
flowManager = new FlowStateManager(flowsCache, {
|
||||
ttl: Time.ONE_MINUTE * 3,
|
||||
logger,
|
||||
});
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@ module.exports = {
|
|||
coverageDirectory: 'coverage',
|
||||
setupFiles: [
|
||||
'./test/jestSetup.js',
|
||||
'./test/__mocks__/KeyvMongo.js',
|
||||
'./test/__mocks__/logger.js',
|
||||
'./test/__mocks__/fetchEventSource.js',
|
||||
],
|
||||
|
|
|
|||
|
|
@ -42,14 +42,13 @@
|
|||
"@azure/storage-blob": "^12.26.0",
|
||||
"@google/generative-ai": "^0.23.0",
|
||||
"@googleapis/youtube": "^20.0.0",
|
||||
"@keyv/mongo": "^3.0.1",
|
||||
"@keyv/redis": "^4.3.3",
|
||||
"@langchain/community": "^0.3.39",
|
||||
"@langchain/core": "^0.3.43",
|
||||
"@langchain/google-genai": "^0.2.2",
|
||||
"@langchain/google-vertexai": "^0.2.3",
|
||||
"@langchain/textsplitters": "^0.1.0",
|
||||
"@librechat/agents": "^2.4.14",
|
||||
"@librechat/agents": "^2.4.17",
|
||||
"@librechat/data-schemas": "*",
|
||||
"@waylaidwanderer/fetch-event-source": "^3.0.1",
|
||||
"axios": "^1.8.2",
|
||||
|
|
|
|||
|
|
@ -238,6 +238,9 @@ function disposeClient(client) {
|
|||
client.run.Graph.streamBuffer = null;
|
||||
client.run.Graph.clientOptions = null;
|
||||
client.run.Graph.graphState = null;
|
||||
if (client.run.Graph.boundModel?.client) {
|
||||
client.run.Graph.boundModel.client = null;
|
||||
}
|
||||
client.run.Graph.boundModel = null;
|
||||
client.run.Graph.systemMessage = null;
|
||||
client.run.Graph.reasoningKey = null;
|
||||
|
|
|
|||
|
|
@ -787,6 +787,8 @@ class AgentClient extends BaseClient {
|
|||
[Callback.TOOL_ERROR]: logToolError,
|
||||
},
|
||||
});
|
||||
|
||||
config.signal = null;
|
||||
};
|
||||
|
||||
await runAgent(this.options.agent, initialMessages);
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
const express = require('express');
|
||||
const jwt = require('jsonwebtoken');
|
||||
const { CacheKeys } = require('librechat-data-provider');
|
||||
const { getAccessToken } = require('~/server/services/TokenService');
|
||||
const { logger, getFlowStateManager } = require('~/config');
|
||||
const { getLogStores } = require('~/cache');
|
||||
|
|
@ -19,8 +20,8 @@ const JWT_SECRET = process.env.JWT_SECRET;
|
|||
router.get('/:action_id/oauth/callback', async (req, res) => {
|
||||
const { action_id } = req.params;
|
||||
const { code, state } = req.query;
|
||||
|
||||
const flowManager = getFlowStateManager(getLogStores);
|
||||
const flowsCache = getLogStores(CacheKeys.FLOWS);
|
||||
const flowManager = getFlowStateManager(flowsCache);
|
||||
let identifier = action_id;
|
||||
try {
|
||||
let decodedState;
|
||||
|
|
|
|||
|
|
@ -74,7 +74,6 @@ async function domainParser(domain, inverse = false) {
|
|||
if (!domain) {
|
||||
return;
|
||||
}
|
||||
|
||||
const domainsCache = getLogStores(CacheKeys.ENCODED_DOMAINS);
|
||||
const cachedDomain = await domainsCache.get(domain);
|
||||
if (inverse && cachedDomain) {
|
||||
|
|
@ -188,7 +187,8 @@ async function createActionTool({
|
|||
expires_at: Date.now() + Time.TWO_MINUTES,
|
||||
},
|
||||
};
|
||||
const flowManager = getFlowStateManager(getLogStores);
|
||||
const flowsCache = getLogStores(CacheKeys.FLOWS);
|
||||
const flowManager = getFlowStateManager(flowsCache);
|
||||
await flowManager.createFlowWithHandler(
|
||||
`${identifier}:oauth_login:${config.metadata.thread_id}:${config.metadata.run_id}`,
|
||||
'oauth_login',
|
||||
|
|
@ -264,7 +264,8 @@ async function createActionTool({
|
|||
encrypted_oauth_client_id: encrypted.oauth_client_id,
|
||||
encrypted_oauth_client_secret: encrypted.oauth_client_secret,
|
||||
});
|
||||
const flowManager = getFlowStateManager(getLogStores);
|
||||
const flowsCache = getLogStores(CacheKeys.FLOWS);
|
||||
const flowManager = getFlowStateManager(flowsCache);
|
||||
const refreshData = await flowManager.createFlowWithHandler(
|
||||
`${identifier}:refresh`,
|
||||
'oauth_refresh',
|
||||
|
|
|
|||
|
|
@ -1,48 +0,0 @@
|
|||
jest.mock('@keyv/mongo', () => {
|
||||
const EventEmitter = require('events');
|
||||
class KeyvMongo extends EventEmitter {
|
||||
constructor(url = 'mongodb://127.0.0.1:27017', options) {
|
||||
super();
|
||||
this.ttlSupport = false;
|
||||
url = url ?? {};
|
||||
if (typeof url === 'string') {
|
||||
url = { url };
|
||||
}
|
||||
if (url.uri) {
|
||||
url = { url: url.uri, ...url };
|
||||
}
|
||||
this.opts = {
|
||||
url,
|
||||
collection: 'keyv',
|
||||
...url,
|
||||
...options,
|
||||
};
|
||||
|
||||
// In-memory store for tests
|
||||
this.store = new Map();
|
||||
}
|
||||
|
||||
async get(key) {
|
||||
return this.store.get(key);
|
||||
}
|
||||
|
||||
async set(key, value, ttl) {
|
||||
this.store.set(key, value);
|
||||
return true;
|
||||
}
|
||||
|
||||
async delete(key) {
|
||||
return this.store.delete(key);
|
||||
}
|
||||
|
||||
async clear() {
|
||||
this.store.clear();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Create a store factory function for the test suite
|
||||
const store = () => new KeyvMongo();
|
||||
|
||||
return { KeyvMongo };
|
||||
});
|
||||
684
package-lock.json
generated
684
package-lock.json
generated
|
|
@ -58,14 +58,13 @@
|
|||
"@azure/storage-blob": "^12.26.0",
|
||||
"@google/generative-ai": "^0.23.0",
|
||||
"@googleapis/youtube": "^20.0.0",
|
||||
"@keyv/mongo": "^3.0.1",
|
||||
"@keyv/redis": "^4.3.3",
|
||||
"@langchain/community": "^0.3.39",
|
||||
"@langchain/core": "^0.3.43",
|
||||
"@langchain/google-genai": "^0.2.2",
|
||||
"@langchain/google-vertexai": "^0.2.3",
|
||||
"@langchain/textsplitters": "^0.1.0",
|
||||
"@librechat/agents": "^2.4.14",
|
||||
"@librechat/agents": "^2.4.17",
|
||||
"@librechat/data-schemas": "*",
|
||||
"@waylaidwanderer/fetch-event-source": "^3.0.1",
|
||||
"axios": "^1.8.2",
|
||||
|
|
@ -158,14 +157,6 @@
|
|||
"node": ">=18.0.0"
|
||||
}
|
||||
},
|
||||
"api/node_modules/@keyv/mongo": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@keyv/mongo/-/mongo-3.0.1.tgz",
|
||||
"integrity": "sha512-dNVIhm68mh/CAySN6q7o1vyBRdBRt41nrJXIDlqLhnXOo4l8IAY1Vj5BlTkUfw1BDLuZ9zjb+g1lr/BMRdzNdg==",
|
||||
"dependencies": {
|
||||
"mongodb": "^6.8.0"
|
||||
}
|
||||
},
|
||||
"api/node_modules/@keyv/redis": {
|
||||
"version": "4.3.3",
|
||||
"resolved": "https://registry.npmjs.org/@keyv/redis/-/redis-4.3.3.tgz",
|
||||
|
|
@ -720,6 +711,31 @@
|
|||
"@langchain/core": ">=0.3.39 <0.4.0"
|
||||
}
|
||||
},
|
||||
"api/node_modules/@librechat/agents": {
|
||||
"version": "2.4.17",
|
||||
"resolved": "https://registry.npmjs.org/@librechat/agents/-/agents-2.4.17.tgz",
|
||||
"integrity": "sha512-lGgOqovIqzaFtO3wUe8LShckJYmFGxa/RAn1edUxmQgK76F4QK53POFivzQhYUxso9z4SNvu1b8q/+vq7lWYaw==",
|
||||
"dependencies": {
|
||||
"@langchain/anthropic": "^0.3.16",
|
||||
"@langchain/aws": "^0.1.7",
|
||||
"@langchain/community": "^0.3.39",
|
||||
"@langchain/core": "^0.3.43",
|
||||
"@langchain/deepseek": "^0.0.1",
|
||||
"@langchain/google-genai": "^0.2.2",
|
||||
"@langchain/google-vertexai": "^0.2.3",
|
||||
"@langchain/langgraph": "^0.2.62",
|
||||
"@langchain/mistralai": "^0.2.0",
|
||||
"@langchain/ollama": "^0.2.0",
|
||||
"@langchain/openai": "^0.5.4",
|
||||
"@langchain/xai": "^0.0.2",
|
||||
"dotenv": "^16.4.7",
|
||||
"https-proxy-agent": "^7.0.6",
|
||||
"nanoid": "^3.3.7"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.0.0"
|
||||
}
|
||||
},
|
||||
"api/node_modules/@types/node": {
|
||||
"version": "18.19.14",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.14.tgz",
|
||||
|
|
@ -846,14 +862,6 @@
|
|||
"node": ">= 14"
|
||||
}
|
||||
},
|
||||
"api/node_modules/keyv": {
|
||||
"version": "5.3.2",
|
||||
"resolved": "https://registry.npmjs.org/keyv/-/keyv-5.3.2.tgz",
|
||||
"integrity": "sha512-Lji2XRxqqa5Wg+CHLVfFKBImfJZ4pCSccu9eVWK6w4c2SDFLd8JAn1zqTuSFnsxb7ope6rMsnIHfp+eBbRBRZQ==",
|
||||
"dependencies": {
|
||||
"@keyv/serialize": "^1.0.3"
|
||||
}
|
||||
},
|
||||
"api/node_modules/keyv-file": {
|
||||
"version": "5.1.2",
|
||||
"resolved": "https://registry.npmjs.org/keyv-file/-/keyv-file-5.1.2.tgz",
|
||||
|
|
@ -17878,604 +17886,6 @@
|
|||
"@lezer/common": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@librechat/agents": {
|
||||
"version": "2.4.14",
|
||||
"resolved": "https://registry.npmjs.org/@librechat/agents/-/agents-2.4.14.tgz",
|
||||
"integrity": "sha512-EYtjjl7/Xb94UZh+6S8XHcbyuqAYrVi41aFk9UFV+8TRTN16ZK/K0zhPix1SGeA8J60Xs3Y1HkZBJdbGMi9X2Q==",
|
||||
"dependencies": {
|
||||
"@langchain/anthropic": "^0.3.16",
|
||||
"@langchain/aws": "^0.1.7",
|
||||
"@langchain/community": "^0.3.39",
|
||||
"@langchain/core": "^0.3.43",
|
||||
"@langchain/deepseek": "^0.0.1",
|
||||
"@langchain/google-genai": "^0.2.2",
|
||||
"@langchain/google-vertexai": "^0.2.3",
|
||||
"@langchain/langgraph": "^0.2.62",
|
||||
"@langchain/mistralai": "^0.2.0",
|
||||
"@langchain/ollama": "^0.2.0",
|
||||
"@langchain/openai": "^0.5.4",
|
||||
"@langchain/xai": "^0.0.2",
|
||||
"dotenv": "^16.4.7",
|
||||
"https-proxy-agent": "^7.0.6",
|
||||
"nanoid": "^3.3.7"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@librechat/agents/node_modules/@langchain/community": {
|
||||
"version": "0.3.40",
|
||||
"resolved": "https://registry.npmjs.org/@langchain/community/-/community-0.3.40.tgz",
|
||||
"integrity": "sha512-UvpEebdFKJsjFBKeUOvvYHOEFsUcjZnyU1qNirtDajwjzTJlszXtv+Mq8F6w5mJsznpI9x7ZMNzAqydVxMG5hA==",
|
||||
"dependencies": {
|
||||
"@langchain/openai": ">=0.2.0 <0.6.0",
|
||||
"binary-extensions": "^2.2.0",
|
||||
"expr-eval": "^2.0.2",
|
||||
"flat": "^5.0.2",
|
||||
"js-yaml": "^4.1.0",
|
||||
"langchain": ">=0.2.3 <0.3.0 || >=0.3.4 <0.4.0",
|
||||
"langsmith": ">=0.2.8 <0.4.0",
|
||||
"uuid": "^10.0.0",
|
||||
"zod": "^3.22.3",
|
||||
"zod-to-json-schema": "^3.22.5"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@arcjet/redact": "^v1.0.0-alpha.23",
|
||||
"@aws-crypto/sha256-js": "^5.0.0",
|
||||
"@aws-sdk/client-bedrock-agent-runtime": "^3.749.0",
|
||||
"@aws-sdk/client-bedrock-runtime": "^3.749.0",
|
||||
"@aws-sdk/client-dynamodb": "^3.749.0",
|
||||
"@aws-sdk/client-kendra": "^3.749.0",
|
||||
"@aws-sdk/client-lambda": "^3.749.0",
|
||||
"@aws-sdk/client-s3": "^3.749.0",
|
||||
"@aws-sdk/client-sagemaker-runtime": "^3.749.0",
|
||||
"@aws-sdk/client-sfn": "^3.749.0",
|
||||
"@aws-sdk/credential-provider-node": "^3.388.0",
|
||||
"@azure/search-documents": "^12.0.0",
|
||||
"@azure/storage-blob": "^12.15.0",
|
||||
"@browserbasehq/sdk": "*",
|
||||
"@browserbasehq/stagehand": "^1.0.0",
|
||||
"@clickhouse/client": "^0.2.5",
|
||||
"@cloudflare/ai": "*",
|
||||
"@datastax/astra-db-ts": "^1.0.0",
|
||||
"@elastic/elasticsearch": "^8.4.0",
|
||||
"@getmetal/metal-sdk": "*",
|
||||
"@getzep/zep-cloud": "^1.0.6",
|
||||
"@getzep/zep-js": "^0.9.0",
|
||||
"@gomomento/sdk": "^1.51.1",
|
||||
"@gomomento/sdk-core": "^1.51.1",
|
||||
"@google-ai/generativelanguage": "*",
|
||||
"@google-cloud/storage": "^6.10.1 || ^7.7.0",
|
||||
"@gradientai/nodejs-sdk": "^1.2.0",
|
||||
"@huggingface/inference": "^2.6.4",
|
||||
"@huggingface/transformers": "^3.2.3",
|
||||
"@ibm-cloud/watsonx-ai": "*",
|
||||
"@lancedb/lancedb": "^0.12.0",
|
||||
"@langchain/core": ">=0.2.21 <0.4.0",
|
||||
"@layerup/layerup-security": "^1.5.12",
|
||||
"@libsql/client": "^0.14.0",
|
||||
"@mendable/firecrawl-js": "^1.4.3",
|
||||
"@mlc-ai/web-llm": "*",
|
||||
"@mozilla/readability": "*",
|
||||
"@neondatabase/serverless": "*",
|
||||
"@notionhq/client": "^2.2.10",
|
||||
"@opensearch-project/opensearch": "*",
|
||||
"@pinecone-database/pinecone": "*",
|
||||
"@planetscale/database": "^1.8.0",
|
||||
"@premai/prem-sdk": "^0.3.25",
|
||||
"@qdrant/js-client-rest": "^1.8.2",
|
||||
"@raycast/api": "^1.55.2",
|
||||
"@rockset/client": "^0.9.1",
|
||||
"@smithy/eventstream-codec": "^2.0.5",
|
||||
"@smithy/protocol-http": "^3.0.6",
|
||||
"@smithy/signature-v4": "^2.0.10",
|
||||
"@smithy/util-utf8": "^2.0.0",
|
||||
"@spider-cloud/spider-client": "^0.0.21",
|
||||
"@supabase/supabase-js": "^2.45.0",
|
||||
"@tensorflow-models/universal-sentence-encoder": "*",
|
||||
"@tensorflow/tfjs-converter": "*",
|
||||
"@tensorflow/tfjs-core": "*",
|
||||
"@upstash/ratelimit": "^1.1.3 || ^2.0.3",
|
||||
"@upstash/redis": "^1.20.6",
|
||||
"@upstash/vector": "^1.1.1",
|
||||
"@vercel/kv": "*",
|
||||
"@vercel/postgres": "*",
|
||||
"@writerai/writer-sdk": "^0.40.2",
|
||||
"@xata.io/client": "^0.28.0",
|
||||
"@zilliz/milvus2-sdk-node": ">=2.3.5",
|
||||
"apify-client": "^2.7.1",
|
||||
"assemblyai": "^4.6.0",
|
||||
"azion": "^1.11.1",
|
||||
"better-sqlite3": ">=9.4.0 <12.0.0",
|
||||
"cassandra-driver": "^4.7.2",
|
||||
"cborg": "^4.1.1",
|
||||
"cheerio": "^1.0.0-rc.12",
|
||||
"chromadb": "*",
|
||||
"closevector-common": "0.1.3",
|
||||
"closevector-node": "0.1.6",
|
||||
"closevector-web": "0.1.6",
|
||||
"cohere-ai": "*",
|
||||
"convex": "^1.3.1",
|
||||
"crypto-js": "^4.2.0",
|
||||
"d3-dsv": "^2.0.0",
|
||||
"discord.js": "^14.14.1",
|
||||
"dria": "^0.0.3",
|
||||
"duck-duck-scrape": "^2.2.5",
|
||||
"epub2": "^3.0.1",
|
||||
"fast-xml-parser": "*",
|
||||
"firebase-admin": "^11.9.0 || ^12.0.0",
|
||||
"google-auth-library": "*",
|
||||
"googleapis": "*",
|
||||
"hnswlib-node": "^3.0.0",
|
||||
"html-to-text": "^9.0.5",
|
||||
"ibm-cloud-sdk-core": "*",
|
||||
"ignore": "^5.2.0",
|
||||
"interface-datastore": "^8.2.11",
|
||||
"ioredis": "^5.3.2",
|
||||
"it-all": "^3.0.4",
|
||||
"jsdom": "*",
|
||||
"jsonwebtoken": "^9.0.2",
|
||||
"llmonitor": "^0.5.9",
|
||||
"lodash": "^4.17.21",
|
||||
"lunary": "^0.7.10",
|
||||
"mammoth": "^1.6.0",
|
||||
"mariadb": "^3.4.0",
|
||||
"mem0ai": "^2.1.8",
|
||||
"mongodb": ">=5.2.0",
|
||||
"mysql2": "^3.9.8",
|
||||
"neo4j-driver": "*",
|
||||
"notion-to-md": "^3.1.0",
|
||||
"officeparser": "^4.0.4",
|
||||
"openai": "*",
|
||||
"pdf-parse": "1.1.1",
|
||||
"pg": "^8.11.0",
|
||||
"pg-copy-streams": "^6.0.5",
|
||||
"pickleparser": "^0.2.1",
|
||||
"playwright": "^1.32.1",
|
||||
"portkey-ai": "^0.1.11",
|
||||
"puppeteer": "*",
|
||||
"pyodide": ">=0.24.1 <0.27.0",
|
||||
"redis": "*",
|
||||
"replicate": "*",
|
||||
"sonix-speech-recognition": "^2.1.1",
|
||||
"srt-parser-2": "^1.2.3",
|
||||
"typeorm": "^0.3.20",
|
||||
"typesense": "^1.5.3",
|
||||
"usearch": "^1.1.1",
|
||||
"voy-search": "0.6.2",
|
||||
"weaviate-ts-client": "*",
|
||||
"web-auth-library": "^1.0.3",
|
||||
"word-extractor": "*",
|
||||
"ws": "^8.14.2",
|
||||
"youtubei.js": "*"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@arcjet/redact": {
|
||||
"optional": true
|
||||
},
|
||||
"@aws-crypto/sha256-js": {
|
||||
"optional": true
|
||||
},
|
||||
"@aws-sdk/client-bedrock-agent-runtime": {
|
||||
"optional": true
|
||||
},
|
||||
"@aws-sdk/client-bedrock-runtime": {
|
||||
"optional": true
|
||||
},
|
||||
"@aws-sdk/client-dynamodb": {
|
||||
"optional": true
|
||||
},
|
||||
"@aws-sdk/client-kendra": {
|
||||
"optional": true
|
||||
},
|
||||
"@aws-sdk/client-lambda": {
|
||||
"optional": true
|
||||
},
|
||||
"@aws-sdk/client-s3": {
|
||||
"optional": true
|
||||
},
|
||||
"@aws-sdk/client-sagemaker-runtime": {
|
||||
"optional": true
|
||||
},
|
||||
"@aws-sdk/client-sfn": {
|
||||
"optional": true
|
||||
},
|
||||
"@aws-sdk/credential-provider-node": {
|
||||
"optional": true
|
||||
},
|
||||
"@aws-sdk/dsql-signer": {
|
||||
"optional": true
|
||||
},
|
||||
"@azure/search-documents": {
|
||||
"optional": true
|
||||
},
|
||||
"@azure/storage-blob": {
|
||||
"optional": true
|
||||
},
|
||||
"@browserbasehq/sdk": {
|
||||
"optional": true
|
||||
},
|
||||
"@clickhouse/client": {
|
||||
"optional": true
|
||||
},
|
||||
"@cloudflare/ai": {
|
||||
"optional": true
|
||||
},
|
||||
"@datastax/astra-db-ts": {
|
||||
"optional": true
|
||||
},
|
||||
"@elastic/elasticsearch": {
|
||||
"optional": true
|
||||
},
|
||||
"@getmetal/metal-sdk": {
|
||||
"optional": true
|
||||
},
|
||||
"@getzep/zep-cloud": {
|
||||
"optional": true
|
||||
},
|
||||
"@getzep/zep-js": {
|
||||
"optional": true
|
||||
},
|
||||
"@gomomento/sdk": {
|
||||
"optional": true
|
||||
},
|
||||
"@gomomento/sdk-core": {
|
||||
"optional": true
|
||||
},
|
||||
"@google-ai/generativelanguage": {
|
||||
"optional": true
|
||||
},
|
||||
"@google-cloud/storage": {
|
||||
"optional": true
|
||||
},
|
||||
"@gradientai/nodejs-sdk": {
|
||||
"optional": true
|
||||
},
|
||||
"@huggingface/inference": {
|
||||
"optional": true
|
||||
},
|
||||
"@huggingface/transformers": {
|
||||
"optional": true
|
||||
},
|
||||
"@lancedb/lancedb": {
|
||||
"optional": true
|
||||
},
|
||||
"@layerup/layerup-security": {
|
||||
"optional": true
|
||||
},
|
||||
"@libsql/client": {
|
||||
"optional": true
|
||||
},
|
||||
"@mendable/firecrawl-js": {
|
||||
"optional": true
|
||||
},
|
||||
"@mlc-ai/web-llm": {
|
||||
"optional": true
|
||||
},
|
||||
"@mozilla/readability": {
|
||||
"optional": true
|
||||
},
|
||||
"@neondatabase/serverless": {
|
||||
"optional": true
|
||||
},
|
||||
"@notionhq/client": {
|
||||
"optional": true
|
||||
},
|
||||
"@opensearch-project/opensearch": {
|
||||
"optional": true
|
||||
},
|
||||
"@pinecone-database/pinecone": {
|
||||
"optional": true
|
||||
},
|
||||
"@planetscale/database": {
|
||||
"optional": true
|
||||
},
|
||||
"@premai/prem-sdk": {
|
||||
"optional": true
|
||||
},
|
||||
"@qdrant/js-client-rest": {
|
||||
"optional": true
|
||||
},
|
||||
"@raycast/api": {
|
||||
"optional": true
|
||||
},
|
||||
"@rockset/client": {
|
||||
"optional": true
|
||||
},
|
||||
"@smithy/eventstream-codec": {
|
||||
"optional": true
|
||||
},
|
||||
"@smithy/protocol-http": {
|
||||
"optional": true
|
||||
},
|
||||
"@smithy/signature-v4": {
|
||||
"optional": true
|
||||
},
|
||||
"@smithy/util-utf8": {
|
||||
"optional": true
|
||||
},
|
||||
"@spider-cloud/spider-client": {
|
||||
"optional": true
|
||||
},
|
||||
"@supabase/supabase-js": {
|
||||
"optional": true
|
||||
},
|
||||
"@tensorflow-models/universal-sentence-encoder": {
|
||||
"optional": true
|
||||
},
|
||||
"@tensorflow/tfjs-converter": {
|
||||
"optional": true
|
||||
},
|
||||
"@tensorflow/tfjs-core": {
|
||||
"optional": true
|
||||
},
|
||||
"@upstash/ratelimit": {
|
||||
"optional": true
|
||||
},
|
||||
"@upstash/redis": {
|
||||
"optional": true
|
||||
},
|
||||
"@upstash/vector": {
|
||||
"optional": true
|
||||
},
|
||||
"@vercel/kv": {
|
||||
"optional": true
|
||||
},
|
||||
"@vercel/postgres": {
|
||||
"optional": true
|
||||
},
|
||||
"@writerai/writer-sdk": {
|
||||
"optional": true
|
||||
},
|
||||
"@xata.io/client": {
|
||||
"optional": true
|
||||
},
|
||||
"@zilliz/milvus2-sdk-node": {
|
||||
"optional": true
|
||||
},
|
||||
"apify-client": {
|
||||
"optional": true
|
||||
},
|
||||
"assemblyai": {
|
||||
"optional": true
|
||||
},
|
||||
"azion": {
|
||||
"optional": true
|
||||
},
|
||||
"better-sqlite3": {
|
||||
"optional": true
|
||||
},
|
||||
"cassandra-driver": {
|
||||
"optional": true
|
||||
},
|
||||
"cborg": {
|
||||
"optional": true
|
||||
},
|
||||
"cheerio": {
|
||||
"optional": true
|
||||
},
|
||||
"chromadb": {
|
||||
"optional": true
|
||||
},
|
||||
"closevector-common": {
|
||||
"optional": true
|
||||
},
|
||||
"closevector-node": {
|
||||
"optional": true
|
||||
},
|
||||
"closevector-web": {
|
||||
"optional": true
|
||||
},
|
||||
"cohere-ai": {
|
||||
"optional": true
|
||||
},
|
||||
"convex": {
|
||||
"optional": true
|
||||
},
|
||||
"crypto-js": {
|
||||
"optional": true
|
||||
},
|
||||
"d3-dsv": {
|
||||
"optional": true
|
||||
},
|
||||
"discord.js": {
|
||||
"optional": true
|
||||
},
|
||||
"dria": {
|
||||
"optional": true
|
||||
},
|
||||
"duck-duck-scrape": {
|
||||
"optional": true
|
||||
},
|
||||
"epub2": {
|
||||
"optional": true
|
||||
},
|
||||
"fast-xml-parser": {
|
||||
"optional": true
|
||||
},
|
||||
"firebase-admin": {
|
||||
"optional": true
|
||||
},
|
||||
"google-auth-library": {
|
||||
"optional": true
|
||||
},
|
||||
"googleapis": {
|
||||
"optional": true
|
||||
},
|
||||
"hnswlib-node": {
|
||||
"optional": true
|
||||
},
|
||||
"html-to-text": {
|
||||
"optional": true
|
||||
},
|
||||
"ignore": {
|
||||
"optional": true
|
||||
},
|
||||
"interface-datastore": {
|
||||
"optional": true
|
||||
},
|
||||
"ioredis": {
|
||||
"optional": true
|
||||
},
|
||||
"it-all": {
|
||||
"optional": true
|
||||
},
|
||||
"jsdom": {
|
||||
"optional": true
|
||||
},
|
||||
"jsonwebtoken": {
|
||||
"optional": true
|
||||
},
|
||||
"llmonitor": {
|
||||
"optional": true
|
||||
},
|
||||
"lodash": {
|
||||
"optional": true
|
||||
},
|
||||
"lunary": {
|
||||
"optional": true
|
||||
},
|
||||
"mammoth": {
|
||||
"optional": true
|
||||
},
|
||||
"mariadb": {
|
||||
"optional": true
|
||||
},
|
||||
"mem0ai": {
|
||||
"optional": true
|
||||
},
|
||||
"mongodb": {
|
||||
"optional": true
|
||||
},
|
||||
"mysql2": {
|
||||
"optional": true
|
||||
},
|
||||
"neo4j-driver": {
|
||||
"optional": true
|
||||
},
|
||||
"notion-to-md": {
|
||||
"optional": true
|
||||
},
|
||||
"officeparser": {
|
||||
"optional": true
|
||||
},
|
||||
"pdf-parse": {
|
||||
"optional": true
|
||||
},
|
||||
"pg": {
|
||||
"optional": true
|
||||
},
|
||||
"pg-copy-streams": {
|
||||
"optional": true
|
||||
},
|
||||
"pickleparser": {
|
||||
"optional": true
|
||||
},
|
||||
"playwright": {
|
||||
"optional": true
|
||||
},
|
||||
"portkey-ai": {
|
||||
"optional": true
|
||||
},
|
||||
"puppeteer": {
|
||||
"optional": true
|
||||
},
|
||||
"pyodide": {
|
||||
"optional": true
|
||||
},
|
||||
"redis": {
|
||||
"optional": true
|
||||
},
|
||||
"replicate": {
|
||||
"optional": true
|
||||
},
|
||||
"sonix-speech-recognition": {
|
||||
"optional": true
|
||||
},
|
||||
"srt-parser-2": {
|
||||
"optional": true
|
||||
},
|
||||
"typeorm": {
|
||||
"optional": true
|
||||
},
|
||||
"typesense": {
|
||||
"optional": true
|
||||
},
|
||||
"usearch": {
|
||||
"optional": true
|
||||
},
|
||||
"voy-search": {
|
||||
"optional": true
|
||||
},
|
||||
"weaviate-ts-client": {
|
||||
"optional": true
|
||||
},
|
||||
"web-auth-library": {
|
||||
"optional": true
|
||||
},
|
||||
"word-extractor": {
|
||||
"optional": true
|
||||
},
|
||||
"ws": {
|
||||
"optional": true
|
||||
},
|
||||
"youtubei.js": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@librechat/agents/node_modules/@langchain/openai": {
|
||||
"version": "0.5.5",
|
||||
"resolved": "https://registry.npmjs.org/@langchain/openai/-/openai-0.5.5.tgz",
|
||||
"integrity": "sha512-QwdZrWcx6FB+UMKQ6+a0M9ZXzeUnZCwXP7ltqCCycPzdfiwxg3TQ6WkSefdEyiPpJcVVq/9HZSxrzGmf18QGyw==",
|
||||
"dependencies": {
|
||||
"js-tiktoken": "^1.0.12",
|
||||
"openai": "^4.87.3",
|
||||
"zod": "^3.22.4",
|
||||
"zod-to-json-schema": "^3.22.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@langchain/core": ">=0.3.39 <0.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@librechat/agents/node_modules/agent-base": {
|
||||
"version": "7.1.3",
|
||||
"resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.3.tgz",
|
||||
"integrity": "sha512-jRR5wdylq8CkOe6hei19GGZnxM6rBGwFl3Bg0YItGDimvjGtAvdZk4Pu6Cl4u4Igsws4a1fd1Vq3ezrhn4KmFw==",
|
||||
"engines": {
|
||||
"node": ">= 14"
|
||||
}
|
||||
},
|
||||
"node_modules/@librechat/agents/node_modules/https-proxy-agent": {
|
||||
"version": "7.0.6",
|
||||
"resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz",
|
||||
"integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==",
|
||||
"dependencies": {
|
||||
"agent-base": "^7.1.2",
|
||||
"debug": "4"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 14"
|
||||
}
|
||||
},
|
||||
"node_modules/@librechat/agents/node_modules/uuid": {
|
||||
"version": "10.0.0",
|
||||
"resolved": "https://registry.npmjs.org/uuid/-/uuid-10.0.0.tgz",
|
||||
"integrity": "sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ==",
|
||||
"funding": [
|
||||
"https://github.com/sponsors/broofa",
|
||||
"https://github.com/sponsors/ctavan"
|
||||
],
|
||||
"bin": {
|
||||
"uuid": "dist/bin/uuid"
|
||||
}
|
||||
},
|
||||
"node_modules/@librechat/backend": {
|
||||
"resolved": "api",
|
||||
"link": true
|
||||
|
|
@ -18698,6 +18108,15 @@
|
|||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@microsoft/eslint-formatter-sarif/node_modules/keyv": {
|
||||
"version": "4.5.4",
|
||||
"resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz",
|
||||
"integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"json-buffer": "3.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@mistralai/mistralai": {
|
||||
"version": "1.5.2",
|
||||
"resolved": "https://registry.npmjs.org/@mistralai/mistralai/-/mistralai-1.5.2.tgz",
|
||||
|
|
@ -28807,6 +28226,15 @@
|
|||
"node": ">=16"
|
||||
}
|
||||
},
|
||||
"node_modules/flat-cache/node_modules/keyv": {
|
||||
"version": "4.5.4",
|
||||
"resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz",
|
||||
"integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"json-buffer": "3.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/flatted": {
|
||||
"version": "3.3.2",
|
||||
"resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.2.tgz",
|
||||
|
|
@ -32035,7 +31463,8 @@
|
|||
"node_modules/json-buffer": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz",
|
||||
"integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ=="
|
||||
"integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/json-parse-even-better-errors": {
|
||||
"version": "2.3.1",
|
||||
|
|
@ -32195,11 +31624,11 @@
|
|||
}
|
||||
},
|
||||
"node_modules/keyv": {
|
||||
"version": "4.5.4",
|
||||
"resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz",
|
||||
"integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==",
|
||||
"version": "5.3.2",
|
||||
"resolved": "https://registry.npmjs.org/keyv/-/keyv-5.3.2.tgz",
|
||||
"integrity": "sha512-Lji2XRxqqa5Wg+CHLVfFKBImfJZ4pCSccu9eVWK6w4c2SDFLd8JAn1zqTuSFnsxb7ope6rMsnIHfp+eBbRBRZQ==",
|
||||
"dependencies": {
|
||||
"json-buffer": "3.0.1"
|
||||
"@keyv/serialize": "^1.0.3"
|
||||
}
|
||||
},
|
||||
"node_modules/kleur": {
|
||||
|
|
@ -37234,6 +36663,15 @@
|
|||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/prettier-eslint/node_modules/keyv": {
|
||||
"version": "4.5.4",
|
||||
"resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz",
|
||||
"integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"json-buffer": "3.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/prettier-eslint/node_modules/ts-api-utils": {
|
||||
"version": "1.4.3",
|
||||
"resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.4.3.tgz",
|
||||
|
|
@ -43684,7 +43122,7 @@
|
|||
"typescript": "^5.0.4"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"keyv": "^4.5.4"
|
||||
"keyv": "^5.3.2"
|
||||
}
|
||||
},
|
||||
"packages/data-schemas/node_modules/@types/whatwg-url": {
|
||||
|
|
@ -43918,7 +43356,7 @@
|
|||
"typescript": "^5.0.4"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"keyv": "^4.5.4"
|
||||
"keyv": "^5.3.2"
|
||||
}
|
||||
},
|
||||
"packages/mcp/node_modules/@modelcontextprotocol/sdk": {
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@
|
|||
"mongoose": "^8.12.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"keyv": "^4.5.4"
|
||||
"keyv": "^5.3.2"
|
||||
},
|
||||
"publishConfig": {
|
||||
"registry": "https://registry.npmjs.org/",
|
||||
|
|
|
|||
|
|
@ -73,6 +73,6 @@
|
|||
"express": "^4.21.2"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"keyv": "^4.5.4"
|
||||
"keyv": "^5.3.2"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { FlowStateManager } from './manager';
|
||||
import Keyv from 'keyv';
|
||||
import { Keyv } from 'keyv';
|
||||
import type { FlowState } from './types';
|
||||
|
||||
// Create a mock class without extending Keyv
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import Keyv from 'keyv';
|
||||
import { Keyv } from 'keyv';
|
||||
import type { StoredDataNoRaw } from 'keyv';
|
||||
import type { Logger } from 'winston';
|
||||
import type { FlowState, FlowMetadata, FlowManagerOptions } from './types';
|
||||
|
||||
|
|
@ -202,7 +203,7 @@ export class FlowStateManager<T = unknown> {
|
|||
/**
|
||||
* Gets current flow state
|
||||
*/
|
||||
async getFlowState(flowId: string, type: string): Promise<FlowState<T> | null> {
|
||||
async getFlowState(flowId: string, type: string): Promise<StoredDataNoRaw<FlowState<T>> | null> {
|
||||
const flowKey = this.getFlowKey(flowId, type);
|
||||
return this.keyv.get(flowKey);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue