🏃‍♂️ refactor: Improve Agent Run Context & Misc. Changes (#6448)

* chore: bump Model Context Protocol SDK dependencies

* fix: correct indentation in MCPConnection class

* refactor: enhance SSE transport with abort controller and add error handling for empty results

* chore: remove outdated Model Context Protocol SDK dependency

* chore: update @modelcontextprotocol/sdk dependency to version 1.7.0

* chore: add debugging comments for PingRequest handling in MCPConnection class

* refactor: update callTool method to accept structured arguments and options

* refactor: simplify maxContextTokens calculation in initializeAgentOptions

* chore: update @babel/runtime dependency to version 7.26.10

* chore: update @librechat/agents dependency to version 2.2.9

* chore: update @librechat/agents dependency to version 2.3.6

* refactor: imports and prevent s3 initialization if strategy not configured

* refactor: mark redis as non-experimental

* refactor: add missing `maxContextTokens` for OpenAI parameters

* refactor: improve log message for Redis initialization

* chore: update @librechat/agents dependency to version 2.3.8

* refactor: extend `streamBuffer` condition to include BEDROCK provider as easily gets throttled by AWS

* refactor: filter out 'think' parts from message content in Anthropic and OpenAI clients
This commit is contained in:
Danny Avila 2025-03-20 22:56:57 -04:00 committed by GitHub
parent e768a07738
commit bc88ac846d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
13 changed files with 446 additions and 382 deletions

View file

@ -68,7 +68,7 @@ async function createRun({
};
// TEMPORARY FOR TESTING
if (agent.provider === Providers.ANTHROPIC) {
if (agent.provider === Providers.ANTHROPIC || agent.provider === Providers.BEDROCK) {
graphConfig.streamBuffer = 2000;
}

View file

@ -201,15 +201,17 @@ const initializeAgentOptions = async ({
const tokensModel =
agent.provider === EModelEndpoint.azureOpenAI ? agent.model : agent.model_parameters.model;
const maxTokens = agent.model_parameters.maxOutputTokens ?? agent.model_parameters.maxTokens ?? 0;
const maxContextTokens =
agent.model_parameters.maxContextTokens ??
agent.max_context_tokens ??
getModelMaxTokens(tokensModel, providerEndpointMap[provider]) ??
4096;
return {
...agent,
tools,
attachments,
toolContextMap,
maxContextTokens:
agent.max_context_tokens ??
((getModelMaxTokens(tokensModel, providerEndpointMap[provider]) ?? 4000) - maxTokens) * 0.9,
maxContextTokens: (maxContextTokens - maxTokens) * 0.9,
};
};

View file

@ -1,15 +1,12 @@
const fs = require('fs');
const path = require('path');
const axios = require('axios');
const fetch = require('node-fetch');
const { getBufferMetadata } = require('~/server/utils');
const { initializeS3 } = require('./initialize');
const { logger } = require('~/config');
const { PutObjectCommand, GetObjectCommand, DeleteObjectCommand } = require('@aws-sdk/client-s3');
const { getSignedUrl } = require('@aws-sdk/s3-request-presigner');
const { initializeS3 } = require('./initialize');
const { logger } = require('~/config');
const bucketName = process.env.AWS_BUCKET_NAME;
const s3 = initializeS3();
const defaultBasePath = 'images';
/**
@ -32,6 +29,7 @@ async function saveBufferToS3({ userId, buffer, fileName, basePath = defaultBase
const params = { Bucket: bucketName, Key: key, Body: buffer };
try {
const s3 = initializeS3();
await s3.send(new PutObjectCommand(params));
return await getS3URL({ userId, fileName, basePath });
} catch (error) {
@ -54,6 +52,7 @@ async function getS3URL({ userId, fileName, basePath = defaultBasePath }) {
const params = { Bucket: bucketName, Key: key };
try {
const s3 = initializeS3();
return await getSignedUrl(s3, new GetObjectCommand(params), { expiresIn: 86400 });
} catch (error) {
logger.error('[getS3URL] Error getting signed URL from S3:', error.message);
@ -97,6 +96,7 @@ async function deleteFileFromS3({ userId, fileName, basePath = defaultBasePath }
const params = { Bucket: bucketName, Key: key };
try {
const s3 = initializeS3();
await s3.send(new DeleteObjectCommand(params));
logger.debug('[deleteFileFromS3] File deleted successfully from S3');
} catch (error) {
@ -144,6 +144,7 @@ async function uploadFileToS3({ req, file, file_id, basePath = defaultBasePath }
async function getS3FileStream(filePath) {
const params = { Bucket: bucketName, Key: filePath };
try {
const s3 = initializeS3();
const data = await s3.send(new GetObjectCommand(params));
return data.Body; // Returns a Node.js ReadableStream.
} catch (error) {

View file

@ -37,11 +37,19 @@ async function createMCPTool({ req, toolKey, provider }) {
}
const [toolName, serverName] = toolKey.split(Constants.mcp_delimiter);
/** @type {(toolInput: Object | string) => Promise<unknown>} */
const _call = async (toolInput) => {
/** @type {(toolArguments: Object | string, config?: GraphRunnableConfig) => Promise<unknown>} */
const _call = async (toolArguments, config) => {
try {
const mcpManager = await getMCPManager();
const result = await mcpManager.callTool(serverName, toolName, provider, toolInput);
const result = await mcpManager.callTool({
serverName,
toolName,
provider,
toolArguments,
options: {
signal: config?.signal,
},
});
if (isAssistantsEndpoint(provider) && Array.isArray(result)) {
return result[0];
}