Merge branch 'main' into feat/multi-lang-Terms-of-service

This commit is contained in:
Ruben Talstra 2025-03-24 17:53:36 +01:00 committed by GitHub
commit 4e82eab01c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
81 changed files with 3178 additions and 1692 deletions

View file

@ -1,6 +1,6 @@
{
"name": "librechat-data-provider",
"version": "0.7.73",
"version": "0.7.74",
"description": "data services for librechat apps",
"main": "dist/index.js",
"module": "dist/index.es.js",

View file

@ -500,11 +500,13 @@ export const intefaceSchema = z
});
export type TInterfaceConfig = z.infer<typeof intefaceSchema>;
export type TBalanceConfig = z.infer<typeof balanceSchema>;
export type TStartupConfig = {
appTitle: string;
socialLogins?: string[];
interface?: TInterfaceConfig;
balance?: TBalanceConfig;
discordLoginEnabled: boolean;
facebookLoginEnabled: boolean;
githubLoginEnabled: boolean;
@ -527,7 +529,6 @@ export type TStartupConfig = {
socialLoginEnabled: boolean;
passwordResetEnabled: boolean;
emailEnabled: boolean;
checkBalance: boolean;
showBirthdayIcon: boolean;
helpAndFaqURL: string;
customFooter?: string;
@ -551,6 +552,18 @@ export const ocrSchema = z.object({
strategy: z.nativeEnum(OCRStrategy).default(OCRStrategy.MISTRAL_OCR),
});
export const balanceSchema = z.object({
enabled: z.boolean().optional().default(false),
startBalance: z.number().optional().default(20000),
autoRefillEnabled: z.boolean().optional().default(false),
refillIntervalValue: z.number().optional().default(30),
refillIntervalUnit: z
.enum(['seconds', 'minutes', 'hours', 'days', 'weeks', 'months'])
.optional()
.default('days'),
refillAmount: z.number().optional().default(10000),
});
export const configSchema = z.object({
version: z.string(),
cache: z.boolean().default(true),
@ -573,6 +586,7 @@ export const configSchema = z.object({
allowedDomains: z.array(z.string()).optional(),
})
.default({ socialLogins: defaultSocialLogins }),
balance: balanceSchema.optional(),
speech: z
.object({
tts: ttsSchema.optional(),

View file

@ -150,11 +150,12 @@ export type File = {
/* Agent types */
export type AgentParameterValue = number | null;
export type AgentParameterValue = number | string | null;
export type AgentModelParameters = {
model?: string;
temperature: AgentParameterValue;
maxContextTokens: AgentParameterValue;
max_context_tokens: AgentParameterValue;
max_output_tokens: AgentParameterValue;
top_p: AgentParameterValue;

View file

@ -1,8 +1,8 @@
{
"name": "@librechat/data-schemas",
"version": "0.0.3",
"type": "module",
"version": "0.0.5",
"description": "Mongoose schemas and models for LibreChat",
"type": "module",
"main": "dist/index.cjs",
"module": "dist/index.es.js",
"types": "./dist/types/index.d.ts",
@ -13,6 +13,9 @@
"types": "./dist/types/index.d.ts"
}
},
"files": [
"dist"
],
"scripts": {
"clean": "rimraf dist",
"build": "npm run clean && rollup -c --silent --bundleConfigAsCjs",
@ -55,14 +58,20 @@
"ts-node": "^10.9.2",
"typescript": "^5.0.4"
},
"publishConfig": {
"registry": "https://registry.npmjs.org/",
"access": "public"
},
"dependencies": {
"mongoose": "^8.12.1"
},
"peerDependencies": {
"keyv": "^4.5.4"
}
},
"publishConfig": {
"registry": "https://registry.npmjs.org/",
"access": "public"
},
"keywords": [
"mongoose",
"schema",
"typescript",
"librechat"
]
}

View file

@ -1,25 +1,40 @@
import json from '@rollup/plugin-json';
import typescript from '@rollup/plugin-typescript';
import commonjs from '@rollup/plugin-commonjs';
import nodeResolve from '@rollup/plugin-node-resolve';
import peerDepsExternal from 'rollup-plugin-peer-deps-external';
export default {
input: 'src/index.ts',
output: [
{
file: 'dist/index.cjs', // Changed from index.js to index.cjs
format: 'cjs',
file: 'dist/index.es.js',
format: 'es',
sourcemap: true,
exports: 'named',
},
{
file: 'dist/index.es.js',
format: 'esm',
file: 'dist/index.cjs',
format: 'cjs',
sourcemap: true,
exports: 'named',
},
],
plugins: [json(), commonjs(), typescript({ tsconfig: './tsconfig.json' })],
external: [
// list your external dependencies
plugins: [
// Allow importing JSON files
json(),
// Automatically externalize peer dependencies
peerDepsExternal(),
// Resolve modules from node_modules
nodeResolve(),
// Convert CommonJS modules to ES6
commonjs(),
// Compile TypeScript files and generate type declarations
typescript({
tsconfig: './tsconfig.json',
declaration: true,
declarationDir: 'dist/types',
rootDir: 'src',
}),
],
// Do not bundle these external dependencies
external: ['mongoose'],
};

View file

@ -1,49 +1,68 @@
import actionSchema from './schema/action';
import agentSchema from './schema/agent';
import assistantSchema from './schema/assistant';
import balanceSchema from './schema/balance';
import bannerSchema from './schema/banner';
import categoriesSchema from './schema/categories';
import conversationTagSchema from './schema/conversationTag';
import convoSchema from './schema/convo';
import fileSchema from './schema/file';
import keySchema from './schema/key';
import messageSchema from './schema/message';
import pluginAuthSchema from './schema/pluginAuth';
import presetSchema from './schema/preset';
import projectSchema from './schema/project';
import promptSchema from './schema/prompt';
import promptGroupSchema from './schema/promptGroup';
import roleSchema from './schema/role';
import sessionSchema from './schema/session';
import shareSchema from './schema/share';
import tokenSchema from './schema/token';
import toolCallSchema from './schema/toolCall';
import transactionSchema from './schema/transaction';
import userSchema from './schema/user';
export { default as actionSchema } from './schema/action';
export type { IAction } from './schema/action';
export {
actionSchema,
agentSchema,
assistantSchema,
balanceSchema,
bannerSchema,
categoriesSchema,
conversationTagSchema,
convoSchema,
fileSchema,
keySchema,
messageSchema,
pluginAuthSchema,
presetSchema,
projectSchema,
promptSchema,
promptGroupSchema,
roleSchema,
sessionSchema,
shareSchema,
tokenSchema,
toolCallSchema,
transactionSchema,
userSchema,
};
export { default as agentSchema } from './schema/agent';
export type { IAgent } from './schema/agent';
export { default as assistantSchema } from './schema/assistant';
export type { IAssistant } from './schema/assistant';
export { default as balanceSchema } from './schema/balance';
export type { IBalance } from './schema/balance';
export { default as bannerSchema } from './schema/banner';
export type { IBanner } from './schema/banner';
export { default as categoriesSchema } from './schema/categories';
export type { ICategory } from './schema/categories';
export { default as conversationTagSchema } from './schema/conversationTag';
export type { IConversationTag } from './schema/conversationTag';
export { default as convoSchema } from './schema/convo';
export type { IConversation } from './schema/convo';
export { default as fileSchema } from './schema/file';
export type { IMongoFile } from './schema/file';
export { default as keySchema } from './schema/key';
export type { IKey } from './schema/key';
export { default as messageSchema } from './schema/message';
export type { IMessage } from './schema/message';
export { default as pluginAuthSchema } from './schema/pluginAuth';
export type { IPluginAuth } from './schema/pluginAuth';
export { default as presetSchema } from './schema/preset';
export type { IPreset } from './schema/preset';
export { default as projectSchema } from './schema/project';
export type { IMongoProject } from './schema/project';
export { default as promptSchema } from './schema/prompt';
export type { IPrompt } from './schema/prompt';
export { default as promptGroupSchema } from './schema/promptGroup';
export type { IPromptGroup, IPromptGroupDocument } from './schema/promptGroup';
export { default as roleSchema } from './schema/role';
export type { IRole } from './schema/role';
export { default as sessionSchema } from './schema/session';
export type { ISession } from './schema/session';
export { default as shareSchema } from './schema/share';
export type { ISharedLink } from './schema/share';
export { default as tokenSchema } from './schema/token';
export type { IToken } from './schema/token';
export { default as toolCallSchema } from './schema/toolCall';
export type { IToolCallData } from './schema/toolCall';
export { default as transactionSchema } from './schema/transaction';
export type { ITransaction } from './schema/transaction';
export { default as userSchema } from './schema/user';
export type { IUser } from './schema/user';

View file

@ -3,6 +3,12 @@ import { Schema, Document, Types } from 'mongoose';
export interface IBalance extends Document {
user: Types.ObjectId;
tokenCredits: number;
// Automatic refill settings
autoRefillEnabled: boolean;
refillIntervalValue: number;
refillIntervalUnit: 'seconds' | 'minutes' | 'hours' | 'days' | 'weeks' | 'months';
lastRefill: Date;
refillAmount: number;
}
const balanceSchema = new Schema<IBalance>({
@ -17,6 +23,29 @@ const balanceSchema = new Schema<IBalance>({
type: Number,
default: 0,
},
// Automatic refill settings
autoRefillEnabled: {
type: Boolean,
default: false,
},
refillIntervalValue: {
type: Number,
default: 30,
},
refillIntervalUnit: {
type: String,
enum: ['seconds', 'minutes', 'hours', 'days', 'weeks', 'months'],
default: 'days',
},
lastRefill: {
type: Date,
default: Date.now,
},
// amount to add on each refill
refillAmount: {
type: Number,
default: 0,
},
});
export default balanceSchema;

View file

@ -1,28 +1,19 @@
{
"compilerOptions": {
"declaration": true,
"declarationDir": "./dist/types",
"module": "esnext",
"noImplicitAny": true,
"outDir": "./dist",
"target": "es2015",
"target": "ES2019",
"module": "ESNext",
"moduleResolution": "node",
"lib": ["es2017", "dom", "ES2021.String"],
"skipLibCheck": true,
"esModuleInterop": true,
"declaration": true,
"declarationDir": "dist/types",
"outDir": "dist",
"strict": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": false,
"sourceMap": true,
"baseUrl": "."
"sourceMap": true
},
"ts-node": {
"experimentalSpecifierResolution": "node",
"transpileOnly": true,
"esm": true
},
"exclude": ["node_modules", "dist", "types"],
"include": ["src/**/*", "types/index.d.ts", "types/react-query/index.d.ts"]
"include": ["src/**/*"],
"exclude": ["node_modules", "dist", "tests"]
}

View file

@ -68,7 +68,7 @@
"registry": "https://registry.npmjs.org/"
},
"dependencies": {
"@modelcontextprotocol/sdk": "^1.6.1",
"@modelcontextprotocol/sdk": "^1.7.0",
"diff": "^7.0.0",
"eventsource": "^3.0.2",
"express": "^4.21.2"

View file

@ -134,7 +134,12 @@ export class MCPConnection extends EventEmitter {
}
const url = new URL(options.url);
this.logger?.info(`[MCP][${this.serverName}] Creating SSE transport: ${url.toString()}`);
const transport = new SSEClientTransport(url);
const abortController = new AbortController();
const transport = new SSEClientTransport(url, {
requestInit: {
signal: abortController.signal,
},
});
transport.onclose = () => {
this.logger?.info(`[MCP][${this.serverName}] SSE transport closed`);
@ -175,6 +180,17 @@ export class MCPConnection extends EventEmitter {
this.isInitializing = false;
this.shouldStopReconnecting = false;
this.reconnectAttempts = 0;
/**
* // FOR DEBUGGING
* // this.client.setRequestHandler(PingRequestSchema, async (request, extra) => {
* // this.logger?.info(`[MCP][${this.serverName}] PingRequest: ${JSON.stringify(request)}`);
* // if (getEventListeners && extra.signal) {
* // const listenerCount = getEventListeners(extra.signal, 'abort').length;
* // this.logger?.debug(`Signal has ${listenerCount} abort listeners`);
* // }
* // return {};
* // });
*/
} else if (state === 'error' && !this.isReconnecting && !this.isInitializing) {
this.handleReconnection().catch((error) => {
this.logger?.error(`[MCP][${this.serverName}] Reconnection handler failed:`, error);
@ -269,7 +285,7 @@ export class MCPConnection extends EventEmitter {
this.transport = this.constructTransport(this.options);
this.setupTransportDebugHandlers();
const connectTimeout = this.options.initTimeout ?? 10000;
const connectTimeout = this.options.initTimeout ?? 10000;
await Promise.race([
this.client.connect(this.transport),
new Promise((_resolve, reject) =>
@ -304,6 +320,9 @@ export class MCPConnection extends EventEmitter {
const originalSend = this.transport.send.bind(this.transport);
this.transport.send = async (msg) => {
if ('result' in msg && !('method' in msg) && Object.keys(msg.result ?? {}).length === 0) {
throw new Error('Empty result');
}
this.logger?.debug(`[MCP][${this.serverName}] Transport sending: ${JSON.stringify(msg)}`);
return originalSend(msg);
};

View file

@ -1,4 +1,5 @@
import { CallToolResultSchema } from '@modelcontextprotocol/sdk/types.js';
import type { RequestOptions } from '@modelcontextprotocol/sdk/shared/protocol.js';
import type { JsonSchemaType, MCPOptions } from 'librechat-data-provider';
import type { Logger } from 'winston';
import type * as t from './types/mcp';
@ -192,12 +193,19 @@ export class MCPManager {
}
}
async callTool(
serverName: string,
toolName: string,
provider: t.Provider,
toolArguments?: Record<string, unknown>,
): Promise<t.FormattedToolResponse> {
async callTool({
serverName,
toolName,
provider,
toolArguments,
options,
}: {
serverName: string;
toolName: string;
provider: t.Provider;
toolArguments?: Record<string, unknown>;
options?: RequestOptions;
}): Promise<t.FormattedToolResponse> {
const connection = this.connections.get(serverName);
if (!connection) {
throw new Error(
@ -213,7 +221,10 @@ export class MCPManager {
},
},
CallToolResultSchema,
{ timeout: connection.timeout },
{
timeout: connection.timeout,
...options,
},
);
return formatToolContent(result, provider);
}