mirror of
https://github.com/danny-avila/LibreChat.git
synced 2026-01-06 18:48:50 +01:00
feat: first pass, bedrock chat. note: AgentClient is returning agents as conversation.endpoint
This commit is contained in:
parent
120a6a55fb
commit
60ee12d3e8
20 changed files with 270 additions and 23 deletions
|
|
@ -2,7 +2,7 @@ const { getAgent } = require('~/models/Agent');
|
|||
const { logger } = require('~/config');
|
||||
|
||||
const buildOptions = (req, endpoint, parsedBody) => {
|
||||
const { agent_id, instructions, spec, ...rest } = parsedBody;
|
||||
const { agent_id, instructions, spec, ...model_parameters } = parsedBody;
|
||||
|
||||
const agentPromise = getAgent({
|
||||
id: agent_id,
|
||||
|
|
@ -19,9 +19,7 @@ const buildOptions = (req, endpoint, parsedBody) => {
|
|||
agent_id,
|
||||
instructions,
|
||||
spec,
|
||||
modelOptions: {
|
||||
...rest,
|
||||
},
|
||||
model_parameters,
|
||||
};
|
||||
|
||||
return endpointOption;
|
||||
|
|
|
|||
37
api/server/services/Endpoints/bedrock/build.js
Normal file
37
api/server/services/Endpoints/bedrock/build.js
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
const { removeNullishValues } = require('librechat-data-provider');
|
||||
const generateArtifactsPrompt = require('~/app/clients/prompts/artifacts');
|
||||
|
||||
const buildOptions = (endpoint, parsedBody) => {
|
||||
const {
|
||||
modelLabel: name,
|
||||
promptPrefix,
|
||||
maxContextTokens,
|
||||
resendFiles = true,
|
||||
imageDetail,
|
||||
iconURL,
|
||||
greeting,
|
||||
spec,
|
||||
artifacts,
|
||||
...model_parameters
|
||||
} = parsedBody;
|
||||
const endpointOption = removeNullishValues({
|
||||
endpoint,
|
||||
name,
|
||||
resendFiles,
|
||||
imageDetail,
|
||||
iconURL,
|
||||
greeting,
|
||||
spec,
|
||||
instructions: promptPrefix,
|
||||
maxContextTokens,
|
||||
model_parameters,
|
||||
});
|
||||
|
||||
if (typeof artifacts === 'string') {
|
||||
endpointOption.artifactsPrompt = generateArtifactsPrompt({ endpoint, artifacts });
|
||||
}
|
||||
|
||||
return endpointOption;
|
||||
};
|
||||
|
||||
module.exports = { buildOptions };
|
||||
7
api/server/services/Endpoints/bedrock/index.js
Normal file
7
api/server/services/Endpoints/bedrock/index.js
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
const build = require('./build');
|
||||
const initialize = require('./initialize');
|
||||
|
||||
module.exports = {
|
||||
...build,
|
||||
...initialize,
|
||||
};
|
||||
55
api/server/services/Endpoints/bedrock/initialize.js
Normal file
55
api/server/services/Endpoints/bedrock/initialize.js
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
const { EModelEndpoint, providerEndpointMap } = require('librechat-data-provider');
|
||||
const { getDefaultHandlers } = require('~/server/controllers/agents/callbacks');
|
||||
// const { loadAgentTools } = require('~/server/services/ToolService');
|
||||
const getOptions = require('~/server/services/Endpoints/bedrock/options');
|
||||
const AgentClient = require('~/server/controllers/agents/client');
|
||||
const { getModelMaxTokens } = require('~/utils');
|
||||
|
||||
const initializeClient = async ({ req, res, endpointOption }) => {
|
||||
if (!endpointOption) {
|
||||
throw new Error('Endpoint option not provided');
|
||||
}
|
||||
|
||||
// TODO: use endpointOption to determine options/modelOptions
|
||||
const eventHandlers = getDefaultHandlers({ res });
|
||||
|
||||
// const tools = [createTavilySearchTool()];
|
||||
|
||||
/** @type {Agent} */
|
||||
const agent = {
|
||||
id: EModelEndpoint.bedrock,
|
||||
name: endpointOption.name,
|
||||
instructions: endpointOption.instructions,
|
||||
provider: EModelEndpoint.bedrock,
|
||||
model: endpointOption.model_parameters.model,
|
||||
model_parameters: endpointOption.model_parameters,
|
||||
};
|
||||
|
||||
let modelOptions = { model: agent.model };
|
||||
|
||||
// TODO: pass-in override settings that are specific to current run
|
||||
const options = await getOptions({
|
||||
req,
|
||||
res,
|
||||
endpointOption,
|
||||
});
|
||||
|
||||
modelOptions = Object.assign(modelOptions, options.llmConfig);
|
||||
const maxContextTokens =
|
||||
agent.max_context_tokens ??
|
||||
getModelMaxTokens(modelOptions.model, providerEndpointMap[agent.provider]);
|
||||
|
||||
const client = new AgentClient({
|
||||
req,
|
||||
agent,
|
||||
// tools,
|
||||
// toolMap,
|
||||
modelOptions,
|
||||
eventHandlers,
|
||||
maxContextTokens,
|
||||
configOptions: options.configOptions,
|
||||
});
|
||||
return { client };
|
||||
};
|
||||
|
||||
module.exports = { initializeClient };
|
||||
72
api/server/services/Endpoints/bedrock/options.js
Normal file
72
api/server/services/Endpoints/bedrock/options.js
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
const { HttpsProxyAgent } = require('https-proxy-agent');
|
||||
const { EModelEndpoint, AuthType, removeNullishValues } = require('librechat-data-provider');
|
||||
const { getUserKey, checkUserKeyExpiry } = require('~/server/services/UserService');
|
||||
|
||||
const getOptions = async ({ req, endpointOption }) => {
|
||||
const {
|
||||
BEDROCK_AWS_SECRET_ACCESS_KEY,
|
||||
BEDROCK_AWS_ACCESS_KEY_ID,
|
||||
BEDROCK_REVERSE_PROXY,
|
||||
BEDROCK_AWS_REGION,
|
||||
PROXY,
|
||||
} = process.env;
|
||||
const expiresAt = req.body.key;
|
||||
const isUserProvided = BEDROCK_AWS_SECRET_ACCESS_KEY === AuthType.USER_PROVIDED;
|
||||
|
||||
const credentials = isUserProvided
|
||||
? await getUserKey({ userId: req.user.id, name: EModelEndpoint.bedrock })
|
||||
: {
|
||||
accessKeyId: BEDROCK_AWS_ACCESS_KEY_ID,
|
||||
secretAccessKey: BEDROCK_AWS_SECRET_ACCESS_KEY,
|
||||
};
|
||||
|
||||
if (!credentials) {
|
||||
throw new Error('Bedrock credentials not provided. Please provide them again.');
|
||||
}
|
||||
|
||||
if (expiresAt && isUserProvided) {
|
||||
checkUserKeyExpiry(expiresAt, EModelEndpoint.bedrock);
|
||||
}
|
||||
|
||||
const clientOptions = {};
|
||||
|
||||
/** @type {undefined | TBaseEndpoint} */
|
||||
const bedrockConfig = req.app.locals[EModelEndpoint.bedrock];
|
||||
|
||||
if (bedrockConfig) {
|
||||
clientOptions.streamRate = bedrockConfig.streamRate;
|
||||
}
|
||||
|
||||
/** @type {undefined | TBaseEndpoint} */
|
||||
const allConfig = req.app.locals.all;
|
||||
if (allConfig) {
|
||||
clientOptions.streamRate = allConfig.streamRate;
|
||||
}
|
||||
|
||||
const requestOptions = Object.assign(
|
||||
{
|
||||
credentials,
|
||||
model: endpointOption.model,
|
||||
region: BEDROCK_AWS_REGION,
|
||||
streaming: true,
|
||||
streamUsage: true,
|
||||
},
|
||||
endpointOption.model_parameters,
|
||||
);
|
||||
|
||||
const configOptions = {};
|
||||
if (PROXY) {
|
||||
configOptions.httpAgent = new HttpsProxyAgent(PROXY);
|
||||
}
|
||||
|
||||
if (BEDROCK_REVERSE_PROXY) {
|
||||
configOptions.endpointHost = BEDROCK_REVERSE_PROXY;
|
||||
}
|
||||
|
||||
return {
|
||||
llmConfig: removeNullishValues(requestOptions),
|
||||
configOptions,
|
||||
};
|
||||
};
|
||||
|
||||
module.exports = getOptions;
|
||||
Loading…
Add table
Add a link
Reference in a new issue