🖼️ refactor: Enhance Env Extraction & Agent Image Handling (#6131)

* refactor: use new image output format for agents using DALL-E tools

* refactor: Enhance image fetching with proxy support and adjust logging placement in DALL-E 3 integration

* refactor: Enhance StableDiffusionAPI to support agent-specific return values and display message for generated images

* refactor: Add unit test execution for librechat-mcp in backend review workflow

* refactor: Update environment variable extraction logic, export from serpate module to avoid circular refs, and remove deprecated tests

* refactor: Add unit tests for environment variable extraction and enhance StdioOptionsSchema to process env variables
This commit is contained in:
Danny Avila 2025-03-01 07:51:12 -05:00 committed by GitHub
parent 2293cd667e
commit 7f6b32ff04
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
14 changed files with 321 additions and 99 deletions

View file

@ -6,8 +6,9 @@ import type {
TValidatedAzureConfig,
TAzureConfigValidationResult,
} from '../src/config';
import { errorsToString, extractEnvVariable, envVarRegex } from '../src/parsers';
import { extractEnvVariable, envVarRegex } from '../src/utils';
import { azureGroupConfigsSchema } from '../src/config';
import { errorsToString } from '../src/parsers';
export const deprecatedAzureVariables = [
/* "related to" precedes description text */

View file

@ -31,5 +31,6 @@ export { default as request } from './request';
export { dataService };
import * as dataService from './data-service';
/* general helpers */
export * from './utils';
export * from './actions';
export { default as createPayload } from './createPayload';

View file

@ -1,4 +1,5 @@
import { z } from 'zod';
import { extractEnvVariable } from './utils';
const BaseOptionsSchema = z.object({
iconPath: z.string().optional(),
@ -18,8 +19,22 @@ export const StdioOptionsSchema = BaseOptionsSchema.extend({
* The environment to use when spawning the process.
*
* If not specified, the result of getDefaultEnvironment() will be used.
* Environment variables can be referenced using ${VAR_NAME} syntax.
*/
env: z.record(z.string(), z.string()).optional(),
env: z
.record(z.string(), z.string())
.optional()
.transform((env) => {
if (!env) {
return env;
}
const processedEnv: Record<string, string> = {};
for (const [key, value] of Object.entries(env)) {
processedEnv[key] = extractEnvVariable(value);
}
return processedEnv;
}),
/**
* How to handle stderr of the child process. This matches the semantics of Node's `child_process.spawn`.
*

View file

@ -19,6 +19,7 @@ import {
compactAssistantSchema,
} from './schemas';
import { bedrockInputSchema } from './bedrock';
import { extractEnvVariable } from './utils';
import { alternateName } from './config';
type EndpointSchema =
@ -122,17 +123,6 @@ export function errorsToString(errors: ZodIssue[]) {
.join(' ');
}
export const envVarRegex = /^\${(.+)}$/;
/** Extracts the value of an environment variable from a string. */
export function extractEnvVariable(value: string) {
const envVarMatch = value.match(envVarRegex);
if (envVarMatch) {
return process.env[envVarMatch[1]] || value;
}
return value;
}
/** Resolves header values to env variables if detected */
export function resolveHeaders(headers: Record<string, string> | undefined) {
const resolvedHeaders = { ...(headers ?? {}) };

View file

@ -0,0 +1,44 @@
export const envVarRegex = /^\${(.+)}$/;
/** Extracts the value of an environment variable from a string. */
export function extractEnvVariable(value: string) {
if (!value) {
return value;
}
// Trim the input
const trimmed = value.trim();
// Special case: if it's just a single environment variable
const singleMatch = trimmed.match(envVarRegex);
if (singleMatch) {
const varName = singleMatch[1];
return process.env[varName] || trimmed;
}
// For multiple variables, process them using a regex loop
const regex = /\${([^}]+)}/g;
let result = trimmed;
// First collect all matches and their positions
const matches = [];
let match;
while ((match = regex.exec(trimmed)) !== null) {
matches.push({
fullMatch: match[0],
varName: match[1],
index: match.index,
});
}
// Process matches in reverse order to avoid position shifts
for (let i = matches.length - 1; i >= 0; i--) {
const { fullMatch, varName, index } = matches[i];
const envValue = process.env[varName] || fullMatch;
// Replace at exact position
result = result.substring(0, index) + envValue + result.substring(index + fullMatch.length);
}
return result;
}