From 16106e0969f3a95d6e643591ab2bf9809d1ed42e Mon Sep 17 00:00:00 2001 From: Danny Avila Date: Mon, 2 Sep 2024 16:10:00 -0400 Subject: [PATCH] WIP: agent provider schema parsing --- api/server/controllers/agents/client.js | 42 +++++++++++---- packages/data-provider/src/parsers.ts | 8 +-- packages/data-provider/src/schemas.ts | 70 ++++++++++++++++++++----- 3 files changed, 94 insertions(+), 26 deletions(-) diff --git a/api/server/controllers/agents/client.js b/api/server/controllers/agents/client.js index 4e157d0620..8932ba8fd9 100644 --- a/api/server/controllers/agents/client.js +++ b/api/server/controllers/agents/client.js @@ -8,7 +8,12 @@ // mapModelToAzureConfig, // } = require('librechat-data-provider'); const { Callback } = require('@librechat/agents'); -const { providerEndpointMap, removeNullishValues } = require('librechat-data-provider'); +const { + providerEndpointMap, + removeNullishValues, + EModelEndpoint, + parseCompactConvo, +} = require('librechat-data-provider'); const { extractBaseURL, // constructAzureURL, @@ -27,6 +32,10 @@ const { logger } = require('~/config'); /** @typedef {import('@librechat/agents').MessageContentComplex} MessageContentComplex */ +const providerSchemas = { + [EModelEndpoint.bedrock]: true, +}; + class AgentClient extends BaseClient { constructor(options = {}) { super(options); @@ -119,6 +128,26 @@ class AgentClient extends BaseClient { } getSaveOptions() { + const hasSchema = providerSchemas[this.options.endpoint]; + let runOptions = + this.options.endpoint === EModelEndpoint.agents + ? { + model: undefined, + // TODO: + // would need to be override settings; otherwise, model needs to be undefined + // model: this.override.model, + // instructions: this.override.instructions, + // additional_instructions: this.override.additional_instructions, + } + : {}; + + if (hasSchema) { + runOptions = parseCompactConvo({ + endpoint: this.options.endpoint, + conversation: this.modelOptions, + }); + } + return removeNullishValues( Object.assign( { @@ -129,15 +158,8 @@ class AgentClient extends BaseClient { imageDetail: this.options.imageDetail, spec: this.options.spec, }, - this.modelOptions, - { - model: undefined, - // TODO: - // would need to be override settings; otherwise, model needs to be undefined - // model: this.override.model, - // instructions: this.override.instructions, - // additional_instructions: this.override.additional_instructions, - }, + // TODO: PARSE OPTIONS BY PROVIDER, MAY CONTAIN SENSITIVE DATA + runOptions, ), ); } diff --git a/packages/data-provider/src/parsers.ts b/packages/data-provider/src/parsers.ts index 79b6a48fe1..253835ec3d 100644 --- a/packages/data-provider/src/parsers.ts +++ b/packages/data-provider/src/parsers.ts @@ -12,6 +12,7 @@ import { assistantSchema, gptPluginsSchema, // agentsSchema, + bedrockInputSchema, compactAgentsSchema, compactOpenAISchema, compactGoogleSchema, @@ -32,7 +33,7 @@ type EndpointSchema = | typeof gptPluginsSchema | typeof assistantSchema | typeof compactAgentsSchema - | typeof compactAgentsSchema; + | typeof bedrockInputSchema; const endpointSchemas: Record = { [EModelEndpoint.openAI]: openAISchema, @@ -46,7 +47,7 @@ const endpointSchemas: Record = { [EModelEndpoint.assistants]: assistantSchema, [EModelEndpoint.azureAssistants]: assistantSchema, [EModelEndpoint.agents]: compactAgentsSchema, - [EModelEndpoint.bedrock]: compactAgentsSchema, + [EModelEndpoint.bedrock]: bedrockInputSchema, }; // const schemaCreators: Record EndpointSchema> = { @@ -305,6 +306,7 @@ type CompactEndpointSchema = | typeof bingAISchema | typeof compactAnthropicSchema | typeof compactChatGPTSchema + | typeof bedrockInputSchema | typeof compactPluginsSchema; const compactEndpointSchemas: Record = { @@ -315,7 +317,7 @@ const compactEndpointSchemas: Record = { [EModelEndpoint.azureAssistants]: compactAssistantSchema, [EModelEndpoint.agents]: compactAgentsSchema, [EModelEndpoint.google]: compactGoogleSchema, - [EModelEndpoint.bedrock]: compactAgentsSchema, + [EModelEndpoint.bedrock]: bedrockInputSchema, /* BingAI needs all fields */ [EModelEndpoint.bingAI]: bingAISchema, [EModelEndpoint.anthropic]: compactAnthropicSchema, diff --git a/packages/data-provider/src/schemas.ts b/packages/data-provider/src/schemas.ts index f5ee402b0b..71857d597a 100644 --- a/packages/data-provider/src/schemas.ts +++ b/packages/data-provider/src/schemas.ts @@ -435,6 +435,25 @@ export const coerceNumber = z.union([z.number(), z.string()]).transform((val) => return val; }); +type DocumentTypeValue = + | null + | boolean + | number + | string + | DocumentTypeValue[] + | { [key: string]: DocumentTypeValue }; + +const DocumentType: z.ZodType = z.lazy(() => + z.union([ + z.null(), + z.boolean(), + z.number(), + z.string(), + z.array(z.lazy(() => DocumentType)), + z.record(z.lazy(() => DocumentType)), + ]), +); + export const tConversationSchema = z.object({ conversationId: z.string().nullable(), endpoint: eModelEndpointSchema.nullable(), @@ -477,6 +496,9 @@ export const tConversationSchema = z.object({ assistant_id: z.string().optional(), /* agents */ agent_id: z.string().optional(), + /* AWS Bedrock */ + maxTokens: z.number().optional(), + additionalModelRequestFields: DocumentType.optional(), /* assistant + agents */ instructions: z.string().optional(), additional_instructions: z.string().optional(), @@ -975,19 +997,6 @@ export const agentsSchema = tConversationSchema maxContextTokens: undefined, })); -export const compactAgentsSchema = tConversationSchema - .pick({ - model: true, - agent_id: true, - instructions: true, - promptPrefix: true, - iconURL: true, - greeting: true, - spec: true, - }) - .transform(removeNullishValues) - .catch(() => ({})); - export const compactOpenAISchema = tConversationSchema .pick({ model: true, @@ -1172,3 +1181,38 @@ export const compactPluginsSchema = tConversationSchema return removeNullishValues(newObj); }) .catch(() => ({})); + +export const compactAgentsSchema = tConversationSchema + .pick({ + model: true, + agent_id: true, + instructions: true, + additional_instructions: true, + iconURL: true, + greeting: true, + spec: true, + }) + .transform(removeNullishValues) + .catch(() => ({})); + +export const bedrockInputSchema = tConversationSchema + .pick({ + /* LibreChat parameters */ + instructions: true, + additional_instructions: true, + iconURL: true, + greeting: true, + spec: true, + maxOutputTokens: true, + /* shared parameters */ + additionalModelRequestFields: true, + model: true, + maxTokens: true, + temperature: true, + topP: true, + stop: true, + }) + .transform(removeNullishValues) + .catch(() => ({})); + +export type BedrockConverseInput = z.infer;