LibreChat/api/server/controllers/PluginController.js

133 lines
5 KiB
JavaScript
Raw Normal View History

const { CacheKeys } = require('librechat-data-provider');
🏗️ feat: bulkWrite isolation, pre-auth context, strict-mode fixes (#12445) * fix: wrap seedDatabase() in runAsSystem() for strict tenant mode seedDatabase() was called without tenant context at startup, causing every Mongoose operation inside it to throw when TENANT_ISOLATION_STRICT=true. Wrapping in runAsSystem() gives it the SYSTEM_TENANT_ID sentinel so the isolation plugin skips filtering, matching the pattern already used for performStartupChecks and updateInterfacePermissions. * fix: chain tenantContextMiddleware in optionalJwtAuth optionalJwtAuth populated req.user but never established ALS tenant context, unlike requireJwtAuth which chains tenantContextMiddleware after successful auth. Authenticated users hitting routes with optionalJwtAuth (e.g. /api/banner) had no tenant isolation. * feat: tenant-safe bulkWrite wrapper and call-site migration Mongoose's bulkWrite() does not trigger schema-level middleware hooks, so the applyTenantIsolation plugin cannot intercept it. This adds a tenantSafeBulkWrite() utility that injects the current ALS tenant context into every operation's filter/document before delegating to native bulkWrite. Migrates all 8 runtime bulkWrite call sites: - agentCategory (seedCategories, ensureDefaultCategories) - conversation (bulkSaveConvos) - message (bulkSaveMessages) - file (batchUpdateFiles) - conversationTag (updateTagsForConversation, bulkIncrementTagCounts) - aclEntry (bulkWriteAclEntries) systemGrant.seedSystemGrants is intentionally not migrated — it uses explicit tenantId: { $exists: false } filters and is exempt from the isolation plugin. * feat: pre-auth tenant middleware and tenant-scoped config cache Adds preAuthTenantMiddleware that reads X-Tenant-Id from the request header and wraps downstream in tenantStorage ALS context. Wired onto /oauth, /api/auth, /api/config, and /api/share — unauthenticated routes that need tenant scoping before JWT auth runs. The /api/config cache key is now tenant-scoped (STARTUP_CONFIG:${tenantId}) so multi-tenant deployments serve the correct login page config per tenant. The middleware is intentionally minimal — no subdomain parsing, no OIDC claim extraction. The private fork's reverse proxy or auth gateway sets the header. * feat: accept optional tenantId in updateInterfacePermissions When tenantId is provided, the function re-enters inside tenantStorage.run({ tenantId }) so all downstream Mongoose queries target that tenant's roles instead of the system context. This lets the private fork's tenant provisioning flow call updateInterfacePermissions per-tenant after creating tenant-scoped ADMIN/USER roles. * fix: tenant-filter $lookup in getPromptGroup aggregation The $lookup stage in getPromptGroup() queried the prompts collection without tenant filtering. While the outer PromptGroup aggregate is protected by the tenantIsolation plugin's pre('aggregate') hook, $lookup runs as an internal MongoDB operation that bypasses Mongoose hooks entirely. Converts from simple field-based $lookup to pipeline-based $lookup with an explicit tenantId match when tenant context is active. * fix: replace field-level unique indexes with tenant-scoped compounds Field-level unique:true creates a globally-unique single-field index in MongoDB, which would cause insert failures across tenants sharing the same ID values. - agent.id: removed field-level unique, added { id, tenantId } compound - convo.conversationId: removed field-level unique (compound at line 50 already exists: { conversationId, user, tenantId }) - message.messageId: removed field-level unique (compound at line 165 already exists: { messageId, user, tenantId }) - preset.presetId: removed field-level unique, added { presetId, tenantId } compound * fix: scope MODELS_CONFIG, ENDPOINT_CONFIG, PLUGINS, TOOLS caches by tenant These caches store per-tenant configuration (available models, endpoint settings, plugin availability, tool definitions) but were using global cache keys. In multi-tenant mode, one tenant's cached config would be served to all tenants. Appends :${tenantId} to cache keys when tenant context is active. Falls back to the unscoped key when no tenant context exists (backward compatible for single-tenant OSS deployments). Covers all read, write, and delete sites: - ModelController.js: get/set MODELS_CONFIG - PluginController.js: get/set PLUGINS, get/set TOOLS - getEndpointsConfig.js: get/set/delete ENDPOINT_CONFIG - app.js: delete ENDPOINT_CONFIG (clearEndpointConfigCache) - mcp.js: delete TOOLS (updateMCPTools, mergeAppTools) - importers.js: get ENDPOINT_CONFIG * fix: add getTenantId to PluginController spec mock The data-schemas mock was missing getTenantId, causing all PluginController tests to throw when the controller calls getTenantId() for tenant-scoped cache keys. * fix: address review findings — migration, strict-mode, DRY, types Addresses all CRITICAL, MAJOR, and MINOR review findings: F1 (CRITICAL): Add agents, conversations, messages, presets to SUPERSEDED_INDEXES in tenantIndexes.ts so dropSupersededTenantIndexes() drops the old single-field unique indexes that block multi-tenant inserts. F2 (CRITICAL): Unknown bulkWrite op types now throw in strict mode instead of silently passing through without tenant injection. F3 (MAJOR): Replace wildcard export with named export for tenantSafeBulkWrite, hiding _resetBulkWriteStrictCache from the public package API. F5 (MAJOR): Restore AnyBulkWriteOperation<IAclEntry>[] typing on bulkWriteAclEntries — the unparameterized wrapper accepts parameterized ops as a subtype. F7 (MAJOR): Fix config.js tenant precedence — JWT-derived req.user.tenantId now takes priority over the X-Tenant-Id header for authenticated requests. F8 (MINOR): Extract scopedCacheKey() helper into tenantContext.ts and replace all 11 inline occurrences across 7 files. F9 (MINOR): Use simple localField/foreignField $lookup for the non-tenant getPromptGroup path (more efficient index seeks). F12 (NIT): Remove redundant BulkOp type alias. F13 (NIT): Remove debug log that leaked raw tenantId. * fix: add new superseded indexes to tenantIndexes test fixture The test creates old indexes to verify the migration drops them. Missing fixture entries for agents.id_1, conversations.conversationId_1, messages.messageId_1, and presets.presetId_1 caused the count assertion to fail (expected 22, got 18). * fix: restore logger.warn for unknown bulk op types in non-strict mode * fix: block SYSTEM_TENANT_ID sentinel from external header input CRITICAL: preAuthTenantMiddleware accepted any string as X-Tenant-Id, including '__SYSTEM__'. The tenantIsolation plugin treats SYSTEM_TENANT_ID as an explicit bypass — skipping ALL query filters. A client sending X-Tenant-Id: __SYSTEM__ to pre-auth routes (/api/share, /api/config, /api/auth, /oauth) would execute Mongoose operations without tenant isolation. Fixes: - preAuthTenantMiddleware rejects SYSTEM_TENANT_ID in header - scopedCacheKey returns the base key (not key:__SYSTEM__) in system context, preventing stale cache entries during runAsSystem() - updateInterfacePermissions guards tenantId against SYSTEM_TENANT_ID - $lookup pipeline separates $expr join from constant tenantId match for better index utilization - Regression test for sentinel rejection in preAuthTenant.spec.ts - Remove redundant getTenantId() call in config.js * test: add missing deleteMany/replaceOne coverage, fix vacuous ALS assertions bulkWrite spec: - deleteMany: verifies tenant-scoped deletion leaves other tenants untouched - replaceOne: verifies tenantId injected into both filter and replacement - replaceOne overwrite: verifies a conflicting tenantId in the replacement document is overwritten by the ALS tenant (defense-in-depth) - empty ops array: verifies graceful handling preAuthTenant spec: - All negative-case tests now use the capturedNext pattern to verify getTenantId() inside the middleware's execution context, not the test runner's outer frame (which was always undefined regardless) * feat: tenant-isolate MESSAGES cache, FLOWS cache, and GenerationJobManager MESSAGES cache (streamAudio.js): - Cache key now uses scopedCacheKey(messageId) to prefix with tenantId, preventing cross-tenant message content reads during TTS streaming. FLOWS cache (FlowStateManager): - getFlowKey() now generates ${type}:${tenantId}:${flowId} when tenant context is active, isolating OAuth flow state per tenant. GenerationJobManager: - tenantId added to SerializableJobData and GenerationJobMetadata - createJob() captures the current ALS tenant context (excluding SYSTEM_TENANT_ID) and stores it in job metadata - SSE subscription endpoint validates job.metadata.tenantId matches req.user.tenantId, blocking cross-tenant stream access - Both InMemoryJobStore and RedisJobStore updated to accept tenantId * fix: add getTenantId and SYSTEM_TENANT_ID to MCP OAuth test mocks FlowStateManager.getFlowKey() now calls getTenantId() for tenant-scoped flow keys. The 4 MCP OAuth test files mock @librechat/data-schemas without these exports, causing TypeError at runtime. * fix: correct import ordering per AGENTS.md conventions Package imports sorted shortest to longest line length, local imports sorted longest to shortest — fixes ordering violations introduced by our new imports across 8 files. * fix: deserialize tenantId in RedisJobStore — cross-tenant SSE guard was no-op in Redis mode serializeJob() writes tenantId to the Redis hash via Object.entries, but deserializeJob() manually enumerates fields and omitted tenantId. Every getJob() from Redis returned tenantId: undefined, causing the SSE route's cross-tenant guard to short-circuit (undefined && ... → false). * test: SSE tenant guard, FlowStateManager key consistency, ALS scope docs SSE stream tenant tests (streamTenant.spec.js): - Cross-tenant user accessing another tenant's stream → 403 - Same-tenant user accessing own stream → allowed - OSS mode (no tenantId on job) → tenant check skipped FlowStateManager tenant tests (manager.tenant.spec.ts): - completeFlow finds flow created under same tenant context - completeFlow does NOT find flow under different tenant context - Unscoped flows are separate from tenant-scoped flows Documentation: - JSDoc on getFlowKey documenting ALS context consistency requirement - Comment on streamAudio.js scopedCacheKey capture site * fix: SSE stream tests hang on success path, remove internal fork references The success-path tests entered the SSE streaming code which never closes, causing timeout. Mock subscribe() to end the response immediately. Restructured assertions to verify non-403/non-404. Removed "private fork" and "OSS" references from code and test descriptions — replaced with "deployment layer", "multi-tenant deployments", and "single-tenant mode". * fix: address review findings — test rigor, tenant ID validation, docs F1: SSE stream tests now mock subscribe() with correct signature (streamId, writeEvent, onDone, onError) and assert 200 status, verifying the tenant guard actually allows through same-tenant users. F2: completeFlow logs the attempted key and ALS tenantId when flow is not found, so reverse proxy misconfiguration (missing X-Tenant-Id on OAuth callback) produces an actionable warning. F3/F10: preAuthTenantMiddleware validates tenant ID format — rejects colons, special characters, and values exceeding 128 chars. Trims whitespace. Prevents cache key collisions via crafted headers. F4: Documented cache invalidation scope limitation in clearEndpointConfigCache — only the calling tenant's key is cleared; other tenants expire via TTL. F7: getFlowKey JSDoc now lists all 8 methods requiring consistent ALS context. F8: Added dedicated scopedCacheKey unit tests — base key without context, base key in system context, scoped key with tenant, no ALS leakage across scope boundaries. * fix: revert flow key tenant scoping, fix SSE test timing FlowStateManager: Reverts tenant-scoped flow keys. OAuth callbacks arrive without tenant ALS context (provider redirects don't carry X-Tenant-Id), so completeFlow/failFlow would never find flows created under tenant context. Flow IDs are random UUIDs with no collision risk, and flow data is ephemeral (TTL-bounded). SSE tests: Use process.nextTick for onDone callback so Express response headers are flushed before res.write/res.end are called. * fix: restore getTenantId import for completeFlow diagnostic log * fix: correct completeFlow warning message, add missing flow test The warning referenced X-Tenant-Id header consistency which was only relevant when flow keys were tenant-scoped (since reverted). Updated to list actual causes: TTL expiry, missing flow, or routing to a different instance without shared Keyv storage. Removed the getTenantId() call and import — no longer needed since flow keys are unscoped. Added test for the !flowState branch in completeFlow — verifies return false and logger.warn on nonexistent flow ID. * fix: add explicit return type to recursive updateInterfacePermissions The recursive call (tenantId branch calls itself without tenantId) causes TypeScript to infer circular return type 'any'. Adding explicit Promise<void> satisfies the rollup typescript plugin. * fix: update MCPOAuthRaceCondition test to match new completeFlow warning * fix: clearEndpointConfigCache deletes both scoped and unscoped keys Unauthenticated /api/endpoints requests populate the unscoped ENDPOINT_CONFIG key. Admin config mutations clear only the tenant-scoped key, leaving the unscoped entry stale indefinitely. Now deletes both when in tenant context. * fix: tenant guard on abort/status endpoints, warn logs, test coverage F1: Add tenant guard to /chat/status/:conversationId and /chat/abort matching the existing guard on /chat/stream/:streamId. The status endpoint exposes aggregatedContent (AI response text) which requires tenant-level access control. F2: preAuthTenantMiddleware now logs warn for rejected __SYSTEM__ sentinel and malformed tenant IDs, providing observability for bypass probing attempts. F3: Abort fallback path (getActiveJobIdsForUser) now has tenant check after resolving the job. F4: Test for strict mode + SYSTEM_TENANT_ID — verifies runAsSystem bypasses tenantSafeBulkWrite without throwing in strict mode. F5: Test for job with tenantId + user without tenantId → 403. F10: Regex uses idiomatic hyphen-at-start form. F11: Test descriptions changed from "rejects" to "ignores" since middleware calls next() (not 4xx). Also fixes MCPOAuthRaceCondition test assertion to match updated completeFlow warning message. * fix: test coverage for logger.warn, status/abort guards, consistency A: preAuthTenant spec now mocks logger and asserts warn calls for __SYSTEM__ sentinel, malformed characters, and oversized headers. B: streamTenant spec expanded with status and abort endpoint tests — cross-tenant status returns 403, same-tenant returns 200 with body, cross-tenant abort returns 403. C: Abort endpoint uses req.user.tenantId (not req.user?.tenantId) matching stream/status pattern — requireJwtAuth guarantees req.user. D: Malformed header warning now includes ip in log metadata, matching the sentinel warning for consistent SOC correlation. * fix: assert ip field in malformed header warn tests * fix: parallelize cache deletes, document tenant guard, fix import order - clearEndpointConfigCache uses Promise.all for independent cache deletes instead of sequential awaits - SSE stream tenant guard has inline comment explaining backward-compat behavior for untenanted legacy jobs - conversation.ts local imports reordered longest-to-shortest per AGENTS.md * fix: tenant-qualify userJobs keys, document tenant guard backward-compat Job store userJobs keys now include tenantId when available: - Redis: stream:user:{tenantId:userId}:jobs (falls back to stream:user:{userId}:jobs when no tenant) - InMemory: composite key tenantId:userId in userJobMap getActiveJobIdsByUser/getActiveJobIdsForUser accept optional tenantId parameter, threaded through from req.user.tenantId at all call sites (/chat/active and /chat/abort fallback). Added inline comments on all three SSE tenant guards explaining the backward-compat design: untenanted legacy jobs remain accessible when the userId check passes. * fix: parallelize cache deletes, document tenant guard, fix import order Fix InMemoryJobStore.getActiveJobIdsByUser empty-set cleanup to use the tenant-qualified userKey instead of bare userId — prevents orphaned empty Sets accumulating in userJobMap for multi-tenant users. Document cross-tenant staleness in clearEndpointConfigCache JSDoc — other tenants' scoped keys expire via TTL, not active invalidation. * fix: cleanup userJobMap leak, startup warning, DRY tenant guard, docs F1: InMemoryJobStore.cleanup() now removes entries from userJobMap before calling deleteJob, preventing orphaned empty Sets from accumulating with tenant-qualified composite keys. F2: Startup warning when TENANT_ISOLATION_STRICT is active — reminds operators to configure reverse proxy to control X-Tenant-Id header. F3: mergeAppTools JSDoc documents that tenant-scoped TOOLS keys are not actively invalidated (matching clearEndpointConfigCache pattern). F5: Abort handler getActiveJobIdsForUser call uses req.user.tenantId (not req.user?.tenantId) — consistent with stream/status handlers. F6: updateInterfacePermissions JSDoc clarifies SYSTEM_TENANT_ID behavior — falls through to caller's ALS context. F7: Extracted hasTenantMismatch() helper, replacing three identical inline tenant guard blocks across stream/status/abort endpoints. F9: scopedCacheKey JSDoc documents both passthrough cases (no context and SYSTEM_TENANT_ID context). * fix: clean userJobMap in evictOldest — same leak as cleanup()
2026-03-28 16:43:50 -04:00
const { logger, scopedCacheKey } = require('@librechat/data-schemas');
const { getToolkitKey, checkPluginAuth, filterUniquePlugins } = require('@librechat/api');
const { getCachedTools, setCachedTools } = require('~/server/services/Config');
const { availableTools, toolkits } = require('~/app/clients/tools');
🛜 refactor: Streamline App Config Usage (#9234) * WIP: app.locals refactoring WIP: appConfig fix: update memory configuration retrieval to use getAppConfig based on user role fix: update comment for AppConfig interface to clarify purpose 🏷️ refactor: Update tests to use getAppConfig for endpoint configurations ci: Update AppService tests to initialize app config instead of app.locals ci: Integrate getAppConfig into remaining tests refactor: Update multer storage destination to use promise-based getAppConfig and improve error handling in tests refactor: Rename initializeAppConfig to setAppConfig and update related tests ci: Mock getAppConfig in various tests to provide default configurations refactor: Update convertMCPToolsToPlugins to use mcpManager for server configuration and adjust related tests chore: rename `Config/getAppConfig` -> `Config/app` fix: streamline OpenAI image tools configuration by removing direct appConfig dependency and using function parameters chore: correct parameter documentation for imageOutputType in ToolService.js refactor: remove `getCustomConfig` dependency in config route refactor: update domain validation to use appConfig for allowed domains refactor: use appConfig registration property chore: remove app parameter from AppService invocation refactor: update AppConfig interface to correct registration and turnstile configurations refactor: remove getCustomConfig dependency and use getAppConfig in PluginController, multer, and MCP services refactor: replace getCustomConfig with getAppConfig in STTService, TTSService, and related files refactor: replace getCustomConfig with getAppConfig in Conversation and Message models, update tempChatRetention functions to use AppConfig type refactor: update getAppConfig calls in Conversation and Message models to include user role for temporary chat expiration ci: update related tests refactor: update getAppConfig call in getCustomConfigSpeech to include user role fix: update appConfig usage to access allowedDomains from actions instead of registration refactor: enhance AppConfig to include fileStrategies and update related file strategy logic refactor: update imports to use normalizeEndpointName from @librechat/api and remove redundant definitions chore: remove deprecated unused RunManager refactor: get balance config primarily from appConfig refactor: remove customConfig dependency for appConfig and streamline loadConfigModels logic refactor: remove getCustomConfig usage and use app config in file citations refactor: consolidate endpoint loading logic into loadEndpoints function refactor: update appConfig access to use endpoints structure across various services refactor: implement custom endpoints configuration and streamline endpoint loading logic refactor: update getAppConfig call to include user role parameter refactor: streamline endpoint configuration and enhance appConfig usage across services refactor: replace getMCPAuthMap with getUserMCPAuthMap and remove unused getCustomConfig file refactor: add type annotation for loadedEndpoints in loadEndpoints function refactor: move /services/Files/images/parse to TS API chore: add missing FILE_CITATIONS permission to IRole interface refactor: restructure toolkits to TS API refactor: separate manifest logic into its own module refactor: consolidate tool loading logic into a new tools module for startup logic refactor: move interface config logic to TS API refactor: migrate checkEmailConfig to TypeScript and update imports refactor: add FunctionTool interface and availableTools to AppConfig refactor: decouple caching and DB operations from AppService, make part of consolidated `getAppConfig` WIP: fix tests * fix: rebase conflicts * refactor: remove app.locals references * refactor: replace getBalanceConfig with getAppConfig in various strategies and middleware * refactor: replace appConfig?.balance with getBalanceConfig in various controllers and clients * test: add balance configuration to titleConvo method in AgentClient tests * chore: remove unused `openai-chat-tokens` package * chore: remove unused imports in initializeMCPs.js * refactor: update balance configuration to use getAppConfig instead of getBalanceConfig * refactor: integrate configMiddleware for centralized configuration handling * refactor: optimize email domain validation by removing unnecessary async calls * refactor: simplify multer storage configuration by removing async calls * refactor: reorder imports for better readability in user.js * refactor: replace getAppConfig calls with req.config for improved performance * chore: replace getAppConfig calls with req.config in tests for centralized configuration handling * chore: remove unused override config * refactor: add configMiddleware to endpoint route and replace getAppConfig with req.config * chore: remove customConfig parameter from TTSService constructor * refactor: pass appConfig from request to processFileCitations for improved configuration handling * refactor: remove configMiddleware from endpoint route and retrieve appConfig directly in getEndpointsConfig if not in `req.config` * test: add mockAppConfig to processFileCitations tests for improved configuration handling * fix: pass req.config to hasCustomUserVars and call without await after synchronous refactor * fix: type safety in useExportConversation * refactor: retrieve appConfig using getAppConfig in PluginController and remove configMiddleware from plugins route, to avoid always retrieving when plugins are cached * chore: change `MongoUser` typedef to `IUser` * fix: Add `user` and `config` fields to ServerRequest and update JSDoc type annotations from Express.Request to ServerRequest * fix: remove unused setAppConfig mock from Server configuration tests
2025-08-26 12:10:18 -04:00
const { getAppConfig } = require('~/server/services/Config');
const { getLogStores } = require('~/cache');
feat: Plugins endpoint - Reverse Engineering of official Plugins features (#197) * components for plugins in progress * WIP: add langchain client implementation for tools/plugins feat(langchain): add loadHistory function for loading chat history from database feat(langchain): add saveMessageToDatabase function for saving chat messages to database * chore(Memory.js): remove Memory.js file from the project directory. * WIP: adding plugin functionality —————————————————— fix(eslintrc.js): change arrow-parens rule to always require parentheses refactor(agent.js): reorganize imports and add new imports feat(agent.js): add support for saving and loading chat history feat(agent.js): add support for saving messages to database feat(agent.js): add ChatAgent class with initialize and sendMessage methods fix(langchain): use getConvo and saveMessage functions from models.js instead of Conversation and Message models feat(langchain): add user parameter to loadHistory and saveMessageToDatabase functions chore(package.json): update langchain package version to 0.0.59 and add langchain script to run test2.js file —————————————————— * WIP: testing agent initialization * WIP: testing various agent methods feat(agent.js): add CustomChatAgent class and initializeAgentExecutorWithOptions method feat(customChatAgent.js): add CustomPromptTemplate and CustomOutputParser classes refactor(langchain): uncomment code for input2 and options feat(langchain): add input1 to read comments on a youtube video docs(langchain): remove commented code and add whitespace to package.json * WIP: feat: plugin endpoint, backend class working * feat(agent.js): add support for Zapier NLA API key feat(agent.js): add ZapierToolKit to tools if zapierApiKey is provided feat(customAgent.js): change prompt prefix and suffix to reflect new task-based prompt feat(test4.js): add test for new task-based prompt * style(langchain): improve readability and add comments to code feat(langchain): update prompt message for custom agent fix(langchain): update message format in test4.js * style(customAgent.js): remove unnecessary capitalization and rephrase some sentences test(langchain): add test2 and test3 scripts to package.json * chore(customAgent.js): fix typo in comment, change "an" to "identical" * WIP: gpt-4 testing * feat(langchain): add AIPluginTool and HumanTool classes fix(langchain): remove zapierApiKey option from ChatAgent constructor refactor(langchain): update langchain package to v0.0.64 misc(langchain): update test2, test3, and test4 scripts to use --inspect flag * feat(langchain): add GoogleSearchAPI tool for searching the web using Google Custom Search API * feat(askGPTPlugins.js): add support for progress callback in ask function fix(agent.js): pass progress callback to sendApiMessage function * refactor(agent.js): load tools from options and initialize them in constructor feat(agent.js): add support for environment variable SERPAPI_API_KEY feat(agent.js): add support for environment variable ZAPIER_NLA_API_KEY docs(agent.js): remove commented out code and add comments to clarify code * chore(langchain): remove unused files loadHistory.js and saveMessage.js * feat(validateTools.js): add function to validate API keys for supported tools * feat(langchain): update langchain package to version 0.0.66 feat(langchain): add support for GPT-4 model fix(server/index.js): fix uncaughtException handler to ignore 'fetch failed' errors * refactor(agent.js): remove FORMAT_INSTRUCTIONS and replace with a more concise message refactor(agent.js): remove unused variable 'errorMessage' refactor(agent.js): change 'result' variable initialization to an empty object instead of null refactor(agent.js): change error message when response generation fails refactor(agent.js): change output message when response generation fails refactor(agent.js): change output message when response generation succeeds * chore(langchain): comment out unused model in ChatAgent constructor feat(langchain): add test5 script to package.json for running test5.js script * refactor(agent.js): change response to answer and update message refactor(test3.js, test5.js): remove commented out code and add comments The changes in agent.js are to improve the message that is returned to the user. The word "response" has been changed to "answer" to better reflect the output of the chatbot. The message has also been updated to provide clearer instructions to the user. The changes in test3.js and test5.js are to remove commented out code and add comments to improve readability. * docs: update links to LOCAL_INSTALL.md and defaultSystemMessage.md fix: fix typo in BingAI/Settings.jsx feat: add Dockerfile for app containerization docs(google_search.md): add guide for setting up Google Custom Search API key and ID * docs: update link to system message guidelines in Bing AI Settings component docs: update link to system message guidelines in GOOGLE_SEARCH.md feat: add JAILBREAK_INFO.md guide for Bing AI jailbreak mode system message guidelines * style(api): remove unnecessary quotes and empty values from .env.example style(agent.js): refactor getActions method to accept an input parameter feat(agent.js): add handleChainEnd method to CustomChatAgent class style(customAgent.js): add a new line to the end of the file style(test5.js): comment out unused variable and update input1 variable style(googleSearch.js): change tool name to kebab-case * chore(langchain): comment out handleChainEnd method in agent.js feat(langchain): add browser tool to ChatAgent in test2.js feat(langchain): add modelOptions to ChatAgent in test2.js feat(langchain): change question in input1 and request article review summary in test5.js * fix(askGPTPlugins.js): fix syntax error by removing extra comma in parentMessageId field feat(askGPTPlugins.js): add default value of null to parentMessageId parameter in ask function * fix(askGPTPlugins.js): change endpoint string from 'GPTPlugins' to 'gptPlugins' feat(endpoints.js): add support for gptPlugins endpoint feat(PresetItem.jsx): add support for gptPlugins endpoint feat(HoverButtons.jsx): add support for gptPlugins endpoint feat(createPayload.ts): add support for gptPlugins endpoint feat(types.ts): add gptPlugins endpoint to EModelEndpoint enum feat(endpoints.js): add gptPlugins endpoint to availableEndpoints selector feat(cleanupPreset.js): add support for gptPlugins endpoint feat(getDefaultConversation.js): add support for gptPlugins endpoint feat(getIcon.jsx): add support for gptPlugins endpoint feat(handleSubmit.js): add support for gptPlugins endpoint * refactor(agent.js): remove debug option from options object refactor(agent.js): change tool name from 'google-search' to 'google' refactor(agent.js): update description for 'google' tool feat(agent.js): add support for citing sources when using web links in response message fix(agent.js): update error message to not mention error to user feat(agent.js): add unique message ids for user message and response message feat(agent.js): limit number of search results to 5 in 'google' tool refactor(validateTools.js): add console log to show valid tools * feat(askGPTPlugins.js): add support for GPT-3.5-turbo model and validate model option refactor(askGPTPlugins.js): remove unused imports and variables refactor(askGPTPlugins.js): remove commented code refactor(askGPTPlugins.js): remove unused parameters in ask function feat(ask/index.js): add askGPTPlugins route to router * feat(NewConversationMenu): add alpha tag to gptPlugins endpoint and rename it to Plugins * refactor(askGPTPlugins.js): remove commented code and unused imports feat(askGPTPlugins.js): add support for debug option in endpointOption feat(askGPTPlugins.js): add support for chatGptLabel, promptPrefix, temperature, top_p, presence_penalty, and frequency_penalty in endpointOption feat(askGPTPlugins.js): add support for sending plugin and pluginend events feat(askGPTPlugins.js): add onAgentAction and onChainEnd callbacks to ChatAgent.sendMessage refactor(titleConvo.js): comment out unused imports refactor(validateTools.js): comment out console.log statement refactor(agent.js): change saveMessage to include unfinished property feat(agent.js): add endpoint property to saveConvo call in saveMessageToDatabase feat(askGPTPlugins.js): add validateTools import and use it to validate endpointOption.tools before passing to ChatAgent constructor feat(askGPTPlugins.js * refactor(MessageHeader.jsx): extract plugins section into a separate variable and add support for gptPlugins endpoint fix(MessageHeader.jsx): disable clicking on non-clickable endpoints * components for plugins in progress * feat(Plugin.jsx): add plugin prop to Plugin component and display plugin name feat(Plugin.jsx): add loading state and display loading spinner feat(Plugin.jsx): add Disclosure component to Plugin component feat(Plugin.jsx): add Disclosure.Panel to Plugin component to display team pricing information feat(Spinner.jsx): add classProp prop to Spinner component to allow for custom styling feat(Landing.jsx): add Plugin component to Landing page for testing testing gpt plugins feat(plugins): Milestone commit - Add formatAction function to format plugin actions. - Add prefix.js file to store the prefix message for ChatAgent. - Update ask function to include plugin object to store plugin data. - Update onAgentAction and onChainEnd functions to format plugin data and send intermediate messages. - Update response object to include plugin data. The `handlers.js` file now includes a `formatAction` function that formats the action object for display in the UI. The `createOnProgress` function now returns a `sendIntermediateMessage` function that sends intermediate messages to the client. feat (client): add support for plugins in messages This commit adds support for plugins in messages. It includes changes to the `handlers.js`, `index.jsx`, `CodeBlock.jsx`, `Message.jsx`, `MessageHeader.jsx`, and `Plugin.jsx` files. The `index.jsx` file now includes a `plugin` property in the `messageHandler` function. The `CodeBlock.jsx` file now includes a `plugin` property that determines the language of the code block. The `Message.jsx` file now includes a `Plugin` component that displays the plugin used in the message. The `MessageHeader.jsx` file now includes a `Plugins` component that displays the enabled plugins. feat(langchain): add OpenAICreateImage tool for generating images based on user prompts fix(langchain): update validateTools to include create-image tool fix(langchain): save plugin data to messageSchema fix(server/routes/askGPTPlugins.js): save userMessage and response to messageSchema feat(langchain): add SelfReflectionTool Add a new tool to the LangChain agent, SelfReflectionTool, which enhances the agent's self-awareness by reflecting on its thoughts before taking action. The tool provides a space for the agent to explore and organize its ideas in response to the user's message. Also, update the prefix message to reflect the changes in the agent's behavior and the way it should engage with the user. The prefix message now emphasizes the use of tools when necessary, and relying on the agent's knowledge for creative requests. It also provides clear instructions on how to use the 'Action' input and how to carry out tasks in the sequence written by the human. Finally, update the OpenAICreateImage tool to return the image URL in markdown format. The tool replaces newlines and spaces in the input text with hyphens to create a valid markdown link. Milestone commit: better error handling with custom output parser, dir and file re-org style(langchain): fix formatting and add comments to prefix.js fix(langchain): remove commented out code in test6.js feat(langchain): reduce maxAttempts from 3 to 2 in CustomChatAgent's buildPromptPrefix method feat(langchain): add null check for result.output in CustomChatAgent's buildPromptPrefix method style(langchain): improve consistency and readability of code This commit improves the consistency and readability of the code in the langchain directory. Specifically, it: - Changes the case of the "Thought" output in the CustomChatAgent class to match the "Thought" output in the SelfReflectionTool class. - Adds a currentDateString property to the CustomChatAgent class to avoid repeating the same code in multiple places. - Updates the prefix in the prefix.js file to match the current objectives of the ChatGPT model. - Changes the description of the OpenAICreateImage tool to request a description of the image to be generated. - Updates the tools used by the ChatAgent in the askGPTPlugins.js file to include the Google and Browser tools instead of the Calculator and Create-Image tools. feat: add wolfram, improve image creation, rename to dall-e * refactor(langchain): update language and formatting in various files - Update tool-based instructions to use proper Markdown syntax for image URLs - Adjust temperature for modelOptions in CustomChatAgent class - Comment out console.debug statement in CustomChatAgent class - Update prefix in initializeCustomAgent function to use proper line breaks - Update prefix in instructions.js to use proper line breaks and change "user" to "human" - Update input in test6.js to use Ezra Pound instead of Hemingway - Update return statement in OpenAICreateImage class to use "generated-image" as alt-text - Update description in SelfReflectionTool class to provide clearer instructions - Update tools in ask function in askGPTPlugins.js to use only the DALL-E tool and enable debug mode feat(ask): add support for DALL-E tool in formatAction function feat(ask): add support for self-reflection tool in formatAction function feat(Plugin.jsx): add support for self-reflection tool in Plugin component fix(Plugin.jsx): fix Plugin component to not display 'None' when latest is not available * docs(openaiCreateImage.js): update tool description to clarify usage * feat(agent.js): add message parameter to initialize function feat(agent.js): pass message parameter to SelfReflectionTool constructor feat(customAgent.js): add longestToolName variable to CustomOutputParser feat(openaiCreateImage.js): replace new lines with spaces in prompt parameter feat(selfReflection.js): add message parameter to SelfReflectionTool constructor feat(selfReflection.js): add placeholder response to selfReflect function * feat: frontend plugin selection * fix: agent updates, available tools via endpoint config * fix: improve frontend plugin selection * feat: further customize agent and bypass executor when no tools are provided * fix: key issue in multiselect and allow setting changes during convo in plugins endpoint * fix: convo will save modelOptions, fix persistent errors with agent * fix: add looser final answer parsing and edit action formatting * fix: handle edge case where stop token is not hit and causes long parsing error * feat: trying new prompt for image creation * fix: improvements based on gpt-3.5 * feat: allow setting model options throughout plugin conversation * fix: agent adjustments * improve final reply for gpt-4, gpt-3.5 needs a more stable approach * fix: better context output for gpt-3.5 * fix: added clarification for better context output for gpt-3.5 * feat(PluginsOptions): add advanced mode to show/hide options style(PluginsOptions): add styles for advanced mode and show/hide options * minor changes to styling * refactor(langchain): add support for custom GPT-4 agent This commit adds support for a custom GPT-4 agent in the langchain module. The `CustomGpt4Agent` class extends the `ZeroShotAgent` class and includes a new `createPrompt` method that generates a prompt template for the agent. The `initializeCustomAgent` function has been updated to use the `CustomGpt4Agent` class when the model is not GPT-3. The `instructions.js` file has also been updated to include new instructions for the GPT-4 agent. The `formatInstructions` method has been removed and replaced with `gpt4Instructions` and `prefix2` and `suffix2` have been added to include the new instructions. feat(langchain): add custom output parser for langchain agents This commit adds a custom output parser for langchain agents. The new parser is called CustomOutputParser and it extends ZeroShotAgentOutputParser. It takes a fields object as a parameter and sets the tools and longestToolName properties. It also sets the finishToolNameRegex property to match the final answer. The parse method of the CustomOutputParser class takes a text parameter and returns an object with returnValues, log, and toolInput properties. This commit also adds a Gpt4OutputParser class that extends ZeroShotAgentOutputParser. It takes a fields object as a parameter and sets the tools and longestToolName properties. It also sets the finishToolNameRegex property to match the final answer. The parse method of the Gpt4OutputParser class takes a text parameter and returns an object with returnValues, log, and toolInput properties. feat(langchain): add isGpt3 parameter to * Stable Diffusion Plugin (#204) * Added stable diffusion plugin * Added example prompt * Fixed naming * Removed brackets in the prompt * fix: improved agent for gpt-3.5 * fix: outparser, gpt3 instructions, and wolfram error handling * chore: update langchain to 0.0.71 * fix: long parsing action input fix * fix: make plugin select close on clicking label/button * fix: make plugin select close on clicking label/button * fix: wolfram input formatting and gpt-3 payload without plugins * chore(api): update axios package version to 1.3.4 feat(api): add requireJwtAuth middleware to askGPTPlugins endpoint fix(api): replace session user with user id in askGPTPlugins endpoint docs(LOCAL_INSTALL.md): update guide for local installation and testing This commit updates the guide for local installation and testing of the ChatGPT-Clone app. It includes instructions for locally running the app, updating the app version, and running tests. It also includes a new option for running the app using Docker. The commit also fixes some typos and formatting issues. * add reverseProxy to plugins client * chore(Dockerfile-app): add Dockerfile for building and running the app in a container docs: remove outdated guides on Google search and Bing jailbreak mode docs(LOCAL_INSTALL.md): remove outdated Windows installation instructions and update MeiliSearch configuration file * fix: handle n/a parsing error better, reduce token waste if no agentic behavior is needed * style: fix formatting and add parentheses around arrow function parameter style: change hover background color to white and dark hover background color to gray-700 * chore: re-organize agent dir and files * feat(ChatAgent.js): add support for PlanAndExecuteAgentExecutor feat(PlanAndExecuteAgentExecutor.js): add PlanAndExecuteAgentExecutor class feat(planExecutor.js): add demo for PlanAndExecuteAgentExecutor * feat: add azure support to plugins * refactor(utils): add basePath endpoint for genAzureEndpoint feat(api): add support for Azure OpenAI API in various modules and tools * feat: add plugin api for fetching available tools * feat: add data service for getting available plugins * feat: first iteration plugin store UI * refactor: rename files to follow proper naming convention * feat: Plugin store UI components * feat: create separate user routes, service, controller, and add plugins to user model * feat: create data service for adding and removing plugins per user * feat: UI for adding and removing plugins, displaying plugins in dropdown based on what user has installed * fix: merge conflicts from main * fix: fix plugin items titles * fix: tool.value -> tool.pluginKey * fix: testing returnDirect for self-reflection * fix: add browser tool to manifest * refactor(outputParser.js): remove commented out code feat(outputParser.js): add support for thought input when there is no action input * handling 'use tool' edge case * merge main to langchain * fix(User.js, auth.service.js, localStrategy.js): change deprecated Joi.validate() to schema.validate() method (#322) * fix(auth.service.js): fixes deprecated error callback in mongoose save method (#323) * chore: run formatting script with new rules * refactor: add requiresAuth to manifest, fix uninstall button * version with plugin auth as dialog modal * feat: Complete frontend for plugin auth * frontend styling updates * feat: api for plugin auth * feat: Add tooltip with field description to plugin auth form * fix: issue with plugin that has no auth * feat(tools): add support for user-specific API keys This commit adds support for user-specific API keys for the following tools: - Google Search API - Web Browser - SerpAPI - Zapier - DALL-E - Wolfram Alpha API It also adds support for OpenAI API key for the Web Browser tool. The `validateTools` function now takes a `user` parameter and checks for user-specific API keys before falling back to environment variables. The `loadTools` function now takes a `user` parameter and initializes the tools with user-specific API keys if available. The `manifest.json` file has been updated to include the new `authConfig` fields for the tools that support user-specific API keys. The `askGPTPlugins.js` file has been updated to use the `validateTools` function with the `user` parameter. refactor(ChatAgent.js): add user parameter to initialize function and pass it to loadTools function refactor(tools/index.js): set default value for tools parameter in validateTools function refactor(askGPTPlugins.js): remove duplicate user variable declaration and use the one from req object * refactor(ChatAgent.js): await validTool() before pushing to this.tools array refactor(tools/index.js): use Map instead of Set to store valid tools refactor(tools/index.js): filter availableTools to only validate tools passed in refactor(PluginController.js): filter out duplicate plugins by pluginKey refactor(crypto.js): use environment variables for encryption key and initialization vector feat(PluginService.js): add null check for pluginAuth in getUserPluginAuthValue() * feat(api): add credentials key and IV to .env.example for securely storing credentials * Adds testing for handling tools, introducing a test env to the backend Fixes bugs & optimizes code as revealed through testing, including: - wolfram.js: fixes bug where wolfram was not handling authentication - ChatAgent.js: ChatAgent modified to reflect 'handleTools' changes - handleTools.js: Moves logic out of index file - handleTools.js: loadTools: returns only requested tools - handleTools.js: validTools: correctly returns tools based on authentication * test(index.test.js): add test to validate a tool from an environment variable * test(tools): add test for initializing an authenticated tool through Environment Variables * refactor(ChatAgent.js): remove commented out code and unused imports * refactor(ChatAgent.js): move instructions to a separate file and import them fix(ChatAgent.js): replace hardcoded instructions with imported ones * refactor(ChatAgent.js): change import path for TextStream refactor(stream.js): remove unused TextStream class * chore(.gitignore): add .env.test to gitignore refactor(ChatAgent.js): rename CustomChatAgent to ChatAgent test(ChatAgent.test.js): add tests for ChatAgent class refactor(outputParser.js): remove OldOutputParser class refactor(outputParser.js): rename CustomOutputParser to OutputParser docs(.env.test.example): add comment explaining how to use OPENAI_API_KEY refactor(jestSetup.js): use dotenv to load environment variables from .env.test file * Various optimizations and config, add tests for PluginStoreDialog * test(ChatAgent.test.js): add test to check if chat history is returned correctly * test: unit tests for plugin store * test: add frontend-test script to root package.json * feat(ChatAgent.js, askGPTPlugins.js): add support for aborting chat requests (in progress) * test: add more client tests * feat(ChatAgent): allow plugin requests to be cancelled * feat(ChatAgent): allow message regeneration * feat(ChatAgent): remember last selected tools * Remove plugins we don't yet have from manifest.json * fix(ChatAgent.js): increase maxAttempts from 1 to 2 fix(ChatAgent.js): change error message to 'Cancelled.' if message was aborted mid-generation fix(openaiCreateImage.js): replace unwanted characters in input string fix(handlers.js): compare action.tool in lowercase to 'self-reflection' * fix(ChatAgent): Fix up plugin I/O formatting for n/a actions * refactor(Plugin.jsx): remove unused import statement feat(Plugin.jsx): add Plugin component with svg paths and styles * refactor: simplify credential encryption/decryption by using a single key and IV for all environments. Update crypto.js and .env.example files accordingly. * fix(ChatAgent.js): reduce maxAttempts from 2 to 1 feat(ChatAgent.js): add model information to responseMessage object feat(Message.js): add model field to messageSchema feat(Message.js): add model field to message object feat(Message.jsx): pass model information to getIcon function feat(getIcon.jsx): add Plugin component and handle plugin messages differently * feat(askGPTPlugins.js): add model property to the ask function response object feat(EndpointItem.jsx): add message property to the EndpointItem component feat(MessageHeader.jsx): add Plugin icon to the plugins section feat(MessageHeader.jsx): change alpha to beta in the plugins section feat(svg): add Plugin, GPTIcon, and BingIcon components to the svg folder refactor(EndpointItems.jsx): remove unused import statement * refactor(googleSearch.js, wolfram.js): change error handling to return a message instead of throwing an error * refactor(CustomAgent): remove commented code and change return object to include returnValues property * feat(CustomAgent.js): add currentDateString to createPrompt method options deps(api/package.json): update langchain to v0.0.81 * fix: do not show pagination if the maxPage is 1 * Add Zapier back to manifest (accidentally removed) * chore(api): update langchain dependency to version 0.0.84 * feat(DALL-E.js): add DALL-E tool for generating images using OpenAI's DALL-E API refactor(handleTools.js): update import for DALL-E tool refactor(index.test.js): update import for DALL-E tool refactor(stablediffusion.js): add check for image directory existence before saving image * refactor(CustomAgent): rename instructions prefix variable to gpt3 and add gpt4 instructions feat(CustomAgent): add support for gpt-4 model fix(initializeCustomAgent.js): pass model name to createPrompt method fix(outputParser.js): set selectedTool to 'self-reflection' when tool parsing fails * style(langchain/tools): update guidelines for image creation in DALL-E and StableDiffusion - Update guidelines for image creation in DALL-E and StableDiffusion tools - Emphasize the importance of "showing" and not "telling" the imagery in crafting input - Update formatting for the example prompt for generating a realistic portrait photo of a man - Generate images only once per human query unless explicitly requested by the user * docs(tools): update tool descriptions for DALL-E and Stable Diffusion - Update the description for DALL-E tool to indicate that it is exclusively for visual content and provide guidelines for generating images with a focus on visual attributes. - Update the description for Stable Diffusion tool to indicate that it is exclusively for visual content and provide guidelines for generating images with a focus on visual attributes. * chore(api): update "@waylaidwanderer/chatgpt-api" dependency to version "^1.36.3" * refactor(ChatAgent.js): use environment variable for reverse proxy url refactor(ChatAgent.js): use environment variable for openai base path refactor(instructions.js): update gpt3 and gpt3-v2 instructions refactor(outputParser.js): update finishToolNameRegex in CustomOutputParser class * refactor(DALL-E.js): change apiKey and azureKey fields to uppercase refactor(googleSearch.js): change cx and apiKey fields to uppercase feat(manifest.json): add authConfig field for Stable Diffusion WebUI API URL refactor(stablediffusion.js): add url field to constructor and change getServerURL() to this.url refactor(wolfram.js): change apiKey field to uppercase WOLFRAM_APP_ID * refactor(handleTools.js): simplify tool loading and add support for custom tool constructors and options * refactor(handleTools.js): remove commented out code and unused imports * refactor(handleTools.js, index.js): change file name from wolfram.js to Wolfram.js and selfReflection.js to SelfReflection.js to follow PascalCase convention * refactor(outputParser.js, askGPTPlugins.js): improve code readability and remove unnecessary comments * feat(GoogleSearch.js): add GoogleSearchAPI tool to allow agents to use the Google Custom Search API feat(SelfReflection.js): add SelfReflectionTool to allow agents to reflect on their thoughts and actions feat(StableDiffusion.js): add StableDiffusionAPI tool to allow agents to generate images using stable diffusion webui's api feat(Wolfram.js): add WolframAlphaAPI tool for computation, math, curated knowledge & real-time data through WolframAlpha. * testing openai specs * doc: fix link in .env.example * package-update * fix(MultiSelectDropDown.jsx): handle null or undefined values in availableValues array * refactor(DALL-E.js, StableDiffusion.js): remove 'dist/' from image path feat(docker-compose.yml): add comments for reverse proxy configuration * chore(.gitignore): ignore client/public/images/ fix(DALL-E.js, StableDiffusion.js): change image path from dist/ to public/ feat(index.js): add support for serving static files from client/public/ directory * fix: remove selected tool when uninstalled * plugin options in progress * fix: fix issue with uninstalling a plugin that is in use and typescript errors * feat(gptPlugins): add Preset support for GPT Plugins endpoint feat(ChatAgent.js): add support for agentOptions object feat(convoSchema.js): add agentOptions field to conversation schema feat(defaults.js): add agentOptions object to defaults feat(presetSchema.js): add agentOptions field to preset schema feat(askGPTPlugins.js): add support for agentOptions object in request body feat(EditPresetDialog.jsx): add support for showing/hiding GPT Plugins agent settings feat(EditPresetDialog.jsx): add support for setting GPT Plugins agent options fix(EndpointOptionsDialog.jsx): change endpoint name from 'gptPlugins' to 'Plugins' feat(AgentSettings.jsx): add AgentSettings component for GPT plugins configuration feat(client): add GPT Plugins settings component and endpoint to Settings component fix(client): remove unused imports in GoogleOptions component feat(PluginsOptions): add support for agent settings and refactor code feat(PluginsOptions): add GPTIcon to show/hide agent settings button feat(index.ts): export SVG components feat(GPTIcon.jsx): add className prop to GPTIcon component feat(GPTIcon.jsx): import cn function from utils feat(BingIcon.tsx): export BingIcon component feat(index.ts): export BingIcon component feat(index.ts): export MessagesSquared component refactor(cleanupPreset.js): add default values for agentOptions in gptPlugins endpoint feat(getDefaultConversation.js, handleSubmit.js): add agentOptions object to conversation object for GPT plugins endpoint. Update default temperature value to 0.8. Add chatGptLabel and promptPrefix properties to conversation object. * fix: set default convo back to null * refactor(ChatAgent.js, askGPTPlugins.js, AgentSettings.jsx): change variable names for better readability and remove redundant code * test: add RecoilRoot to layout-test-utils * refactor(askGPTPlugins.js): remove redundant code and use endpointOption directly feat(askGPTPlugins.js): add validation for tools in endpointOption before using it * chore(ChatAgent.js, Settings.jsx): add agentOptions to saveConvo function and adjust Settings component height The ChatAgent.js file was modified to include the agentOptions object in the saveConvo function. The Settings.jsx file was modified to adjust the height of the component to ensure that all content is visible. * refactor(ChatAgent.js): extract reverseProxyUrl option to a class property and add support for it feat(ChatAgent.js): add support for completionMode option in sendApiMessage method feat(ChatAgent.js): add support for user-provided promptPrefix in buildPrompt method * feat(plugins): allow preset change mid conversation * chore: update OPENAI_KEY to OPENAI_API_KEY in .github/playwright.yml and api/.env.example refactor(chatgpt-client.js): update OPENAI_KEY to OPENAI_API_KEY feat(langchain): add demo-aiplugin.js and demo-yaml.js, remove test2.js, test3.js, and test4.js chore: remove unused test files fix(titleConvo.js): fix typo in environment variable name fix(askGPTPlugins.js): fix typo in environment variable name fix(endpoints.js): fix typo in environment variable name docs: update installation guide to use OPENAI_API_KEY instead of OPENAI_KEY in .env file * fix(index.test.js): change import of GoogleSearchAPI to use uppercase G in GoogleSearch * chore(api): bump langchain version * feat(PluginController.js): authenticate plugins from environment variables if they are set feat(PluginStoreDialog.tsx): show plugin auth form only if plugin is not authenticated by env var and require authentication feat(types.ts): add authenticated field to TPlugin type definition * docs: update google_search.md and add stable_diffusion.md * Update stable_diffusion.md * refactor(Wolfram.js): remove newline characters from query before encoding docs(wolfram.md): add instructions for setting WOLFRAM_APP_ID in api.env to bypass prompt for AppID in plugin * refactor(Wolfram.js): replace deprecated replaceAll method with replace method * Update wolfram.md * fix(askGPTPlugins): error message will reference correct Parent Message * refactor(chatgpt-client.js, ChatAgent.js): simplify maxContextTokens calculation and add promptPrefix parameter to buildPrompt method * docs: initial draft of intro to plugins * Update introduction.md * Update introduction.md * Feature: User/Reg cleanup + Install / Upgrade script for langchain (#427) * test: login tests * test: finish login tests * test: initial tests for registration * test: registration specs * feature: Init a app config file - Simplifies the ENV vars too - Legacy fallbacks for older builds * refactor(auth): Refactor log in/out controllers - Moves both login and logout controllers to their own file * chore(jwt): Throw warning if secret is default * feature(frontend): Ability to disable registration * feature(env): Env in the root + version support ie .env.prod, .env.dev, .env.test * feature: Upgrade .env script for users * chore(config): Refactor and remove legacy env refs * feature(upgrade): Upgrade script for .env changes * feature: Install script and upgrade script * bugfix: Uncomment line to remove old .env file * chore: rename OPENAI_KEY to OPENAI_API_KEY * chore: Cleanup config changes/bugs * bugfix: Fix config and node env issues * bugfix: Config validation logic * bugfix: Handle unusual env configs gracefully * bugfix: Revert route changes and fix registration disable calling * bugfix: Fix env issues in frontend * bugfix: Fix login * bugfix: Fix frontend envs * bugfix: Fix frontend jest tests * bugfix: Fix upgrade scripts * bugfix: Allow install in non-tty envs * bugfix(windows): Use cross-env to set for windows * bugfix(env): Handle .env being incorrect to begin with for client domain * chore(merge-conflict): Update to LibreChat * chore(merge-conflict): Update to package-lock --------- Co-authored-by: Daniel D Orlando <dan@danorlando.com> * chore: comment out unused agent options * Update langchain plugins docs (#461) * Update: install docs (LibreChat) (#458) * Release: rename project from ChatGPT Clone to LibreChat Release: rename project from ChatGPT Clone to LibreChat * Release: rename project from ChatGPT Clone to LibreChat Release: rename project from ChatGPT Clone to LibreChat * Release: rename project from ChatGPT Clone to LibreChat Release: rename project from ChatGPT Clone to LibreChat * Release: rename project from ChatGPT Clone to LibreChat Release: rename project from ChatGPT Clone to LibreChat * Update documentation_guidelines.md * Update introduction.md add link to readme * Update stable_diffusion.md add link back to readme * Update wolfram.md add link back to readme * Update README.md add Plugins to ToC * feat(ChatAgent.js): add support for langchainProxy configuration option Add a new configuration option `langchainProxy` to the ChatAgent class. If the option is set, the `basePath` configuration option of the `ChatOpenAI` instance is set to the base path of `langchainProxy`. * bugfix(errors): Possible workaround for error flashing (#463) * Test/user auth system client tests (#462) * test: login tests * test: finish login tests * test: initial tests for registration * test: registration specs * chore(api): update langchain dependency to version 0.0.91 * Update introduction.md * Update introduction.md * Update introduction.md * fix: no longer renders html in markdown content fix: patch XSS vulnerability completely by handling cursor on the frontend without css/html * fix(Content.jsx): fix cursor logic so it never shows for static messages * bugfix(langchain): Upgrade script, docker, env and docs (#465) * bugfix(errors): Remove incorrect manual fix from misunderstanding * chore(env): Lets not make a .env.prod and use the prod values in the default root .env - .env.dev will still be created * chore(upgrade.js): Lets tell the user about .env.dev if we create it * bugfix(env): Move to full name environments for vite - .env.prod => .env.production - .env.dev => .env.development * chore(env-example): Explain how to get google login working in production * bugfix(oauth): Minor fix to point isProduction to a correct value * bugfix: Typo in public * chore(docs): Update docs to note the changes to .env * chore(docs): Include note on how to get google auth working in dev and how to disable registration * bugfix: Fix missing env changes * bugfix: Fix up docker to work with new env / npm changes * Update .env.example Cleanup the env of the palm2 instruction and fix to formating * chore(docker): Simplify Docker deployments - Needs work to support dev env/hotreload * bugfix: Remove volume map for client dir * chore(env-example): Change instructions to be more user centric --------- Co-authored-by: Fuegovic <32828263+fuegovic@users.noreply.github.com> * update: install docs (#466) * Add files via upload * Update apis-and-tokens.md * Update apis-and-tokens.md * Update docker_install.md * Update linux_install.md * Rename apis-and-tokens.md to apis_and_tokens.md * Update docker_install.md * Update linux_install.md * Update mac_install.md * Update linux_install.md * Update docker_install.md * Update windows_install.md * Update apis_and_tokens.md * Update mac_install.md * Update linux_install.md * Update docker_install.md * Update README.md * Update README.md : Breaking Changes --------- Co-authored-by: Danny Avila <110412045+danny-avila@users.noreply.github.com> * Update README.md (#468) add new API/Token docs to Toc * docs: guide on how to create your own plugin * Update make_your_own.md * Update make_your_own.md * feat(docker): add build args for frontend variables in Dockerfile feat(docker-compose): add build args for frontend variables in docker-compose.yml * Update docker_install.md * Update docker_install.md * Update docker_install.md * Update docker_install.md * docs: update (#469) * Update: make_your_own.md * Update README.md add `make_your_own.md` to ToC * Update linux_install.md * Update mac_install.md * Update windows_install.md * Update apis_and_tokens.md * Update docker_install.md * Update docker_install.md * Update linux_install.md * Update mac_install.md * Update windows_install.md * Update apis_and_tokens.md * Update user_auth_system.md * Update docker_install.md clean up of repeated information * Update docker_install.md * Update docker_install.md typo * fix: fix issue with pluginstore next and prev buttons going out of bounds * fix: add icon for web browser plugin * docs(GoogleSearch.js): update description of GoogleSearchAPI class to be more descriptive of its functionality * feat(ask/handlers.js): add cursor to indicate ongoing progress of a long-running task fix(Content.jsx): handle null content in the message stream by replacing it with an empty string (with a space so a text space is rendered) * Update README.md * Update README.md * fix: plugin option stacking order * update: web browser icon (#470) * Delete web-browser.png * update: web browser icon * Update readme (#472) * Update README.md Discord badge now displays the number of online users Project description has been updated to reflect current status Feature section has been updated to reflect current capabilities Sponsors section is now located just above the contributors section Roadmap has been removed as it was outdated. * Delete roadmap.md Roadmap has been removed to streamline document maintenance. * Update README.md * Update README.md * Delete CHANGELOG.md * fix: pluginstore in mobile view getting clipped and not scrolling * docs(linux_install.md): remove duplicate git clone command * chore(Dockerfile): comment out nginx-client build stage docs(README.md): update installation instructions and mention docker-compose changes docs(features/plugins/introduction.md): bold plugin names and add emphasis to notes * feat: add superscript and subscript support to markdown rendering refactor: support markdown citations for BingAI * refactor: support markdown citations for BingAI --------- Co-authored-by: David Shin <42793498+dncc89@users.noreply.github.com> Co-authored-by: Daniel D Orlando <dan@danorlando.com> Co-authored-by: LaraClara <2524209+ClaraLeigh@users.noreply.github.com> Co-authored-by: Fuegovic <32828263+fuegovic@users.noreply.github.com>
2023-06-10 19:10:03 -04:00
const getAvailablePluginsController = async (req, res) => {
try {
const cache = getLogStores(CacheKeys.TOOL_CACHE);
🏗️ feat: bulkWrite isolation, pre-auth context, strict-mode fixes (#12445) * fix: wrap seedDatabase() in runAsSystem() for strict tenant mode seedDatabase() was called without tenant context at startup, causing every Mongoose operation inside it to throw when TENANT_ISOLATION_STRICT=true. Wrapping in runAsSystem() gives it the SYSTEM_TENANT_ID sentinel so the isolation plugin skips filtering, matching the pattern already used for performStartupChecks and updateInterfacePermissions. * fix: chain tenantContextMiddleware in optionalJwtAuth optionalJwtAuth populated req.user but never established ALS tenant context, unlike requireJwtAuth which chains tenantContextMiddleware after successful auth. Authenticated users hitting routes with optionalJwtAuth (e.g. /api/banner) had no tenant isolation. * feat: tenant-safe bulkWrite wrapper and call-site migration Mongoose's bulkWrite() does not trigger schema-level middleware hooks, so the applyTenantIsolation plugin cannot intercept it. This adds a tenantSafeBulkWrite() utility that injects the current ALS tenant context into every operation's filter/document before delegating to native bulkWrite. Migrates all 8 runtime bulkWrite call sites: - agentCategory (seedCategories, ensureDefaultCategories) - conversation (bulkSaveConvos) - message (bulkSaveMessages) - file (batchUpdateFiles) - conversationTag (updateTagsForConversation, bulkIncrementTagCounts) - aclEntry (bulkWriteAclEntries) systemGrant.seedSystemGrants is intentionally not migrated — it uses explicit tenantId: { $exists: false } filters and is exempt from the isolation plugin. * feat: pre-auth tenant middleware and tenant-scoped config cache Adds preAuthTenantMiddleware that reads X-Tenant-Id from the request header and wraps downstream in tenantStorage ALS context. Wired onto /oauth, /api/auth, /api/config, and /api/share — unauthenticated routes that need tenant scoping before JWT auth runs. The /api/config cache key is now tenant-scoped (STARTUP_CONFIG:${tenantId}) so multi-tenant deployments serve the correct login page config per tenant. The middleware is intentionally minimal — no subdomain parsing, no OIDC claim extraction. The private fork's reverse proxy or auth gateway sets the header. * feat: accept optional tenantId in updateInterfacePermissions When tenantId is provided, the function re-enters inside tenantStorage.run({ tenantId }) so all downstream Mongoose queries target that tenant's roles instead of the system context. This lets the private fork's tenant provisioning flow call updateInterfacePermissions per-tenant after creating tenant-scoped ADMIN/USER roles. * fix: tenant-filter $lookup in getPromptGroup aggregation The $lookup stage in getPromptGroup() queried the prompts collection without tenant filtering. While the outer PromptGroup aggregate is protected by the tenantIsolation plugin's pre('aggregate') hook, $lookup runs as an internal MongoDB operation that bypasses Mongoose hooks entirely. Converts from simple field-based $lookup to pipeline-based $lookup with an explicit tenantId match when tenant context is active. * fix: replace field-level unique indexes with tenant-scoped compounds Field-level unique:true creates a globally-unique single-field index in MongoDB, which would cause insert failures across tenants sharing the same ID values. - agent.id: removed field-level unique, added { id, tenantId } compound - convo.conversationId: removed field-level unique (compound at line 50 already exists: { conversationId, user, tenantId }) - message.messageId: removed field-level unique (compound at line 165 already exists: { messageId, user, tenantId }) - preset.presetId: removed field-level unique, added { presetId, tenantId } compound * fix: scope MODELS_CONFIG, ENDPOINT_CONFIG, PLUGINS, TOOLS caches by tenant These caches store per-tenant configuration (available models, endpoint settings, plugin availability, tool definitions) but were using global cache keys. In multi-tenant mode, one tenant's cached config would be served to all tenants. Appends :${tenantId} to cache keys when tenant context is active. Falls back to the unscoped key when no tenant context exists (backward compatible for single-tenant OSS deployments). Covers all read, write, and delete sites: - ModelController.js: get/set MODELS_CONFIG - PluginController.js: get/set PLUGINS, get/set TOOLS - getEndpointsConfig.js: get/set/delete ENDPOINT_CONFIG - app.js: delete ENDPOINT_CONFIG (clearEndpointConfigCache) - mcp.js: delete TOOLS (updateMCPTools, mergeAppTools) - importers.js: get ENDPOINT_CONFIG * fix: add getTenantId to PluginController spec mock The data-schemas mock was missing getTenantId, causing all PluginController tests to throw when the controller calls getTenantId() for tenant-scoped cache keys. * fix: address review findings — migration, strict-mode, DRY, types Addresses all CRITICAL, MAJOR, and MINOR review findings: F1 (CRITICAL): Add agents, conversations, messages, presets to SUPERSEDED_INDEXES in tenantIndexes.ts so dropSupersededTenantIndexes() drops the old single-field unique indexes that block multi-tenant inserts. F2 (CRITICAL): Unknown bulkWrite op types now throw in strict mode instead of silently passing through without tenant injection. F3 (MAJOR): Replace wildcard export with named export for tenantSafeBulkWrite, hiding _resetBulkWriteStrictCache from the public package API. F5 (MAJOR): Restore AnyBulkWriteOperation<IAclEntry>[] typing on bulkWriteAclEntries — the unparameterized wrapper accepts parameterized ops as a subtype. F7 (MAJOR): Fix config.js tenant precedence — JWT-derived req.user.tenantId now takes priority over the X-Tenant-Id header for authenticated requests. F8 (MINOR): Extract scopedCacheKey() helper into tenantContext.ts and replace all 11 inline occurrences across 7 files. F9 (MINOR): Use simple localField/foreignField $lookup for the non-tenant getPromptGroup path (more efficient index seeks). F12 (NIT): Remove redundant BulkOp type alias. F13 (NIT): Remove debug log that leaked raw tenantId. * fix: add new superseded indexes to tenantIndexes test fixture The test creates old indexes to verify the migration drops them. Missing fixture entries for agents.id_1, conversations.conversationId_1, messages.messageId_1, and presets.presetId_1 caused the count assertion to fail (expected 22, got 18). * fix: restore logger.warn for unknown bulk op types in non-strict mode * fix: block SYSTEM_TENANT_ID sentinel from external header input CRITICAL: preAuthTenantMiddleware accepted any string as X-Tenant-Id, including '__SYSTEM__'. The tenantIsolation plugin treats SYSTEM_TENANT_ID as an explicit bypass — skipping ALL query filters. A client sending X-Tenant-Id: __SYSTEM__ to pre-auth routes (/api/share, /api/config, /api/auth, /oauth) would execute Mongoose operations without tenant isolation. Fixes: - preAuthTenantMiddleware rejects SYSTEM_TENANT_ID in header - scopedCacheKey returns the base key (not key:__SYSTEM__) in system context, preventing stale cache entries during runAsSystem() - updateInterfacePermissions guards tenantId against SYSTEM_TENANT_ID - $lookup pipeline separates $expr join from constant tenantId match for better index utilization - Regression test for sentinel rejection in preAuthTenant.spec.ts - Remove redundant getTenantId() call in config.js * test: add missing deleteMany/replaceOne coverage, fix vacuous ALS assertions bulkWrite spec: - deleteMany: verifies tenant-scoped deletion leaves other tenants untouched - replaceOne: verifies tenantId injected into both filter and replacement - replaceOne overwrite: verifies a conflicting tenantId in the replacement document is overwritten by the ALS tenant (defense-in-depth) - empty ops array: verifies graceful handling preAuthTenant spec: - All negative-case tests now use the capturedNext pattern to verify getTenantId() inside the middleware's execution context, not the test runner's outer frame (which was always undefined regardless) * feat: tenant-isolate MESSAGES cache, FLOWS cache, and GenerationJobManager MESSAGES cache (streamAudio.js): - Cache key now uses scopedCacheKey(messageId) to prefix with tenantId, preventing cross-tenant message content reads during TTS streaming. FLOWS cache (FlowStateManager): - getFlowKey() now generates ${type}:${tenantId}:${flowId} when tenant context is active, isolating OAuth flow state per tenant. GenerationJobManager: - tenantId added to SerializableJobData and GenerationJobMetadata - createJob() captures the current ALS tenant context (excluding SYSTEM_TENANT_ID) and stores it in job metadata - SSE subscription endpoint validates job.metadata.tenantId matches req.user.tenantId, blocking cross-tenant stream access - Both InMemoryJobStore and RedisJobStore updated to accept tenantId * fix: add getTenantId and SYSTEM_TENANT_ID to MCP OAuth test mocks FlowStateManager.getFlowKey() now calls getTenantId() for tenant-scoped flow keys. The 4 MCP OAuth test files mock @librechat/data-schemas without these exports, causing TypeError at runtime. * fix: correct import ordering per AGENTS.md conventions Package imports sorted shortest to longest line length, local imports sorted longest to shortest — fixes ordering violations introduced by our new imports across 8 files. * fix: deserialize tenantId in RedisJobStore — cross-tenant SSE guard was no-op in Redis mode serializeJob() writes tenantId to the Redis hash via Object.entries, but deserializeJob() manually enumerates fields and omitted tenantId. Every getJob() from Redis returned tenantId: undefined, causing the SSE route's cross-tenant guard to short-circuit (undefined && ... → false). * test: SSE tenant guard, FlowStateManager key consistency, ALS scope docs SSE stream tenant tests (streamTenant.spec.js): - Cross-tenant user accessing another tenant's stream → 403 - Same-tenant user accessing own stream → allowed - OSS mode (no tenantId on job) → tenant check skipped FlowStateManager tenant tests (manager.tenant.spec.ts): - completeFlow finds flow created under same tenant context - completeFlow does NOT find flow under different tenant context - Unscoped flows are separate from tenant-scoped flows Documentation: - JSDoc on getFlowKey documenting ALS context consistency requirement - Comment on streamAudio.js scopedCacheKey capture site * fix: SSE stream tests hang on success path, remove internal fork references The success-path tests entered the SSE streaming code which never closes, causing timeout. Mock subscribe() to end the response immediately. Restructured assertions to verify non-403/non-404. Removed "private fork" and "OSS" references from code and test descriptions — replaced with "deployment layer", "multi-tenant deployments", and "single-tenant mode". * fix: address review findings — test rigor, tenant ID validation, docs F1: SSE stream tests now mock subscribe() with correct signature (streamId, writeEvent, onDone, onError) and assert 200 status, verifying the tenant guard actually allows through same-tenant users. F2: completeFlow logs the attempted key and ALS tenantId when flow is not found, so reverse proxy misconfiguration (missing X-Tenant-Id on OAuth callback) produces an actionable warning. F3/F10: preAuthTenantMiddleware validates tenant ID format — rejects colons, special characters, and values exceeding 128 chars. Trims whitespace. Prevents cache key collisions via crafted headers. F4: Documented cache invalidation scope limitation in clearEndpointConfigCache — only the calling tenant's key is cleared; other tenants expire via TTL. F7: getFlowKey JSDoc now lists all 8 methods requiring consistent ALS context. F8: Added dedicated scopedCacheKey unit tests — base key without context, base key in system context, scoped key with tenant, no ALS leakage across scope boundaries. * fix: revert flow key tenant scoping, fix SSE test timing FlowStateManager: Reverts tenant-scoped flow keys. OAuth callbacks arrive without tenant ALS context (provider redirects don't carry X-Tenant-Id), so completeFlow/failFlow would never find flows created under tenant context. Flow IDs are random UUIDs with no collision risk, and flow data is ephemeral (TTL-bounded). SSE tests: Use process.nextTick for onDone callback so Express response headers are flushed before res.write/res.end are called. * fix: restore getTenantId import for completeFlow diagnostic log * fix: correct completeFlow warning message, add missing flow test The warning referenced X-Tenant-Id header consistency which was only relevant when flow keys were tenant-scoped (since reverted). Updated to list actual causes: TTL expiry, missing flow, or routing to a different instance without shared Keyv storage. Removed the getTenantId() call and import — no longer needed since flow keys are unscoped. Added test for the !flowState branch in completeFlow — verifies return false and logger.warn on nonexistent flow ID. * fix: add explicit return type to recursive updateInterfacePermissions The recursive call (tenantId branch calls itself without tenantId) causes TypeScript to infer circular return type 'any'. Adding explicit Promise<void> satisfies the rollup typescript plugin. * fix: update MCPOAuthRaceCondition test to match new completeFlow warning * fix: clearEndpointConfigCache deletes both scoped and unscoped keys Unauthenticated /api/endpoints requests populate the unscoped ENDPOINT_CONFIG key. Admin config mutations clear only the tenant-scoped key, leaving the unscoped entry stale indefinitely. Now deletes both when in tenant context. * fix: tenant guard on abort/status endpoints, warn logs, test coverage F1: Add tenant guard to /chat/status/:conversationId and /chat/abort matching the existing guard on /chat/stream/:streamId. The status endpoint exposes aggregatedContent (AI response text) which requires tenant-level access control. F2: preAuthTenantMiddleware now logs warn for rejected __SYSTEM__ sentinel and malformed tenant IDs, providing observability for bypass probing attempts. F3: Abort fallback path (getActiveJobIdsForUser) now has tenant check after resolving the job. F4: Test for strict mode + SYSTEM_TENANT_ID — verifies runAsSystem bypasses tenantSafeBulkWrite without throwing in strict mode. F5: Test for job with tenantId + user without tenantId → 403. F10: Regex uses idiomatic hyphen-at-start form. F11: Test descriptions changed from "rejects" to "ignores" since middleware calls next() (not 4xx). Also fixes MCPOAuthRaceCondition test assertion to match updated completeFlow warning message. * fix: test coverage for logger.warn, status/abort guards, consistency A: preAuthTenant spec now mocks logger and asserts warn calls for __SYSTEM__ sentinel, malformed characters, and oversized headers. B: streamTenant spec expanded with status and abort endpoint tests — cross-tenant status returns 403, same-tenant returns 200 with body, cross-tenant abort returns 403. C: Abort endpoint uses req.user.tenantId (not req.user?.tenantId) matching stream/status pattern — requireJwtAuth guarantees req.user. D: Malformed header warning now includes ip in log metadata, matching the sentinel warning for consistent SOC correlation. * fix: assert ip field in malformed header warn tests * fix: parallelize cache deletes, document tenant guard, fix import order - clearEndpointConfigCache uses Promise.all for independent cache deletes instead of sequential awaits - SSE stream tenant guard has inline comment explaining backward-compat behavior for untenanted legacy jobs - conversation.ts local imports reordered longest-to-shortest per AGENTS.md * fix: tenant-qualify userJobs keys, document tenant guard backward-compat Job store userJobs keys now include tenantId when available: - Redis: stream:user:{tenantId:userId}:jobs (falls back to stream:user:{userId}:jobs when no tenant) - InMemory: composite key tenantId:userId in userJobMap getActiveJobIdsByUser/getActiveJobIdsForUser accept optional tenantId parameter, threaded through from req.user.tenantId at all call sites (/chat/active and /chat/abort fallback). Added inline comments on all three SSE tenant guards explaining the backward-compat design: untenanted legacy jobs remain accessible when the userId check passes. * fix: parallelize cache deletes, document tenant guard, fix import order Fix InMemoryJobStore.getActiveJobIdsByUser empty-set cleanup to use the tenant-qualified userKey instead of bare userId — prevents orphaned empty Sets accumulating in userJobMap for multi-tenant users. Document cross-tenant staleness in clearEndpointConfigCache JSDoc — other tenants' scoped keys expire via TTL, not active invalidation. * fix: cleanup userJobMap leak, startup warning, DRY tenant guard, docs F1: InMemoryJobStore.cleanup() now removes entries from userJobMap before calling deleteJob, preventing orphaned empty Sets from accumulating with tenant-qualified composite keys. F2: Startup warning when TENANT_ISOLATION_STRICT is active — reminds operators to configure reverse proxy to control X-Tenant-Id header. F3: mergeAppTools JSDoc documents that tenant-scoped TOOLS keys are not actively invalidated (matching clearEndpointConfigCache pattern). F5: Abort handler getActiveJobIdsForUser call uses req.user.tenantId (not req.user?.tenantId) — consistent with stream/status handlers. F6: updateInterfacePermissions JSDoc clarifies SYSTEM_TENANT_ID behavior — falls through to caller's ALS context. F7: Extracted hasTenantMismatch() helper, replacing three identical inline tenant guard blocks across stream/status/abort endpoints. F9: scopedCacheKey JSDoc documents both passthrough cases (no context and SYSTEM_TENANT_ID context). * fix: clean userJobMap in evictOldest — same leak as cleanup()
2026-03-28 16:43:50 -04:00
const pluginsCacheKey = scopedCacheKey(CacheKeys.PLUGINS);
const cachedPlugins = await cache.get(pluginsCacheKey);
if (cachedPlugins) {
res.status(200).json(cachedPlugins);
return;
}
🧵 feat: ALS Context Middleware, Tenant Threading, and Config Cache Invalidation (#12407) * feat: add tenant context middleware for ALS-based isolation Introduces tenantContextMiddleware that propagates req.user.tenantId into AsyncLocalStorage, activating the Mongoose applyTenantIsolation plugin for all downstream DB queries within a request. - Strict mode (TENANT_ISOLATION_STRICT=true) returns 403 if no tenantId - Non-strict mode passes through for backward compatibility - No-op for unauthenticated requests - Includes 6 unit tests covering all paths * feat: register tenant middleware and wrap startup/auth in runAsSystem() - Register tenantContextMiddleware in Express app after capability middleware - Wrap server startup initialization in runAsSystem() for strict mode compat - Wrap auth strategy getAppConfig() calls in runAsSystem() since they run before user context is established (LDAP, SAML, OpenID, social login, AuthService) * feat: thread tenantId through all getAppConfig callers Pass tenantId from req.user to getAppConfig() across all callers that have request context, ensuring correct per-tenant cache key resolution. Also fixes getBaseConfig admin endpoint to scope to requesting admin's tenant instead of returning the unscoped base config. Files updated: - Controllers: UserController, PluginController - Middleware: checkDomainAllowed, balance - Routes: config - Services: loadConfigModels, loadDefaultModels, getEndpointsConfig, MCP - Audio services: TTSService, STTService, getVoices, getCustomConfigSpeech - Admin: getBaseConfig endpoint * feat: add config cache invalidation on admin mutations - Add clearOverrideCache(tenantId?) to flush per-principal override caches by enumerating Keyv store keys matching _OVERRIDE_: prefix - Add invalidateConfigCaches() helper that clears base config, override caches, tool caches, and endpoint config cache in one call - Wire invalidation into all 5 admin config mutation handlers (upsert, patch, delete field, delete overrides, toggle active) - Add strict mode warning when __default__ tenant fallback is used - Add 3 new tests for clearOverrideCache (all/scoped/base-preserving) * chore: update getUserPrincipals comment to reflect ALS-based tenant filtering The TODO(#12091) about missing tenantId filtering is resolved by the tenant context middleware + applyTenantIsolation Mongoose plugin. Group queries are now automatically scoped by tenantId via ALS. * fix: replace runAsSystem with baseOnly for pre-tenant code paths App configs are tenant-owned — runAsSystem() would bypass tenant isolation and return cross-tenant DB overrides. Instead, add baseOnly option to getAppConfig() that returns YAML-derived config only, with zero DB queries. All startup code, auth strategies, and MCP initialization now use getAppConfig({ baseOnly: true }) to get the YAML config without touching the Config collection. * fix: address PR review findings — middleware ordering, types, cache safety - Chain tenantContextMiddleware inside requireJwtAuth after passport auth instead of global app.use() where req.user is always undefined (Finding 1) - Remove global tenantContextMiddleware registration from index.js - Update BalanceMiddlewareOptions to include tenantId, remove redundant cast (Finding 4) - Add warning log when clearOverrideCache cannot enumerate keys on Redis (Finding 3) - Use startsWith instead of includes for cache key filtering (Finding 12) - Use generator loop instead of Array.from for key enumeration (Finding 3) - Selective barrel export — exclude _resetTenantMiddlewareStrictCache (Finding 5) - Move isMainThread check to module level, remove per-request check (Finding 9) - Move mid-file require to top of app.js (Finding 8) - Parallelize invalidateConfigCaches with Promise.all (Finding 10) - Remove clearOverrideCache from public app.js exports (internal only) - Strengthen getUserPrincipals comment re: ALS dependency (Finding 2) * fix: restore runAsSystem for startup DB ops, consolidate require, clarify baseOnly - Restore runAsSystem() around performStartupChecks, updateInterfacePermissions, initializeMCPs, and initializeOAuthReconnectManager — these make Mongoose queries that need system context in strict tenant mode (NEW-3) - Consolidate duplicate require('@librechat/api') in requireJwtAuth.js (NEW-1) - Document that baseOnly ignores role/userId/tenantId in JSDoc (NEW-2) * test: add requireJwtAuth tenant chaining + invalidateConfigCaches tests - requireJwtAuth: 5 tests verifying ALS tenant context is set after passport auth, isolated between concurrent requests, and not set when user has no tenantId (Finding 6) - invalidateConfigCaches: 4 tests verifying all four caches are cleared, tenantId is threaded through, partial failure is handled gracefully, and operations run in parallel via Promise.all (Finding 11) * fix: address Copilot review — passport errors, namespaced cache keys, /base scoping - Forward passport errors in requireJwtAuth before entering tenant middleware — prevents silent auth failures from reaching handlers (P1) - Account for Keyv namespace prefix in clearOverrideCache — stored keys are namespaced as "APP_CONFIG:_OVERRIDE_:..." not "_OVERRIDE_:...", so override caches were never actually matched/cleared (P2) - Remove role from getBaseConfig — /base should return tenant-scoped base config, not role-merged config that drifts per admin role (P2) - Return tenantStorage.run() for cleaner async semantics - Update mock cache in service.spec.ts to simulate Keyv namespacing * fix: address second review — cache safety, code quality, test reliability - Decouple cache invalidation from mutation response: fire-and-forget with logging so DB mutation success is not masked by cache failures - Extract clearEndpointConfigCache helper from inline IIFE - Move isMainThread check to lazy once-per-process guard (no import side effect) - Memoize process.env read in overrideCacheKey to avoid per-request env lookups and log flooding in strict mode - Remove flaky timer-based parallelism assertion, use structural check - Merge orphaned double JSDoc block on getUserPrincipals - Fix stale [getAppConfig] log prefix → [ensureBaseConfig] - Fix import order in tenant.spec.ts (package types before local values) - Replace "Finding 1" reference with self-contained description - Use real tenantStorage primitives in requireJwtAuth spec mock * fix: move JSDoc to correct function after clearEndpointConfigCache extraction * refactor: remove Redis SCAN from clearOverrideCache, rely on TTL expiry Redis SCAN causes 60s+ stalls under concurrent load (see #12410). APP_CONFIG defaults to FORCED_IN_MEMORY_CACHE_NAMESPACES, so the in-memory store.keys() path handles the standard case. When APP_CONFIG is Redis-backed, overrides expire naturally via overrideCacheTtl (60s default) — an acceptable window for admin config mutations. * fix: remove return from tenantStorage.run to satisfy void middleware signature * fix: address second review — cache safety, code quality, test reliability - Switch invalidateConfigCaches from Promise.all to Promise.allSettled so partial failures are logged individually instead of producing one undifferentiated error (Finding 3) - Gate overrideCacheKey strict-mode warning behind a once-per-process flag to prevent log flooding under load (Finding 4) - Add test for passport error forwarding in requireJwtAuth — the if (err) { return next(err) } branch now has coverage (Finding 5) - Add test for real partial failure in invalidateConfigCaches where clearAppConfigCache rejects (not just the swallowed endpoint error) * chore: reorder imports in index.js and app.js for consistency - Moved logger and runAsSystem imports to maintain a consistent import order across files. - Improved code readability by ensuring related imports are grouped together.
2026-03-26 17:35:00 -04:00
const appConfig = await getAppConfig({ role: req.user?.role, tenantId: req.user?.tenantId });
/** @type {{ filteredTools: string[], includedTools: string[] }} */
🛜 refactor: Streamline App Config Usage (#9234) * WIP: app.locals refactoring WIP: appConfig fix: update memory configuration retrieval to use getAppConfig based on user role fix: update comment for AppConfig interface to clarify purpose 🏷️ refactor: Update tests to use getAppConfig for endpoint configurations ci: Update AppService tests to initialize app config instead of app.locals ci: Integrate getAppConfig into remaining tests refactor: Update multer storage destination to use promise-based getAppConfig and improve error handling in tests refactor: Rename initializeAppConfig to setAppConfig and update related tests ci: Mock getAppConfig in various tests to provide default configurations refactor: Update convertMCPToolsToPlugins to use mcpManager for server configuration and adjust related tests chore: rename `Config/getAppConfig` -> `Config/app` fix: streamline OpenAI image tools configuration by removing direct appConfig dependency and using function parameters chore: correct parameter documentation for imageOutputType in ToolService.js refactor: remove `getCustomConfig` dependency in config route refactor: update domain validation to use appConfig for allowed domains refactor: use appConfig registration property chore: remove app parameter from AppService invocation refactor: update AppConfig interface to correct registration and turnstile configurations refactor: remove getCustomConfig dependency and use getAppConfig in PluginController, multer, and MCP services refactor: replace getCustomConfig with getAppConfig in STTService, TTSService, and related files refactor: replace getCustomConfig with getAppConfig in Conversation and Message models, update tempChatRetention functions to use AppConfig type refactor: update getAppConfig calls in Conversation and Message models to include user role for temporary chat expiration ci: update related tests refactor: update getAppConfig call in getCustomConfigSpeech to include user role fix: update appConfig usage to access allowedDomains from actions instead of registration refactor: enhance AppConfig to include fileStrategies and update related file strategy logic refactor: update imports to use normalizeEndpointName from @librechat/api and remove redundant definitions chore: remove deprecated unused RunManager refactor: get balance config primarily from appConfig refactor: remove customConfig dependency for appConfig and streamline loadConfigModels logic refactor: remove getCustomConfig usage and use app config in file citations refactor: consolidate endpoint loading logic into loadEndpoints function refactor: update appConfig access to use endpoints structure across various services refactor: implement custom endpoints configuration and streamline endpoint loading logic refactor: update getAppConfig call to include user role parameter refactor: streamline endpoint configuration and enhance appConfig usage across services refactor: replace getMCPAuthMap with getUserMCPAuthMap and remove unused getCustomConfig file refactor: add type annotation for loadedEndpoints in loadEndpoints function refactor: move /services/Files/images/parse to TS API chore: add missing FILE_CITATIONS permission to IRole interface refactor: restructure toolkits to TS API refactor: separate manifest logic into its own module refactor: consolidate tool loading logic into a new tools module for startup logic refactor: move interface config logic to TS API refactor: migrate checkEmailConfig to TypeScript and update imports refactor: add FunctionTool interface and availableTools to AppConfig refactor: decouple caching and DB operations from AppService, make part of consolidated `getAppConfig` WIP: fix tests * fix: rebase conflicts * refactor: remove app.locals references * refactor: replace getBalanceConfig with getAppConfig in various strategies and middleware * refactor: replace appConfig?.balance with getBalanceConfig in various controllers and clients * test: add balance configuration to titleConvo method in AgentClient tests * chore: remove unused `openai-chat-tokens` package * chore: remove unused imports in initializeMCPs.js * refactor: update balance configuration to use getAppConfig instead of getBalanceConfig * refactor: integrate configMiddleware for centralized configuration handling * refactor: optimize email domain validation by removing unnecessary async calls * refactor: simplify multer storage configuration by removing async calls * refactor: reorder imports for better readability in user.js * refactor: replace getAppConfig calls with req.config for improved performance * chore: replace getAppConfig calls with req.config in tests for centralized configuration handling * chore: remove unused override config * refactor: add configMiddleware to endpoint route and replace getAppConfig with req.config * chore: remove customConfig parameter from TTSService constructor * refactor: pass appConfig from request to processFileCitations for improved configuration handling * refactor: remove configMiddleware from endpoint route and retrieve appConfig directly in getEndpointsConfig if not in `req.config` * test: add mockAppConfig to processFileCitations tests for improved configuration handling * fix: pass req.config to hasCustomUserVars and call without await after synchronous refactor * fix: type safety in useExportConversation * refactor: retrieve appConfig using getAppConfig in PluginController and remove configMiddleware from plugins route, to avoid always retrieving when plugins are cached * chore: change `MongoUser` typedef to `IUser` * fix: Add `user` and `config` fields to ServerRequest and update JSDoc type annotations from Express.Request to ServerRequest * fix: remove unused setAppConfig mock from Server configuration tests
2025-08-26 12:10:18 -04:00
const { filteredTools = [], includedTools = [] } = appConfig;
/** @type {import('@librechat/api').LCManifestTool[]} */
const pluginManifest = availableTools;
const uniquePlugins = filterUniquePlugins(pluginManifest);
let authenticatedPlugins = [];
for (const plugin of uniquePlugins) {
authenticatedPlugins.push(
🚧 WIP: Merge Dev Build (#4611) * refactor: Agent CodeFiles, abortUpload WIP * feat: code environment file upload * refactor: useLazyEffect * refactor: - Add `watch` from `useFormContext` to check if code execution is enabled - Disable file upload button if `agent_id` is not selected or code execution is disabled * WIP: primeCodeFiles; refactor: rename sessionId to session_id for uniformity * Refactor: Rename session_id to sessionId for uniformity in AuthService.js * chore: bump @librechat/agents to version 1.7.1 * WIP: prime code files * refactor: Update code env file upload method to use read stream * feat: reupload code env file if no longer active * refactor: isAssistantTool -> isEntityTool + address type issues * feat: execute code tool hook * refactor: Rename isPluginAuthenticated to checkPluginAuth in PluginController.js * refactor: Update PluginController.js to use AuthType constant for comparison * feat: verify tool authentication (execute_code) * feat: enter librechat_code_api_key * refactor: Remove unused imports in BookmarkForm.tsx * feat: authenticate code tool * refactor: Update Action.tsx to conditionally render the key and revoke key buttons * refactor(Code/Action): prevent uncheck-able 'Run Code' capability when key is revoked * refactor(Code/Action): Update Action.tsx to conditionally render the key and revoke key buttons * fix: agent file upload edge cases * chore: bump @librechat/agents * fix: custom endpoint providerValue icon * feat: ollama meta modal token values + context * feat: ollama agents * refactor: Update token models for Ollama models * chore: Comment out CodeForm * refactor: Update token models for Ollama and Meta models
2024-11-01 18:36:39 -04:00
checkPluginAuth(plugin) ? { ...plugin, authenticated: true } : plugin,
);
}
🤖 feat: Model Specs & Save Tools per Convo/Preset (#2578) * WIP: first pass ModelSpecs * refactor(onSelectEndpoint): use `getConvoSwitchLogic` * feat: introduce iconURL, greeting, frontend fields for conversations/presets/messages * feat: conversation.iconURL & greeting in Landing * feat: conversation.iconURL & greeting in New Chat button * feat: message.iconURL * refactor: ConversationIcon -> ConvoIconURL * WIP: add spec as a conversation field * refactor: useAppStartup, set spec on initial load for new chat, allow undefined spec, add localStorage keys enum, additional type fields for spec * feat: handle `showIconInMenu`, `showIconInHeader`, undefined `iconURL` and no specs on initial load * chore: handle undefined or empty modelSpecs * WIP: first pass, modelSpec schema for custom config * refactor: move default filtered tools definition to ToolService * feat: pass modelSpecs from backend via startupConfig * refactor: modelSpecs config, return and define list * fix: react error and include iconURL in responseMessage * refactor: add iconURL to responseMessage only * refactor: getIconEndpoint * refactor: pass TSpecsConfig * fix(assistants): differentiate compactAssistantSchema, correctly resets shared conversation state with other endpoints * refactor: assistant id prefix localStorage key * refactor: add more LocalStorageKeys and replace hardcoded values * feat: prioritize spec on new chat behavior: last selected modelSpec behavior (localStorage) * feat: first pass, interface config * chore: WIP, todo: add warnings based on config.modelSpecs settings. * feat: enforce modelSpecs if configured * feat: show config file yaml errors * chore: delete unused legacy Plugins component * refactor: set tools to localStorage from recoil store * chore: add stable recoil setter to useEffect deps * refactor: save tools to conversation documents * style(MultiSelectPop): dynamic height, remove unused import * refactor(react-query): use localstorage keys and pass config to useAvailablePluginsQuery * feat(utils): add mapPlugins * refactor(Convo): use conversation.tools if defined, lastSelectedTools if not * refactor: remove unused legacy code using `useSetOptions`, remove conditional flag `isMultiChat` for using legacy settings * refactor(PluginStoreDialog): add exhaustive-deps which are stable react state setters * fix(HeaderOptions): pass `popover` as true * refactor(useSetStorage): use project enums * refactor: use LocalStorageKeys enum * fix: prevent setConversation from setting falsy values in lastSelectedTools * refactor: use map for availableTools state and available Plugins query * refactor(updateLastSelectedModel): organize logic better and add note on purpose * fix(setAgentOption): prevent reseting last model to secondary model for gptPlugins * refactor(buildDefaultConvo): use enum * refactor: remove `useSetStorage` and consolidate areas where conversation state is saved to localStorage * fix: conversations retain tools on refresh * fix(gptPlugins): prevent nullish tools from being saved * chore: delete useServerStream * refactor: move initial plugins logic to useAppStartup * refactor(MultiSelectDropDown): add more pass-in className props * feat: use tools in presets * chore: delete unused usePresetOptions * refactor: new agentOptions default handling * chore: note * feat: add label and custom instructions to agents * chore: remove 'disabled with tools' message * style: move plugins to 2nd column in parameters * fix: TPreset type for agentOptions * fix: interface controls * refactor: add interfaceConfig, use Separator within Switcher * refactor: hide Assistants panel if interface.parameters are disabled * fix(Header): only modelSpecs if list is greater than 0 * refactor: separate MessageIcon logic from useMessageHelpers for better react rule-following * fix(AppService): don't use reserved keyword 'interface' * feat: set existing Icon for custom endpoints through iconURL * fix(ci): tests passing for App Service * docs: refactor custom_config.md for readability and better organization, also include missing values * docs: interface section and re-organize docs * docs: update modelSpecs info * chore: remove unused files * chore: remove unused files * chore: move useSetIndexOptions * chore: remove unused file * chore: move useConversation(s) * chore: move useDefaultConvo * chore: move useNavigateToConvo * refactor: use plugin install hook so it can be used elsewhere * chore: import order * update docs * refactor(OpenAI/Plugins): allow modelLabel as an initial value for chatGptLabel * chore: remove unused EndpointOptionsPopover and hide 'Save as Preset' button if preset UI visibility disabled * feat(loadDefaultInterface): issue warnings based on values * feat: changelog for custom config file * docs: add additional changelog note * fix: prevent unavailable tool selection from preset and update availableTools on Plugin installations * feat: add `filteredTools` option in custom config * chore: changelog * fix(MessageIcon): always overwrite conversation.iconURL in messageSettings * fix(ModelSpecsMenu): icon edge cases * fix(NewChat): dynamic icon * fix(PluginsClient): always include endpoint in responseMessage * fix: always include endpoint and iconURL in responseMessage across different response methods * feat: interchangeable keys for modelSpec enforcing
2024-04-30 22:11:48 -04:00
let plugins = authenticatedPlugins;
if (includedTools.length > 0) {
plugins = plugins.filter((plugin) => includedTools.includes(plugin.pluginKey));
} else {
plugins = plugins.filter((plugin) => !filteredTools.includes(plugin.pluginKey));
}
🤖 feat: Model Specs & Save Tools per Convo/Preset (#2578) * WIP: first pass ModelSpecs * refactor(onSelectEndpoint): use `getConvoSwitchLogic` * feat: introduce iconURL, greeting, frontend fields for conversations/presets/messages * feat: conversation.iconURL & greeting in Landing * feat: conversation.iconURL & greeting in New Chat button * feat: message.iconURL * refactor: ConversationIcon -> ConvoIconURL * WIP: add spec as a conversation field * refactor: useAppStartup, set spec on initial load for new chat, allow undefined spec, add localStorage keys enum, additional type fields for spec * feat: handle `showIconInMenu`, `showIconInHeader`, undefined `iconURL` and no specs on initial load * chore: handle undefined or empty modelSpecs * WIP: first pass, modelSpec schema for custom config * refactor: move default filtered tools definition to ToolService * feat: pass modelSpecs from backend via startupConfig * refactor: modelSpecs config, return and define list * fix: react error and include iconURL in responseMessage * refactor: add iconURL to responseMessage only * refactor: getIconEndpoint * refactor: pass TSpecsConfig * fix(assistants): differentiate compactAssistantSchema, correctly resets shared conversation state with other endpoints * refactor: assistant id prefix localStorage key * refactor: add more LocalStorageKeys and replace hardcoded values * feat: prioritize spec on new chat behavior: last selected modelSpec behavior (localStorage) * feat: first pass, interface config * chore: WIP, todo: add warnings based on config.modelSpecs settings. * feat: enforce modelSpecs if configured * feat: show config file yaml errors * chore: delete unused legacy Plugins component * refactor: set tools to localStorage from recoil store * chore: add stable recoil setter to useEffect deps * refactor: save tools to conversation documents * style(MultiSelectPop): dynamic height, remove unused import * refactor(react-query): use localstorage keys and pass config to useAvailablePluginsQuery * feat(utils): add mapPlugins * refactor(Convo): use conversation.tools if defined, lastSelectedTools if not * refactor: remove unused legacy code using `useSetOptions`, remove conditional flag `isMultiChat` for using legacy settings * refactor(PluginStoreDialog): add exhaustive-deps which are stable react state setters * fix(HeaderOptions): pass `popover` as true * refactor(useSetStorage): use project enums * refactor: use LocalStorageKeys enum * fix: prevent setConversation from setting falsy values in lastSelectedTools * refactor: use map for availableTools state and available Plugins query * refactor(updateLastSelectedModel): organize logic better and add note on purpose * fix(setAgentOption): prevent reseting last model to secondary model for gptPlugins * refactor(buildDefaultConvo): use enum * refactor: remove `useSetStorage` and consolidate areas where conversation state is saved to localStorage * fix: conversations retain tools on refresh * fix(gptPlugins): prevent nullish tools from being saved * chore: delete useServerStream * refactor: move initial plugins logic to useAppStartup * refactor(MultiSelectDropDown): add more pass-in className props * feat: use tools in presets * chore: delete unused usePresetOptions * refactor: new agentOptions default handling * chore: note * feat: add label and custom instructions to agents * chore: remove 'disabled with tools' message * style: move plugins to 2nd column in parameters * fix: TPreset type for agentOptions * fix: interface controls * refactor: add interfaceConfig, use Separator within Switcher * refactor: hide Assistants panel if interface.parameters are disabled * fix(Header): only modelSpecs if list is greater than 0 * refactor: separate MessageIcon logic from useMessageHelpers for better react rule-following * fix(AppService): don't use reserved keyword 'interface' * feat: set existing Icon for custom endpoints through iconURL * fix(ci): tests passing for App Service * docs: refactor custom_config.md for readability and better organization, also include missing values * docs: interface section and re-organize docs * docs: update modelSpecs info * chore: remove unused files * chore: remove unused files * chore: move useSetIndexOptions * chore: remove unused file * chore: move useConversation(s) * chore: move useDefaultConvo * chore: move useNavigateToConvo * refactor: use plugin install hook so it can be used elsewhere * chore: import order * update docs * refactor(OpenAI/Plugins): allow modelLabel as an initial value for chatGptLabel * chore: remove unused EndpointOptionsPopover and hide 'Save as Preset' button if preset UI visibility disabled * feat(loadDefaultInterface): issue warnings based on values * feat: changelog for custom config file * docs: add additional changelog note * fix: prevent unavailable tool selection from preset and update availableTools on Plugin installations * feat: add `filteredTools` option in custom config * chore: changelog * fix(MessageIcon): always overwrite conversation.iconURL in messageSettings * fix(ModelSpecsMenu): icon edge cases * fix(NewChat): dynamic icon * fix(PluginsClient): always include endpoint in responseMessage * fix: always include endpoint and iconURL in responseMessage across different response methods * feat: interchangeable keys for modelSpec enforcing
2024-04-30 22:11:48 -04:00
🏗️ feat: bulkWrite isolation, pre-auth context, strict-mode fixes (#12445) * fix: wrap seedDatabase() in runAsSystem() for strict tenant mode seedDatabase() was called without tenant context at startup, causing every Mongoose operation inside it to throw when TENANT_ISOLATION_STRICT=true. Wrapping in runAsSystem() gives it the SYSTEM_TENANT_ID sentinel so the isolation plugin skips filtering, matching the pattern already used for performStartupChecks and updateInterfacePermissions. * fix: chain tenantContextMiddleware in optionalJwtAuth optionalJwtAuth populated req.user but never established ALS tenant context, unlike requireJwtAuth which chains tenantContextMiddleware after successful auth. Authenticated users hitting routes with optionalJwtAuth (e.g. /api/banner) had no tenant isolation. * feat: tenant-safe bulkWrite wrapper and call-site migration Mongoose's bulkWrite() does not trigger schema-level middleware hooks, so the applyTenantIsolation plugin cannot intercept it. This adds a tenantSafeBulkWrite() utility that injects the current ALS tenant context into every operation's filter/document before delegating to native bulkWrite. Migrates all 8 runtime bulkWrite call sites: - agentCategory (seedCategories, ensureDefaultCategories) - conversation (bulkSaveConvos) - message (bulkSaveMessages) - file (batchUpdateFiles) - conversationTag (updateTagsForConversation, bulkIncrementTagCounts) - aclEntry (bulkWriteAclEntries) systemGrant.seedSystemGrants is intentionally not migrated — it uses explicit tenantId: { $exists: false } filters and is exempt from the isolation plugin. * feat: pre-auth tenant middleware and tenant-scoped config cache Adds preAuthTenantMiddleware that reads X-Tenant-Id from the request header and wraps downstream in tenantStorage ALS context. Wired onto /oauth, /api/auth, /api/config, and /api/share — unauthenticated routes that need tenant scoping before JWT auth runs. The /api/config cache key is now tenant-scoped (STARTUP_CONFIG:${tenantId}) so multi-tenant deployments serve the correct login page config per tenant. The middleware is intentionally minimal — no subdomain parsing, no OIDC claim extraction. The private fork's reverse proxy or auth gateway sets the header. * feat: accept optional tenantId in updateInterfacePermissions When tenantId is provided, the function re-enters inside tenantStorage.run({ tenantId }) so all downstream Mongoose queries target that tenant's roles instead of the system context. This lets the private fork's tenant provisioning flow call updateInterfacePermissions per-tenant after creating tenant-scoped ADMIN/USER roles. * fix: tenant-filter $lookup in getPromptGroup aggregation The $lookup stage in getPromptGroup() queried the prompts collection without tenant filtering. While the outer PromptGroup aggregate is protected by the tenantIsolation plugin's pre('aggregate') hook, $lookup runs as an internal MongoDB operation that bypasses Mongoose hooks entirely. Converts from simple field-based $lookup to pipeline-based $lookup with an explicit tenantId match when tenant context is active. * fix: replace field-level unique indexes with tenant-scoped compounds Field-level unique:true creates a globally-unique single-field index in MongoDB, which would cause insert failures across tenants sharing the same ID values. - agent.id: removed field-level unique, added { id, tenantId } compound - convo.conversationId: removed field-level unique (compound at line 50 already exists: { conversationId, user, tenantId }) - message.messageId: removed field-level unique (compound at line 165 already exists: { messageId, user, tenantId }) - preset.presetId: removed field-level unique, added { presetId, tenantId } compound * fix: scope MODELS_CONFIG, ENDPOINT_CONFIG, PLUGINS, TOOLS caches by tenant These caches store per-tenant configuration (available models, endpoint settings, plugin availability, tool definitions) but were using global cache keys. In multi-tenant mode, one tenant's cached config would be served to all tenants. Appends :${tenantId} to cache keys when tenant context is active. Falls back to the unscoped key when no tenant context exists (backward compatible for single-tenant OSS deployments). Covers all read, write, and delete sites: - ModelController.js: get/set MODELS_CONFIG - PluginController.js: get/set PLUGINS, get/set TOOLS - getEndpointsConfig.js: get/set/delete ENDPOINT_CONFIG - app.js: delete ENDPOINT_CONFIG (clearEndpointConfigCache) - mcp.js: delete TOOLS (updateMCPTools, mergeAppTools) - importers.js: get ENDPOINT_CONFIG * fix: add getTenantId to PluginController spec mock The data-schemas mock was missing getTenantId, causing all PluginController tests to throw when the controller calls getTenantId() for tenant-scoped cache keys. * fix: address review findings — migration, strict-mode, DRY, types Addresses all CRITICAL, MAJOR, and MINOR review findings: F1 (CRITICAL): Add agents, conversations, messages, presets to SUPERSEDED_INDEXES in tenantIndexes.ts so dropSupersededTenantIndexes() drops the old single-field unique indexes that block multi-tenant inserts. F2 (CRITICAL): Unknown bulkWrite op types now throw in strict mode instead of silently passing through without tenant injection. F3 (MAJOR): Replace wildcard export with named export for tenantSafeBulkWrite, hiding _resetBulkWriteStrictCache from the public package API. F5 (MAJOR): Restore AnyBulkWriteOperation<IAclEntry>[] typing on bulkWriteAclEntries — the unparameterized wrapper accepts parameterized ops as a subtype. F7 (MAJOR): Fix config.js tenant precedence — JWT-derived req.user.tenantId now takes priority over the X-Tenant-Id header for authenticated requests. F8 (MINOR): Extract scopedCacheKey() helper into tenantContext.ts and replace all 11 inline occurrences across 7 files. F9 (MINOR): Use simple localField/foreignField $lookup for the non-tenant getPromptGroup path (more efficient index seeks). F12 (NIT): Remove redundant BulkOp type alias. F13 (NIT): Remove debug log that leaked raw tenantId. * fix: add new superseded indexes to tenantIndexes test fixture The test creates old indexes to verify the migration drops them. Missing fixture entries for agents.id_1, conversations.conversationId_1, messages.messageId_1, and presets.presetId_1 caused the count assertion to fail (expected 22, got 18). * fix: restore logger.warn for unknown bulk op types in non-strict mode * fix: block SYSTEM_TENANT_ID sentinel from external header input CRITICAL: preAuthTenantMiddleware accepted any string as X-Tenant-Id, including '__SYSTEM__'. The tenantIsolation plugin treats SYSTEM_TENANT_ID as an explicit bypass — skipping ALL query filters. A client sending X-Tenant-Id: __SYSTEM__ to pre-auth routes (/api/share, /api/config, /api/auth, /oauth) would execute Mongoose operations without tenant isolation. Fixes: - preAuthTenantMiddleware rejects SYSTEM_TENANT_ID in header - scopedCacheKey returns the base key (not key:__SYSTEM__) in system context, preventing stale cache entries during runAsSystem() - updateInterfacePermissions guards tenantId against SYSTEM_TENANT_ID - $lookup pipeline separates $expr join from constant tenantId match for better index utilization - Regression test for sentinel rejection in preAuthTenant.spec.ts - Remove redundant getTenantId() call in config.js * test: add missing deleteMany/replaceOne coverage, fix vacuous ALS assertions bulkWrite spec: - deleteMany: verifies tenant-scoped deletion leaves other tenants untouched - replaceOne: verifies tenantId injected into both filter and replacement - replaceOne overwrite: verifies a conflicting tenantId in the replacement document is overwritten by the ALS tenant (defense-in-depth) - empty ops array: verifies graceful handling preAuthTenant spec: - All negative-case tests now use the capturedNext pattern to verify getTenantId() inside the middleware's execution context, not the test runner's outer frame (which was always undefined regardless) * feat: tenant-isolate MESSAGES cache, FLOWS cache, and GenerationJobManager MESSAGES cache (streamAudio.js): - Cache key now uses scopedCacheKey(messageId) to prefix with tenantId, preventing cross-tenant message content reads during TTS streaming. FLOWS cache (FlowStateManager): - getFlowKey() now generates ${type}:${tenantId}:${flowId} when tenant context is active, isolating OAuth flow state per tenant. GenerationJobManager: - tenantId added to SerializableJobData and GenerationJobMetadata - createJob() captures the current ALS tenant context (excluding SYSTEM_TENANT_ID) and stores it in job metadata - SSE subscription endpoint validates job.metadata.tenantId matches req.user.tenantId, blocking cross-tenant stream access - Both InMemoryJobStore and RedisJobStore updated to accept tenantId * fix: add getTenantId and SYSTEM_TENANT_ID to MCP OAuth test mocks FlowStateManager.getFlowKey() now calls getTenantId() for tenant-scoped flow keys. The 4 MCP OAuth test files mock @librechat/data-schemas without these exports, causing TypeError at runtime. * fix: correct import ordering per AGENTS.md conventions Package imports sorted shortest to longest line length, local imports sorted longest to shortest — fixes ordering violations introduced by our new imports across 8 files. * fix: deserialize tenantId in RedisJobStore — cross-tenant SSE guard was no-op in Redis mode serializeJob() writes tenantId to the Redis hash via Object.entries, but deserializeJob() manually enumerates fields and omitted tenantId. Every getJob() from Redis returned tenantId: undefined, causing the SSE route's cross-tenant guard to short-circuit (undefined && ... → false). * test: SSE tenant guard, FlowStateManager key consistency, ALS scope docs SSE stream tenant tests (streamTenant.spec.js): - Cross-tenant user accessing another tenant's stream → 403 - Same-tenant user accessing own stream → allowed - OSS mode (no tenantId on job) → tenant check skipped FlowStateManager tenant tests (manager.tenant.spec.ts): - completeFlow finds flow created under same tenant context - completeFlow does NOT find flow under different tenant context - Unscoped flows are separate from tenant-scoped flows Documentation: - JSDoc on getFlowKey documenting ALS context consistency requirement - Comment on streamAudio.js scopedCacheKey capture site * fix: SSE stream tests hang on success path, remove internal fork references The success-path tests entered the SSE streaming code which never closes, causing timeout. Mock subscribe() to end the response immediately. Restructured assertions to verify non-403/non-404. Removed "private fork" and "OSS" references from code and test descriptions — replaced with "deployment layer", "multi-tenant deployments", and "single-tenant mode". * fix: address review findings — test rigor, tenant ID validation, docs F1: SSE stream tests now mock subscribe() with correct signature (streamId, writeEvent, onDone, onError) and assert 200 status, verifying the tenant guard actually allows through same-tenant users. F2: completeFlow logs the attempted key and ALS tenantId when flow is not found, so reverse proxy misconfiguration (missing X-Tenant-Id on OAuth callback) produces an actionable warning. F3/F10: preAuthTenantMiddleware validates tenant ID format — rejects colons, special characters, and values exceeding 128 chars. Trims whitespace. Prevents cache key collisions via crafted headers. F4: Documented cache invalidation scope limitation in clearEndpointConfigCache — only the calling tenant's key is cleared; other tenants expire via TTL. F7: getFlowKey JSDoc now lists all 8 methods requiring consistent ALS context. F8: Added dedicated scopedCacheKey unit tests — base key without context, base key in system context, scoped key with tenant, no ALS leakage across scope boundaries. * fix: revert flow key tenant scoping, fix SSE test timing FlowStateManager: Reverts tenant-scoped flow keys. OAuth callbacks arrive without tenant ALS context (provider redirects don't carry X-Tenant-Id), so completeFlow/failFlow would never find flows created under tenant context. Flow IDs are random UUIDs with no collision risk, and flow data is ephemeral (TTL-bounded). SSE tests: Use process.nextTick for onDone callback so Express response headers are flushed before res.write/res.end are called. * fix: restore getTenantId import for completeFlow diagnostic log * fix: correct completeFlow warning message, add missing flow test The warning referenced X-Tenant-Id header consistency which was only relevant when flow keys were tenant-scoped (since reverted). Updated to list actual causes: TTL expiry, missing flow, or routing to a different instance without shared Keyv storage. Removed the getTenantId() call and import — no longer needed since flow keys are unscoped. Added test for the !flowState branch in completeFlow — verifies return false and logger.warn on nonexistent flow ID. * fix: add explicit return type to recursive updateInterfacePermissions The recursive call (tenantId branch calls itself without tenantId) causes TypeScript to infer circular return type 'any'. Adding explicit Promise<void> satisfies the rollup typescript plugin. * fix: update MCPOAuthRaceCondition test to match new completeFlow warning * fix: clearEndpointConfigCache deletes both scoped and unscoped keys Unauthenticated /api/endpoints requests populate the unscoped ENDPOINT_CONFIG key. Admin config mutations clear only the tenant-scoped key, leaving the unscoped entry stale indefinitely. Now deletes both when in tenant context. * fix: tenant guard on abort/status endpoints, warn logs, test coverage F1: Add tenant guard to /chat/status/:conversationId and /chat/abort matching the existing guard on /chat/stream/:streamId. The status endpoint exposes aggregatedContent (AI response text) which requires tenant-level access control. F2: preAuthTenantMiddleware now logs warn for rejected __SYSTEM__ sentinel and malformed tenant IDs, providing observability for bypass probing attempts. F3: Abort fallback path (getActiveJobIdsForUser) now has tenant check after resolving the job. F4: Test for strict mode + SYSTEM_TENANT_ID — verifies runAsSystem bypasses tenantSafeBulkWrite without throwing in strict mode. F5: Test for job with tenantId + user without tenantId → 403. F10: Regex uses idiomatic hyphen-at-start form. F11: Test descriptions changed from "rejects" to "ignores" since middleware calls next() (not 4xx). Also fixes MCPOAuthRaceCondition test assertion to match updated completeFlow warning message. * fix: test coverage for logger.warn, status/abort guards, consistency A: preAuthTenant spec now mocks logger and asserts warn calls for __SYSTEM__ sentinel, malformed characters, and oversized headers. B: streamTenant spec expanded with status and abort endpoint tests — cross-tenant status returns 403, same-tenant returns 200 with body, cross-tenant abort returns 403. C: Abort endpoint uses req.user.tenantId (not req.user?.tenantId) matching stream/status pattern — requireJwtAuth guarantees req.user. D: Malformed header warning now includes ip in log metadata, matching the sentinel warning for consistent SOC correlation. * fix: assert ip field in malformed header warn tests * fix: parallelize cache deletes, document tenant guard, fix import order - clearEndpointConfigCache uses Promise.all for independent cache deletes instead of sequential awaits - SSE stream tenant guard has inline comment explaining backward-compat behavior for untenanted legacy jobs - conversation.ts local imports reordered longest-to-shortest per AGENTS.md * fix: tenant-qualify userJobs keys, document tenant guard backward-compat Job store userJobs keys now include tenantId when available: - Redis: stream:user:{tenantId:userId}:jobs (falls back to stream:user:{userId}:jobs when no tenant) - InMemory: composite key tenantId:userId in userJobMap getActiveJobIdsByUser/getActiveJobIdsForUser accept optional tenantId parameter, threaded through from req.user.tenantId at all call sites (/chat/active and /chat/abort fallback). Added inline comments on all three SSE tenant guards explaining the backward-compat design: untenanted legacy jobs remain accessible when the userId check passes. * fix: parallelize cache deletes, document tenant guard, fix import order Fix InMemoryJobStore.getActiveJobIdsByUser empty-set cleanup to use the tenant-qualified userKey instead of bare userId — prevents orphaned empty Sets accumulating in userJobMap for multi-tenant users. Document cross-tenant staleness in clearEndpointConfigCache JSDoc — other tenants' scoped keys expire via TTL, not active invalidation. * fix: cleanup userJobMap leak, startup warning, DRY tenant guard, docs F1: InMemoryJobStore.cleanup() now removes entries from userJobMap before calling deleteJob, preventing orphaned empty Sets from accumulating with tenant-qualified composite keys. F2: Startup warning when TENANT_ISOLATION_STRICT is active — reminds operators to configure reverse proxy to control X-Tenant-Id header. F3: mergeAppTools JSDoc documents that tenant-scoped TOOLS keys are not actively invalidated (matching clearEndpointConfigCache pattern). F5: Abort handler getActiveJobIdsForUser call uses req.user.tenantId (not req.user?.tenantId) — consistent with stream/status handlers. F6: updateInterfacePermissions JSDoc clarifies SYSTEM_TENANT_ID behavior — falls through to caller's ALS context. F7: Extracted hasTenantMismatch() helper, replacing three identical inline tenant guard blocks across stream/status/abort endpoints. F9: scopedCacheKey JSDoc documents both passthrough cases (no context and SYSTEM_TENANT_ID context). * fix: clean userJobMap in evictOldest — same leak as cleanup()
2026-03-28 16:43:50 -04:00
await cache.set(pluginsCacheKey, plugins);
feat: ChatGPT Plugins/OpenAPI specs for Plugins Endpoint (#620) * wip: proof of concept for openapi chain * chore(api): update langchain dependency to version 0.0.105 * feat(Plugins): use ChatGPT Plugins/OpenAPI specs (first pass) * chore(manifest.json): update pluginKey for "Browser" tool to "web-browser" chore(handleTools.js): update customConstructor key for "web-browser" tool * fix(handleSubmit.js): set unfinished property to false for all endpoints * fix(handlers.js): remove unnecessary capitalizeWords function and use action.tool directly refactor(endpoints.js): rename availableTools to tools and transform it into a map * feat(endpoints): add plugins selector to endpoints file refactor(CodeBlock.tsx): refactor to typescript refactor(Plugin.tsx): use recoil Map for plugin name and refactor to typescript chore(Message.jsx): linting chore(PluginsOptions/index.jsx): remove comment/linting chore(svg): export Clipboard and CheckMark components from SVG index and refactor to typescript * fix(OpenAPIPlugin.js): rename readYamlFile function to readSpecFile fix(OpenAPIPlugin.js): handle JSON files in readSpecFile function fix(OpenAPIPlugin.js): handle JSON URLs in getSpec function fix(OpenAPIPlugin.js): handle JSON variables in createOpenAPIPlugin function fix(OpenAPIPlugin.js): add description for variables in createOpenAPIPlugin function fix(OpenAPIPlugin.js): add optional flag for is_user_authenticated and has_user_authentication in ManifestDefinition fix(loadSpecs.js): add optional flag for is_user_authenticated and has_user_authentication in ManifestDefinition fix(Plugin.tsx): remove unnecessary callback parameter in getPluginName function fix(getDefaultConversation.js): fix browser console error: handle null value for lastConversationSetup in getDefaultConversation function * feat(api): add new tools Add Ai PDF tool for super-fast, interactive chats with PDFs of any size, complete with page references for fact checking. Add VoxScript tool for searching through YouTube transcripts, financial data sources, Google Search results, and more. Add WebPilot tool for browsing and QA of webpages, PDFs, and data. Generate articles from one or more URLs. feat(api): update OpenAPIPlugin.js - Add support for bearer token authorization in the OpenAPIPlugin. - Add support for custom headers in the OpenAPIPlugin. fix(api): fix loadTools.js - Pass the user parameter to the loadSpecs function. * feat(PluginsClient.js): import findMessageContent function from utils feat(PluginsClient.js): add message parameter to options object in initializeCustomAgent function feat(PluginsClient.js): add content to errorMessage if message content is found feat(PluginsClient.js): break out of loop if message content is found feat(PluginsClient.js): add delay option with value of 8 to generateTextStream function feat(PluginsClient.js): add support for process.env.PORT environment variable in app.listen function feat(askyourpdf.json): add askyourpdf plugin configuration feat(metar.json): add metar plugin configuration feat(askyourpdf.yaml): add askyourpdf plugin OpenAPI specification feat(OpenAPIPlugin.js): add message parameter to createOpenAPIPlugin function feat(OpenAPIPlugin.js): add description_for_model to chain run message feat(addOpenAPISpecs.js): remove verbose option from loadSpecs function call fix(loadSpecs.js): add 'message' parameter to the loadSpecs function feat(findMessageContent.js): add utility function to find message content in JSON objects * fix(PluginStoreDialog.tsx): update z-index value for the dialog container The z-index value for the dialog container was updated to "102" to ensure it appears above other elements on the page. * chore(web_pilot.json): add "params" field with "user_has_request" parameter set to true * chore(eslintrc.js): update eslint rules fix(Login.tsx): add missing semicolon after import statement * fix(package-lock.json): update langchain dependency to version ^0.0.105 * fix(OpenAPIPlugin.js): change header key from 'id' to 'librechat_user_id' for consistency and clarity feat(plugins): add documentation for using official ChatGPT Plugins with OpenAPI specs This commit adds a new file `chatgpt_plugins_openapi.md` to the `docs/features/plugins` directory. The file provides detailed information on how to use official ChatGPT Plugins with OpenAPI specifications. It explains the components of a plugin, including the Plugin Manifest file and the OpenAPI spec. It also covers the process of adding a plugin, editing manifest files, and customizing OpenAPI spec files. Additionally, the commit includes disclaimers about the limitations and compatibility of plugins with LibreChat. The documentation also clarifies that the use of ChatGPT Plugins with LibreChat does not violate OpenAI's Terms of Service. The purpose of this commit is to provide comprehensive documentation for developers who want to integrate ChatGPT Plugins into their projects using OpenAPI specs. It aims to guide them through the process of adding and configuring plugins, as well as addressing potential issues and chore(introduction.md): update link to ChatGPT Plugins documentation docs(introduction.md): clarify the purpose of the plugins endpoint and its capabilities * fix(OpenAPIPlugin.js): update SUFFIX variable to provide a clearer description docs(chatgpt_plugins_openapi.md): update information about adding plugins via url on the frontend * feat(PluginsClient.js): sendIntermediateMessage on successful Agent load fix(PluginsClient.js, server/index.js, gptPlugins.js): linting fixes docs(chatgpt_plugins_openapi.md): update links and add additional information * Update chatgpt_plugins_openapi.md * chore: rebuild package-lock file * chore: format/lint all files with new rules * chore: format all files * chore(README.md): update AI model selection list The AI model selection list in the README.md file has been updated to reflect the current options available. The "Anthropic" model has been added as an alternative name for the "Claude" model. * fix(Plugin.tsx): type issue * feat(tools): add new tool WebPilot feat(tools): remove tool Weather Report feat(tools): add new tool Prompt Perfect feat(tools): add new tool Scholarly Graph Link * feat(OpenAPIPlugin.js): add getSpec and readSpecFile functions feat(OpenAPIPlugin.spec.js): add tests for readSpecFile, getSpec, and createOpenAPIPlugin functions * chore(agent-demo-1.js): remove unused code and dependencies chore(agent-demo-2.js): remove unused code and dependencies chore(demo.js): remove unused code and dependencies * feat(addOpenAPISpecs): add function to transform OpenAPI specs into desired format feat(addOpenAPISpecs.spec): add tests for transformSpec function fix(loadSpecs): remove debugging code * feat(loadSpecs.spec.js): add unit tests for ManifestDefinition, validateJson, and loadSpecs functions * fix: package file resolution bug * chore: move scholarly_graph_link manifest to 'has-issues' * refactor(client/hooks): convert to TS and export from index * Update introduction.md * Update chatgpt_plugins_openapi.md
2023-07-16 12:19:47 -04:00
res.status(200).json(plugins);
feat: Plugins endpoint - Reverse Engineering of official Plugins features (#197) * components for plugins in progress * WIP: add langchain client implementation for tools/plugins feat(langchain): add loadHistory function for loading chat history from database feat(langchain): add saveMessageToDatabase function for saving chat messages to database * chore(Memory.js): remove Memory.js file from the project directory. * WIP: adding plugin functionality —————————————————— fix(eslintrc.js): change arrow-parens rule to always require parentheses refactor(agent.js): reorganize imports and add new imports feat(agent.js): add support for saving and loading chat history feat(agent.js): add support for saving messages to database feat(agent.js): add ChatAgent class with initialize and sendMessage methods fix(langchain): use getConvo and saveMessage functions from models.js instead of Conversation and Message models feat(langchain): add user parameter to loadHistory and saveMessageToDatabase functions chore(package.json): update langchain package version to 0.0.59 and add langchain script to run test2.js file —————————————————— * WIP: testing agent initialization * WIP: testing various agent methods feat(agent.js): add CustomChatAgent class and initializeAgentExecutorWithOptions method feat(customChatAgent.js): add CustomPromptTemplate and CustomOutputParser classes refactor(langchain): uncomment code for input2 and options feat(langchain): add input1 to read comments on a youtube video docs(langchain): remove commented code and add whitespace to package.json * WIP: feat: plugin endpoint, backend class working * feat(agent.js): add support for Zapier NLA API key feat(agent.js): add ZapierToolKit to tools if zapierApiKey is provided feat(customAgent.js): change prompt prefix and suffix to reflect new task-based prompt feat(test4.js): add test for new task-based prompt * style(langchain): improve readability and add comments to code feat(langchain): update prompt message for custom agent fix(langchain): update message format in test4.js * style(customAgent.js): remove unnecessary capitalization and rephrase some sentences test(langchain): add test2 and test3 scripts to package.json * chore(customAgent.js): fix typo in comment, change "an" to "identical" * WIP: gpt-4 testing * feat(langchain): add AIPluginTool and HumanTool classes fix(langchain): remove zapierApiKey option from ChatAgent constructor refactor(langchain): update langchain package to v0.0.64 misc(langchain): update test2, test3, and test4 scripts to use --inspect flag * feat(langchain): add GoogleSearchAPI tool for searching the web using Google Custom Search API * feat(askGPTPlugins.js): add support for progress callback in ask function fix(agent.js): pass progress callback to sendApiMessage function * refactor(agent.js): load tools from options and initialize them in constructor feat(agent.js): add support for environment variable SERPAPI_API_KEY feat(agent.js): add support for environment variable ZAPIER_NLA_API_KEY docs(agent.js): remove commented out code and add comments to clarify code * chore(langchain): remove unused files loadHistory.js and saveMessage.js * feat(validateTools.js): add function to validate API keys for supported tools * feat(langchain): update langchain package to version 0.0.66 feat(langchain): add support for GPT-4 model fix(server/index.js): fix uncaughtException handler to ignore 'fetch failed' errors * refactor(agent.js): remove FORMAT_INSTRUCTIONS and replace with a more concise message refactor(agent.js): remove unused variable 'errorMessage' refactor(agent.js): change 'result' variable initialization to an empty object instead of null refactor(agent.js): change error message when response generation fails refactor(agent.js): change output message when response generation fails refactor(agent.js): change output message when response generation succeeds * chore(langchain): comment out unused model in ChatAgent constructor feat(langchain): add test5 script to package.json for running test5.js script * refactor(agent.js): change response to answer and update message refactor(test3.js, test5.js): remove commented out code and add comments The changes in agent.js are to improve the message that is returned to the user. The word "response" has been changed to "answer" to better reflect the output of the chatbot. The message has also been updated to provide clearer instructions to the user. The changes in test3.js and test5.js are to remove commented out code and add comments to improve readability. * docs: update links to LOCAL_INSTALL.md and defaultSystemMessage.md fix: fix typo in BingAI/Settings.jsx feat: add Dockerfile for app containerization docs(google_search.md): add guide for setting up Google Custom Search API key and ID * docs: update link to system message guidelines in Bing AI Settings component docs: update link to system message guidelines in GOOGLE_SEARCH.md feat: add JAILBREAK_INFO.md guide for Bing AI jailbreak mode system message guidelines * style(api): remove unnecessary quotes and empty values from .env.example style(agent.js): refactor getActions method to accept an input parameter feat(agent.js): add handleChainEnd method to CustomChatAgent class style(customAgent.js): add a new line to the end of the file style(test5.js): comment out unused variable and update input1 variable style(googleSearch.js): change tool name to kebab-case * chore(langchain): comment out handleChainEnd method in agent.js feat(langchain): add browser tool to ChatAgent in test2.js feat(langchain): add modelOptions to ChatAgent in test2.js feat(langchain): change question in input1 and request article review summary in test5.js * fix(askGPTPlugins.js): fix syntax error by removing extra comma in parentMessageId field feat(askGPTPlugins.js): add default value of null to parentMessageId parameter in ask function * fix(askGPTPlugins.js): change endpoint string from 'GPTPlugins' to 'gptPlugins' feat(endpoints.js): add support for gptPlugins endpoint feat(PresetItem.jsx): add support for gptPlugins endpoint feat(HoverButtons.jsx): add support for gptPlugins endpoint feat(createPayload.ts): add support for gptPlugins endpoint feat(types.ts): add gptPlugins endpoint to EModelEndpoint enum feat(endpoints.js): add gptPlugins endpoint to availableEndpoints selector feat(cleanupPreset.js): add support for gptPlugins endpoint feat(getDefaultConversation.js): add support for gptPlugins endpoint feat(getIcon.jsx): add support for gptPlugins endpoint feat(handleSubmit.js): add support for gptPlugins endpoint * refactor(agent.js): remove debug option from options object refactor(agent.js): change tool name from 'google-search' to 'google' refactor(agent.js): update description for 'google' tool feat(agent.js): add support for citing sources when using web links in response message fix(agent.js): update error message to not mention error to user feat(agent.js): add unique message ids for user message and response message feat(agent.js): limit number of search results to 5 in 'google' tool refactor(validateTools.js): add console log to show valid tools * feat(askGPTPlugins.js): add support for GPT-3.5-turbo model and validate model option refactor(askGPTPlugins.js): remove unused imports and variables refactor(askGPTPlugins.js): remove commented code refactor(askGPTPlugins.js): remove unused parameters in ask function feat(ask/index.js): add askGPTPlugins route to router * feat(NewConversationMenu): add alpha tag to gptPlugins endpoint and rename it to Plugins * refactor(askGPTPlugins.js): remove commented code and unused imports feat(askGPTPlugins.js): add support for debug option in endpointOption feat(askGPTPlugins.js): add support for chatGptLabel, promptPrefix, temperature, top_p, presence_penalty, and frequency_penalty in endpointOption feat(askGPTPlugins.js): add support for sending plugin and pluginend events feat(askGPTPlugins.js): add onAgentAction and onChainEnd callbacks to ChatAgent.sendMessage refactor(titleConvo.js): comment out unused imports refactor(validateTools.js): comment out console.log statement refactor(agent.js): change saveMessage to include unfinished property feat(agent.js): add endpoint property to saveConvo call in saveMessageToDatabase feat(askGPTPlugins.js): add validateTools import and use it to validate endpointOption.tools before passing to ChatAgent constructor feat(askGPTPlugins.js * refactor(MessageHeader.jsx): extract plugins section into a separate variable and add support for gptPlugins endpoint fix(MessageHeader.jsx): disable clicking on non-clickable endpoints * components for plugins in progress * feat(Plugin.jsx): add plugin prop to Plugin component and display plugin name feat(Plugin.jsx): add loading state and display loading spinner feat(Plugin.jsx): add Disclosure component to Plugin component feat(Plugin.jsx): add Disclosure.Panel to Plugin component to display team pricing information feat(Spinner.jsx): add classProp prop to Spinner component to allow for custom styling feat(Landing.jsx): add Plugin component to Landing page for testing testing gpt plugins feat(plugins): Milestone commit - Add formatAction function to format plugin actions. - Add prefix.js file to store the prefix message for ChatAgent. - Update ask function to include plugin object to store plugin data. - Update onAgentAction and onChainEnd functions to format plugin data and send intermediate messages. - Update response object to include plugin data. The `handlers.js` file now includes a `formatAction` function that formats the action object for display in the UI. The `createOnProgress` function now returns a `sendIntermediateMessage` function that sends intermediate messages to the client. feat (client): add support for plugins in messages This commit adds support for plugins in messages. It includes changes to the `handlers.js`, `index.jsx`, `CodeBlock.jsx`, `Message.jsx`, `MessageHeader.jsx`, and `Plugin.jsx` files. The `index.jsx` file now includes a `plugin` property in the `messageHandler` function. The `CodeBlock.jsx` file now includes a `plugin` property that determines the language of the code block. The `Message.jsx` file now includes a `Plugin` component that displays the plugin used in the message. The `MessageHeader.jsx` file now includes a `Plugins` component that displays the enabled plugins. feat(langchain): add OpenAICreateImage tool for generating images based on user prompts fix(langchain): update validateTools to include create-image tool fix(langchain): save plugin data to messageSchema fix(server/routes/askGPTPlugins.js): save userMessage and response to messageSchema feat(langchain): add SelfReflectionTool Add a new tool to the LangChain agent, SelfReflectionTool, which enhances the agent's self-awareness by reflecting on its thoughts before taking action. The tool provides a space for the agent to explore and organize its ideas in response to the user's message. Also, update the prefix message to reflect the changes in the agent's behavior and the way it should engage with the user. The prefix message now emphasizes the use of tools when necessary, and relying on the agent's knowledge for creative requests. It also provides clear instructions on how to use the 'Action' input and how to carry out tasks in the sequence written by the human. Finally, update the OpenAICreateImage tool to return the image URL in markdown format. The tool replaces newlines and spaces in the input text with hyphens to create a valid markdown link. Milestone commit: better error handling with custom output parser, dir and file re-org style(langchain): fix formatting and add comments to prefix.js fix(langchain): remove commented out code in test6.js feat(langchain): reduce maxAttempts from 3 to 2 in CustomChatAgent's buildPromptPrefix method feat(langchain): add null check for result.output in CustomChatAgent's buildPromptPrefix method style(langchain): improve consistency and readability of code This commit improves the consistency and readability of the code in the langchain directory. Specifically, it: - Changes the case of the "Thought" output in the CustomChatAgent class to match the "Thought" output in the SelfReflectionTool class. - Adds a currentDateString property to the CustomChatAgent class to avoid repeating the same code in multiple places. - Updates the prefix in the prefix.js file to match the current objectives of the ChatGPT model. - Changes the description of the OpenAICreateImage tool to request a description of the image to be generated. - Updates the tools used by the ChatAgent in the askGPTPlugins.js file to include the Google and Browser tools instead of the Calculator and Create-Image tools. feat: add wolfram, improve image creation, rename to dall-e * refactor(langchain): update language and formatting in various files - Update tool-based instructions to use proper Markdown syntax for image URLs - Adjust temperature for modelOptions in CustomChatAgent class - Comment out console.debug statement in CustomChatAgent class - Update prefix in initializeCustomAgent function to use proper line breaks - Update prefix in instructions.js to use proper line breaks and change "user" to "human" - Update input in test6.js to use Ezra Pound instead of Hemingway - Update return statement in OpenAICreateImage class to use "generated-image" as alt-text - Update description in SelfReflectionTool class to provide clearer instructions - Update tools in ask function in askGPTPlugins.js to use only the DALL-E tool and enable debug mode feat(ask): add support for DALL-E tool in formatAction function feat(ask): add support for self-reflection tool in formatAction function feat(Plugin.jsx): add support for self-reflection tool in Plugin component fix(Plugin.jsx): fix Plugin component to not display 'None' when latest is not available * docs(openaiCreateImage.js): update tool description to clarify usage * feat(agent.js): add message parameter to initialize function feat(agent.js): pass message parameter to SelfReflectionTool constructor feat(customAgent.js): add longestToolName variable to CustomOutputParser feat(openaiCreateImage.js): replace new lines with spaces in prompt parameter feat(selfReflection.js): add message parameter to SelfReflectionTool constructor feat(selfReflection.js): add placeholder response to selfReflect function * feat: frontend plugin selection * fix: agent updates, available tools via endpoint config * fix: improve frontend plugin selection * feat: further customize agent and bypass executor when no tools are provided * fix: key issue in multiselect and allow setting changes during convo in plugins endpoint * fix: convo will save modelOptions, fix persistent errors with agent * fix: add looser final answer parsing and edit action formatting * fix: handle edge case where stop token is not hit and causes long parsing error * feat: trying new prompt for image creation * fix: improvements based on gpt-3.5 * feat: allow setting model options throughout plugin conversation * fix: agent adjustments * improve final reply for gpt-4, gpt-3.5 needs a more stable approach * fix: better context output for gpt-3.5 * fix: added clarification for better context output for gpt-3.5 * feat(PluginsOptions): add advanced mode to show/hide options style(PluginsOptions): add styles for advanced mode and show/hide options * minor changes to styling * refactor(langchain): add support for custom GPT-4 agent This commit adds support for a custom GPT-4 agent in the langchain module. The `CustomGpt4Agent` class extends the `ZeroShotAgent` class and includes a new `createPrompt` method that generates a prompt template for the agent. The `initializeCustomAgent` function has been updated to use the `CustomGpt4Agent` class when the model is not GPT-3. The `instructions.js` file has also been updated to include new instructions for the GPT-4 agent. The `formatInstructions` method has been removed and replaced with `gpt4Instructions` and `prefix2` and `suffix2` have been added to include the new instructions. feat(langchain): add custom output parser for langchain agents This commit adds a custom output parser for langchain agents. The new parser is called CustomOutputParser and it extends ZeroShotAgentOutputParser. It takes a fields object as a parameter and sets the tools and longestToolName properties. It also sets the finishToolNameRegex property to match the final answer. The parse method of the CustomOutputParser class takes a text parameter and returns an object with returnValues, log, and toolInput properties. This commit also adds a Gpt4OutputParser class that extends ZeroShotAgentOutputParser. It takes a fields object as a parameter and sets the tools and longestToolName properties. It also sets the finishToolNameRegex property to match the final answer. The parse method of the Gpt4OutputParser class takes a text parameter and returns an object with returnValues, log, and toolInput properties. feat(langchain): add isGpt3 parameter to * Stable Diffusion Plugin (#204) * Added stable diffusion plugin * Added example prompt * Fixed naming * Removed brackets in the prompt * fix: improved agent for gpt-3.5 * fix: outparser, gpt3 instructions, and wolfram error handling * chore: update langchain to 0.0.71 * fix: long parsing action input fix * fix: make plugin select close on clicking label/button * fix: make plugin select close on clicking label/button * fix: wolfram input formatting and gpt-3 payload without plugins * chore(api): update axios package version to 1.3.4 feat(api): add requireJwtAuth middleware to askGPTPlugins endpoint fix(api): replace session user with user id in askGPTPlugins endpoint docs(LOCAL_INSTALL.md): update guide for local installation and testing This commit updates the guide for local installation and testing of the ChatGPT-Clone app. It includes instructions for locally running the app, updating the app version, and running tests. It also includes a new option for running the app using Docker. The commit also fixes some typos and formatting issues. * add reverseProxy to plugins client * chore(Dockerfile-app): add Dockerfile for building and running the app in a container docs: remove outdated guides on Google search and Bing jailbreak mode docs(LOCAL_INSTALL.md): remove outdated Windows installation instructions and update MeiliSearch configuration file * fix: handle n/a parsing error better, reduce token waste if no agentic behavior is needed * style: fix formatting and add parentheses around arrow function parameter style: change hover background color to white and dark hover background color to gray-700 * chore: re-organize agent dir and files * feat(ChatAgent.js): add support for PlanAndExecuteAgentExecutor feat(PlanAndExecuteAgentExecutor.js): add PlanAndExecuteAgentExecutor class feat(planExecutor.js): add demo for PlanAndExecuteAgentExecutor * feat: add azure support to plugins * refactor(utils): add basePath endpoint for genAzureEndpoint feat(api): add support for Azure OpenAI API in various modules and tools * feat: add plugin api for fetching available tools * feat: add data service for getting available plugins * feat: first iteration plugin store UI * refactor: rename files to follow proper naming convention * feat: Plugin store UI components * feat: create separate user routes, service, controller, and add plugins to user model * feat: create data service for adding and removing plugins per user * feat: UI for adding and removing plugins, displaying plugins in dropdown based on what user has installed * fix: merge conflicts from main * fix: fix plugin items titles * fix: tool.value -> tool.pluginKey * fix: testing returnDirect for self-reflection * fix: add browser tool to manifest * refactor(outputParser.js): remove commented out code feat(outputParser.js): add support for thought input when there is no action input * handling 'use tool' edge case * merge main to langchain * fix(User.js, auth.service.js, localStrategy.js): change deprecated Joi.validate() to schema.validate() method (#322) * fix(auth.service.js): fixes deprecated error callback in mongoose save method (#323) * chore: run formatting script with new rules * refactor: add requiresAuth to manifest, fix uninstall button * version with plugin auth as dialog modal * feat: Complete frontend for plugin auth * frontend styling updates * feat: api for plugin auth * feat: Add tooltip with field description to plugin auth form * fix: issue with plugin that has no auth * feat(tools): add support for user-specific API keys This commit adds support for user-specific API keys for the following tools: - Google Search API - Web Browser - SerpAPI - Zapier - DALL-E - Wolfram Alpha API It also adds support for OpenAI API key for the Web Browser tool. The `validateTools` function now takes a `user` parameter and checks for user-specific API keys before falling back to environment variables. The `loadTools` function now takes a `user` parameter and initializes the tools with user-specific API keys if available. The `manifest.json` file has been updated to include the new `authConfig` fields for the tools that support user-specific API keys. The `askGPTPlugins.js` file has been updated to use the `validateTools` function with the `user` parameter. refactor(ChatAgent.js): add user parameter to initialize function and pass it to loadTools function refactor(tools/index.js): set default value for tools parameter in validateTools function refactor(askGPTPlugins.js): remove duplicate user variable declaration and use the one from req object * refactor(ChatAgent.js): await validTool() before pushing to this.tools array refactor(tools/index.js): use Map instead of Set to store valid tools refactor(tools/index.js): filter availableTools to only validate tools passed in refactor(PluginController.js): filter out duplicate plugins by pluginKey refactor(crypto.js): use environment variables for encryption key and initialization vector feat(PluginService.js): add null check for pluginAuth in getUserPluginAuthValue() * feat(api): add credentials key and IV to .env.example for securely storing credentials * Adds testing for handling tools, introducing a test env to the backend Fixes bugs & optimizes code as revealed through testing, including: - wolfram.js: fixes bug where wolfram was not handling authentication - ChatAgent.js: ChatAgent modified to reflect 'handleTools' changes - handleTools.js: Moves logic out of index file - handleTools.js: loadTools: returns only requested tools - handleTools.js: validTools: correctly returns tools based on authentication * test(index.test.js): add test to validate a tool from an environment variable * test(tools): add test for initializing an authenticated tool through Environment Variables * refactor(ChatAgent.js): remove commented out code and unused imports * refactor(ChatAgent.js): move instructions to a separate file and import them fix(ChatAgent.js): replace hardcoded instructions with imported ones * refactor(ChatAgent.js): change import path for TextStream refactor(stream.js): remove unused TextStream class * chore(.gitignore): add .env.test to gitignore refactor(ChatAgent.js): rename CustomChatAgent to ChatAgent test(ChatAgent.test.js): add tests for ChatAgent class refactor(outputParser.js): remove OldOutputParser class refactor(outputParser.js): rename CustomOutputParser to OutputParser docs(.env.test.example): add comment explaining how to use OPENAI_API_KEY refactor(jestSetup.js): use dotenv to load environment variables from .env.test file * Various optimizations and config, add tests for PluginStoreDialog * test(ChatAgent.test.js): add test to check if chat history is returned correctly * test: unit tests for plugin store * test: add frontend-test script to root package.json * feat(ChatAgent.js, askGPTPlugins.js): add support for aborting chat requests (in progress) * test: add more client tests * feat(ChatAgent): allow plugin requests to be cancelled * feat(ChatAgent): allow message regeneration * feat(ChatAgent): remember last selected tools * Remove plugins we don't yet have from manifest.json * fix(ChatAgent.js): increase maxAttempts from 1 to 2 fix(ChatAgent.js): change error message to 'Cancelled.' if message was aborted mid-generation fix(openaiCreateImage.js): replace unwanted characters in input string fix(handlers.js): compare action.tool in lowercase to 'self-reflection' * fix(ChatAgent): Fix up plugin I/O formatting for n/a actions * refactor(Plugin.jsx): remove unused import statement feat(Plugin.jsx): add Plugin component with svg paths and styles * refactor: simplify credential encryption/decryption by using a single key and IV for all environments. Update crypto.js and .env.example files accordingly. * fix(ChatAgent.js): reduce maxAttempts from 2 to 1 feat(ChatAgent.js): add model information to responseMessage object feat(Message.js): add model field to messageSchema feat(Message.js): add model field to message object feat(Message.jsx): pass model information to getIcon function feat(getIcon.jsx): add Plugin component and handle plugin messages differently * feat(askGPTPlugins.js): add model property to the ask function response object feat(EndpointItem.jsx): add message property to the EndpointItem component feat(MessageHeader.jsx): add Plugin icon to the plugins section feat(MessageHeader.jsx): change alpha to beta in the plugins section feat(svg): add Plugin, GPTIcon, and BingIcon components to the svg folder refactor(EndpointItems.jsx): remove unused import statement * refactor(googleSearch.js, wolfram.js): change error handling to return a message instead of throwing an error * refactor(CustomAgent): remove commented code and change return object to include returnValues property * feat(CustomAgent.js): add currentDateString to createPrompt method options deps(api/package.json): update langchain to v0.0.81 * fix: do not show pagination if the maxPage is 1 * Add Zapier back to manifest (accidentally removed) * chore(api): update langchain dependency to version 0.0.84 * feat(DALL-E.js): add DALL-E tool for generating images using OpenAI's DALL-E API refactor(handleTools.js): update import for DALL-E tool refactor(index.test.js): update import for DALL-E tool refactor(stablediffusion.js): add check for image directory existence before saving image * refactor(CustomAgent): rename instructions prefix variable to gpt3 and add gpt4 instructions feat(CustomAgent): add support for gpt-4 model fix(initializeCustomAgent.js): pass model name to createPrompt method fix(outputParser.js): set selectedTool to 'self-reflection' when tool parsing fails * style(langchain/tools): update guidelines for image creation in DALL-E and StableDiffusion - Update guidelines for image creation in DALL-E and StableDiffusion tools - Emphasize the importance of "showing" and not "telling" the imagery in crafting input - Update formatting for the example prompt for generating a realistic portrait photo of a man - Generate images only once per human query unless explicitly requested by the user * docs(tools): update tool descriptions for DALL-E and Stable Diffusion - Update the description for DALL-E tool to indicate that it is exclusively for visual content and provide guidelines for generating images with a focus on visual attributes. - Update the description for Stable Diffusion tool to indicate that it is exclusively for visual content and provide guidelines for generating images with a focus on visual attributes. * chore(api): update "@waylaidwanderer/chatgpt-api" dependency to version "^1.36.3" * refactor(ChatAgent.js): use environment variable for reverse proxy url refactor(ChatAgent.js): use environment variable for openai base path refactor(instructions.js): update gpt3 and gpt3-v2 instructions refactor(outputParser.js): update finishToolNameRegex in CustomOutputParser class * refactor(DALL-E.js): change apiKey and azureKey fields to uppercase refactor(googleSearch.js): change cx and apiKey fields to uppercase feat(manifest.json): add authConfig field for Stable Diffusion WebUI API URL refactor(stablediffusion.js): add url field to constructor and change getServerURL() to this.url refactor(wolfram.js): change apiKey field to uppercase WOLFRAM_APP_ID * refactor(handleTools.js): simplify tool loading and add support for custom tool constructors and options * refactor(handleTools.js): remove commented out code and unused imports * refactor(handleTools.js, index.js): change file name from wolfram.js to Wolfram.js and selfReflection.js to SelfReflection.js to follow PascalCase convention * refactor(outputParser.js, askGPTPlugins.js): improve code readability and remove unnecessary comments * feat(GoogleSearch.js): add GoogleSearchAPI tool to allow agents to use the Google Custom Search API feat(SelfReflection.js): add SelfReflectionTool to allow agents to reflect on their thoughts and actions feat(StableDiffusion.js): add StableDiffusionAPI tool to allow agents to generate images using stable diffusion webui's api feat(Wolfram.js): add WolframAlphaAPI tool for computation, math, curated knowledge & real-time data through WolframAlpha. * testing openai specs * doc: fix link in .env.example * package-update * fix(MultiSelectDropDown.jsx): handle null or undefined values in availableValues array * refactor(DALL-E.js, StableDiffusion.js): remove 'dist/' from image path feat(docker-compose.yml): add comments for reverse proxy configuration * chore(.gitignore): ignore client/public/images/ fix(DALL-E.js, StableDiffusion.js): change image path from dist/ to public/ feat(index.js): add support for serving static files from client/public/ directory * fix: remove selected tool when uninstalled * plugin options in progress * fix: fix issue with uninstalling a plugin that is in use and typescript errors * feat(gptPlugins): add Preset support for GPT Plugins endpoint feat(ChatAgent.js): add support for agentOptions object feat(convoSchema.js): add agentOptions field to conversation schema feat(defaults.js): add agentOptions object to defaults feat(presetSchema.js): add agentOptions field to preset schema feat(askGPTPlugins.js): add support for agentOptions object in request body feat(EditPresetDialog.jsx): add support for showing/hiding GPT Plugins agent settings feat(EditPresetDialog.jsx): add support for setting GPT Plugins agent options fix(EndpointOptionsDialog.jsx): change endpoint name from 'gptPlugins' to 'Plugins' feat(AgentSettings.jsx): add AgentSettings component for GPT plugins configuration feat(client): add GPT Plugins settings component and endpoint to Settings component fix(client): remove unused imports in GoogleOptions component feat(PluginsOptions): add support for agent settings and refactor code feat(PluginsOptions): add GPTIcon to show/hide agent settings button feat(index.ts): export SVG components feat(GPTIcon.jsx): add className prop to GPTIcon component feat(GPTIcon.jsx): import cn function from utils feat(BingIcon.tsx): export BingIcon component feat(index.ts): export BingIcon component feat(index.ts): export MessagesSquared component refactor(cleanupPreset.js): add default values for agentOptions in gptPlugins endpoint feat(getDefaultConversation.js, handleSubmit.js): add agentOptions object to conversation object for GPT plugins endpoint. Update default temperature value to 0.8. Add chatGptLabel and promptPrefix properties to conversation object. * fix: set default convo back to null * refactor(ChatAgent.js, askGPTPlugins.js, AgentSettings.jsx): change variable names for better readability and remove redundant code * test: add RecoilRoot to layout-test-utils * refactor(askGPTPlugins.js): remove redundant code and use endpointOption directly feat(askGPTPlugins.js): add validation for tools in endpointOption before using it * chore(ChatAgent.js, Settings.jsx): add agentOptions to saveConvo function and adjust Settings component height The ChatAgent.js file was modified to include the agentOptions object in the saveConvo function. The Settings.jsx file was modified to adjust the height of the component to ensure that all content is visible. * refactor(ChatAgent.js): extract reverseProxyUrl option to a class property and add support for it feat(ChatAgent.js): add support for completionMode option in sendApiMessage method feat(ChatAgent.js): add support for user-provided promptPrefix in buildPrompt method * feat(plugins): allow preset change mid conversation * chore: update OPENAI_KEY to OPENAI_API_KEY in .github/playwright.yml and api/.env.example refactor(chatgpt-client.js): update OPENAI_KEY to OPENAI_API_KEY feat(langchain): add demo-aiplugin.js and demo-yaml.js, remove test2.js, test3.js, and test4.js chore: remove unused test files fix(titleConvo.js): fix typo in environment variable name fix(askGPTPlugins.js): fix typo in environment variable name fix(endpoints.js): fix typo in environment variable name docs: update installation guide to use OPENAI_API_KEY instead of OPENAI_KEY in .env file * fix(index.test.js): change import of GoogleSearchAPI to use uppercase G in GoogleSearch * chore(api): bump langchain version * feat(PluginController.js): authenticate plugins from environment variables if they are set feat(PluginStoreDialog.tsx): show plugin auth form only if plugin is not authenticated by env var and require authentication feat(types.ts): add authenticated field to TPlugin type definition * docs: update google_search.md and add stable_diffusion.md * Update stable_diffusion.md * refactor(Wolfram.js): remove newline characters from query before encoding docs(wolfram.md): add instructions for setting WOLFRAM_APP_ID in api.env to bypass prompt for AppID in plugin * refactor(Wolfram.js): replace deprecated replaceAll method with replace method * Update wolfram.md * fix(askGPTPlugins): error message will reference correct Parent Message * refactor(chatgpt-client.js, ChatAgent.js): simplify maxContextTokens calculation and add promptPrefix parameter to buildPrompt method * docs: initial draft of intro to plugins * Update introduction.md * Update introduction.md * Feature: User/Reg cleanup + Install / Upgrade script for langchain (#427) * test: login tests * test: finish login tests * test: initial tests for registration * test: registration specs * feature: Init a app config file - Simplifies the ENV vars too - Legacy fallbacks for older builds * refactor(auth): Refactor log in/out controllers - Moves both login and logout controllers to their own file * chore(jwt): Throw warning if secret is default * feature(frontend): Ability to disable registration * feature(env): Env in the root + version support ie .env.prod, .env.dev, .env.test * feature: Upgrade .env script for users * chore(config): Refactor and remove legacy env refs * feature(upgrade): Upgrade script for .env changes * feature: Install script and upgrade script * bugfix: Uncomment line to remove old .env file * chore: rename OPENAI_KEY to OPENAI_API_KEY * chore: Cleanup config changes/bugs * bugfix: Fix config and node env issues * bugfix: Config validation logic * bugfix: Handle unusual env configs gracefully * bugfix: Revert route changes and fix registration disable calling * bugfix: Fix env issues in frontend * bugfix: Fix login * bugfix: Fix frontend envs * bugfix: Fix frontend jest tests * bugfix: Fix upgrade scripts * bugfix: Allow install in non-tty envs * bugfix(windows): Use cross-env to set for windows * bugfix(env): Handle .env being incorrect to begin with for client domain * chore(merge-conflict): Update to LibreChat * chore(merge-conflict): Update to package-lock --------- Co-authored-by: Daniel D Orlando <dan@danorlando.com> * chore: comment out unused agent options * Update langchain plugins docs (#461) * Update: install docs (LibreChat) (#458) * Release: rename project from ChatGPT Clone to LibreChat Release: rename project from ChatGPT Clone to LibreChat * Release: rename project from ChatGPT Clone to LibreChat Release: rename project from ChatGPT Clone to LibreChat * Release: rename project from ChatGPT Clone to LibreChat Release: rename project from ChatGPT Clone to LibreChat * Release: rename project from ChatGPT Clone to LibreChat Release: rename project from ChatGPT Clone to LibreChat * Update documentation_guidelines.md * Update introduction.md add link to readme * Update stable_diffusion.md add link back to readme * Update wolfram.md add link back to readme * Update README.md add Plugins to ToC * feat(ChatAgent.js): add support for langchainProxy configuration option Add a new configuration option `langchainProxy` to the ChatAgent class. If the option is set, the `basePath` configuration option of the `ChatOpenAI` instance is set to the base path of `langchainProxy`. * bugfix(errors): Possible workaround for error flashing (#463) * Test/user auth system client tests (#462) * test: login tests * test: finish login tests * test: initial tests for registration * test: registration specs * chore(api): update langchain dependency to version 0.0.91 * Update introduction.md * Update introduction.md * Update introduction.md * fix: no longer renders html in markdown content fix: patch XSS vulnerability completely by handling cursor on the frontend without css/html * fix(Content.jsx): fix cursor logic so it never shows for static messages * bugfix(langchain): Upgrade script, docker, env and docs (#465) * bugfix(errors): Remove incorrect manual fix from misunderstanding * chore(env): Lets not make a .env.prod and use the prod values in the default root .env - .env.dev will still be created * chore(upgrade.js): Lets tell the user about .env.dev if we create it * bugfix(env): Move to full name environments for vite - .env.prod => .env.production - .env.dev => .env.development * chore(env-example): Explain how to get google login working in production * bugfix(oauth): Minor fix to point isProduction to a correct value * bugfix: Typo in public * chore(docs): Update docs to note the changes to .env * chore(docs): Include note on how to get google auth working in dev and how to disable registration * bugfix: Fix missing env changes * bugfix: Fix up docker to work with new env / npm changes * Update .env.example Cleanup the env of the palm2 instruction and fix to formating * chore(docker): Simplify Docker deployments - Needs work to support dev env/hotreload * bugfix: Remove volume map for client dir * chore(env-example): Change instructions to be more user centric --------- Co-authored-by: Fuegovic <32828263+fuegovic@users.noreply.github.com> * update: install docs (#466) * Add files via upload * Update apis-and-tokens.md * Update apis-and-tokens.md * Update docker_install.md * Update linux_install.md * Rename apis-and-tokens.md to apis_and_tokens.md * Update docker_install.md * Update linux_install.md * Update mac_install.md * Update linux_install.md * Update docker_install.md * Update windows_install.md * Update apis_and_tokens.md * Update mac_install.md * Update linux_install.md * Update docker_install.md * Update README.md * Update README.md : Breaking Changes --------- Co-authored-by: Danny Avila <110412045+danny-avila@users.noreply.github.com> * Update README.md (#468) add new API/Token docs to Toc * docs: guide on how to create your own plugin * Update make_your_own.md * Update make_your_own.md * feat(docker): add build args for frontend variables in Dockerfile feat(docker-compose): add build args for frontend variables in docker-compose.yml * Update docker_install.md * Update docker_install.md * Update docker_install.md * Update docker_install.md * docs: update (#469) * Update: make_your_own.md * Update README.md add `make_your_own.md` to ToC * Update linux_install.md * Update mac_install.md * Update windows_install.md * Update apis_and_tokens.md * Update docker_install.md * Update docker_install.md * Update linux_install.md * Update mac_install.md * Update windows_install.md * Update apis_and_tokens.md * Update user_auth_system.md * Update docker_install.md clean up of repeated information * Update docker_install.md * Update docker_install.md typo * fix: fix issue with pluginstore next and prev buttons going out of bounds * fix: add icon for web browser plugin * docs(GoogleSearch.js): update description of GoogleSearchAPI class to be more descriptive of its functionality * feat(ask/handlers.js): add cursor to indicate ongoing progress of a long-running task fix(Content.jsx): handle null content in the message stream by replacing it with an empty string (with a space so a text space is rendered) * Update README.md * Update README.md * fix: plugin option stacking order * update: web browser icon (#470) * Delete web-browser.png * update: web browser icon * Update readme (#472) * Update README.md Discord badge now displays the number of online users Project description has been updated to reflect current status Feature section has been updated to reflect current capabilities Sponsors section is now located just above the contributors section Roadmap has been removed as it was outdated. * Delete roadmap.md Roadmap has been removed to streamline document maintenance. * Update README.md * Update README.md * Delete CHANGELOG.md * fix: pluginstore in mobile view getting clipped and not scrolling * docs(linux_install.md): remove duplicate git clone command * chore(Dockerfile): comment out nginx-client build stage docs(README.md): update installation instructions and mention docker-compose changes docs(features/plugins/introduction.md): bold plugin names and add emphasis to notes * feat: add superscript and subscript support to markdown rendering refactor: support markdown citations for BingAI * refactor: support markdown citations for BingAI --------- Co-authored-by: David Shin <42793498+dncc89@users.noreply.github.com> Co-authored-by: Daniel D Orlando <dan@danorlando.com> Co-authored-by: LaraClara <2524209+ClaraLeigh@users.noreply.github.com> Co-authored-by: Fuegovic <32828263+fuegovic@users.noreply.github.com>
2023-06-10 19:10:03 -04:00
} catch (error) {
res.status(500).json({ message: error.message });
}
};
✨ feat: Assistants API, General File Support, Side Panel, File Explorer (#1696) * feat: assistant name/icon in Landing & Header * feat: assistname in textarea placeholder, and use `Assistant` as default name * feat: display non-image files in user messages * fix: only render files if files.length is > 0 * refactor(config -> file-config): move file related configuration values to separate module, add excel types * chore: spreadsheet file rendering * fix(Landing): dark mode style for Assistant Name * refactor: move progress incrementing to own hook, start smaller, cap near limit \(1\) * refactor(useContentHandler): add empty Text part if last part was completed tool or image * chore: add accordion trigger border styling for dark mode * feat: Assistant Builder model selection * chore: use Spinner when Assistant is mutating * fix(get/assistants): return correct response object `AssistantListResponse` * refactor(Spinner): pass size as prop * refactor: make assistant crud mutations optimistic, add types for options * chore: remove assistants route and view * chore: move assistant builder components to separate directory * feat(ContextButton): delete Assistant via context button/dialog, add localization * refactor: conditionally show use and context menu buttons, add localization for create assistant * feat: save side panel states to localStorage * style(SidePanel): improve avatar menu and assistant select styling for dark mode * refactor: make NavToggle reusable for either side (left or right), add SidePanel Toggle with ability to close it completely * fix: resize handle and navToggle behavior * fix(/avatar/:assistant_id): await `deleteFile` and assign unique name to uploaded image * WIP: file UI components from PR #576 * refactor(OpenAIMinimalIcon): pass className * feat: formatDate helper fn * feat: DataTableColumnHeader * feat: add row selection, formatted row values, number of rows selected * WIP: add files to Side panel temporarily * feat: `LB_QueueAsyncCall`: Leaky Bucket queue for external APIs, use in `processDeleteRequest` * fix(TFile): correct `source` type with `FileSources` * fix(useFileHandling): use `continue` instead of return when iterating multiple files, add file type to extendedFile * chore: add generic setter type * refactor(processDeleteRequest): settle promises to prevent rejections from processing deletions, log errors * feat: `useFileDeletion` to reuse file deletion logic * refactor(useFileDeletion): make `setFiles` an optional param and use object as param * feat: useDeleteFilesFromTable * feat: use real `files` data and add deletion action to data table * fix(Table): make headers sticky * feat: add dynamic filtering for columns; only show to user Host or OpenAI storage type * style(DropdownMenu): replace `slate` with `gray` * style(DataTable): apply dark mode themes and other misc styling * style(Columns): add color to OpenAI Storage option * refactor(FileContainer): make file preview reusable * refactor(Images): make image preview reusable * refactor(FilePreview): make file prop optional for FileIcon and FilePreview, fix relative style * feat(Columns): add file/image previews, set a minimum size to show for file size in bytes * WIP: File Panel with real files and formatted * feat: open files dialog from panel * style: file data table mobile and general column styling fixes * refactor(api/files): return files sorted by the most recently updated * refactor: provide fileMap through context to prevent re-selecting files to map in different areas; remove unused imports commented out in PanelColumns * refactor(ExtendFile): make File type optional, add `attached` to prevent attached files from being deleted on remove, make Message.files a partial TFile type * feat: attach files through file panel * refactor(useFileHandling): move files to the start of cache list when uploaded * refactor(useDeleteFilesMutation): delete files from cache when successfully deleted from server * fix(FileRow): handle possible edge case of duplication due to attaching recently uploaded file * style(SidePanel): make resize grip border transparent, remove unnecessary styling on close sidepanel button * feat: action utilities and tests * refactor(actions): add `ValidationResult` type and change wording for no server URL found * refactor(actions): check for empty server URL * fix(data-provider): revert tsconfig to fix type issue resolution * feat(client): first pass of actions input for assistants * refactor(FunctionSignature): change method to output object instead of string * refactor(models/Assistant): add actions field to schema, use searchParams object for methods, and add `getAssistant` * feat: post actions input first pass - create new Action document - add actions to Assistant DB document - create /action/:assistant_id POST route - pass more props down from PanelSwitcher, derive assistant_id from switcher - move privacy policy to ActionInput - reset data on input change/validation - add `useUpdateAction` - conform FunctionSignature type to FunctionTool - add action, assistant doc, update hook related types * refactor: optimize assistant/actions relationship - past domain in metadata as hostname and not a URL - include domain in tool name - add `getActions` for actions retrieval by user - add `getAssistants` for assistant docs retrieval by user - add `assistant_id` to Action schema - move actions to own module as a subroute to `api/assistants` - add `useGetActionsQuery` and `useGetAssistantDocsQuery` hooks - fix Action type def * feat: show assistant actions in assistant builder * feat: switch to actions on action click, editing action styling * fix: add Assistant state for builder panel to allow immediate selection of newly created assistants as well as retaining the current assistant when switching to a different panel within the builder * refactor(SidePanel/NavToggle): offset less from right when SidePanel is completely collapsed * chore: rename `processActions` -> `processRequiredActions` * chore: rename Assistant API Action to RequiredAction * refactor(actions): avoid nesting actual API params under generic `requestBody` to optimize LLM token usage * fix(handleTools): avoid calling `validTool` if not defined, add optional param to skip the loading of specs, which throws an error in the context of assistants * WIP: working first pass of toolCalls generated from openapi specs * WIP: first pass ToolCall styling * feat: programmatic iv encryption/decryption helpers * fix: correct ActionAuth types/enums, and define type for AuthForm * feat: encryption/decryption helpers for Action AuthMetadata * refactor(getActions): remove sensitive fields from query response * refactor(POST/actions): encrypt and remove sensitive fields from mutation response * fix(ActionService): change ESM import to CJS * feat: frontend auth handling for actions + optimistic update on action update/creation * refactor(actions): use the correct variables and types for setAuth method * refactor: POST /:assistant_id action can now handle updating an existing action, add `saved_auth_fields` to determine when user explicitly saves new auth creds. only send auth metadata if user explicitly saved fields * refactor(createActionTool): catch errors and send back meaningful error message, add flag to `getActions` to determine whether to retrieve sensitive values or not * refactor(ToolService): add `action` property to ToolCall PartMetadata to determine if the tool call was an action, fix parsing function name issue with actionDelimiter * fix(ActionRequest): use URL class to correctly join endpoint parts for `execute` call * feat: delete assistant actions * refactor: conditionally show Available actions * refactor: show `retrieval` and `code_interpreter` as Capabilities, swap `Switch` for `Checkbox` * chore: remove shadow-stroke from messages * WIP: first pass of Assistants Knowledge attachments * refactor: remove AssistantsProvider in favor of FormProvider, fix selectedAssistant re-render bug, map Assistant file_ids to files via fileMap, initialize Knowledge component with mapped files if any exist * fix: prevent deleting files on assistant file upload * chore: remove console.log * refactor(useUploadFileMutation): update files and assistants cache on upload * chore: disable oauth option as not supported yet * feat: cancel assistant runs * refactor: initialize OpenAI client with helper function, resolve all related circular dependencies * fix(DALL-E): initialization * fix(process): openai client initialization * fix: select an existing Assistant when the active one is deleted * chore: allow attaching files for assistant endpoint, send back relevant OpenAI error message when uploading, deconstruct openAI initialization correctly, add `message_file` to formData when a file is attached to the message but not the assistant * fix: add assistant_id on newConvo * fix(initializeClient): import fix * chore: swap setAssistant for setOption in useEffect * fix(DALL-E): add processFileURL to loadTools call * chore: add customConfig to debug logs * feat: delete threads on convo delete * chore: replace Assistants icon * chore: remove console.dir() in `abortRun` * feat(AssistantService): accumulate text values from run in openai.responseText * feat: titling for assistants endpoint * chore: move panel file components to appropriate directory, add file checks for attaching files, change icon for Attach Files * refactor: add localizations to tools, plugins, add condition for adding/remove user plugins so tool selections don't affect this value * chore: disable `import from url` action for now * chore: remove textMimeTypes from default fileConfig for now * fix: catch tool errors and send as outputs with error messages * fix: React warning about button as descendant of button * style: retrieval and cancelled icon * WIP: pass isSubmitting to Parts, use InProgressCall to display cancelled tool calls correctly, show domain/function name * fix(meilisearch): fix `postSaveHook` issue where indexing expects a mongo document, and join all text content parts for meili indexing * ci: fix dall-e tests * ci: fix client tests * fix: button types in actions panel * fix: plugin auth form persisting across tool selections * fix(ci): update AppService spec with `loadAndFormatTools` * fix(clearConvos): add id check earlier on * refactor(AssistantAvatar): set previewURL dynamically when emtadata.avatar changes * feat(assistants): addTitle cache setting * fix(useSSE): resolve rebase conflicts * fix: delete mutation * style(SidePanel): make grip visible on active and hover, invisible otherwise * ci: add data-provider tests to workflow, also update eslint/tsconfig to recognize specs, and add `text/csv` to fileConfig * fix: handle edge case where auth object is undefined, and log errors * refactor(actions): resolve schemas, add tests for resolving refs, import specs from separate file for tests * chore: remove comment * fix(ActionsInput): re-render bug when initializing states with action fields * fix(patch/assistant): filter undefined tools * chore: add logging for errors in assistants routes * fix(updateAssistant): map actions to functions to avoid overwriting * fix(actions): properly handle GET paths * fix(convos): unhandled delete thread exception * refactor(AssistantService): pass both thread_id and conversationId when sending intermediate assistant messages, remove `mapMessagesToSteps` from AssistantService * refactor(useSSE): replace all messages with runMessages and pass latestMessageId to abortRun; fix(checkMessageGaps): include tool calls when syncing messages * refactor(assistants/chat): invoke `createOnTextProgress` after thread creation * chore: add typing * style: sidepanel styling * style: action tool call domain styling * feat(assistants): default models, limit retrieval to certain models, add env variables to to env.example * feat: assistants api key in EndpointService * refactor: set assistant model to conversation on assistant switch * refactor: set assistant model to conversation on assistant select from panel * fix(retrieveAndProcessFile): catch attempt to download file with `assistant` purpose which is not allowed; add logging * feat: retrieval styling, handling, and logging * chore: rename ASSISTANTS_REVERSE_PROXY to ASSISTANTS_BASE_URL * feat: FileContext for file metadata * feat: context file mgmt and filtering * style(Select): hover/rounded changes * refactor: explicit conversation switch, endpoint dependent, through `useSelectAssistant`, which does not create new chat if current endpoint is assistant endpoint * fix(AssistantAvatar): make empty previewURL if no avatar present * refactor: side panel mobile styling * style: merge tool and action section, optimize mobile styling for action/tool buttons * fix: localStorage issues * fix(useSelectAssistant): invoke react query hook directly in select hook as Map was not being updated in time * style: light mode fixes * fix: prevent sidepanel nav styling from shifting layout up * refactor: change default layout (collapsed by default) * style: mobile optimization of DataTable * style: datatable * feat: client-side hide right-side panel * chore(useNewConvo): add partial typing for preset * fix(useSelectAssistant): pass correct model name by using template as preset * WIP: assistant presets * refactor(ToolService): add native solution for `TavilySearchResults` and log tool output errors * refactor: organize imports and use native TavilySearchResults * fix(TavilySearchResults): stringify result * fix(ToolCall): show tool call outputs when not an action * chore: rename Prompt Prefix to custom instructions (in user facing text only) * refactor(EditPresetDialog): Optimize setting title by debouncing, reset preset on dialog close to avoid state mixture * feat: add `presetOverride` to overwrite active conversation settings when saving a Preset (relevant for client side updates only) * feat: Assistant preset settings (client-side) * fix(Switcher): only set assistant_id and model if current endpoint is Assistants * feat: use `useDebouncedInput` for updating conversation settings, starting with EditPresetDialog title setting and Assistant instructions setting * feat(Assistants): add instructions field to settings * feat(chat/assistants): pass conversation settings to run body * wip: begin localization and only allow actions if the assistant is created * refactor(AssistantsPanel): knowledge localization, allow tools on creation * feat: experimental: allow 'priming' values before assistant is created, that would normally require an assistant_id to be defined * chore: trim console logs and make more meaningful * chore: toast messages * fix(ci): date test * feat: create file when uploading Assistant Avatar * feat: file upload rate limiting from custom config with dynamic file route initialization * refactor: use file upload limiters on post routes only * refactor(fileConfig): add endpoints field for endpoint specific fileconfigs, add mergeConfig function, add tests * refactor: fileConfig route, dynamic multer instances used on all '/' and '/images' POST routes, data service and query hook * feat: supportedMimeTypesSchema, test for array of regex * feat: configurable file config limits * chore: clarify assistants file knowledge prereq. * chore(useTextarea): default to localized 'Assistant' if assistant name is empty * feat: configurable file limits and toggle file upload per endpoint * fix(useUploadFileMutation): prevent updating assistant.files cache if file upload is a message_file attachment * fix(AssistantSelect): set last selected assistant only when timeout successfully runs * refactor(queries): disable assistant queries if assistants endpoint is not enabled * chore(Switcher): add localization * chore: pluralize `assistant` for `EModelEndpoint key and value * feat: show/hide assistant UI components based on endpoint availability; librechat.yaml config for disabling builder section and setting polling/timeout intervals * fix(compactEndpointSchemas): use EModelEndpoint for schema access * feat(runAssistant): use configured values from `librechat.yaml` for `pollIntervalMs` and `timeout` * fix: naming issue * wip: revert landing * 🎉 happy birthday LibreChat (#1768) * happy birthday LibreChat * Refactor endpoint condition in Landing component * Update birthday message in Eng.tsx * fix(/config): avoid nesting ternaries * refactor(/config): check birthday --------- Co-authored-by: Danny Avila <messagedaniel@protonmail.com> * fix: landing * fix: landing * fix(useMessageHelpers): hardcoded check to use EModelEndpoint instead * fix(ci): convo test revert to main * fix(assistants/chat): fix issue where assistant_id was being saved as model for convo * chore: added logging, promises racing to prevent longer timeouts, explicit setting of maxRetries and timeouts, robust catching of invalid abortRun params * refactor: use recoil state for `showStopButton` and only show for assistants endpoint after syncing conversation data * refactor: optimize abortRun strategy using localStorage, refactor `abortConversation` to use async/await and await the result, refactor how the abortKey cache is set for runs * fix(checkMessageGaps): assign `assistant_id` to synced messages if defined; prevents UI from showing blank assistant for cancelled messages * refactor: re-order sequence of chat route, only allow aborting messages after run is created, cancel abortRun if there was a cancelling error (likely due already cancelled in chat route), and add extra logging * chore(typedefs): add httpAgent type to OpenAIClient * refactor: use custom implementation of retrieving run with axios to allow for timing out run query * fix(waitForRun): handle timed out run retrieval query * refactor: update preset conditions: - presets will retain settings when a different endpoint is selected; for existing convos, either when modular or is assistant switch - no longer use `navigateToConvo` on preset select * fix: temporary calculator hack as expects string input when invoked * fix: cancel abortRun only when cancelling error is a result of the run already being cancelled * chore: remove use of `fileMaxSizeMB` and total counterpart (redundant) * docs: custom config documentation update * docs: assistants api setup and dotenv, new custom config fields * refactor(Switcher): make Assistant switcher sticky in SidePanel * chore(useSSE): remove console log of data and message index * refactor(AssistantPanel): button styling and add secondary select button to bottom of panel * refactor(OpenAIClient): allow passing conversationId to RunManager through titleConvo and initializeLLM to properly record title context tokens used in cases where conversationId was not defined by the client * feat(assistants): token tracking for assistant runs * chore(spendTokens): improve logging * feat: support/exclude specific assistant Ids * chore: add update `librechat.example.yaml`, optimize `AppService` handling, new tests for `AppService`, optimize missing/outdate config logging * chore: mount docker logs to root of project * chore: condense axios errors * chore: bump vite * chore: vite hot reload fix using latest version * chore(getOpenAIModels): sort instruct models to the end of models list * fix(assistants): user provided key * fix(assistants): user provided key, invalidate more queries on revoke --------- Co-authored-by: Marco Beretta <81851188+Berry-13@users.noreply.github.com>
2024-02-13 20:42:27 -05:00
/**
* Retrieves and returns a list of available tools, either from a cache or by reading a plugin manifest file.
*
* This function first attempts to retrieve the list of tools from a cache. If the tools are not found in the cache,
* it reads a plugin manifest file, filters for unique plugins, and determines if each plugin is authenticated.
* Only plugins that are marked as available in the application's local state are included in the final list.
* The resulting list of tools is then cached and sent to the client.
*
* @param {object} req - The request object, containing information about the HTTP request.
* @param {object} res - The response object, used to send back the desired HTTP response.
* @returns {Promise<void>} A promise that resolves when the function has completed.
*/
const getAvailableTools = async (req, res) => {
try {
const userId = req.user?.id;
if (!userId) {
logger.warn('[getAvailableTools] User ID not found in request');
return res.status(401).json({ message: 'Unauthorized' });
}
const cache = getLogStores(CacheKeys.TOOL_CACHE);
🏗️ feat: bulkWrite isolation, pre-auth context, strict-mode fixes (#12445) * fix: wrap seedDatabase() in runAsSystem() for strict tenant mode seedDatabase() was called without tenant context at startup, causing every Mongoose operation inside it to throw when TENANT_ISOLATION_STRICT=true. Wrapping in runAsSystem() gives it the SYSTEM_TENANT_ID sentinel so the isolation plugin skips filtering, matching the pattern already used for performStartupChecks and updateInterfacePermissions. * fix: chain tenantContextMiddleware in optionalJwtAuth optionalJwtAuth populated req.user but never established ALS tenant context, unlike requireJwtAuth which chains tenantContextMiddleware after successful auth. Authenticated users hitting routes with optionalJwtAuth (e.g. /api/banner) had no tenant isolation. * feat: tenant-safe bulkWrite wrapper and call-site migration Mongoose's bulkWrite() does not trigger schema-level middleware hooks, so the applyTenantIsolation plugin cannot intercept it. This adds a tenantSafeBulkWrite() utility that injects the current ALS tenant context into every operation's filter/document before delegating to native bulkWrite. Migrates all 8 runtime bulkWrite call sites: - agentCategory (seedCategories, ensureDefaultCategories) - conversation (bulkSaveConvos) - message (bulkSaveMessages) - file (batchUpdateFiles) - conversationTag (updateTagsForConversation, bulkIncrementTagCounts) - aclEntry (bulkWriteAclEntries) systemGrant.seedSystemGrants is intentionally not migrated — it uses explicit tenantId: { $exists: false } filters and is exempt from the isolation plugin. * feat: pre-auth tenant middleware and tenant-scoped config cache Adds preAuthTenantMiddleware that reads X-Tenant-Id from the request header and wraps downstream in tenantStorage ALS context. Wired onto /oauth, /api/auth, /api/config, and /api/share — unauthenticated routes that need tenant scoping before JWT auth runs. The /api/config cache key is now tenant-scoped (STARTUP_CONFIG:${tenantId}) so multi-tenant deployments serve the correct login page config per tenant. The middleware is intentionally minimal — no subdomain parsing, no OIDC claim extraction. The private fork's reverse proxy or auth gateway sets the header. * feat: accept optional tenantId in updateInterfacePermissions When tenantId is provided, the function re-enters inside tenantStorage.run({ tenantId }) so all downstream Mongoose queries target that tenant's roles instead of the system context. This lets the private fork's tenant provisioning flow call updateInterfacePermissions per-tenant after creating tenant-scoped ADMIN/USER roles. * fix: tenant-filter $lookup in getPromptGroup aggregation The $lookup stage in getPromptGroup() queried the prompts collection without tenant filtering. While the outer PromptGroup aggregate is protected by the tenantIsolation plugin's pre('aggregate') hook, $lookup runs as an internal MongoDB operation that bypasses Mongoose hooks entirely. Converts from simple field-based $lookup to pipeline-based $lookup with an explicit tenantId match when tenant context is active. * fix: replace field-level unique indexes with tenant-scoped compounds Field-level unique:true creates a globally-unique single-field index in MongoDB, which would cause insert failures across tenants sharing the same ID values. - agent.id: removed field-level unique, added { id, tenantId } compound - convo.conversationId: removed field-level unique (compound at line 50 already exists: { conversationId, user, tenantId }) - message.messageId: removed field-level unique (compound at line 165 already exists: { messageId, user, tenantId }) - preset.presetId: removed field-level unique, added { presetId, tenantId } compound * fix: scope MODELS_CONFIG, ENDPOINT_CONFIG, PLUGINS, TOOLS caches by tenant These caches store per-tenant configuration (available models, endpoint settings, plugin availability, tool definitions) but were using global cache keys. In multi-tenant mode, one tenant's cached config would be served to all tenants. Appends :${tenantId} to cache keys when tenant context is active. Falls back to the unscoped key when no tenant context exists (backward compatible for single-tenant OSS deployments). Covers all read, write, and delete sites: - ModelController.js: get/set MODELS_CONFIG - PluginController.js: get/set PLUGINS, get/set TOOLS - getEndpointsConfig.js: get/set/delete ENDPOINT_CONFIG - app.js: delete ENDPOINT_CONFIG (clearEndpointConfigCache) - mcp.js: delete TOOLS (updateMCPTools, mergeAppTools) - importers.js: get ENDPOINT_CONFIG * fix: add getTenantId to PluginController spec mock The data-schemas mock was missing getTenantId, causing all PluginController tests to throw when the controller calls getTenantId() for tenant-scoped cache keys. * fix: address review findings — migration, strict-mode, DRY, types Addresses all CRITICAL, MAJOR, and MINOR review findings: F1 (CRITICAL): Add agents, conversations, messages, presets to SUPERSEDED_INDEXES in tenantIndexes.ts so dropSupersededTenantIndexes() drops the old single-field unique indexes that block multi-tenant inserts. F2 (CRITICAL): Unknown bulkWrite op types now throw in strict mode instead of silently passing through without tenant injection. F3 (MAJOR): Replace wildcard export with named export for tenantSafeBulkWrite, hiding _resetBulkWriteStrictCache from the public package API. F5 (MAJOR): Restore AnyBulkWriteOperation<IAclEntry>[] typing on bulkWriteAclEntries — the unparameterized wrapper accepts parameterized ops as a subtype. F7 (MAJOR): Fix config.js tenant precedence — JWT-derived req.user.tenantId now takes priority over the X-Tenant-Id header for authenticated requests. F8 (MINOR): Extract scopedCacheKey() helper into tenantContext.ts and replace all 11 inline occurrences across 7 files. F9 (MINOR): Use simple localField/foreignField $lookup for the non-tenant getPromptGroup path (more efficient index seeks). F12 (NIT): Remove redundant BulkOp type alias. F13 (NIT): Remove debug log that leaked raw tenantId. * fix: add new superseded indexes to tenantIndexes test fixture The test creates old indexes to verify the migration drops them. Missing fixture entries for agents.id_1, conversations.conversationId_1, messages.messageId_1, and presets.presetId_1 caused the count assertion to fail (expected 22, got 18). * fix: restore logger.warn for unknown bulk op types in non-strict mode * fix: block SYSTEM_TENANT_ID sentinel from external header input CRITICAL: preAuthTenantMiddleware accepted any string as X-Tenant-Id, including '__SYSTEM__'. The tenantIsolation plugin treats SYSTEM_TENANT_ID as an explicit bypass — skipping ALL query filters. A client sending X-Tenant-Id: __SYSTEM__ to pre-auth routes (/api/share, /api/config, /api/auth, /oauth) would execute Mongoose operations without tenant isolation. Fixes: - preAuthTenantMiddleware rejects SYSTEM_TENANT_ID in header - scopedCacheKey returns the base key (not key:__SYSTEM__) in system context, preventing stale cache entries during runAsSystem() - updateInterfacePermissions guards tenantId against SYSTEM_TENANT_ID - $lookup pipeline separates $expr join from constant tenantId match for better index utilization - Regression test for sentinel rejection in preAuthTenant.spec.ts - Remove redundant getTenantId() call in config.js * test: add missing deleteMany/replaceOne coverage, fix vacuous ALS assertions bulkWrite spec: - deleteMany: verifies tenant-scoped deletion leaves other tenants untouched - replaceOne: verifies tenantId injected into both filter and replacement - replaceOne overwrite: verifies a conflicting tenantId in the replacement document is overwritten by the ALS tenant (defense-in-depth) - empty ops array: verifies graceful handling preAuthTenant spec: - All negative-case tests now use the capturedNext pattern to verify getTenantId() inside the middleware's execution context, not the test runner's outer frame (which was always undefined regardless) * feat: tenant-isolate MESSAGES cache, FLOWS cache, and GenerationJobManager MESSAGES cache (streamAudio.js): - Cache key now uses scopedCacheKey(messageId) to prefix with tenantId, preventing cross-tenant message content reads during TTS streaming. FLOWS cache (FlowStateManager): - getFlowKey() now generates ${type}:${tenantId}:${flowId} when tenant context is active, isolating OAuth flow state per tenant. GenerationJobManager: - tenantId added to SerializableJobData and GenerationJobMetadata - createJob() captures the current ALS tenant context (excluding SYSTEM_TENANT_ID) and stores it in job metadata - SSE subscription endpoint validates job.metadata.tenantId matches req.user.tenantId, blocking cross-tenant stream access - Both InMemoryJobStore and RedisJobStore updated to accept tenantId * fix: add getTenantId and SYSTEM_TENANT_ID to MCP OAuth test mocks FlowStateManager.getFlowKey() now calls getTenantId() for tenant-scoped flow keys. The 4 MCP OAuth test files mock @librechat/data-schemas without these exports, causing TypeError at runtime. * fix: correct import ordering per AGENTS.md conventions Package imports sorted shortest to longest line length, local imports sorted longest to shortest — fixes ordering violations introduced by our new imports across 8 files. * fix: deserialize tenantId in RedisJobStore — cross-tenant SSE guard was no-op in Redis mode serializeJob() writes tenantId to the Redis hash via Object.entries, but deserializeJob() manually enumerates fields and omitted tenantId. Every getJob() from Redis returned tenantId: undefined, causing the SSE route's cross-tenant guard to short-circuit (undefined && ... → false). * test: SSE tenant guard, FlowStateManager key consistency, ALS scope docs SSE stream tenant tests (streamTenant.spec.js): - Cross-tenant user accessing another tenant's stream → 403 - Same-tenant user accessing own stream → allowed - OSS mode (no tenantId on job) → tenant check skipped FlowStateManager tenant tests (manager.tenant.spec.ts): - completeFlow finds flow created under same tenant context - completeFlow does NOT find flow under different tenant context - Unscoped flows are separate from tenant-scoped flows Documentation: - JSDoc on getFlowKey documenting ALS context consistency requirement - Comment on streamAudio.js scopedCacheKey capture site * fix: SSE stream tests hang on success path, remove internal fork references The success-path tests entered the SSE streaming code which never closes, causing timeout. Mock subscribe() to end the response immediately. Restructured assertions to verify non-403/non-404. Removed "private fork" and "OSS" references from code and test descriptions — replaced with "deployment layer", "multi-tenant deployments", and "single-tenant mode". * fix: address review findings — test rigor, tenant ID validation, docs F1: SSE stream tests now mock subscribe() with correct signature (streamId, writeEvent, onDone, onError) and assert 200 status, verifying the tenant guard actually allows through same-tenant users. F2: completeFlow logs the attempted key and ALS tenantId when flow is not found, so reverse proxy misconfiguration (missing X-Tenant-Id on OAuth callback) produces an actionable warning. F3/F10: preAuthTenantMiddleware validates tenant ID format — rejects colons, special characters, and values exceeding 128 chars. Trims whitespace. Prevents cache key collisions via crafted headers. F4: Documented cache invalidation scope limitation in clearEndpointConfigCache — only the calling tenant's key is cleared; other tenants expire via TTL. F7: getFlowKey JSDoc now lists all 8 methods requiring consistent ALS context. F8: Added dedicated scopedCacheKey unit tests — base key without context, base key in system context, scoped key with tenant, no ALS leakage across scope boundaries. * fix: revert flow key tenant scoping, fix SSE test timing FlowStateManager: Reverts tenant-scoped flow keys. OAuth callbacks arrive without tenant ALS context (provider redirects don't carry X-Tenant-Id), so completeFlow/failFlow would never find flows created under tenant context. Flow IDs are random UUIDs with no collision risk, and flow data is ephemeral (TTL-bounded). SSE tests: Use process.nextTick for onDone callback so Express response headers are flushed before res.write/res.end are called. * fix: restore getTenantId import for completeFlow diagnostic log * fix: correct completeFlow warning message, add missing flow test The warning referenced X-Tenant-Id header consistency which was only relevant when flow keys were tenant-scoped (since reverted). Updated to list actual causes: TTL expiry, missing flow, or routing to a different instance without shared Keyv storage. Removed the getTenantId() call and import — no longer needed since flow keys are unscoped. Added test for the !flowState branch in completeFlow — verifies return false and logger.warn on nonexistent flow ID. * fix: add explicit return type to recursive updateInterfacePermissions The recursive call (tenantId branch calls itself without tenantId) causes TypeScript to infer circular return type 'any'. Adding explicit Promise<void> satisfies the rollup typescript plugin. * fix: update MCPOAuthRaceCondition test to match new completeFlow warning * fix: clearEndpointConfigCache deletes both scoped and unscoped keys Unauthenticated /api/endpoints requests populate the unscoped ENDPOINT_CONFIG key. Admin config mutations clear only the tenant-scoped key, leaving the unscoped entry stale indefinitely. Now deletes both when in tenant context. * fix: tenant guard on abort/status endpoints, warn logs, test coverage F1: Add tenant guard to /chat/status/:conversationId and /chat/abort matching the existing guard on /chat/stream/:streamId. The status endpoint exposes aggregatedContent (AI response text) which requires tenant-level access control. F2: preAuthTenantMiddleware now logs warn for rejected __SYSTEM__ sentinel and malformed tenant IDs, providing observability for bypass probing attempts. F3: Abort fallback path (getActiveJobIdsForUser) now has tenant check after resolving the job. F4: Test for strict mode + SYSTEM_TENANT_ID — verifies runAsSystem bypasses tenantSafeBulkWrite without throwing in strict mode. F5: Test for job with tenantId + user without tenantId → 403. F10: Regex uses idiomatic hyphen-at-start form. F11: Test descriptions changed from "rejects" to "ignores" since middleware calls next() (not 4xx). Also fixes MCPOAuthRaceCondition test assertion to match updated completeFlow warning message. * fix: test coverage for logger.warn, status/abort guards, consistency A: preAuthTenant spec now mocks logger and asserts warn calls for __SYSTEM__ sentinel, malformed characters, and oversized headers. B: streamTenant spec expanded with status and abort endpoint tests — cross-tenant status returns 403, same-tenant returns 200 with body, cross-tenant abort returns 403. C: Abort endpoint uses req.user.tenantId (not req.user?.tenantId) matching stream/status pattern — requireJwtAuth guarantees req.user. D: Malformed header warning now includes ip in log metadata, matching the sentinel warning for consistent SOC correlation. * fix: assert ip field in malformed header warn tests * fix: parallelize cache deletes, document tenant guard, fix import order - clearEndpointConfigCache uses Promise.all for independent cache deletes instead of sequential awaits - SSE stream tenant guard has inline comment explaining backward-compat behavior for untenanted legacy jobs - conversation.ts local imports reordered longest-to-shortest per AGENTS.md * fix: tenant-qualify userJobs keys, document tenant guard backward-compat Job store userJobs keys now include tenantId when available: - Redis: stream:user:{tenantId:userId}:jobs (falls back to stream:user:{userId}:jobs when no tenant) - InMemory: composite key tenantId:userId in userJobMap getActiveJobIdsByUser/getActiveJobIdsForUser accept optional tenantId parameter, threaded through from req.user.tenantId at all call sites (/chat/active and /chat/abort fallback). Added inline comments on all three SSE tenant guards explaining the backward-compat design: untenanted legacy jobs remain accessible when the userId check passes. * fix: parallelize cache deletes, document tenant guard, fix import order Fix InMemoryJobStore.getActiveJobIdsByUser empty-set cleanup to use the tenant-qualified userKey instead of bare userId — prevents orphaned empty Sets accumulating in userJobMap for multi-tenant users. Document cross-tenant staleness in clearEndpointConfigCache JSDoc — other tenants' scoped keys expire via TTL, not active invalidation. * fix: cleanup userJobMap leak, startup warning, DRY tenant guard, docs F1: InMemoryJobStore.cleanup() now removes entries from userJobMap before calling deleteJob, preventing orphaned empty Sets from accumulating with tenant-qualified composite keys. F2: Startup warning when TENANT_ISOLATION_STRICT is active — reminds operators to configure reverse proxy to control X-Tenant-Id header. F3: mergeAppTools JSDoc documents that tenant-scoped TOOLS keys are not actively invalidated (matching clearEndpointConfigCache pattern). F5: Abort handler getActiveJobIdsForUser call uses req.user.tenantId (not req.user?.tenantId) — consistent with stream/status handlers. F6: updateInterfacePermissions JSDoc clarifies SYSTEM_TENANT_ID behavior — falls through to caller's ALS context. F7: Extracted hasTenantMismatch() helper, replacing three identical inline tenant guard blocks across stream/status/abort endpoints. F9: scopedCacheKey JSDoc documents both passthrough cases (no context and SYSTEM_TENANT_ID context). * fix: clean userJobMap in evictOldest — same leak as cleanup()
2026-03-28 16:43:50 -04:00
const toolsCacheKey = scopedCacheKey(CacheKeys.TOOLS);
const cachedToolsArray = await cache.get(toolsCacheKey);
🛜 refactor: Streamline App Config Usage (#9234) * WIP: app.locals refactoring WIP: appConfig fix: update memory configuration retrieval to use getAppConfig based on user role fix: update comment for AppConfig interface to clarify purpose 🏷️ refactor: Update tests to use getAppConfig for endpoint configurations ci: Update AppService tests to initialize app config instead of app.locals ci: Integrate getAppConfig into remaining tests refactor: Update multer storage destination to use promise-based getAppConfig and improve error handling in tests refactor: Rename initializeAppConfig to setAppConfig and update related tests ci: Mock getAppConfig in various tests to provide default configurations refactor: Update convertMCPToolsToPlugins to use mcpManager for server configuration and adjust related tests chore: rename `Config/getAppConfig` -> `Config/app` fix: streamline OpenAI image tools configuration by removing direct appConfig dependency and using function parameters chore: correct parameter documentation for imageOutputType in ToolService.js refactor: remove `getCustomConfig` dependency in config route refactor: update domain validation to use appConfig for allowed domains refactor: use appConfig registration property chore: remove app parameter from AppService invocation refactor: update AppConfig interface to correct registration and turnstile configurations refactor: remove getCustomConfig dependency and use getAppConfig in PluginController, multer, and MCP services refactor: replace getCustomConfig with getAppConfig in STTService, TTSService, and related files refactor: replace getCustomConfig with getAppConfig in Conversation and Message models, update tempChatRetention functions to use AppConfig type refactor: update getAppConfig calls in Conversation and Message models to include user role for temporary chat expiration ci: update related tests refactor: update getAppConfig call in getCustomConfigSpeech to include user role fix: update appConfig usage to access allowedDomains from actions instead of registration refactor: enhance AppConfig to include fileStrategies and update related file strategy logic refactor: update imports to use normalizeEndpointName from @librechat/api and remove redundant definitions chore: remove deprecated unused RunManager refactor: get balance config primarily from appConfig refactor: remove customConfig dependency for appConfig and streamline loadConfigModels logic refactor: remove getCustomConfig usage and use app config in file citations refactor: consolidate endpoint loading logic into loadEndpoints function refactor: update appConfig access to use endpoints structure across various services refactor: implement custom endpoints configuration and streamline endpoint loading logic refactor: update getAppConfig call to include user role parameter refactor: streamline endpoint configuration and enhance appConfig usage across services refactor: replace getMCPAuthMap with getUserMCPAuthMap and remove unused getCustomConfig file refactor: add type annotation for loadedEndpoints in loadEndpoints function refactor: move /services/Files/images/parse to TS API chore: add missing FILE_CITATIONS permission to IRole interface refactor: restructure toolkits to TS API refactor: separate manifest logic into its own module refactor: consolidate tool loading logic into a new tools module for startup logic refactor: move interface config logic to TS API refactor: migrate checkEmailConfig to TypeScript and update imports refactor: add FunctionTool interface and availableTools to AppConfig refactor: decouple caching and DB operations from AppService, make part of consolidated `getAppConfig` WIP: fix tests * fix: rebase conflicts * refactor: remove app.locals references * refactor: replace getBalanceConfig with getAppConfig in various strategies and middleware * refactor: replace appConfig?.balance with getBalanceConfig in various controllers and clients * test: add balance configuration to titleConvo method in AgentClient tests * chore: remove unused `openai-chat-tokens` package * chore: remove unused imports in initializeMCPs.js * refactor: update balance configuration to use getAppConfig instead of getBalanceConfig * refactor: integrate configMiddleware for centralized configuration handling * refactor: optimize email domain validation by removing unnecessary async calls * refactor: simplify multer storage configuration by removing async calls * refactor: reorder imports for better readability in user.js * refactor: replace getAppConfig calls with req.config for improved performance * chore: replace getAppConfig calls with req.config in tests for centralized configuration handling * chore: remove unused override config * refactor: add configMiddleware to endpoint route and replace getAppConfig with req.config * chore: remove customConfig parameter from TTSService constructor * refactor: pass appConfig from request to processFileCitations for improved configuration handling * refactor: remove configMiddleware from endpoint route and retrieve appConfig directly in getEndpointsConfig if not in `req.config` * test: add mockAppConfig to processFileCitations tests for improved configuration handling * fix: pass req.config to hasCustomUserVars and call without await after synchronous refactor * fix: type safety in useExportConversation * refactor: retrieve appConfig using getAppConfig in PluginController and remove configMiddleware from plugins route, to avoid always retrieving when plugins are cached * chore: change `MongoUser` typedef to `IUser` * fix: Add `user` and `config` fields to ServerRequest and update JSDoc type annotations from Express.Request to ServerRequest * fix: remove unused setAppConfig mock from Server configuration tests
2025-08-26 12:10:18 -04:00
🧵 feat: ALS Context Middleware, Tenant Threading, and Config Cache Invalidation (#12407) * feat: add tenant context middleware for ALS-based isolation Introduces tenantContextMiddleware that propagates req.user.tenantId into AsyncLocalStorage, activating the Mongoose applyTenantIsolation plugin for all downstream DB queries within a request. - Strict mode (TENANT_ISOLATION_STRICT=true) returns 403 if no tenantId - Non-strict mode passes through for backward compatibility - No-op for unauthenticated requests - Includes 6 unit tests covering all paths * feat: register tenant middleware and wrap startup/auth in runAsSystem() - Register tenantContextMiddleware in Express app after capability middleware - Wrap server startup initialization in runAsSystem() for strict mode compat - Wrap auth strategy getAppConfig() calls in runAsSystem() since they run before user context is established (LDAP, SAML, OpenID, social login, AuthService) * feat: thread tenantId through all getAppConfig callers Pass tenantId from req.user to getAppConfig() across all callers that have request context, ensuring correct per-tenant cache key resolution. Also fixes getBaseConfig admin endpoint to scope to requesting admin's tenant instead of returning the unscoped base config. Files updated: - Controllers: UserController, PluginController - Middleware: checkDomainAllowed, balance - Routes: config - Services: loadConfigModels, loadDefaultModels, getEndpointsConfig, MCP - Audio services: TTSService, STTService, getVoices, getCustomConfigSpeech - Admin: getBaseConfig endpoint * feat: add config cache invalidation on admin mutations - Add clearOverrideCache(tenantId?) to flush per-principal override caches by enumerating Keyv store keys matching _OVERRIDE_: prefix - Add invalidateConfigCaches() helper that clears base config, override caches, tool caches, and endpoint config cache in one call - Wire invalidation into all 5 admin config mutation handlers (upsert, patch, delete field, delete overrides, toggle active) - Add strict mode warning when __default__ tenant fallback is used - Add 3 new tests for clearOverrideCache (all/scoped/base-preserving) * chore: update getUserPrincipals comment to reflect ALS-based tenant filtering The TODO(#12091) about missing tenantId filtering is resolved by the tenant context middleware + applyTenantIsolation Mongoose plugin. Group queries are now automatically scoped by tenantId via ALS. * fix: replace runAsSystem with baseOnly for pre-tenant code paths App configs are tenant-owned — runAsSystem() would bypass tenant isolation and return cross-tenant DB overrides. Instead, add baseOnly option to getAppConfig() that returns YAML-derived config only, with zero DB queries. All startup code, auth strategies, and MCP initialization now use getAppConfig({ baseOnly: true }) to get the YAML config without touching the Config collection. * fix: address PR review findings — middleware ordering, types, cache safety - Chain tenantContextMiddleware inside requireJwtAuth after passport auth instead of global app.use() where req.user is always undefined (Finding 1) - Remove global tenantContextMiddleware registration from index.js - Update BalanceMiddlewareOptions to include tenantId, remove redundant cast (Finding 4) - Add warning log when clearOverrideCache cannot enumerate keys on Redis (Finding 3) - Use startsWith instead of includes for cache key filtering (Finding 12) - Use generator loop instead of Array.from for key enumeration (Finding 3) - Selective barrel export — exclude _resetTenantMiddlewareStrictCache (Finding 5) - Move isMainThread check to module level, remove per-request check (Finding 9) - Move mid-file require to top of app.js (Finding 8) - Parallelize invalidateConfigCaches with Promise.all (Finding 10) - Remove clearOverrideCache from public app.js exports (internal only) - Strengthen getUserPrincipals comment re: ALS dependency (Finding 2) * fix: restore runAsSystem for startup DB ops, consolidate require, clarify baseOnly - Restore runAsSystem() around performStartupChecks, updateInterfacePermissions, initializeMCPs, and initializeOAuthReconnectManager — these make Mongoose queries that need system context in strict tenant mode (NEW-3) - Consolidate duplicate require('@librechat/api') in requireJwtAuth.js (NEW-1) - Document that baseOnly ignores role/userId/tenantId in JSDoc (NEW-2) * test: add requireJwtAuth tenant chaining + invalidateConfigCaches tests - requireJwtAuth: 5 tests verifying ALS tenant context is set after passport auth, isolated between concurrent requests, and not set when user has no tenantId (Finding 6) - invalidateConfigCaches: 4 tests verifying all four caches are cleared, tenantId is threaded through, partial failure is handled gracefully, and operations run in parallel via Promise.all (Finding 11) * fix: address Copilot review — passport errors, namespaced cache keys, /base scoping - Forward passport errors in requireJwtAuth before entering tenant middleware — prevents silent auth failures from reaching handlers (P1) - Account for Keyv namespace prefix in clearOverrideCache — stored keys are namespaced as "APP_CONFIG:_OVERRIDE_:..." not "_OVERRIDE_:...", so override caches were never actually matched/cleared (P2) - Remove role from getBaseConfig — /base should return tenant-scoped base config, not role-merged config that drifts per admin role (P2) - Return tenantStorage.run() for cleaner async semantics - Update mock cache in service.spec.ts to simulate Keyv namespacing * fix: address second review — cache safety, code quality, test reliability - Decouple cache invalidation from mutation response: fire-and-forget with logging so DB mutation success is not masked by cache failures - Extract clearEndpointConfigCache helper from inline IIFE - Move isMainThread check to lazy once-per-process guard (no import side effect) - Memoize process.env read in overrideCacheKey to avoid per-request env lookups and log flooding in strict mode - Remove flaky timer-based parallelism assertion, use structural check - Merge orphaned double JSDoc block on getUserPrincipals - Fix stale [getAppConfig] log prefix → [ensureBaseConfig] - Fix import order in tenant.spec.ts (package types before local values) - Replace "Finding 1" reference with self-contained description - Use real tenantStorage primitives in requireJwtAuth spec mock * fix: move JSDoc to correct function after clearEndpointConfigCache extraction * refactor: remove Redis SCAN from clearOverrideCache, rely on TTL expiry Redis SCAN causes 60s+ stalls under concurrent load (see #12410). APP_CONFIG defaults to FORCED_IN_MEMORY_CACHE_NAMESPACES, so the in-memory store.keys() path handles the standard case. When APP_CONFIG is Redis-backed, overrides expire naturally via overrideCacheTtl (60s default) — an acceptable window for admin config mutations. * fix: remove return from tenantStorage.run to satisfy void middleware signature * fix: address second review — cache safety, code quality, test reliability - Switch invalidateConfigCaches from Promise.all to Promise.allSettled so partial failures are logged individually instead of producing one undifferentiated error (Finding 3) - Gate overrideCacheKey strict-mode warning behind a once-per-process flag to prevent log flooding under load (Finding 4) - Add test for passport error forwarding in requireJwtAuth — the if (err) { return next(err) } branch now has coverage (Finding 5) - Add test for real partial failure in invalidateConfigCaches where clearAppConfigCache rejects (not just the swallowed endpoint error) * chore: reorder imports in index.js and app.js for consistency - Moved logger and runAsSystem imports to maintain a consistent import order across files. - Improved code readability by ensuring related imports are grouped together.
2026-03-26 17:35:00 -04:00
const appConfig =
req.config ?? (await getAppConfig({ role: req.user?.role, tenantId: req.user?.tenantId }));
// Return early if we have cached tools
if (cachedToolsArray != null) {
res.status(200).json(cachedToolsArray);
✨ feat: Assistants API, General File Support, Side Panel, File Explorer (#1696) * feat: assistant name/icon in Landing & Header * feat: assistname in textarea placeholder, and use `Assistant` as default name * feat: display non-image files in user messages * fix: only render files if files.length is > 0 * refactor(config -> file-config): move file related configuration values to separate module, add excel types * chore: spreadsheet file rendering * fix(Landing): dark mode style for Assistant Name * refactor: move progress incrementing to own hook, start smaller, cap near limit \(1\) * refactor(useContentHandler): add empty Text part if last part was completed tool or image * chore: add accordion trigger border styling for dark mode * feat: Assistant Builder model selection * chore: use Spinner when Assistant is mutating * fix(get/assistants): return correct response object `AssistantListResponse` * refactor(Spinner): pass size as prop * refactor: make assistant crud mutations optimistic, add types for options * chore: remove assistants route and view * chore: move assistant builder components to separate directory * feat(ContextButton): delete Assistant via context button/dialog, add localization * refactor: conditionally show use and context menu buttons, add localization for create assistant * feat: save side panel states to localStorage * style(SidePanel): improve avatar menu and assistant select styling for dark mode * refactor: make NavToggle reusable for either side (left or right), add SidePanel Toggle with ability to close it completely * fix: resize handle and navToggle behavior * fix(/avatar/:assistant_id): await `deleteFile` and assign unique name to uploaded image * WIP: file UI components from PR #576 * refactor(OpenAIMinimalIcon): pass className * feat: formatDate helper fn * feat: DataTableColumnHeader * feat: add row selection, formatted row values, number of rows selected * WIP: add files to Side panel temporarily * feat: `LB_QueueAsyncCall`: Leaky Bucket queue for external APIs, use in `processDeleteRequest` * fix(TFile): correct `source` type with `FileSources` * fix(useFileHandling): use `continue` instead of return when iterating multiple files, add file type to extendedFile * chore: add generic setter type * refactor(processDeleteRequest): settle promises to prevent rejections from processing deletions, log errors * feat: `useFileDeletion` to reuse file deletion logic * refactor(useFileDeletion): make `setFiles` an optional param and use object as param * feat: useDeleteFilesFromTable * feat: use real `files` data and add deletion action to data table * fix(Table): make headers sticky * feat: add dynamic filtering for columns; only show to user Host or OpenAI storage type * style(DropdownMenu): replace `slate` with `gray` * style(DataTable): apply dark mode themes and other misc styling * style(Columns): add color to OpenAI Storage option * refactor(FileContainer): make file preview reusable * refactor(Images): make image preview reusable * refactor(FilePreview): make file prop optional for FileIcon and FilePreview, fix relative style * feat(Columns): add file/image previews, set a minimum size to show for file size in bytes * WIP: File Panel with real files and formatted * feat: open files dialog from panel * style: file data table mobile and general column styling fixes * refactor(api/files): return files sorted by the most recently updated * refactor: provide fileMap through context to prevent re-selecting files to map in different areas; remove unused imports commented out in PanelColumns * refactor(ExtendFile): make File type optional, add `attached` to prevent attached files from being deleted on remove, make Message.files a partial TFile type * feat: attach files through file panel * refactor(useFileHandling): move files to the start of cache list when uploaded * refactor(useDeleteFilesMutation): delete files from cache when successfully deleted from server * fix(FileRow): handle possible edge case of duplication due to attaching recently uploaded file * style(SidePanel): make resize grip border transparent, remove unnecessary styling on close sidepanel button * feat: action utilities and tests * refactor(actions): add `ValidationResult` type and change wording for no server URL found * refactor(actions): check for empty server URL * fix(data-provider): revert tsconfig to fix type issue resolution * feat(client): first pass of actions input for assistants * refactor(FunctionSignature): change method to output object instead of string * refactor(models/Assistant): add actions field to schema, use searchParams object for methods, and add `getAssistant` * feat: post actions input first pass - create new Action document - add actions to Assistant DB document - create /action/:assistant_id POST route - pass more props down from PanelSwitcher, derive assistant_id from switcher - move privacy policy to ActionInput - reset data on input change/validation - add `useUpdateAction` - conform FunctionSignature type to FunctionTool - add action, assistant doc, update hook related types * refactor: optimize assistant/actions relationship - past domain in metadata as hostname and not a URL - include domain in tool name - add `getActions` for actions retrieval by user - add `getAssistants` for assistant docs retrieval by user - add `assistant_id` to Action schema - move actions to own module as a subroute to `api/assistants` - add `useGetActionsQuery` and `useGetAssistantDocsQuery` hooks - fix Action type def * feat: show assistant actions in assistant builder * feat: switch to actions on action click, editing action styling * fix: add Assistant state for builder panel to allow immediate selection of newly created assistants as well as retaining the current assistant when switching to a different panel within the builder * refactor(SidePanel/NavToggle): offset less from right when SidePanel is completely collapsed * chore: rename `processActions` -> `processRequiredActions` * chore: rename Assistant API Action to RequiredAction * refactor(actions): avoid nesting actual API params under generic `requestBody` to optimize LLM token usage * fix(handleTools): avoid calling `validTool` if not defined, add optional param to skip the loading of specs, which throws an error in the context of assistants * WIP: working first pass of toolCalls generated from openapi specs * WIP: first pass ToolCall styling * feat: programmatic iv encryption/decryption helpers * fix: correct ActionAuth types/enums, and define type for AuthForm * feat: encryption/decryption helpers for Action AuthMetadata * refactor(getActions): remove sensitive fields from query response * refactor(POST/actions): encrypt and remove sensitive fields from mutation response * fix(ActionService): change ESM import to CJS * feat: frontend auth handling for actions + optimistic update on action update/creation * refactor(actions): use the correct variables and types for setAuth method * refactor: POST /:assistant_id action can now handle updating an existing action, add `saved_auth_fields` to determine when user explicitly saves new auth creds. only send auth metadata if user explicitly saved fields * refactor(createActionTool): catch errors and send back meaningful error message, add flag to `getActions` to determine whether to retrieve sensitive values or not * refactor(ToolService): add `action` property to ToolCall PartMetadata to determine if the tool call was an action, fix parsing function name issue with actionDelimiter * fix(ActionRequest): use URL class to correctly join endpoint parts for `execute` call * feat: delete assistant actions * refactor: conditionally show Available actions * refactor: show `retrieval` and `code_interpreter` as Capabilities, swap `Switch` for `Checkbox` * chore: remove shadow-stroke from messages * WIP: first pass of Assistants Knowledge attachments * refactor: remove AssistantsProvider in favor of FormProvider, fix selectedAssistant re-render bug, map Assistant file_ids to files via fileMap, initialize Knowledge component with mapped files if any exist * fix: prevent deleting files on assistant file upload * chore: remove console.log * refactor(useUploadFileMutation): update files and assistants cache on upload * chore: disable oauth option as not supported yet * feat: cancel assistant runs * refactor: initialize OpenAI client with helper function, resolve all related circular dependencies * fix(DALL-E): initialization * fix(process): openai client initialization * fix: select an existing Assistant when the active one is deleted * chore: allow attaching files for assistant endpoint, send back relevant OpenAI error message when uploading, deconstruct openAI initialization correctly, add `message_file` to formData when a file is attached to the message but not the assistant * fix: add assistant_id on newConvo * fix(initializeClient): import fix * chore: swap setAssistant for setOption in useEffect * fix(DALL-E): add processFileURL to loadTools call * chore: add customConfig to debug logs * feat: delete threads on convo delete * chore: replace Assistants icon * chore: remove console.dir() in `abortRun` * feat(AssistantService): accumulate text values from run in openai.responseText * feat: titling for assistants endpoint * chore: move panel file components to appropriate directory, add file checks for attaching files, change icon for Attach Files * refactor: add localizations to tools, plugins, add condition for adding/remove user plugins so tool selections don't affect this value * chore: disable `import from url` action for now * chore: remove textMimeTypes from default fileConfig for now * fix: catch tool errors and send as outputs with error messages * fix: React warning about button as descendant of button * style: retrieval and cancelled icon * WIP: pass isSubmitting to Parts, use InProgressCall to display cancelled tool calls correctly, show domain/function name * fix(meilisearch): fix `postSaveHook` issue where indexing expects a mongo document, and join all text content parts for meili indexing * ci: fix dall-e tests * ci: fix client tests * fix: button types in actions panel * fix: plugin auth form persisting across tool selections * fix(ci): update AppService spec with `loadAndFormatTools` * fix(clearConvos): add id check earlier on * refactor(AssistantAvatar): set previewURL dynamically when emtadata.avatar changes * feat(assistants): addTitle cache setting * fix(useSSE): resolve rebase conflicts * fix: delete mutation * style(SidePanel): make grip visible on active and hover, invisible otherwise * ci: add data-provider tests to workflow, also update eslint/tsconfig to recognize specs, and add `text/csv` to fileConfig * fix: handle edge case where auth object is undefined, and log errors * refactor(actions): resolve schemas, add tests for resolving refs, import specs from separate file for tests * chore: remove comment * fix(ActionsInput): re-render bug when initializing states with action fields * fix(patch/assistant): filter undefined tools * chore: add logging for errors in assistants routes * fix(updateAssistant): map actions to functions to avoid overwriting * fix(actions): properly handle GET paths * fix(convos): unhandled delete thread exception * refactor(AssistantService): pass both thread_id and conversationId when sending intermediate assistant messages, remove `mapMessagesToSteps` from AssistantService * refactor(useSSE): replace all messages with runMessages and pass latestMessageId to abortRun; fix(checkMessageGaps): include tool calls when syncing messages * refactor(assistants/chat): invoke `createOnTextProgress` after thread creation * chore: add typing * style: sidepanel styling * style: action tool call domain styling * feat(assistants): default models, limit retrieval to certain models, add env variables to to env.example * feat: assistants api key in EndpointService * refactor: set assistant model to conversation on assistant switch * refactor: set assistant model to conversation on assistant select from panel * fix(retrieveAndProcessFile): catch attempt to download file with `assistant` purpose which is not allowed; add logging * feat: retrieval styling, handling, and logging * chore: rename ASSISTANTS_REVERSE_PROXY to ASSISTANTS_BASE_URL * feat: FileContext for file metadata * feat: context file mgmt and filtering * style(Select): hover/rounded changes * refactor: explicit conversation switch, endpoint dependent, through `useSelectAssistant`, which does not create new chat if current endpoint is assistant endpoint * fix(AssistantAvatar): make empty previewURL if no avatar present * refactor: side panel mobile styling * style: merge tool and action section, optimize mobile styling for action/tool buttons * fix: localStorage issues * fix(useSelectAssistant): invoke react query hook directly in select hook as Map was not being updated in time * style: light mode fixes * fix: prevent sidepanel nav styling from shifting layout up * refactor: change default layout (collapsed by default) * style: mobile optimization of DataTable * style: datatable * feat: client-side hide right-side panel * chore(useNewConvo): add partial typing for preset * fix(useSelectAssistant): pass correct model name by using template as preset * WIP: assistant presets * refactor(ToolService): add native solution for `TavilySearchResults` and log tool output errors * refactor: organize imports and use native TavilySearchResults * fix(TavilySearchResults): stringify result * fix(ToolCall): show tool call outputs when not an action * chore: rename Prompt Prefix to custom instructions (in user facing text only) * refactor(EditPresetDialog): Optimize setting title by debouncing, reset preset on dialog close to avoid state mixture * feat: add `presetOverride` to overwrite active conversation settings when saving a Preset (relevant for client side updates only) * feat: Assistant preset settings (client-side) * fix(Switcher): only set assistant_id and model if current endpoint is Assistants * feat: use `useDebouncedInput` for updating conversation settings, starting with EditPresetDialog title setting and Assistant instructions setting * feat(Assistants): add instructions field to settings * feat(chat/assistants): pass conversation settings to run body * wip: begin localization and only allow actions if the assistant is created * refactor(AssistantsPanel): knowledge localization, allow tools on creation * feat: experimental: allow 'priming' values before assistant is created, that would normally require an assistant_id to be defined * chore: trim console logs and make more meaningful * chore: toast messages * fix(ci): date test * feat: create file when uploading Assistant Avatar * feat: file upload rate limiting from custom config with dynamic file route initialization * refactor: use file upload limiters on post routes only * refactor(fileConfig): add endpoints field for endpoint specific fileconfigs, add mergeConfig function, add tests * refactor: fileConfig route, dynamic multer instances used on all '/' and '/images' POST routes, data service and query hook * feat: supportedMimeTypesSchema, test for array of regex * feat: configurable file config limits * chore: clarify assistants file knowledge prereq. * chore(useTextarea): default to localized 'Assistant' if assistant name is empty * feat: configurable file limits and toggle file upload per endpoint * fix(useUploadFileMutation): prevent updating assistant.files cache if file upload is a message_file attachment * fix(AssistantSelect): set last selected assistant only when timeout successfully runs * refactor(queries): disable assistant queries if assistants endpoint is not enabled * chore(Switcher): add localization * chore: pluralize `assistant` for `EModelEndpoint key and value * feat: show/hide assistant UI components based on endpoint availability; librechat.yaml config for disabling builder section and setting polling/timeout intervals * fix(compactEndpointSchemas): use EModelEndpoint for schema access * feat(runAssistant): use configured values from `librechat.yaml` for `pollIntervalMs` and `timeout` * fix: naming issue * wip: revert landing * 🎉 happy birthday LibreChat (#1768) * happy birthday LibreChat * Refactor endpoint condition in Landing component * Update birthday message in Eng.tsx * fix(/config): avoid nesting ternaries * refactor(/config): check birthday --------- Co-authored-by: Danny Avila <messagedaniel@protonmail.com> * fix: landing * fix: landing * fix(useMessageHelpers): hardcoded check to use EModelEndpoint instead * fix(ci): convo test revert to main * fix(assistants/chat): fix issue where assistant_id was being saved as model for convo * chore: added logging, promises racing to prevent longer timeouts, explicit setting of maxRetries and timeouts, robust catching of invalid abortRun params * refactor: use recoil state for `showStopButton` and only show for assistants endpoint after syncing conversation data * refactor: optimize abortRun strategy using localStorage, refactor `abortConversation` to use async/await and await the result, refactor how the abortKey cache is set for runs * fix(checkMessageGaps): assign `assistant_id` to synced messages if defined; prevents UI from showing blank assistant for cancelled messages * refactor: re-order sequence of chat route, only allow aborting messages after run is created, cancel abortRun if there was a cancelling error (likely due already cancelled in chat route), and add extra logging * chore(typedefs): add httpAgent type to OpenAIClient * refactor: use custom implementation of retrieving run with axios to allow for timing out run query * fix(waitForRun): handle timed out run retrieval query * refactor: update preset conditions: - presets will retain settings when a different endpoint is selected; for existing convos, either when modular or is assistant switch - no longer use `navigateToConvo` on preset select * fix: temporary calculator hack as expects string input when invoked * fix: cancel abortRun only when cancelling error is a result of the run already being cancelled * chore: remove use of `fileMaxSizeMB` and total counterpart (redundant) * docs: custom config documentation update * docs: assistants api setup and dotenv, new custom config fields * refactor(Switcher): make Assistant switcher sticky in SidePanel * chore(useSSE): remove console log of data and message index * refactor(AssistantPanel): button styling and add secondary select button to bottom of panel * refactor(OpenAIClient): allow passing conversationId to RunManager through titleConvo and initializeLLM to properly record title context tokens used in cases where conversationId was not defined by the client * feat(assistants): token tracking for assistant runs * chore(spendTokens): improve logging * feat: support/exclude specific assistant Ids * chore: add update `librechat.example.yaml`, optimize `AppService` handling, new tests for `AppService`, optimize missing/outdate config logging * chore: mount docker logs to root of project * chore: condense axios errors * chore: bump vite * chore: vite hot reload fix using latest version * chore(getOpenAIModels): sort instruct models to the end of models list * fix(assistants): user provided key * fix(assistants): user provided key, invalidate more queries on revoke --------- Co-authored-by: Marco Beretta <81851188+Berry-13@users.noreply.github.com>
2024-02-13 20:42:27 -05:00
return;
}
/** @type {Record<string, FunctionTool> | null} Get tool definitions to filter which tools are actually available */
let toolDefinitions = await getCachedTools();
if (toolDefinitions == null && appConfig?.availableTools != null) {
logger.warn('[getAvailableTools] Tool cache was empty, re-initializing from app config');
await setCachedTools(appConfig.availableTools);
toolDefinitions = appConfig.availableTools;
}
/** @type {import('@librechat/api').LCManifestTool[]} */
let pluginManifest = availableTools;
🛜 refactor: Streamline App Config Usage (#9234) * WIP: app.locals refactoring WIP: appConfig fix: update memory configuration retrieval to use getAppConfig based on user role fix: update comment for AppConfig interface to clarify purpose 🏷️ refactor: Update tests to use getAppConfig for endpoint configurations ci: Update AppService tests to initialize app config instead of app.locals ci: Integrate getAppConfig into remaining tests refactor: Update multer storage destination to use promise-based getAppConfig and improve error handling in tests refactor: Rename initializeAppConfig to setAppConfig and update related tests ci: Mock getAppConfig in various tests to provide default configurations refactor: Update convertMCPToolsToPlugins to use mcpManager for server configuration and adjust related tests chore: rename `Config/getAppConfig` -> `Config/app` fix: streamline OpenAI image tools configuration by removing direct appConfig dependency and using function parameters chore: correct parameter documentation for imageOutputType in ToolService.js refactor: remove `getCustomConfig` dependency in config route refactor: update domain validation to use appConfig for allowed domains refactor: use appConfig registration property chore: remove app parameter from AppService invocation refactor: update AppConfig interface to correct registration and turnstile configurations refactor: remove getCustomConfig dependency and use getAppConfig in PluginController, multer, and MCP services refactor: replace getCustomConfig with getAppConfig in STTService, TTSService, and related files refactor: replace getCustomConfig with getAppConfig in Conversation and Message models, update tempChatRetention functions to use AppConfig type refactor: update getAppConfig calls in Conversation and Message models to include user role for temporary chat expiration ci: update related tests refactor: update getAppConfig call in getCustomConfigSpeech to include user role fix: update appConfig usage to access allowedDomains from actions instead of registration refactor: enhance AppConfig to include fileStrategies and update related file strategy logic refactor: update imports to use normalizeEndpointName from @librechat/api and remove redundant definitions chore: remove deprecated unused RunManager refactor: get balance config primarily from appConfig refactor: remove customConfig dependency for appConfig and streamline loadConfigModels logic refactor: remove getCustomConfig usage and use app config in file citations refactor: consolidate endpoint loading logic into loadEndpoints function refactor: update appConfig access to use endpoints structure across various services refactor: implement custom endpoints configuration and streamline endpoint loading logic refactor: update getAppConfig call to include user role parameter refactor: streamline endpoint configuration and enhance appConfig usage across services refactor: replace getMCPAuthMap with getUserMCPAuthMap and remove unused getCustomConfig file refactor: add type annotation for loadedEndpoints in loadEndpoints function refactor: move /services/Files/images/parse to TS API chore: add missing FILE_CITATIONS permission to IRole interface refactor: restructure toolkits to TS API refactor: separate manifest logic into its own module refactor: consolidate tool loading logic into a new tools module for startup logic refactor: move interface config logic to TS API refactor: migrate checkEmailConfig to TypeScript and update imports refactor: add FunctionTool interface and availableTools to AppConfig refactor: decouple caching and DB operations from AppService, make part of consolidated `getAppConfig` WIP: fix tests * fix: rebase conflicts * refactor: remove app.locals references * refactor: replace getBalanceConfig with getAppConfig in various strategies and middleware * refactor: replace appConfig?.balance with getBalanceConfig in various controllers and clients * test: add balance configuration to titleConvo method in AgentClient tests * chore: remove unused `openai-chat-tokens` package * chore: remove unused imports in initializeMCPs.js * refactor: update balance configuration to use getAppConfig instead of getBalanceConfig * refactor: integrate configMiddleware for centralized configuration handling * refactor: optimize email domain validation by removing unnecessary async calls * refactor: simplify multer storage configuration by removing async calls * refactor: reorder imports for better readability in user.js * refactor: replace getAppConfig calls with req.config for improved performance * chore: replace getAppConfig calls with req.config in tests for centralized configuration handling * chore: remove unused override config * refactor: add configMiddleware to endpoint route and replace getAppConfig with req.config * chore: remove customConfig parameter from TTSService constructor * refactor: pass appConfig from request to processFileCitations for improved configuration handling * refactor: remove configMiddleware from endpoint route and retrieve appConfig directly in getEndpointsConfig if not in `req.config` * test: add mockAppConfig to processFileCitations tests for improved configuration handling * fix: pass req.config to hasCustomUserVars and call without await after synchronous refactor * fix: type safety in useExportConversation * refactor: retrieve appConfig using getAppConfig in PluginController and remove configMiddleware from plugins route, to avoid always retrieving when plugins are cached * chore: change `MongoUser` typedef to `IUser` * fix: Add `user` and `config` fields to ServerRequest and update JSDoc type annotations from Express.Request to ServerRequest * fix: remove unused setAppConfig mock from Server configuration tests
2025-08-26 12:10:18 -04:00
/** @type {TPlugin[]} Deduplicate and authenticate plugins */
const uniquePlugins = filterUniquePlugins(pluginManifest);
✨ feat: Assistants API, General File Support, Side Panel, File Explorer (#1696) * feat: assistant name/icon in Landing & Header * feat: assistname in textarea placeholder, and use `Assistant` as default name * feat: display non-image files in user messages * fix: only render files if files.length is > 0 * refactor(config -> file-config): move file related configuration values to separate module, add excel types * chore: spreadsheet file rendering * fix(Landing): dark mode style for Assistant Name * refactor: move progress incrementing to own hook, start smaller, cap near limit \(1\) * refactor(useContentHandler): add empty Text part if last part was completed tool or image * chore: add accordion trigger border styling for dark mode * feat: Assistant Builder model selection * chore: use Spinner when Assistant is mutating * fix(get/assistants): return correct response object `AssistantListResponse` * refactor(Spinner): pass size as prop * refactor: make assistant crud mutations optimistic, add types for options * chore: remove assistants route and view * chore: move assistant builder components to separate directory * feat(ContextButton): delete Assistant via context button/dialog, add localization * refactor: conditionally show use and context menu buttons, add localization for create assistant * feat: save side panel states to localStorage * style(SidePanel): improve avatar menu and assistant select styling for dark mode * refactor: make NavToggle reusable for either side (left or right), add SidePanel Toggle with ability to close it completely * fix: resize handle and navToggle behavior * fix(/avatar/:assistant_id): await `deleteFile` and assign unique name to uploaded image * WIP: file UI components from PR #576 * refactor(OpenAIMinimalIcon): pass className * feat: formatDate helper fn * feat: DataTableColumnHeader * feat: add row selection, formatted row values, number of rows selected * WIP: add files to Side panel temporarily * feat: `LB_QueueAsyncCall`: Leaky Bucket queue for external APIs, use in `processDeleteRequest` * fix(TFile): correct `source` type with `FileSources` * fix(useFileHandling): use `continue` instead of return when iterating multiple files, add file type to extendedFile * chore: add generic setter type * refactor(processDeleteRequest): settle promises to prevent rejections from processing deletions, log errors * feat: `useFileDeletion` to reuse file deletion logic * refactor(useFileDeletion): make `setFiles` an optional param and use object as param * feat: useDeleteFilesFromTable * feat: use real `files` data and add deletion action to data table * fix(Table): make headers sticky * feat: add dynamic filtering for columns; only show to user Host or OpenAI storage type * style(DropdownMenu): replace `slate` with `gray` * style(DataTable): apply dark mode themes and other misc styling * style(Columns): add color to OpenAI Storage option * refactor(FileContainer): make file preview reusable * refactor(Images): make image preview reusable * refactor(FilePreview): make file prop optional for FileIcon and FilePreview, fix relative style * feat(Columns): add file/image previews, set a minimum size to show for file size in bytes * WIP: File Panel with real files and formatted * feat: open files dialog from panel * style: file data table mobile and general column styling fixes * refactor(api/files): return files sorted by the most recently updated * refactor: provide fileMap through context to prevent re-selecting files to map in different areas; remove unused imports commented out in PanelColumns * refactor(ExtendFile): make File type optional, add `attached` to prevent attached files from being deleted on remove, make Message.files a partial TFile type * feat: attach files through file panel * refactor(useFileHandling): move files to the start of cache list when uploaded * refactor(useDeleteFilesMutation): delete files from cache when successfully deleted from server * fix(FileRow): handle possible edge case of duplication due to attaching recently uploaded file * style(SidePanel): make resize grip border transparent, remove unnecessary styling on close sidepanel button * feat: action utilities and tests * refactor(actions): add `ValidationResult` type and change wording for no server URL found * refactor(actions): check for empty server URL * fix(data-provider): revert tsconfig to fix type issue resolution * feat(client): first pass of actions input for assistants * refactor(FunctionSignature): change method to output object instead of string * refactor(models/Assistant): add actions field to schema, use searchParams object for methods, and add `getAssistant` * feat: post actions input first pass - create new Action document - add actions to Assistant DB document - create /action/:assistant_id POST route - pass more props down from PanelSwitcher, derive assistant_id from switcher - move privacy policy to ActionInput - reset data on input change/validation - add `useUpdateAction` - conform FunctionSignature type to FunctionTool - add action, assistant doc, update hook related types * refactor: optimize assistant/actions relationship - past domain in metadata as hostname and not a URL - include domain in tool name - add `getActions` for actions retrieval by user - add `getAssistants` for assistant docs retrieval by user - add `assistant_id` to Action schema - move actions to own module as a subroute to `api/assistants` - add `useGetActionsQuery` and `useGetAssistantDocsQuery` hooks - fix Action type def * feat: show assistant actions in assistant builder * feat: switch to actions on action click, editing action styling * fix: add Assistant state for builder panel to allow immediate selection of newly created assistants as well as retaining the current assistant when switching to a different panel within the builder * refactor(SidePanel/NavToggle): offset less from right when SidePanel is completely collapsed * chore: rename `processActions` -> `processRequiredActions` * chore: rename Assistant API Action to RequiredAction * refactor(actions): avoid nesting actual API params under generic `requestBody` to optimize LLM token usage * fix(handleTools): avoid calling `validTool` if not defined, add optional param to skip the loading of specs, which throws an error in the context of assistants * WIP: working first pass of toolCalls generated from openapi specs * WIP: first pass ToolCall styling * feat: programmatic iv encryption/decryption helpers * fix: correct ActionAuth types/enums, and define type for AuthForm * feat: encryption/decryption helpers for Action AuthMetadata * refactor(getActions): remove sensitive fields from query response * refactor(POST/actions): encrypt and remove sensitive fields from mutation response * fix(ActionService): change ESM import to CJS * feat: frontend auth handling for actions + optimistic update on action update/creation * refactor(actions): use the correct variables and types for setAuth method * refactor: POST /:assistant_id action can now handle updating an existing action, add `saved_auth_fields` to determine when user explicitly saves new auth creds. only send auth metadata if user explicitly saved fields * refactor(createActionTool): catch errors and send back meaningful error message, add flag to `getActions` to determine whether to retrieve sensitive values or not * refactor(ToolService): add `action` property to ToolCall PartMetadata to determine if the tool call was an action, fix parsing function name issue with actionDelimiter * fix(ActionRequest): use URL class to correctly join endpoint parts for `execute` call * feat: delete assistant actions * refactor: conditionally show Available actions * refactor: show `retrieval` and `code_interpreter` as Capabilities, swap `Switch` for `Checkbox` * chore: remove shadow-stroke from messages * WIP: first pass of Assistants Knowledge attachments * refactor: remove AssistantsProvider in favor of FormProvider, fix selectedAssistant re-render bug, map Assistant file_ids to files via fileMap, initialize Knowledge component with mapped files if any exist * fix: prevent deleting files on assistant file upload * chore: remove console.log * refactor(useUploadFileMutation): update files and assistants cache on upload * chore: disable oauth option as not supported yet * feat: cancel assistant runs * refactor: initialize OpenAI client with helper function, resolve all related circular dependencies * fix(DALL-E): initialization * fix(process): openai client initialization * fix: select an existing Assistant when the active one is deleted * chore: allow attaching files for assistant endpoint, send back relevant OpenAI error message when uploading, deconstruct openAI initialization correctly, add `message_file` to formData when a file is attached to the message but not the assistant * fix: add assistant_id on newConvo * fix(initializeClient): import fix * chore: swap setAssistant for setOption in useEffect * fix(DALL-E): add processFileURL to loadTools call * chore: add customConfig to debug logs * feat: delete threads on convo delete * chore: replace Assistants icon * chore: remove console.dir() in `abortRun` * feat(AssistantService): accumulate text values from run in openai.responseText * feat: titling for assistants endpoint * chore: move panel file components to appropriate directory, add file checks for attaching files, change icon for Attach Files * refactor: add localizations to tools, plugins, add condition for adding/remove user plugins so tool selections don't affect this value * chore: disable `import from url` action for now * chore: remove textMimeTypes from default fileConfig for now * fix: catch tool errors and send as outputs with error messages * fix: React warning about button as descendant of button * style: retrieval and cancelled icon * WIP: pass isSubmitting to Parts, use InProgressCall to display cancelled tool calls correctly, show domain/function name * fix(meilisearch): fix `postSaveHook` issue where indexing expects a mongo document, and join all text content parts for meili indexing * ci: fix dall-e tests * ci: fix client tests * fix: button types in actions panel * fix: plugin auth form persisting across tool selections * fix(ci): update AppService spec with `loadAndFormatTools` * fix(clearConvos): add id check earlier on * refactor(AssistantAvatar): set previewURL dynamically when emtadata.avatar changes * feat(assistants): addTitle cache setting * fix(useSSE): resolve rebase conflicts * fix: delete mutation * style(SidePanel): make grip visible on active and hover, invisible otherwise * ci: add data-provider tests to workflow, also update eslint/tsconfig to recognize specs, and add `text/csv` to fileConfig * fix: handle edge case where auth object is undefined, and log errors * refactor(actions): resolve schemas, add tests for resolving refs, import specs from separate file for tests * chore: remove comment * fix(ActionsInput): re-render bug when initializing states with action fields * fix(patch/assistant): filter undefined tools * chore: add logging for errors in assistants routes * fix(updateAssistant): map actions to functions to avoid overwriting * fix(actions): properly handle GET paths * fix(convos): unhandled delete thread exception * refactor(AssistantService): pass both thread_id and conversationId when sending intermediate assistant messages, remove `mapMessagesToSteps` from AssistantService * refactor(useSSE): replace all messages with runMessages and pass latestMessageId to abortRun; fix(checkMessageGaps): include tool calls when syncing messages * refactor(assistants/chat): invoke `createOnTextProgress` after thread creation * chore: add typing * style: sidepanel styling * style: action tool call domain styling * feat(assistants): default models, limit retrieval to certain models, add env variables to to env.example * feat: assistants api key in EndpointService * refactor: set assistant model to conversation on assistant switch * refactor: set assistant model to conversation on assistant select from panel * fix(retrieveAndProcessFile): catch attempt to download file with `assistant` purpose which is not allowed; add logging * feat: retrieval styling, handling, and logging * chore: rename ASSISTANTS_REVERSE_PROXY to ASSISTANTS_BASE_URL * feat: FileContext for file metadata * feat: context file mgmt and filtering * style(Select): hover/rounded changes * refactor: explicit conversation switch, endpoint dependent, through `useSelectAssistant`, which does not create new chat if current endpoint is assistant endpoint * fix(AssistantAvatar): make empty previewURL if no avatar present * refactor: side panel mobile styling * style: merge tool and action section, optimize mobile styling for action/tool buttons * fix: localStorage issues * fix(useSelectAssistant): invoke react query hook directly in select hook as Map was not being updated in time * style: light mode fixes * fix: prevent sidepanel nav styling from shifting layout up * refactor: change default layout (collapsed by default) * style: mobile optimization of DataTable * style: datatable * feat: client-side hide right-side panel * chore(useNewConvo): add partial typing for preset * fix(useSelectAssistant): pass correct model name by using template as preset * WIP: assistant presets * refactor(ToolService): add native solution for `TavilySearchResults` and log tool output errors * refactor: organize imports and use native TavilySearchResults * fix(TavilySearchResults): stringify result * fix(ToolCall): show tool call outputs when not an action * chore: rename Prompt Prefix to custom instructions (in user facing text only) * refactor(EditPresetDialog): Optimize setting title by debouncing, reset preset on dialog close to avoid state mixture * feat: add `presetOverride` to overwrite active conversation settings when saving a Preset (relevant for client side updates only) * feat: Assistant preset settings (client-side) * fix(Switcher): only set assistant_id and model if current endpoint is Assistants * feat: use `useDebouncedInput` for updating conversation settings, starting with EditPresetDialog title setting and Assistant instructions setting * feat(Assistants): add instructions field to settings * feat(chat/assistants): pass conversation settings to run body * wip: begin localization and only allow actions if the assistant is created * refactor(AssistantsPanel): knowledge localization, allow tools on creation * feat: experimental: allow 'priming' values before assistant is created, that would normally require an assistant_id to be defined * chore: trim console logs and make more meaningful * chore: toast messages * fix(ci): date test * feat: create file when uploading Assistant Avatar * feat: file upload rate limiting from custom config with dynamic file route initialization * refactor: use file upload limiters on post routes only * refactor(fileConfig): add endpoints field for endpoint specific fileconfigs, add mergeConfig function, add tests * refactor: fileConfig route, dynamic multer instances used on all '/' and '/images' POST routes, data service and query hook * feat: supportedMimeTypesSchema, test for array of regex * feat: configurable file config limits * chore: clarify assistants file knowledge prereq. * chore(useTextarea): default to localized 'Assistant' if assistant name is empty * feat: configurable file limits and toggle file upload per endpoint * fix(useUploadFileMutation): prevent updating assistant.files cache if file upload is a message_file attachment * fix(AssistantSelect): set last selected assistant only when timeout successfully runs * refactor(queries): disable assistant queries if assistants endpoint is not enabled * chore(Switcher): add localization * chore: pluralize `assistant` for `EModelEndpoint key and value * feat: show/hide assistant UI components based on endpoint availability; librechat.yaml config for disabling builder section and setting polling/timeout intervals * fix(compactEndpointSchemas): use EModelEndpoint for schema access * feat(runAssistant): use configured values from `librechat.yaml` for `pollIntervalMs` and `timeout` * fix: naming issue * wip: revert landing * 🎉 happy birthday LibreChat (#1768) * happy birthday LibreChat * Refactor endpoint condition in Landing component * Update birthday message in Eng.tsx * fix(/config): avoid nesting ternaries * refactor(/config): check birthday --------- Co-authored-by: Danny Avila <messagedaniel@protonmail.com> * fix: landing * fix: landing * fix(useMessageHelpers): hardcoded check to use EModelEndpoint instead * fix(ci): convo test revert to main * fix(assistants/chat): fix issue where assistant_id was being saved as model for convo * chore: added logging, promises racing to prevent longer timeouts, explicit setting of maxRetries and timeouts, robust catching of invalid abortRun params * refactor: use recoil state for `showStopButton` and only show for assistants endpoint after syncing conversation data * refactor: optimize abortRun strategy using localStorage, refactor `abortConversation` to use async/await and await the result, refactor how the abortKey cache is set for runs * fix(checkMessageGaps): assign `assistant_id` to synced messages if defined; prevents UI from showing blank assistant for cancelled messages * refactor: re-order sequence of chat route, only allow aborting messages after run is created, cancel abortRun if there was a cancelling error (likely due already cancelled in chat route), and add extra logging * chore(typedefs): add httpAgent type to OpenAIClient * refactor: use custom implementation of retrieving run with axios to allow for timing out run query * fix(waitForRun): handle timed out run retrieval query * refactor: update preset conditions: - presets will retain settings when a different endpoint is selected; for existing convos, either when modular or is assistant switch - no longer use `navigateToConvo` on preset select * fix: temporary calculator hack as expects string input when invoked * fix: cancel abortRun only when cancelling error is a result of the run already being cancelled * chore: remove use of `fileMaxSizeMB` and total counterpart (redundant) * docs: custom config documentation update * docs: assistants api setup and dotenv, new custom config fields * refactor(Switcher): make Assistant switcher sticky in SidePanel * chore(useSSE): remove console log of data and message index * refactor(AssistantPanel): button styling and add secondary select button to bottom of panel * refactor(OpenAIClient): allow passing conversationId to RunManager through titleConvo and initializeLLM to properly record title context tokens used in cases where conversationId was not defined by the client * feat(assistants): token tracking for assistant runs * chore(spendTokens): improve logging * feat: support/exclude specific assistant Ids * chore: add update `librechat.example.yaml`, optimize `AppService` handling, new tests for `AppService`, optimize missing/outdate config logging * chore: mount docker logs to root of project * chore: condense axios errors * chore: bump vite * chore: vite hot reload fix using latest version * chore(getOpenAIModels): sort instruct models to the end of models list * fix(assistants): user provided key * fix(assistants): user provided key, invalidate more queries on revoke --------- Co-authored-by: Marco Beretta <81851188+Berry-13@users.noreply.github.com>
2024-02-13 20:42:27 -05:00
const authenticatedPlugins = uniquePlugins.map((plugin) => {
🚧 WIP: Merge Dev Build (#4611) * refactor: Agent CodeFiles, abortUpload WIP * feat: code environment file upload * refactor: useLazyEffect * refactor: - Add `watch` from `useFormContext` to check if code execution is enabled - Disable file upload button if `agent_id` is not selected or code execution is disabled * WIP: primeCodeFiles; refactor: rename sessionId to session_id for uniformity * Refactor: Rename session_id to sessionId for uniformity in AuthService.js * chore: bump @librechat/agents to version 1.7.1 * WIP: prime code files * refactor: Update code env file upload method to use read stream * feat: reupload code env file if no longer active * refactor: isAssistantTool -> isEntityTool + address type issues * feat: execute code tool hook * refactor: Rename isPluginAuthenticated to checkPluginAuth in PluginController.js * refactor: Update PluginController.js to use AuthType constant for comparison * feat: verify tool authentication (execute_code) * feat: enter librechat_code_api_key * refactor: Remove unused imports in BookmarkForm.tsx * feat: authenticate code tool * refactor: Update Action.tsx to conditionally render the key and revoke key buttons * refactor(Code/Action): prevent uncheck-able 'Run Code' capability when key is revoked * refactor(Code/Action): Update Action.tsx to conditionally render the key and revoke key buttons * fix: agent file upload edge cases * chore: bump @librechat/agents * fix: custom endpoint providerValue icon * feat: ollama meta modal token values + context * feat: ollama agents * refactor: Update token models for Ollama models * chore: Comment out CodeForm * refactor: Update token models for Ollama and Meta models
2024-11-01 18:36:39 -04:00
if (checkPluginAuth(plugin)) {
✨ feat: Assistants API, General File Support, Side Panel, File Explorer (#1696) * feat: assistant name/icon in Landing & Header * feat: assistname in textarea placeholder, and use `Assistant` as default name * feat: display non-image files in user messages * fix: only render files if files.length is > 0 * refactor(config -> file-config): move file related configuration values to separate module, add excel types * chore: spreadsheet file rendering * fix(Landing): dark mode style for Assistant Name * refactor: move progress incrementing to own hook, start smaller, cap near limit \(1\) * refactor(useContentHandler): add empty Text part if last part was completed tool or image * chore: add accordion trigger border styling for dark mode * feat: Assistant Builder model selection * chore: use Spinner when Assistant is mutating * fix(get/assistants): return correct response object `AssistantListResponse` * refactor(Spinner): pass size as prop * refactor: make assistant crud mutations optimistic, add types for options * chore: remove assistants route and view * chore: move assistant builder components to separate directory * feat(ContextButton): delete Assistant via context button/dialog, add localization * refactor: conditionally show use and context menu buttons, add localization for create assistant * feat: save side panel states to localStorage * style(SidePanel): improve avatar menu and assistant select styling for dark mode * refactor: make NavToggle reusable for either side (left or right), add SidePanel Toggle with ability to close it completely * fix: resize handle and navToggle behavior * fix(/avatar/:assistant_id): await `deleteFile` and assign unique name to uploaded image * WIP: file UI components from PR #576 * refactor(OpenAIMinimalIcon): pass className * feat: formatDate helper fn * feat: DataTableColumnHeader * feat: add row selection, formatted row values, number of rows selected * WIP: add files to Side panel temporarily * feat: `LB_QueueAsyncCall`: Leaky Bucket queue for external APIs, use in `processDeleteRequest` * fix(TFile): correct `source` type with `FileSources` * fix(useFileHandling): use `continue` instead of return when iterating multiple files, add file type to extendedFile * chore: add generic setter type * refactor(processDeleteRequest): settle promises to prevent rejections from processing deletions, log errors * feat: `useFileDeletion` to reuse file deletion logic * refactor(useFileDeletion): make `setFiles` an optional param and use object as param * feat: useDeleteFilesFromTable * feat: use real `files` data and add deletion action to data table * fix(Table): make headers sticky * feat: add dynamic filtering for columns; only show to user Host or OpenAI storage type * style(DropdownMenu): replace `slate` with `gray` * style(DataTable): apply dark mode themes and other misc styling * style(Columns): add color to OpenAI Storage option * refactor(FileContainer): make file preview reusable * refactor(Images): make image preview reusable * refactor(FilePreview): make file prop optional for FileIcon and FilePreview, fix relative style * feat(Columns): add file/image previews, set a minimum size to show for file size in bytes * WIP: File Panel with real files and formatted * feat: open files dialog from panel * style: file data table mobile and general column styling fixes * refactor(api/files): return files sorted by the most recently updated * refactor: provide fileMap through context to prevent re-selecting files to map in different areas; remove unused imports commented out in PanelColumns * refactor(ExtendFile): make File type optional, add `attached` to prevent attached files from being deleted on remove, make Message.files a partial TFile type * feat: attach files through file panel * refactor(useFileHandling): move files to the start of cache list when uploaded * refactor(useDeleteFilesMutation): delete files from cache when successfully deleted from server * fix(FileRow): handle possible edge case of duplication due to attaching recently uploaded file * style(SidePanel): make resize grip border transparent, remove unnecessary styling on close sidepanel button * feat: action utilities and tests * refactor(actions): add `ValidationResult` type and change wording for no server URL found * refactor(actions): check for empty server URL * fix(data-provider): revert tsconfig to fix type issue resolution * feat(client): first pass of actions input for assistants * refactor(FunctionSignature): change method to output object instead of string * refactor(models/Assistant): add actions field to schema, use searchParams object for methods, and add `getAssistant` * feat: post actions input first pass - create new Action document - add actions to Assistant DB document - create /action/:assistant_id POST route - pass more props down from PanelSwitcher, derive assistant_id from switcher - move privacy policy to ActionInput - reset data on input change/validation - add `useUpdateAction` - conform FunctionSignature type to FunctionTool - add action, assistant doc, update hook related types * refactor: optimize assistant/actions relationship - past domain in metadata as hostname and not a URL - include domain in tool name - add `getActions` for actions retrieval by user - add `getAssistants` for assistant docs retrieval by user - add `assistant_id` to Action schema - move actions to own module as a subroute to `api/assistants` - add `useGetActionsQuery` and `useGetAssistantDocsQuery` hooks - fix Action type def * feat: show assistant actions in assistant builder * feat: switch to actions on action click, editing action styling * fix: add Assistant state for builder panel to allow immediate selection of newly created assistants as well as retaining the current assistant when switching to a different panel within the builder * refactor(SidePanel/NavToggle): offset less from right when SidePanel is completely collapsed * chore: rename `processActions` -> `processRequiredActions` * chore: rename Assistant API Action to RequiredAction * refactor(actions): avoid nesting actual API params under generic `requestBody` to optimize LLM token usage * fix(handleTools): avoid calling `validTool` if not defined, add optional param to skip the loading of specs, which throws an error in the context of assistants * WIP: working first pass of toolCalls generated from openapi specs * WIP: first pass ToolCall styling * feat: programmatic iv encryption/decryption helpers * fix: correct ActionAuth types/enums, and define type for AuthForm * feat: encryption/decryption helpers for Action AuthMetadata * refactor(getActions): remove sensitive fields from query response * refactor(POST/actions): encrypt and remove sensitive fields from mutation response * fix(ActionService): change ESM import to CJS * feat: frontend auth handling for actions + optimistic update on action update/creation * refactor(actions): use the correct variables and types for setAuth method * refactor: POST /:assistant_id action can now handle updating an existing action, add `saved_auth_fields` to determine when user explicitly saves new auth creds. only send auth metadata if user explicitly saved fields * refactor(createActionTool): catch errors and send back meaningful error message, add flag to `getActions` to determine whether to retrieve sensitive values or not * refactor(ToolService): add `action` property to ToolCall PartMetadata to determine if the tool call was an action, fix parsing function name issue with actionDelimiter * fix(ActionRequest): use URL class to correctly join endpoint parts for `execute` call * feat: delete assistant actions * refactor: conditionally show Available actions * refactor: show `retrieval` and `code_interpreter` as Capabilities, swap `Switch` for `Checkbox` * chore: remove shadow-stroke from messages * WIP: first pass of Assistants Knowledge attachments * refactor: remove AssistantsProvider in favor of FormProvider, fix selectedAssistant re-render bug, map Assistant file_ids to files via fileMap, initialize Knowledge component with mapped files if any exist * fix: prevent deleting files on assistant file upload * chore: remove console.log * refactor(useUploadFileMutation): update files and assistants cache on upload * chore: disable oauth option as not supported yet * feat: cancel assistant runs * refactor: initialize OpenAI client with helper function, resolve all related circular dependencies * fix(DALL-E): initialization * fix(process): openai client initialization * fix: select an existing Assistant when the active one is deleted * chore: allow attaching files for assistant endpoint, send back relevant OpenAI error message when uploading, deconstruct openAI initialization correctly, add `message_file` to formData when a file is attached to the message but not the assistant * fix: add assistant_id on newConvo * fix(initializeClient): import fix * chore: swap setAssistant for setOption in useEffect * fix(DALL-E): add processFileURL to loadTools call * chore: add customConfig to debug logs * feat: delete threads on convo delete * chore: replace Assistants icon * chore: remove console.dir() in `abortRun` * feat(AssistantService): accumulate text values from run in openai.responseText * feat: titling for assistants endpoint * chore: move panel file components to appropriate directory, add file checks for attaching files, change icon for Attach Files * refactor: add localizations to tools, plugins, add condition for adding/remove user plugins so tool selections don't affect this value * chore: disable `import from url` action for now * chore: remove textMimeTypes from default fileConfig for now * fix: catch tool errors and send as outputs with error messages * fix: React warning about button as descendant of button * style: retrieval and cancelled icon * WIP: pass isSubmitting to Parts, use InProgressCall to display cancelled tool calls correctly, show domain/function name * fix(meilisearch): fix `postSaveHook` issue where indexing expects a mongo document, and join all text content parts for meili indexing * ci: fix dall-e tests * ci: fix client tests * fix: button types in actions panel * fix: plugin auth form persisting across tool selections * fix(ci): update AppService spec with `loadAndFormatTools` * fix(clearConvos): add id check earlier on * refactor(AssistantAvatar): set previewURL dynamically when emtadata.avatar changes * feat(assistants): addTitle cache setting * fix(useSSE): resolve rebase conflicts * fix: delete mutation * style(SidePanel): make grip visible on active and hover, invisible otherwise * ci: add data-provider tests to workflow, also update eslint/tsconfig to recognize specs, and add `text/csv` to fileConfig * fix: handle edge case where auth object is undefined, and log errors * refactor(actions): resolve schemas, add tests for resolving refs, import specs from separate file for tests * chore: remove comment * fix(ActionsInput): re-render bug when initializing states with action fields * fix(patch/assistant): filter undefined tools * chore: add logging for errors in assistants routes * fix(updateAssistant): map actions to functions to avoid overwriting * fix(actions): properly handle GET paths * fix(convos): unhandled delete thread exception * refactor(AssistantService): pass both thread_id and conversationId when sending intermediate assistant messages, remove `mapMessagesToSteps` from AssistantService * refactor(useSSE): replace all messages with runMessages and pass latestMessageId to abortRun; fix(checkMessageGaps): include tool calls when syncing messages * refactor(assistants/chat): invoke `createOnTextProgress` after thread creation * chore: add typing * style: sidepanel styling * style: action tool call domain styling * feat(assistants): default models, limit retrieval to certain models, add env variables to to env.example * feat: assistants api key in EndpointService * refactor: set assistant model to conversation on assistant switch * refactor: set assistant model to conversation on assistant select from panel * fix(retrieveAndProcessFile): catch attempt to download file with `assistant` purpose which is not allowed; add logging * feat: retrieval styling, handling, and logging * chore: rename ASSISTANTS_REVERSE_PROXY to ASSISTANTS_BASE_URL * feat: FileContext for file metadata * feat: context file mgmt and filtering * style(Select): hover/rounded changes * refactor: explicit conversation switch, endpoint dependent, through `useSelectAssistant`, which does not create new chat if current endpoint is assistant endpoint * fix(AssistantAvatar): make empty previewURL if no avatar present * refactor: side panel mobile styling * style: merge tool and action section, optimize mobile styling for action/tool buttons * fix: localStorage issues * fix(useSelectAssistant): invoke react query hook directly in select hook as Map was not being updated in time * style: light mode fixes * fix: prevent sidepanel nav styling from shifting layout up * refactor: change default layout (collapsed by default) * style: mobile optimization of DataTable * style: datatable * feat: client-side hide right-side panel * chore(useNewConvo): add partial typing for preset * fix(useSelectAssistant): pass correct model name by using template as preset * WIP: assistant presets * refactor(ToolService): add native solution for `TavilySearchResults` and log tool output errors * refactor: organize imports and use native TavilySearchResults * fix(TavilySearchResults): stringify result * fix(ToolCall): show tool call outputs when not an action * chore: rename Prompt Prefix to custom instructions (in user facing text only) * refactor(EditPresetDialog): Optimize setting title by debouncing, reset preset on dialog close to avoid state mixture * feat: add `presetOverride` to overwrite active conversation settings when saving a Preset (relevant for client side updates only) * feat: Assistant preset settings (client-side) * fix(Switcher): only set assistant_id and model if current endpoint is Assistants * feat: use `useDebouncedInput` for updating conversation settings, starting with EditPresetDialog title setting and Assistant instructions setting * feat(Assistants): add instructions field to settings * feat(chat/assistants): pass conversation settings to run body * wip: begin localization and only allow actions if the assistant is created * refactor(AssistantsPanel): knowledge localization, allow tools on creation * feat: experimental: allow 'priming' values before assistant is created, that would normally require an assistant_id to be defined * chore: trim console logs and make more meaningful * chore: toast messages * fix(ci): date test * feat: create file when uploading Assistant Avatar * feat: file upload rate limiting from custom config with dynamic file route initialization * refactor: use file upload limiters on post routes only * refactor(fileConfig): add endpoints field for endpoint specific fileconfigs, add mergeConfig function, add tests * refactor: fileConfig route, dynamic multer instances used on all '/' and '/images' POST routes, data service and query hook * feat: supportedMimeTypesSchema, test for array of regex * feat: configurable file config limits * chore: clarify assistants file knowledge prereq. * chore(useTextarea): default to localized 'Assistant' if assistant name is empty * feat: configurable file limits and toggle file upload per endpoint * fix(useUploadFileMutation): prevent updating assistant.files cache if file upload is a message_file attachment * fix(AssistantSelect): set last selected assistant only when timeout successfully runs * refactor(queries): disable assistant queries if assistants endpoint is not enabled * chore(Switcher): add localization * chore: pluralize `assistant` for `EModelEndpoint key and value * feat: show/hide assistant UI components based on endpoint availability; librechat.yaml config for disabling builder section and setting polling/timeout intervals * fix(compactEndpointSchemas): use EModelEndpoint for schema access * feat(runAssistant): use configured values from `librechat.yaml` for `pollIntervalMs` and `timeout` * fix: naming issue * wip: revert landing * 🎉 happy birthday LibreChat (#1768) * happy birthday LibreChat * Refactor endpoint condition in Landing component * Update birthday message in Eng.tsx * fix(/config): avoid nesting ternaries * refactor(/config): check birthday --------- Co-authored-by: Danny Avila <messagedaniel@protonmail.com> * fix: landing * fix: landing * fix(useMessageHelpers): hardcoded check to use EModelEndpoint instead * fix(ci): convo test revert to main * fix(assistants/chat): fix issue where assistant_id was being saved as model for convo * chore: added logging, promises racing to prevent longer timeouts, explicit setting of maxRetries and timeouts, robust catching of invalid abortRun params * refactor: use recoil state for `showStopButton` and only show for assistants endpoint after syncing conversation data * refactor: optimize abortRun strategy using localStorage, refactor `abortConversation` to use async/await and await the result, refactor how the abortKey cache is set for runs * fix(checkMessageGaps): assign `assistant_id` to synced messages if defined; prevents UI from showing blank assistant for cancelled messages * refactor: re-order sequence of chat route, only allow aborting messages after run is created, cancel abortRun if there was a cancelling error (likely due already cancelled in chat route), and add extra logging * chore(typedefs): add httpAgent type to OpenAIClient * refactor: use custom implementation of retrieving run with axios to allow for timing out run query * fix(waitForRun): handle timed out run retrieval query * refactor: update preset conditions: - presets will retain settings when a different endpoint is selected; for existing convos, either when modular or is assistant switch - no longer use `navigateToConvo` on preset select * fix: temporary calculator hack as expects string input when invoked * fix: cancel abortRun only when cancelling error is a result of the run already being cancelled * chore: remove use of `fileMaxSizeMB` and total counterpart (redundant) * docs: custom config documentation update * docs: assistants api setup and dotenv, new custom config fields * refactor(Switcher): make Assistant switcher sticky in SidePanel * chore(useSSE): remove console log of data and message index * refactor(AssistantPanel): button styling and add secondary select button to bottom of panel * refactor(OpenAIClient): allow passing conversationId to RunManager through titleConvo and initializeLLM to properly record title context tokens used in cases where conversationId was not defined by the client * feat(assistants): token tracking for assistant runs * chore(spendTokens): improve logging * feat: support/exclude specific assistant Ids * chore: add update `librechat.example.yaml`, optimize `AppService` handling, new tests for `AppService`, optimize missing/outdate config logging * chore: mount docker logs to root of project * chore: condense axios errors * chore: bump vite * chore: vite hot reload fix using latest version * chore(getOpenAIModels): sort instruct models to the end of models list * fix(assistants): user provided key * fix(assistants): user provided key, invalidate more queries on revoke --------- Co-authored-by: Marco Beretta <81851188+Berry-13@users.noreply.github.com>
2024-02-13 20:42:27 -05:00
return { ...plugin, authenticated: true };
} else {
return plugin;
}
});
/** Filter plugins based on availability */
🗝️ feat: User Provided Credentials for MCP Servers (#7980) * 🗝️ feat: Per-User Credentials for MCP Servers chore: add aider to gitignore feat: fill custom variables to MCP server feat: replace placeholders with custom user MCP variables feat: handle MCP install/uninstall (uses pluginauths) feat: add MCP custom variables dialog to MCPSelect feat: add MCP custom variables dialog to the side panel feat: do not require to fill MCP credentials for in tools dialog feat: add translations keys (en+cs) for custom MCP variables fix: handle LIBRECHAT_USER_ID correctly during MCP var replacement style: remove unused MCP translation keys style: fix eslint for MCP custom vars chore: move aider gitignore to AI section * feat: Add Plugin Authentication Methods to data-schemas * refactor: Replace PluginAuth model methods with new utility functions for improved code organization and maintainability * refactor: Move IPluginAuth interface to types directory for better organization and update pluginAuth schema to use the new import * refactor: Remove unused getUsersPluginsAuthValuesMap function and streamline PluginService.js; add new getPluginAuthMap function for improved plugin authentication handling * chore: fix typing for optional tools property with GenericTool[] type * chore: update librechat-data-provider version to 0.7.88 * refactor: optimize getUserMCPAuthMap function by reducing variable usage and improving server key collection logic * refactor: streamline MCP tool creation by removing customUserVars parameter and enhancing user-specific authentication handling to avoid closure encapsulation * refactor: extract processSingleValue function to streamline MCP environment variable processing and enhance readability * refactor: enhance MCP tool processing logic by simplifying conditions and improving authentication handling for custom user variables * ci: fix action tests * chore: fix imports, remove comments * chore: remove non-english translations * fix: remove newline at end of translation.json file --------- Co-authored-by: Aleš Kůtek <kutekales@gmail.com>
2025-06-19 18:27:55 -04:00
const toolsOutput = [];
for (const plugin of authenticatedPlugins) {
const isToolDefined = toolDefinitions?.[plugin.pluginKey] !== undefined;
🗝️ feat: User Provided Credentials for MCP Servers (#7980) * 🗝️ feat: Per-User Credentials for MCP Servers chore: add aider to gitignore feat: fill custom variables to MCP server feat: replace placeholders with custom user MCP variables feat: handle MCP install/uninstall (uses pluginauths) feat: add MCP custom variables dialog to MCPSelect feat: add MCP custom variables dialog to the side panel feat: do not require to fill MCP credentials for in tools dialog feat: add translations keys (en+cs) for custom MCP variables fix: handle LIBRECHAT_USER_ID correctly during MCP var replacement style: remove unused MCP translation keys style: fix eslint for MCP custom vars chore: move aider gitignore to AI section * feat: Add Plugin Authentication Methods to data-schemas * refactor: Replace PluginAuth model methods with new utility functions for improved code organization and maintainability * refactor: Move IPluginAuth interface to types directory for better organization and update pluginAuth schema to use the new import * refactor: Remove unused getUsersPluginsAuthValuesMap function and streamline PluginService.js; add new getPluginAuthMap function for improved plugin authentication handling * chore: fix typing for optional tools property with GenericTool[] type * chore: update librechat-data-provider version to 0.7.88 * refactor: optimize getUserMCPAuthMap function by reducing variable usage and improving server key collection logic * refactor: streamline MCP tool creation by removing customUserVars parameter and enhancing user-specific authentication handling to avoid closure encapsulation * refactor: extract processSingleValue function to streamline MCP environment variable processing and enhance readability * refactor: enhance MCP tool processing logic by simplifying conditions and improving authentication handling for custom user variables * ci: fix action tests * chore: fix imports, remove comments * chore: remove non-english translations * fix: remove newline at end of translation.json file --------- Co-authored-by: Aleš Kůtek <kutekales@gmail.com>
2025-06-19 18:27:55 -04:00
const isToolkit =
plugin.toolkit === true &&
Object.keys(toolDefinitions ?? {}).some(
(key) => getToolkitKey({ toolkits, toolName: key }) === plugin.pluginKey,
);
🗝️ feat: User Provided Credentials for MCP Servers (#7980) * 🗝️ feat: Per-User Credentials for MCP Servers chore: add aider to gitignore feat: fill custom variables to MCP server feat: replace placeholders with custom user MCP variables feat: handle MCP install/uninstall (uses pluginauths) feat: add MCP custom variables dialog to MCPSelect feat: add MCP custom variables dialog to the side panel feat: do not require to fill MCP credentials for in tools dialog feat: add translations keys (en+cs) for custom MCP variables fix: handle LIBRECHAT_USER_ID correctly during MCP var replacement style: remove unused MCP translation keys style: fix eslint for MCP custom vars chore: move aider gitignore to AI section * feat: Add Plugin Authentication Methods to data-schemas * refactor: Replace PluginAuth model methods with new utility functions for improved code organization and maintainability * refactor: Move IPluginAuth interface to types directory for better organization and update pluginAuth schema to use the new import * refactor: Remove unused getUsersPluginsAuthValuesMap function and streamline PluginService.js; add new getPluginAuthMap function for improved plugin authentication handling * chore: fix typing for optional tools property with GenericTool[] type * chore: update librechat-data-provider version to 0.7.88 * refactor: optimize getUserMCPAuthMap function by reducing variable usage and improving server key collection logic * refactor: streamline MCP tool creation by removing customUserVars parameter and enhancing user-specific authentication handling to avoid closure encapsulation * refactor: extract processSingleValue function to streamline MCP environment variable processing and enhance readability * refactor: enhance MCP tool processing logic by simplifying conditions and improving authentication handling for custom user variables * ci: fix action tests * chore: fix imports, remove comments * chore: remove non-english translations * fix: remove newline at end of translation.json file --------- Co-authored-by: Aleš Kůtek <kutekales@gmail.com>
2025-06-19 18:27:55 -04:00
if (!isToolDefined && !isToolkit) {
continue;
}
toolsOutput.push(plugin);
🗝️ feat: User Provided Credentials for MCP Servers (#7980) * 🗝️ feat: Per-User Credentials for MCP Servers chore: add aider to gitignore feat: fill custom variables to MCP server feat: replace placeholders with custom user MCP variables feat: handle MCP install/uninstall (uses pluginauths) feat: add MCP custom variables dialog to MCPSelect feat: add MCP custom variables dialog to the side panel feat: do not require to fill MCP credentials for in tools dialog feat: add translations keys (en+cs) for custom MCP variables fix: handle LIBRECHAT_USER_ID correctly during MCP var replacement style: remove unused MCP translation keys style: fix eslint for MCP custom vars chore: move aider gitignore to AI section * feat: Add Plugin Authentication Methods to data-schemas * refactor: Replace PluginAuth model methods with new utility functions for improved code organization and maintainability * refactor: Move IPluginAuth interface to types directory for better organization and update pluginAuth schema to use the new import * refactor: Remove unused getUsersPluginsAuthValuesMap function and streamline PluginService.js; add new getPluginAuthMap function for improved plugin authentication handling * chore: fix typing for optional tools property with GenericTool[] type * chore: update librechat-data-provider version to 0.7.88 * refactor: optimize getUserMCPAuthMap function by reducing variable usage and improving server key collection logic * refactor: streamline MCP tool creation by removing customUserVars parameter and enhancing user-specific authentication handling to avoid closure encapsulation * refactor: extract processSingleValue function to streamline MCP environment variable processing and enhance readability * refactor: enhance MCP tool processing logic by simplifying conditions and improving authentication handling for custom user variables * ci: fix action tests * chore: fix imports, remove comments * chore: remove non-english translations * fix: remove newline at end of translation.json file --------- Co-authored-by: Aleš Kůtek <kutekales@gmail.com>
2025-06-19 18:27:55 -04:00
}
🗝️ feat: User Provided Credentials for MCP Servers (#7980) * 🗝️ feat: Per-User Credentials for MCP Servers chore: add aider to gitignore feat: fill custom variables to MCP server feat: replace placeholders with custom user MCP variables feat: handle MCP install/uninstall (uses pluginauths) feat: add MCP custom variables dialog to MCPSelect feat: add MCP custom variables dialog to the side panel feat: do not require to fill MCP credentials for in tools dialog feat: add translations keys (en+cs) for custom MCP variables fix: handle LIBRECHAT_USER_ID correctly during MCP var replacement style: remove unused MCP translation keys style: fix eslint for MCP custom vars chore: move aider gitignore to AI section * feat: Add Plugin Authentication Methods to data-schemas * refactor: Replace PluginAuth model methods with new utility functions for improved code organization and maintainability * refactor: Move IPluginAuth interface to types directory for better organization and update pluginAuth schema to use the new import * refactor: Remove unused getUsersPluginsAuthValuesMap function and streamline PluginService.js; add new getPluginAuthMap function for improved plugin authentication handling * chore: fix typing for optional tools property with GenericTool[] type * chore: update librechat-data-provider version to 0.7.88 * refactor: optimize getUserMCPAuthMap function by reducing variable usage and improving server key collection logic * refactor: streamline MCP tool creation by removing customUserVars parameter and enhancing user-specific authentication handling to avoid closure encapsulation * refactor: extract processSingleValue function to streamline MCP environment variable processing and enhance readability * refactor: enhance MCP tool processing logic by simplifying conditions and improving authentication handling for custom user variables * ci: fix action tests * chore: fix imports, remove comments * chore: remove non-english translations * fix: remove newline at end of translation.json file --------- Co-authored-by: Aleš Kůtek <kutekales@gmail.com>
2025-06-19 18:27:55 -04:00
const finalTools = filterUniquePlugins(toolsOutput);
🏗️ feat: bulkWrite isolation, pre-auth context, strict-mode fixes (#12445) * fix: wrap seedDatabase() in runAsSystem() for strict tenant mode seedDatabase() was called without tenant context at startup, causing every Mongoose operation inside it to throw when TENANT_ISOLATION_STRICT=true. Wrapping in runAsSystem() gives it the SYSTEM_TENANT_ID sentinel so the isolation plugin skips filtering, matching the pattern already used for performStartupChecks and updateInterfacePermissions. * fix: chain tenantContextMiddleware in optionalJwtAuth optionalJwtAuth populated req.user but never established ALS tenant context, unlike requireJwtAuth which chains tenantContextMiddleware after successful auth. Authenticated users hitting routes with optionalJwtAuth (e.g. /api/banner) had no tenant isolation. * feat: tenant-safe bulkWrite wrapper and call-site migration Mongoose's bulkWrite() does not trigger schema-level middleware hooks, so the applyTenantIsolation plugin cannot intercept it. This adds a tenantSafeBulkWrite() utility that injects the current ALS tenant context into every operation's filter/document before delegating to native bulkWrite. Migrates all 8 runtime bulkWrite call sites: - agentCategory (seedCategories, ensureDefaultCategories) - conversation (bulkSaveConvos) - message (bulkSaveMessages) - file (batchUpdateFiles) - conversationTag (updateTagsForConversation, bulkIncrementTagCounts) - aclEntry (bulkWriteAclEntries) systemGrant.seedSystemGrants is intentionally not migrated — it uses explicit tenantId: { $exists: false } filters and is exempt from the isolation plugin. * feat: pre-auth tenant middleware and tenant-scoped config cache Adds preAuthTenantMiddleware that reads X-Tenant-Id from the request header and wraps downstream in tenantStorage ALS context. Wired onto /oauth, /api/auth, /api/config, and /api/share — unauthenticated routes that need tenant scoping before JWT auth runs. The /api/config cache key is now tenant-scoped (STARTUP_CONFIG:${tenantId}) so multi-tenant deployments serve the correct login page config per tenant. The middleware is intentionally minimal — no subdomain parsing, no OIDC claim extraction. The private fork's reverse proxy or auth gateway sets the header. * feat: accept optional tenantId in updateInterfacePermissions When tenantId is provided, the function re-enters inside tenantStorage.run({ tenantId }) so all downstream Mongoose queries target that tenant's roles instead of the system context. This lets the private fork's tenant provisioning flow call updateInterfacePermissions per-tenant after creating tenant-scoped ADMIN/USER roles. * fix: tenant-filter $lookup in getPromptGroup aggregation The $lookup stage in getPromptGroup() queried the prompts collection without tenant filtering. While the outer PromptGroup aggregate is protected by the tenantIsolation plugin's pre('aggregate') hook, $lookup runs as an internal MongoDB operation that bypasses Mongoose hooks entirely. Converts from simple field-based $lookup to pipeline-based $lookup with an explicit tenantId match when tenant context is active. * fix: replace field-level unique indexes with tenant-scoped compounds Field-level unique:true creates a globally-unique single-field index in MongoDB, which would cause insert failures across tenants sharing the same ID values. - agent.id: removed field-level unique, added { id, tenantId } compound - convo.conversationId: removed field-level unique (compound at line 50 already exists: { conversationId, user, tenantId }) - message.messageId: removed field-level unique (compound at line 165 already exists: { messageId, user, tenantId }) - preset.presetId: removed field-level unique, added { presetId, tenantId } compound * fix: scope MODELS_CONFIG, ENDPOINT_CONFIG, PLUGINS, TOOLS caches by tenant These caches store per-tenant configuration (available models, endpoint settings, plugin availability, tool definitions) but were using global cache keys. In multi-tenant mode, one tenant's cached config would be served to all tenants. Appends :${tenantId} to cache keys when tenant context is active. Falls back to the unscoped key when no tenant context exists (backward compatible for single-tenant OSS deployments). Covers all read, write, and delete sites: - ModelController.js: get/set MODELS_CONFIG - PluginController.js: get/set PLUGINS, get/set TOOLS - getEndpointsConfig.js: get/set/delete ENDPOINT_CONFIG - app.js: delete ENDPOINT_CONFIG (clearEndpointConfigCache) - mcp.js: delete TOOLS (updateMCPTools, mergeAppTools) - importers.js: get ENDPOINT_CONFIG * fix: add getTenantId to PluginController spec mock The data-schemas mock was missing getTenantId, causing all PluginController tests to throw when the controller calls getTenantId() for tenant-scoped cache keys. * fix: address review findings — migration, strict-mode, DRY, types Addresses all CRITICAL, MAJOR, and MINOR review findings: F1 (CRITICAL): Add agents, conversations, messages, presets to SUPERSEDED_INDEXES in tenantIndexes.ts so dropSupersededTenantIndexes() drops the old single-field unique indexes that block multi-tenant inserts. F2 (CRITICAL): Unknown bulkWrite op types now throw in strict mode instead of silently passing through without tenant injection. F3 (MAJOR): Replace wildcard export with named export for tenantSafeBulkWrite, hiding _resetBulkWriteStrictCache from the public package API. F5 (MAJOR): Restore AnyBulkWriteOperation<IAclEntry>[] typing on bulkWriteAclEntries — the unparameterized wrapper accepts parameterized ops as a subtype. F7 (MAJOR): Fix config.js tenant precedence — JWT-derived req.user.tenantId now takes priority over the X-Tenant-Id header for authenticated requests. F8 (MINOR): Extract scopedCacheKey() helper into tenantContext.ts and replace all 11 inline occurrences across 7 files. F9 (MINOR): Use simple localField/foreignField $lookup for the non-tenant getPromptGroup path (more efficient index seeks). F12 (NIT): Remove redundant BulkOp type alias. F13 (NIT): Remove debug log that leaked raw tenantId. * fix: add new superseded indexes to tenantIndexes test fixture The test creates old indexes to verify the migration drops them. Missing fixture entries for agents.id_1, conversations.conversationId_1, messages.messageId_1, and presets.presetId_1 caused the count assertion to fail (expected 22, got 18). * fix: restore logger.warn for unknown bulk op types in non-strict mode * fix: block SYSTEM_TENANT_ID sentinel from external header input CRITICAL: preAuthTenantMiddleware accepted any string as X-Tenant-Id, including '__SYSTEM__'. The tenantIsolation plugin treats SYSTEM_TENANT_ID as an explicit bypass — skipping ALL query filters. A client sending X-Tenant-Id: __SYSTEM__ to pre-auth routes (/api/share, /api/config, /api/auth, /oauth) would execute Mongoose operations without tenant isolation. Fixes: - preAuthTenantMiddleware rejects SYSTEM_TENANT_ID in header - scopedCacheKey returns the base key (not key:__SYSTEM__) in system context, preventing stale cache entries during runAsSystem() - updateInterfacePermissions guards tenantId against SYSTEM_TENANT_ID - $lookup pipeline separates $expr join from constant tenantId match for better index utilization - Regression test for sentinel rejection in preAuthTenant.spec.ts - Remove redundant getTenantId() call in config.js * test: add missing deleteMany/replaceOne coverage, fix vacuous ALS assertions bulkWrite spec: - deleteMany: verifies tenant-scoped deletion leaves other tenants untouched - replaceOne: verifies tenantId injected into both filter and replacement - replaceOne overwrite: verifies a conflicting tenantId in the replacement document is overwritten by the ALS tenant (defense-in-depth) - empty ops array: verifies graceful handling preAuthTenant spec: - All negative-case tests now use the capturedNext pattern to verify getTenantId() inside the middleware's execution context, not the test runner's outer frame (which was always undefined regardless) * feat: tenant-isolate MESSAGES cache, FLOWS cache, and GenerationJobManager MESSAGES cache (streamAudio.js): - Cache key now uses scopedCacheKey(messageId) to prefix with tenantId, preventing cross-tenant message content reads during TTS streaming. FLOWS cache (FlowStateManager): - getFlowKey() now generates ${type}:${tenantId}:${flowId} when tenant context is active, isolating OAuth flow state per tenant. GenerationJobManager: - tenantId added to SerializableJobData and GenerationJobMetadata - createJob() captures the current ALS tenant context (excluding SYSTEM_TENANT_ID) and stores it in job metadata - SSE subscription endpoint validates job.metadata.tenantId matches req.user.tenantId, blocking cross-tenant stream access - Both InMemoryJobStore and RedisJobStore updated to accept tenantId * fix: add getTenantId and SYSTEM_TENANT_ID to MCP OAuth test mocks FlowStateManager.getFlowKey() now calls getTenantId() for tenant-scoped flow keys. The 4 MCP OAuth test files mock @librechat/data-schemas without these exports, causing TypeError at runtime. * fix: correct import ordering per AGENTS.md conventions Package imports sorted shortest to longest line length, local imports sorted longest to shortest — fixes ordering violations introduced by our new imports across 8 files. * fix: deserialize tenantId in RedisJobStore — cross-tenant SSE guard was no-op in Redis mode serializeJob() writes tenantId to the Redis hash via Object.entries, but deserializeJob() manually enumerates fields and omitted tenantId. Every getJob() from Redis returned tenantId: undefined, causing the SSE route's cross-tenant guard to short-circuit (undefined && ... → false). * test: SSE tenant guard, FlowStateManager key consistency, ALS scope docs SSE stream tenant tests (streamTenant.spec.js): - Cross-tenant user accessing another tenant's stream → 403 - Same-tenant user accessing own stream → allowed - OSS mode (no tenantId on job) → tenant check skipped FlowStateManager tenant tests (manager.tenant.spec.ts): - completeFlow finds flow created under same tenant context - completeFlow does NOT find flow under different tenant context - Unscoped flows are separate from tenant-scoped flows Documentation: - JSDoc on getFlowKey documenting ALS context consistency requirement - Comment on streamAudio.js scopedCacheKey capture site * fix: SSE stream tests hang on success path, remove internal fork references The success-path tests entered the SSE streaming code which never closes, causing timeout. Mock subscribe() to end the response immediately. Restructured assertions to verify non-403/non-404. Removed "private fork" and "OSS" references from code and test descriptions — replaced with "deployment layer", "multi-tenant deployments", and "single-tenant mode". * fix: address review findings — test rigor, tenant ID validation, docs F1: SSE stream tests now mock subscribe() with correct signature (streamId, writeEvent, onDone, onError) and assert 200 status, verifying the tenant guard actually allows through same-tenant users. F2: completeFlow logs the attempted key and ALS tenantId when flow is not found, so reverse proxy misconfiguration (missing X-Tenant-Id on OAuth callback) produces an actionable warning. F3/F10: preAuthTenantMiddleware validates tenant ID format — rejects colons, special characters, and values exceeding 128 chars. Trims whitespace. Prevents cache key collisions via crafted headers. F4: Documented cache invalidation scope limitation in clearEndpointConfigCache — only the calling tenant's key is cleared; other tenants expire via TTL. F7: getFlowKey JSDoc now lists all 8 methods requiring consistent ALS context. F8: Added dedicated scopedCacheKey unit tests — base key without context, base key in system context, scoped key with tenant, no ALS leakage across scope boundaries. * fix: revert flow key tenant scoping, fix SSE test timing FlowStateManager: Reverts tenant-scoped flow keys. OAuth callbacks arrive without tenant ALS context (provider redirects don't carry X-Tenant-Id), so completeFlow/failFlow would never find flows created under tenant context. Flow IDs are random UUIDs with no collision risk, and flow data is ephemeral (TTL-bounded). SSE tests: Use process.nextTick for onDone callback so Express response headers are flushed before res.write/res.end are called. * fix: restore getTenantId import for completeFlow diagnostic log * fix: correct completeFlow warning message, add missing flow test The warning referenced X-Tenant-Id header consistency which was only relevant when flow keys were tenant-scoped (since reverted). Updated to list actual causes: TTL expiry, missing flow, or routing to a different instance without shared Keyv storage. Removed the getTenantId() call and import — no longer needed since flow keys are unscoped. Added test for the !flowState branch in completeFlow — verifies return false and logger.warn on nonexistent flow ID. * fix: add explicit return type to recursive updateInterfacePermissions The recursive call (tenantId branch calls itself without tenantId) causes TypeScript to infer circular return type 'any'. Adding explicit Promise<void> satisfies the rollup typescript plugin. * fix: update MCPOAuthRaceCondition test to match new completeFlow warning * fix: clearEndpointConfigCache deletes both scoped and unscoped keys Unauthenticated /api/endpoints requests populate the unscoped ENDPOINT_CONFIG key. Admin config mutations clear only the tenant-scoped key, leaving the unscoped entry stale indefinitely. Now deletes both when in tenant context. * fix: tenant guard on abort/status endpoints, warn logs, test coverage F1: Add tenant guard to /chat/status/:conversationId and /chat/abort matching the existing guard on /chat/stream/:streamId. The status endpoint exposes aggregatedContent (AI response text) which requires tenant-level access control. F2: preAuthTenantMiddleware now logs warn for rejected __SYSTEM__ sentinel and malformed tenant IDs, providing observability for bypass probing attempts. F3: Abort fallback path (getActiveJobIdsForUser) now has tenant check after resolving the job. F4: Test for strict mode + SYSTEM_TENANT_ID — verifies runAsSystem bypasses tenantSafeBulkWrite without throwing in strict mode. F5: Test for job with tenantId + user without tenantId → 403. F10: Regex uses idiomatic hyphen-at-start form. F11: Test descriptions changed from "rejects" to "ignores" since middleware calls next() (not 4xx). Also fixes MCPOAuthRaceCondition test assertion to match updated completeFlow warning message. * fix: test coverage for logger.warn, status/abort guards, consistency A: preAuthTenant spec now mocks logger and asserts warn calls for __SYSTEM__ sentinel, malformed characters, and oversized headers. B: streamTenant spec expanded with status and abort endpoint tests — cross-tenant status returns 403, same-tenant returns 200 with body, cross-tenant abort returns 403. C: Abort endpoint uses req.user.tenantId (not req.user?.tenantId) matching stream/status pattern — requireJwtAuth guarantees req.user. D: Malformed header warning now includes ip in log metadata, matching the sentinel warning for consistent SOC correlation. * fix: assert ip field in malformed header warn tests * fix: parallelize cache deletes, document tenant guard, fix import order - clearEndpointConfigCache uses Promise.all for independent cache deletes instead of sequential awaits - SSE stream tenant guard has inline comment explaining backward-compat behavior for untenanted legacy jobs - conversation.ts local imports reordered longest-to-shortest per AGENTS.md * fix: tenant-qualify userJobs keys, document tenant guard backward-compat Job store userJobs keys now include tenantId when available: - Redis: stream:user:{tenantId:userId}:jobs (falls back to stream:user:{userId}:jobs when no tenant) - InMemory: composite key tenantId:userId in userJobMap getActiveJobIdsByUser/getActiveJobIdsForUser accept optional tenantId parameter, threaded through from req.user.tenantId at all call sites (/chat/active and /chat/abort fallback). Added inline comments on all three SSE tenant guards explaining the backward-compat design: untenanted legacy jobs remain accessible when the userId check passes. * fix: parallelize cache deletes, document tenant guard, fix import order Fix InMemoryJobStore.getActiveJobIdsByUser empty-set cleanup to use the tenant-qualified userKey instead of bare userId — prevents orphaned empty Sets accumulating in userJobMap for multi-tenant users. Document cross-tenant staleness in clearEndpointConfigCache JSDoc — other tenants' scoped keys expire via TTL, not active invalidation. * fix: cleanup userJobMap leak, startup warning, DRY tenant guard, docs F1: InMemoryJobStore.cleanup() now removes entries from userJobMap before calling deleteJob, preventing orphaned empty Sets from accumulating with tenant-qualified composite keys. F2: Startup warning when TENANT_ISOLATION_STRICT is active — reminds operators to configure reverse proxy to control X-Tenant-Id header. F3: mergeAppTools JSDoc documents that tenant-scoped TOOLS keys are not actively invalidated (matching clearEndpointConfigCache pattern). F5: Abort handler getActiveJobIdsForUser call uses req.user.tenantId (not req.user?.tenantId) — consistent with stream/status handlers. F6: updateInterfacePermissions JSDoc clarifies SYSTEM_TENANT_ID behavior — falls through to caller's ALS context. F7: Extracted hasTenantMismatch() helper, replacing three identical inline tenant guard blocks across stream/status/abort endpoints. F9: scopedCacheKey JSDoc documents both passthrough cases (no context and SYSTEM_TENANT_ID context). * fix: clean userJobMap in evictOldest — same leak as cleanup()
2026-03-28 16:43:50 -04:00
await cache.set(toolsCacheKey, finalTools);
res.status(200).json(finalTools);
✨ feat: Assistants API, General File Support, Side Panel, File Explorer (#1696) * feat: assistant name/icon in Landing & Header * feat: assistname in textarea placeholder, and use `Assistant` as default name * feat: display non-image files in user messages * fix: only render files if files.length is > 0 * refactor(config -> file-config): move file related configuration values to separate module, add excel types * chore: spreadsheet file rendering * fix(Landing): dark mode style for Assistant Name * refactor: move progress incrementing to own hook, start smaller, cap near limit \(1\) * refactor(useContentHandler): add empty Text part if last part was completed tool or image * chore: add accordion trigger border styling for dark mode * feat: Assistant Builder model selection * chore: use Spinner when Assistant is mutating * fix(get/assistants): return correct response object `AssistantListResponse` * refactor(Spinner): pass size as prop * refactor: make assistant crud mutations optimistic, add types for options * chore: remove assistants route and view * chore: move assistant builder components to separate directory * feat(ContextButton): delete Assistant via context button/dialog, add localization * refactor: conditionally show use and context menu buttons, add localization for create assistant * feat: save side panel states to localStorage * style(SidePanel): improve avatar menu and assistant select styling for dark mode * refactor: make NavToggle reusable for either side (left or right), add SidePanel Toggle with ability to close it completely * fix: resize handle and navToggle behavior * fix(/avatar/:assistant_id): await `deleteFile` and assign unique name to uploaded image * WIP: file UI components from PR #576 * refactor(OpenAIMinimalIcon): pass className * feat: formatDate helper fn * feat: DataTableColumnHeader * feat: add row selection, formatted row values, number of rows selected * WIP: add files to Side panel temporarily * feat: `LB_QueueAsyncCall`: Leaky Bucket queue for external APIs, use in `processDeleteRequest` * fix(TFile): correct `source` type with `FileSources` * fix(useFileHandling): use `continue` instead of return when iterating multiple files, add file type to extendedFile * chore: add generic setter type * refactor(processDeleteRequest): settle promises to prevent rejections from processing deletions, log errors * feat: `useFileDeletion` to reuse file deletion logic * refactor(useFileDeletion): make `setFiles` an optional param and use object as param * feat: useDeleteFilesFromTable * feat: use real `files` data and add deletion action to data table * fix(Table): make headers sticky * feat: add dynamic filtering for columns; only show to user Host or OpenAI storage type * style(DropdownMenu): replace `slate` with `gray` * style(DataTable): apply dark mode themes and other misc styling * style(Columns): add color to OpenAI Storage option * refactor(FileContainer): make file preview reusable * refactor(Images): make image preview reusable * refactor(FilePreview): make file prop optional for FileIcon and FilePreview, fix relative style * feat(Columns): add file/image previews, set a minimum size to show for file size in bytes * WIP: File Panel with real files and formatted * feat: open files dialog from panel * style: file data table mobile and general column styling fixes * refactor(api/files): return files sorted by the most recently updated * refactor: provide fileMap through context to prevent re-selecting files to map in different areas; remove unused imports commented out in PanelColumns * refactor(ExtendFile): make File type optional, add `attached` to prevent attached files from being deleted on remove, make Message.files a partial TFile type * feat: attach files through file panel * refactor(useFileHandling): move files to the start of cache list when uploaded * refactor(useDeleteFilesMutation): delete files from cache when successfully deleted from server * fix(FileRow): handle possible edge case of duplication due to attaching recently uploaded file * style(SidePanel): make resize grip border transparent, remove unnecessary styling on close sidepanel button * feat: action utilities and tests * refactor(actions): add `ValidationResult` type and change wording for no server URL found * refactor(actions): check for empty server URL * fix(data-provider): revert tsconfig to fix type issue resolution * feat(client): first pass of actions input for assistants * refactor(FunctionSignature): change method to output object instead of string * refactor(models/Assistant): add actions field to schema, use searchParams object for methods, and add `getAssistant` * feat: post actions input first pass - create new Action document - add actions to Assistant DB document - create /action/:assistant_id POST route - pass more props down from PanelSwitcher, derive assistant_id from switcher - move privacy policy to ActionInput - reset data on input change/validation - add `useUpdateAction` - conform FunctionSignature type to FunctionTool - add action, assistant doc, update hook related types * refactor: optimize assistant/actions relationship - past domain in metadata as hostname and not a URL - include domain in tool name - add `getActions` for actions retrieval by user - add `getAssistants` for assistant docs retrieval by user - add `assistant_id` to Action schema - move actions to own module as a subroute to `api/assistants` - add `useGetActionsQuery` and `useGetAssistantDocsQuery` hooks - fix Action type def * feat: show assistant actions in assistant builder * feat: switch to actions on action click, editing action styling * fix: add Assistant state for builder panel to allow immediate selection of newly created assistants as well as retaining the current assistant when switching to a different panel within the builder * refactor(SidePanel/NavToggle): offset less from right when SidePanel is completely collapsed * chore: rename `processActions` -> `processRequiredActions` * chore: rename Assistant API Action to RequiredAction * refactor(actions): avoid nesting actual API params under generic `requestBody` to optimize LLM token usage * fix(handleTools): avoid calling `validTool` if not defined, add optional param to skip the loading of specs, which throws an error in the context of assistants * WIP: working first pass of toolCalls generated from openapi specs * WIP: first pass ToolCall styling * feat: programmatic iv encryption/decryption helpers * fix: correct ActionAuth types/enums, and define type for AuthForm * feat: encryption/decryption helpers for Action AuthMetadata * refactor(getActions): remove sensitive fields from query response * refactor(POST/actions): encrypt and remove sensitive fields from mutation response * fix(ActionService): change ESM import to CJS * feat: frontend auth handling for actions + optimistic update on action update/creation * refactor(actions): use the correct variables and types for setAuth method * refactor: POST /:assistant_id action can now handle updating an existing action, add `saved_auth_fields` to determine when user explicitly saves new auth creds. only send auth metadata if user explicitly saved fields * refactor(createActionTool): catch errors and send back meaningful error message, add flag to `getActions` to determine whether to retrieve sensitive values or not * refactor(ToolService): add `action` property to ToolCall PartMetadata to determine if the tool call was an action, fix parsing function name issue with actionDelimiter * fix(ActionRequest): use URL class to correctly join endpoint parts for `execute` call * feat: delete assistant actions * refactor: conditionally show Available actions * refactor: show `retrieval` and `code_interpreter` as Capabilities, swap `Switch` for `Checkbox` * chore: remove shadow-stroke from messages * WIP: first pass of Assistants Knowledge attachments * refactor: remove AssistantsProvider in favor of FormProvider, fix selectedAssistant re-render bug, map Assistant file_ids to files via fileMap, initialize Knowledge component with mapped files if any exist * fix: prevent deleting files on assistant file upload * chore: remove console.log * refactor(useUploadFileMutation): update files and assistants cache on upload * chore: disable oauth option as not supported yet * feat: cancel assistant runs * refactor: initialize OpenAI client with helper function, resolve all related circular dependencies * fix(DALL-E): initialization * fix(process): openai client initialization * fix: select an existing Assistant when the active one is deleted * chore: allow attaching files for assistant endpoint, send back relevant OpenAI error message when uploading, deconstruct openAI initialization correctly, add `message_file` to formData when a file is attached to the message but not the assistant * fix: add assistant_id on newConvo * fix(initializeClient): import fix * chore: swap setAssistant for setOption in useEffect * fix(DALL-E): add processFileURL to loadTools call * chore: add customConfig to debug logs * feat: delete threads on convo delete * chore: replace Assistants icon * chore: remove console.dir() in `abortRun` * feat(AssistantService): accumulate text values from run in openai.responseText * feat: titling for assistants endpoint * chore: move panel file components to appropriate directory, add file checks for attaching files, change icon for Attach Files * refactor: add localizations to tools, plugins, add condition for adding/remove user plugins so tool selections don't affect this value * chore: disable `import from url` action for now * chore: remove textMimeTypes from default fileConfig for now * fix: catch tool errors and send as outputs with error messages * fix: React warning about button as descendant of button * style: retrieval and cancelled icon * WIP: pass isSubmitting to Parts, use InProgressCall to display cancelled tool calls correctly, show domain/function name * fix(meilisearch): fix `postSaveHook` issue where indexing expects a mongo document, and join all text content parts for meili indexing * ci: fix dall-e tests * ci: fix client tests * fix: button types in actions panel * fix: plugin auth form persisting across tool selections * fix(ci): update AppService spec with `loadAndFormatTools` * fix(clearConvos): add id check earlier on * refactor(AssistantAvatar): set previewURL dynamically when emtadata.avatar changes * feat(assistants): addTitle cache setting * fix(useSSE): resolve rebase conflicts * fix: delete mutation * style(SidePanel): make grip visible on active and hover, invisible otherwise * ci: add data-provider tests to workflow, also update eslint/tsconfig to recognize specs, and add `text/csv` to fileConfig * fix: handle edge case where auth object is undefined, and log errors * refactor(actions): resolve schemas, add tests for resolving refs, import specs from separate file for tests * chore: remove comment * fix(ActionsInput): re-render bug when initializing states with action fields * fix(patch/assistant): filter undefined tools * chore: add logging for errors in assistants routes * fix(updateAssistant): map actions to functions to avoid overwriting * fix(actions): properly handle GET paths * fix(convos): unhandled delete thread exception * refactor(AssistantService): pass both thread_id and conversationId when sending intermediate assistant messages, remove `mapMessagesToSteps` from AssistantService * refactor(useSSE): replace all messages with runMessages and pass latestMessageId to abortRun; fix(checkMessageGaps): include tool calls when syncing messages * refactor(assistants/chat): invoke `createOnTextProgress` after thread creation * chore: add typing * style: sidepanel styling * style: action tool call domain styling * feat(assistants): default models, limit retrieval to certain models, add env variables to to env.example * feat: assistants api key in EndpointService * refactor: set assistant model to conversation on assistant switch * refactor: set assistant model to conversation on assistant select from panel * fix(retrieveAndProcessFile): catch attempt to download file with `assistant` purpose which is not allowed; add logging * feat: retrieval styling, handling, and logging * chore: rename ASSISTANTS_REVERSE_PROXY to ASSISTANTS_BASE_URL * feat: FileContext for file metadata * feat: context file mgmt and filtering * style(Select): hover/rounded changes * refactor: explicit conversation switch, endpoint dependent, through `useSelectAssistant`, which does not create new chat if current endpoint is assistant endpoint * fix(AssistantAvatar): make empty previewURL if no avatar present * refactor: side panel mobile styling * style: merge tool and action section, optimize mobile styling for action/tool buttons * fix: localStorage issues * fix(useSelectAssistant): invoke react query hook directly in select hook as Map was not being updated in time * style: light mode fixes * fix: prevent sidepanel nav styling from shifting layout up * refactor: change default layout (collapsed by default) * style: mobile optimization of DataTable * style: datatable * feat: client-side hide right-side panel * chore(useNewConvo): add partial typing for preset * fix(useSelectAssistant): pass correct model name by using template as preset * WIP: assistant presets * refactor(ToolService): add native solution for `TavilySearchResults` and log tool output errors * refactor: organize imports and use native TavilySearchResults * fix(TavilySearchResults): stringify result * fix(ToolCall): show tool call outputs when not an action * chore: rename Prompt Prefix to custom instructions (in user facing text only) * refactor(EditPresetDialog): Optimize setting title by debouncing, reset preset on dialog close to avoid state mixture * feat: add `presetOverride` to overwrite active conversation settings when saving a Preset (relevant for client side updates only) * feat: Assistant preset settings (client-side) * fix(Switcher): only set assistant_id and model if current endpoint is Assistants * feat: use `useDebouncedInput` for updating conversation settings, starting with EditPresetDialog title setting and Assistant instructions setting * feat(Assistants): add instructions field to settings * feat(chat/assistants): pass conversation settings to run body * wip: begin localization and only allow actions if the assistant is created * refactor(AssistantsPanel): knowledge localization, allow tools on creation * feat: experimental: allow 'priming' values before assistant is created, that would normally require an assistant_id to be defined * chore: trim console logs and make more meaningful * chore: toast messages * fix(ci): date test * feat: create file when uploading Assistant Avatar * feat: file upload rate limiting from custom config with dynamic file route initialization * refactor: use file upload limiters on post routes only * refactor(fileConfig): add endpoints field for endpoint specific fileconfigs, add mergeConfig function, add tests * refactor: fileConfig route, dynamic multer instances used on all '/' and '/images' POST routes, data service and query hook * feat: supportedMimeTypesSchema, test for array of regex * feat: configurable file config limits * chore: clarify assistants file knowledge prereq. * chore(useTextarea): default to localized 'Assistant' if assistant name is empty * feat: configurable file limits and toggle file upload per endpoint * fix(useUploadFileMutation): prevent updating assistant.files cache if file upload is a message_file attachment * fix(AssistantSelect): set last selected assistant only when timeout successfully runs * refactor(queries): disable assistant queries if assistants endpoint is not enabled * chore(Switcher): add localization * chore: pluralize `assistant` for `EModelEndpoint key and value * feat: show/hide assistant UI components based on endpoint availability; librechat.yaml config for disabling builder section and setting polling/timeout intervals * fix(compactEndpointSchemas): use EModelEndpoint for schema access * feat(runAssistant): use configured values from `librechat.yaml` for `pollIntervalMs` and `timeout` * fix: naming issue * wip: revert landing * 🎉 happy birthday LibreChat (#1768) * happy birthday LibreChat * Refactor endpoint condition in Landing component * Update birthday message in Eng.tsx * fix(/config): avoid nesting ternaries * refactor(/config): check birthday --------- Co-authored-by: Danny Avila <messagedaniel@protonmail.com> * fix: landing * fix: landing * fix(useMessageHelpers): hardcoded check to use EModelEndpoint instead * fix(ci): convo test revert to main * fix(assistants/chat): fix issue where assistant_id was being saved as model for convo * chore: added logging, promises racing to prevent longer timeouts, explicit setting of maxRetries and timeouts, robust catching of invalid abortRun params * refactor: use recoil state for `showStopButton` and only show for assistants endpoint after syncing conversation data * refactor: optimize abortRun strategy using localStorage, refactor `abortConversation` to use async/await and await the result, refactor how the abortKey cache is set for runs * fix(checkMessageGaps): assign `assistant_id` to synced messages if defined; prevents UI from showing blank assistant for cancelled messages * refactor: re-order sequence of chat route, only allow aborting messages after run is created, cancel abortRun if there was a cancelling error (likely due already cancelled in chat route), and add extra logging * chore(typedefs): add httpAgent type to OpenAIClient * refactor: use custom implementation of retrieving run with axios to allow for timing out run query * fix(waitForRun): handle timed out run retrieval query * refactor: update preset conditions: - presets will retain settings when a different endpoint is selected; for existing convos, either when modular or is assistant switch - no longer use `navigateToConvo` on preset select * fix: temporary calculator hack as expects string input when invoked * fix: cancel abortRun only when cancelling error is a result of the run already being cancelled * chore: remove use of `fileMaxSizeMB` and total counterpart (redundant) * docs: custom config documentation update * docs: assistants api setup and dotenv, new custom config fields * refactor(Switcher): make Assistant switcher sticky in SidePanel * chore(useSSE): remove console log of data and message index * refactor(AssistantPanel): button styling and add secondary select button to bottom of panel * refactor(OpenAIClient): allow passing conversationId to RunManager through titleConvo and initializeLLM to properly record title context tokens used in cases where conversationId was not defined by the client * feat(assistants): token tracking for assistant runs * chore(spendTokens): improve logging * feat: support/exclude specific assistant Ids * chore: add update `librechat.example.yaml`, optimize `AppService` handling, new tests for `AppService`, optimize missing/outdate config logging * chore: mount docker logs to root of project * chore: condense axios errors * chore: bump vite * chore: vite hot reload fix using latest version * chore(getOpenAIModels): sort instruct models to the end of models list * fix(assistants): user provided key * fix(assistants): user provided key, invalidate more queries on revoke --------- Co-authored-by: Marco Beretta <81851188+Berry-13@users.noreply.github.com>
2024-02-13 20:42:27 -05:00
} catch (error) {
🗝️ feat: User Provided Credentials for MCP Servers (#7980) * 🗝️ feat: Per-User Credentials for MCP Servers chore: add aider to gitignore feat: fill custom variables to MCP server feat: replace placeholders with custom user MCP variables feat: handle MCP install/uninstall (uses pluginauths) feat: add MCP custom variables dialog to MCPSelect feat: add MCP custom variables dialog to the side panel feat: do not require to fill MCP credentials for in tools dialog feat: add translations keys (en+cs) for custom MCP variables fix: handle LIBRECHAT_USER_ID correctly during MCP var replacement style: remove unused MCP translation keys style: fix eslint for MCP custom vars chore: move aider gitignore to AI section * feat: Add Plugin Authentication Methods to data-schemas * refactor: Replace PluginAuth model methods with new utility functions for improved code organization and maintainability * refactor: Move IPluginAuth interface to types directory for better organization and update pluginAuth schema to use the new import * refactor: Remove unused getUsersPluginsAuthValuesMap function and streamline PluginService.js; add new getPluginAuthMap function for improved plugin authentication handling * chore: fix typing for optional tools property with GenericTool[] type * chore: update librechat-data-provider version to 0.7.88 * refactor: optimize getUserMCPAuthMap function by reducing variable usage and improving server key collection logic * refactor: streamline MCP tool creation by removing customUserVars parameter and enhancing user-specific authentication handling to avoid closure encapsulation * refactor: extract processSingleValue function to streamline MCP environment variable processing and enhance readability * refactor: enhance MCP tool processing logic by simplifying conditions and improving authentication handling for custom user variables * ci: fix action tests * chore: fix imports, remove comments * chore: remove non-english translations * fix: remove newline at end of translation.json file --------- Co-authored-by: Aleš Kůtek <kutekales@gmail.com>
2025-06-19 18:27:55 -04:00
logger.error('[getAvailableTools]', error);
✨ feat: Assistants API, General File Support, Side Panel, File Explorer (#1696) * feat: assistant name/icon in Landing & Header * feat: assistname in textarea placeholder, and use `Assistant` as default name * feat: display non-image files in user messages * fix: only render files if files.length is > 0 * refactor(config -> file-config): move file related configuration values to separate module, add excel types * chore: spreadsheet file rendering * fix(Landing): dark mode style for Assistant Name * refactor: move progress incrementing to own hook, start smaller, cap near limit \(1\) * refactor(useContentHandler): add empty Text part if last part was completed tool or image * chore: add accordion trigger border styling for dark mode * feat: Assistant Builder model selection * chore: use Spinner when Assistant is mutating * fix(get/assistants): return correct response object `AssistantListResponse` * refactor(Spinner): pass size as prop * refactor: make assistant crud mutations optimistic, add types for options * chore: remove assistants route and view * chore: move assistant builder components to separate directory * feat(ContextButton): delete Assistant via context button/dialog, add localization * refactor: conditionally show use and context menu buttons, add localization for create assistant * feat: save side panel states to localStorage * style(SidePanel): improve avatar menu and assistant select styling for dark mode * refactor: make NavToggle reusable for either side (left or right), add SidePanel Toggle with ability to close it completely * fix: resize handle and navToggle behavior * fix(/avatar/:assistant_id): await `deleteFile` and assign unique name to uploaded image * WIP: file UI components from PR #576 * refactor(OpenAIMinimalIcon): pass className * feat: formatDate helper fn * feat: DataTableColumnHeader * feat: add row selection, formatted row values, number of rows selected * WIP: add files to Side panel temporarily * feat: `LB_QueueAsyncCall`: Leaky Bucket queue for external APIs, use in `processDeleteRequest` * fix(TFile): correct `source` type with `FileSources` * fix(useFileHandling): use `continue` instead of return when iterating multiple files, add file type to extendedFile * chore: add generic setter type * refactor(processDeleteRequest): settle promises to prevent rejections from processing deletions, log errors * feat: `useFileDeletion` to reuse file deletion logic * refactor(useFileDeletion): make `setFiles` an optional param and use object as param * feat: useDeleteFilesFromTable * feat: use real `files` data and add deletion action to data table * fix(Table): make headers sticky * feat: add dynamic filtering for columns; only show to user Host or OpenAI storage type * style(DropdownMenu): replace `slate` with `gray` * style(DataTable): apply dark mode themes and other misc styling * style(Columns): add color to OpenAI Storage option * refactor(FileContainer): make file preview reusable * refactor(Images): make image preview reusable * refactor(FilePreview): make file prop optional for FileIcon and FilePreview, fix relative style * feat(Columns): add file/image previews, set a minimum size to show for file size in bytes * WIP: File Panel with real files and formatted * feat: open files dialog from panel * style: file data table mobile and general column styling fixes * refactor(api/files): return files sorted by the most recently updated * refactor: provide fileMap through context to prevent re-selecting files to map in different areas; remove unused imports commented out in PanelColumns * refactor(ExtendFile): make File type optional, add `attached` to prevent attached files from being deleted on remove, make Message.files a partial TFile type * feat: attach files through file panel * refactor(useFileHandling): move files to the start of cache list when uploaded * refactor(useDeleteFilesMutation): delete files from cache when successfully deleted from server * fix(FileRow): handle possible edge case of duplication due to attaching recently uploaded file * style(SidePanel): make resize grip border transparent, remove unnecessary styling on close sidepanel button * feat: action utilities and tests * refactor(actions): add `ValidationResult` type and change wording for no server URL found * refactor(actions): check for empty server URL * fix(data-provider): revert tsconfig to fix type issue resolution * feat(client): first pass of actions input for assistants * refactor(FunctionSignature): change method to output object instead of string * refactor(models/Assistant): add actions field to schema, use searchParams object for methods, and add `getAssistant` * feat: post actions input first pass - create new Action document - add actions to Assistant DB document - create /action/:assistant_id POST route - pass more props down from PanelSwitcher, derive assistant_id from switcher - move privacy policy to ActionInput - reset data on input change/validation - add `useUpdateAction` - conform FunctionSignature type to FunctionTool - add action, assistant doc, update hook related types * refactor: optimize assistant/actions relationship - past domain in metadata as hostname and not a URL - include domain in tool name - add `getActions` for actions retrieval by user - add `getAssistants` for assistant docs retrieval by user - add `assistant_id` to Action schema - move actions to own module as a subroute to `api/assistants` - add `useGetActionsQuery` and `useGetAssistantDocsQuery` hooks - fix Action type def * feat: show assistant actions in assistant builder * feat: switch to actions on action click, editing action styling * fix: add Assistant state for builder panel to allow immediate selection of newly created assistants as well as retaining the current assistant when switching to a different panel within the builder * refactor(SidePanel/NavToggle): offset less from right when SidePanel is completely collapsed * chore: rename `processActions` -> `processRequiredActions` * chore: rename Assistant API Action to RequiredAction * refactor(actions): avoid nesting actual API params under generic `requestBody` to optimize LLM token usage * fix(handleTools): avoid calling `validTool` if not defined, add optional param to skip the loading of specs, which throws an error in the context of assistants * WIP: working first pass of toolCalls generated from openapi specs * WIP: first pass ToolCall styling * feat: programmatic iv encryption/decryption helpers * fix: correct ActionAuth types/enums, and define type for AuthForm * feat: encryption/decryption helpers for Action AuthMetadata * refactor(getActions): remove sensitive fields from query response * refactor(POST/actions): encrypt and remove sensitive fields from mutation response * fix(ActionService): change ESM import to CJS * feat: frontend auth handling for actions + optimistic update on action update/creation * refactor(actions): use the correct variables and types for setAuth method * refactor: POST /:assistant_id action can now handle updating an existing action, add `saved_auth_fields` to determine when user explicitly saves new auth creds. only send auth metadata if user explicitly saved fields * refactor(createActionTool): catch errors and send back meaningful error message, add flag to `getActions` to determine whether to retrieve sensitive values or not * refactor(ToolService): add `action` property to ToolCall PartMetadata to determine if the tool call was an action, fix parsing function name issue with actionDelimiter * fix(ActionRequest): use URL class to correctly join endpoint parts for `execute` call * feat: delete assistant actions * refactor: conditionally show Available actions * refactor: show `retrieval` and `code_interpreter` as Capabilities, swap `Switch` for `Checkbox` * chore: remove shadow-stroke from messages * WIP: first pass of Assistants Knowledge attachments * refactor: remove AssistantsProvider in favor of FormProvider, fix selectedAssistant re-render bug, map Assistant file_ids to files via fileMap, initialize Knowledge component with mapped files if any exist * fix: prevent deleting files on assistant file upload * chore: remove console.log * refactor(useUploadFileMutation): update files and assistants cache on upload * chore: disable oauth option as not supported yet * feat: cancel assistant runs * refactor: initialize OpenAI client with helper function, resolve all related circular dependencies * fix(DALL-E): initialization * fix(process): openai client initialization * fix: select an existing Assistant when the active one is deleted * chore: allow attaching files for assistant endpoint, send back relevant OpenAI error message when uploading, deconstruct openAI initialization correctly, add `message_file` to formData when a file is attached to the message but not the assistant * fix: add assistant_id on newConvo * fix(initializeClient): import fix * chore: swap setAssistant for setOption in useEffect * fix(DALL-E): add processFileURL to loadTools call * chore: add customConfig to debug logs * feat: delete threads on convo delete * chore: replace Assistants icon * chore: remove console.dir() in `abortRun` * feat(AssistantService): accumulate text values from run in openai.responseText * feat: titling for assistants endpoint * chore: move panel file components to appropriate directory, add file checks for attaching files, change icon for Attach Files * refactor: add localizations to tools, plugins, add condition for adding/remove user plugins so tool selections don't affect this value * chore: disable `import from url` action for now * chore: remove textMimeTypes from default fileConfig for now * fix: catch tool errors and send as outputs with error messages * fix: React warning about button as descendant of button * style: retrieval and cancelled icon * WIP: pass isSubmitting to Parts, use InProgressCall to display cancelled tool calls correctly, show domain/function name * fix(meilisearch): fix `postSaveHook` issue where indexing expects a mongo document, and join all text content parts for meili indexing * ci: fix dall-e tests * ci: fix client tests * fix: button types in actions panel * fix: plugin auth form persisting across tool selections * fix(ci): update AppService spec with `loadAndFormatTools` * fix(clearConvos): add id check earlier on * refactor(AssistantAvatar): set previewURL dynamically when emtadata.avatar changes * feat(assistants): addTitle cache setting * fix(useSSE): resolve rebase conflicts * fix: delete mutation * style(SidePanel): make grip visible on active and hover, invisible otherwise * ci: add data-provider tests to workflow, also update eslint/tsconfig to recognize specs, and add `text/csv` to fileConfig * fix: handle edge case where auth object is undefined, and log errors * refactor(actions): resolve schemas, add tests for resolving refs, import specs from separate file for tests * chore: remove comment * fix(ActionsInput): re-render bug when initializing states with action fields * fix(patch/assistant): filter undefined tools * chore: add logging for errors in assistants routes * fix(updateAssistant): map actions to functions to avoid overwriting * fix(actions): properly handle GET paths * fix(convos): unhandled delete thread exception * refactor(AssistantService): pass both thread_id and conversationId when sending intermediate assistant messages, remove `mapMessagesToSteps` from AssistantService * refactor(useSSE): replace all messages with runMessages and pass latestMessageId to abortRun; fix(checkMessageGaps): include tool calls when syncing messages * refactor(assistants/chat): invoke `createOnTextProgress` after thread creation * chore: add typing * style: sidepanel styling * style: action tool call domain styling * feat(assistants): default models, limit retrieval to certain models, add env variables to to env.example * feat: assistants api key in EndpointService * refactor: set assistant model to conversation on assistant switch * refactor: set assistant model to conversation on assistant select from panel * fix(retrieveAndProcessFile): catch attempt to download file with `assistant` purpose which is not allowed; add logging * feat: retrieval styling, handling, and logging * chore: rename ASSISTANTS_REVERSE_PROXY to ASSISTANTS_BASE_URL * feat: FileContext for file metadata * feat: context file mgmt and filtering * style(Select): hover/rounded changes * refactor: explicit conversation switch, endpoint dependent, through `useSelectAssistant`, which does not create new chat if current endpoint is assistant endpoint * fix(AssistantAvatar): make empty previewURL if no avatar present * refactor: side panel mobile styling * style: merge tool and action section, optimize mobile styling for action/tool buttons * fix: localStorage issues * fix(useSelectAssistant): invoke react query hook directly in select hook as Map was not being updated in time * style: light mode fixes * fix: prevent sidepanel nav styling from shifting layout up * refactor: change default layout (collapsed by default) * style: mobile optimization of DataTable * style: datatable * feat: client-side hide right-side panel * chore(useNewConvo): add partial typing for preset * fix(useSelectAssistant): pass correct model name by using template as preset * WIP: assistant presets * refactor(ToolService): add native solution for `TavilySearchResults` and log tool output errors * refactor: organize imports and use native TavilySearchResults * fix(TavilySearchResults): stringify result * fix(ToolCall): show tool call outputs when not an action * chore: rename Prompt Prefix to custom instructions (in user facing text only) * refactor(EditPresetDialog): Optimize setting title by debouncing, reset preset on dialog close to avoid state mixture * feat: add `presetOverride` to overwrite active conversation settings when saving a Preset (relevant for client side updates only) * feat: Assistant preset settings (client-side) * fix(Switcher): only set assistant_id and model if current endpoint is Assistants * feat: use `useDebouncedInput` for updating conversation settings, starting with EditPresetDialog title setting and Assistant instructions setting * feat(Assistants): add instructions field to settings * feat(chat/assistants): pass conversation settings to run body * wip: begin localization and only allow actions if the assistant is created * refactor(AssistantsPanel): knowledge localization, allow tools on creation * feat: experimental: allow 'priming' values before assistant is created, that would normally require an assistant_id to be defined * chore: trim console logs and make more meaningful * chore: toast messages * fix(ci): date test * feat: create file when uploading Assistant Avatar * feat: file upload rate limiting from custom config with dynamic file route initialization * refactor: use file upload limiters on post routes only * refactor(fileConfig): add endpoints field for endpoint specific fileconfigs, add mergeConfig function, add tests * refactor: fileConfig route, dynamic multer instances used on all '/' and '/images' POST routes, data service and query hook * feat: supportedMimeTypesSchema, test for array of regex * feat: configurable file config limits * chore: clarify assistants file knowledge prereq. * chore(useTextarea): default to localized 'Assistant' if assistant name is empty * feat: configurable file limits and toggle file upload per endpoint * fix(useUploadFileMutation): prevent updating assistant.files cache if file upload is a message_file attachment * fix(AssistantSelect): set last selected assistant only when timeout successfully runs * refactor(queries): disable assistant queries if assistants endpoint is not enabled * chore(Switcher): add localization * chore: pluralize `assistant` for `EModelEndpoint key and value * feat: show/hide assistant UI components based on endpoint availability; librechat.yaml config for disabling builder section and setting polling/timeout intervals * fix(compactEndpointSchemas): use EModelEndpoint for schema access * feat(runAssistant): use configured values from `librechat.yaml` for `pollIntervalMs` and `timeout` * fix: naming issue * wip: revert landing * 🎉 happy birthday LibreChat (#1768) * happy birthday LibreChat * Refactor endpoint condition in Landing component * Update birthday message in Eng.tsx * fix(/config): avoid nesting ternaries * refactor(/config): check birthday --------- Co-authored-by: Danny Avila <messagedaniel@protonmail.com> * fix: landing * fix: landing * fix(useMessageHelpers): hardcoded check to use EModelEndpoint instead * fix(ci): convo test revert to main * fix(assistants/chat): fix issue where assistant_id was being saved as model for convo * chore: added logging, promises racing to prevent longer timeouts, explicit setting of maxRetries and timeouts, robust catching of invalid abortRun params * refactor: use recoil state for `showStopButton` and only show for assistants endpoint after syncing conversation data * refactor: optimize abortRun strategy using localStorage, refactor `abortConversation` to use async/await and await the result, refactor how the abortKey cache is set for runs * fix(checkMessageGaps): assign `assistant_id` to synced messages if defined; prevents UI from showing blank assistant for cancelled messages * refactor: re-order sequence of chat route, only allow aborting messages after run is created, cancel abortRun if there was a cancelling error (likely due already cancelled in chat route), and add extra logging * chore(typedefs): add httpAgent type to OpenAIClient * refactor: use custom implementation of retrieving run with axios to allow for timing out run query * fix(waitForRun): handle timed out run retrieval query * refactor: update preset conditions: - presets will retain settings when a different endpoint is selected; for existing convos, either when modular or is assistant switch - no longer use `navigateToConvo` on preset select * fix: temporary calculator hack as expects string input when invoked * fix: cancel abortRun only when cancelling error is a result of the run already being cancelled * chore: remove use of `fileMaxSizeMB` and total counterpart (redundant) * docs: custom config documentation update * docs: assistants api setup and dotenv, new custom config fields * refactor(Switcher): make Assistant switcher sticky in SidePanel * chore(useSSE): remove console log of data and message index * refactor(AssistantPanel): button styling and add secondary select button to bottom of panel * refactor(OpenAIClient): allow passing conversationId to RunManager through titleConvo and initializeLLM to properly record title context tokens used in cases where conversationId was not defined by the client * feat(assistants): token tracking for assistant runs * chore(spendTokens): improve logging * feat: support/exclude specific assistant Ids * chore: add update `librechat.example.yaml`, optimize `AppService` handling, new tests for `AppService`, optimize missing/outdate config logging * chore: mount docker logs to root of project * chore: condense axios errors * chore: bump vite * chore: vite hot reload fix using latest version * chore(getOpenAIModels): sort instruct models to the end of models list * fix(assistants): user provided key * fix(assistants): user provided key, invalidate more queries on revoke --------- Co-authored-by: Marco Beretta <81851188+Berry-13@users.noreply.github.com>
2024-02-13 20:42:27 -05:00
res.status(500).json({ message: error.message });
}
};
feat: Plugins endpoint - Reverse Engineering of official Plugins features (#197) * components for plugins in progress * WIP: add langchain client implementation for tools/plugins feat(langchain): add loadHistory function for loading chat history from database feat(langchain): add saveMessageToDatabase function for saving chat messages to database * chore(Memory.js): remove Memory.js file from the project directory. * WIP: adding plugin functionality —————————————————— fix(eslintrc.js): change arrow-parens rule to always require parentheses refactor(agent.js): reorganize imports and add new imports feat(agent.js): add support for saving and loading chat history feat(agent.js): add support for saving messages to database feat(agent.js): add ChatAgent class with initialize and sendMessage methods fix(langchain): use getConvo and saveMessage functions from models.js instead of Conversation and Message models feat(langchain): add user parameter to loadHistory and saveMessageToDatabase functions chore(package.json): update langchain package version to 0.0.59 and add langchain script to run test2.js file —————————————————— * WIP: testing agent initialization * WIP: testing various agent methods feat(agent.js): add CustomChatAgent class and initializeAgentExecutorWithOptions method feat(customChatAgent.js): add CustomPromptTemplate and CustomOutputParser classes refactor(langchain): uncomment code for input2 and options feat(langchain): add input1 to read comments on a youtube video docs(langchain): remove commented code and add whitespace to package.json * WIP: feat: plugin endpoint, backend class working * feat(agent.js): add support for Zapier NLA API key feat(agent.js): add ZapierToolKit to tools if zapierApiKey is provided feat(customAgent.js): change prompt prefix and suffix to reflect new task-based prompt feat(test4.js): add test for new task-based prompt * style(langchain): improve readability and add comments to code feat(langchain): update prompt message for custom agent fix(langchain): update message format in test4.js * style(customAgent.js): remove unnecessary capitalization and rephrase some sentences test(langchain): add test2 and test3 scripts to package.json * chore(customAgent.js): fix typo in comment, change "an" to "identical" * WIP: gpt-4 testing * feat(langchain): add AIPluginTool and HumanTool classes fix(langchain): remove zapierApiKey option from ChatAgent constructor refactor(langchain): update langchain package to v0.0.64 misc(langchain): update test2, test3, and test4 scripts to use --inspect flag * feat(langchain): add GoogleSearchAPI tool for searching the web using Google Custom Search API * feat(askGPTPlugins.js): add support for progress callback in ask function fix(agent.js): pass progress callback to sendApiMessage function * refactor(agent.js): load tools from options and initialize them in constructor feat(agent.js): add support for environment variable SERPAPI_API_KEY feat(agent.js): add support for environment variable ZAPIER_NLA_API_KEY docs(agent.js): remove commented out code and add comments to clarify code * chore(langchain): remove unused files loadHistory.js and saveMessage.js * feat(validateTools.js): add function to validate API keys for supported tools * feat(langchain): update langchain package to version 0.0.66 feat(langchain): add support for GPT-4 model fix(server/index.js): fix uncaughtException handler to ignore 'fetch failed' errors * refactor(agent.js): remove FORMAT_INSTRUCTIONS and replace with a more concise message refactor(agent.js): remove unused variable 'errorMessage' refactor(agent.js): change 'result' variable initialization to an empty object instead of null refactor(agent.js): change error message when response generation fails refactor(agent.js): change output message when response generation fails refactor(agent.js): change output message when response generation succeeds * chore(langchain): comment out unused model in ChatAgent constructor feat(langchain): add test5 script to package.json for running test5.js script * refactor(agent.js): change response to answer and update message refactor(test3.js, test5.js): remove commented out code and add comments The changes in agent.js are to improve the message that is returned to the user. The word "response" has been changed to "answer" to better reflect the output of the chatbot. The message has also been updated to provide clearer instructions to the user. The changes in test3.js and test5.js are to remove commented out code and add comments to improve readability. * docs: update links to LOCAL_INSTALL.md and defaultSystemMessage.md fix: fix typo in BingAI/Settings.jsx feat: add Dockerfile for app containerization docs(google_search.md): add guide for setting up Google Custom Search API key and ID * docs: update link to system message guidelines in Bing AI Settings component docs: update link to system message guidelines in GOOGLE_SEARCH.md feat: add JAILBREAK_INFO.md guide for Bing AI jailbreak mode system message guidelines * style(api): remove unnecessary quotes and empty values from .env.example style(agent.js): refactor getActions method to accept an input parameter feat(agent.js): add handleChainEnd method to CustomChatAgent class style(customAgent.js): add a new line to the end of the file style(test5.js): comment out unused variable and update input1 variable style(googleSearch.js): change tool name to kebab-case * chore(langchain): comment out handleChainEnd method in agent.js feat(langchain): add browser tool to ChatAgent in test2.js feat(langchain): add modelOptions to ChatAgent in test2.js feat(langchain): change question in input1 and request article review summary in test5.js * fix(askGPTPlugins.js): fix syntax error by removing extra comma in parentMessageId field feat(askGPTPlugins.js): add default value of null to parentMessageId parameter in ask function * fix(askGPTPlugins.js): change endpoint string from 'GPTPlugins' to 'gptPlugins' feat(endpoints.js): add support for gptPlugins endpoint feat(PresetItem.jsx): add support for gptPlugins endpoint feat(HoverButtons.jsx): add support for gptPlugins endpoint feat(createPayload.ts): add support for gptPlugins endpoint feat(types.ts): add gptPlugins endpoint to EModelEndpoint enum feat(endpoints.js): add gptPlugins endpoint to availableEndpoints selector feat(cleanupPreset.js): add support for gptPlugins endpoint feat(getDefaultConversation.js): add support for gptPlugins endpoint feat(getIcon.jsx): add support for gptPlugins endpoint feat(handleSubmit.js): add support for gptPlugins endpoint * refactor(agent.js): remove debug option from options object refactor(agent.js): change tool name from 'google-search' to 'google' refactor(agent.js): update description for 'google' tool feat(agent.js): add support for citing sources when using web links in response message fix(agent.js): update error message to not mention error to user feat(agent.js): add unique message ids for user message and response message feat(agent.js): limit number of search results to 5 in 'google' tool refactor(validateTools.js): add console log to show valid tools * feat(askGPTPlugins.js): add support for GPT-3.5-turbo model and validate model option refactor(askGPTPlugins.js): remove unused imports and variables refactor(askGPTPlugins.js): remove commented code refactor(askGPTPlugins.js): remove unused parameters in ask function feat(ask/index.js): add askGPTPlugins route to router * feat(NewConversationMenu): add alpha tag to gptPlugins endpoint and rename it to Plugins * refactor(askGPTPlugins.js): remove commented code and unused imports feat(askGPTPlugins.js): add support for debug option in endpointOption feat(askGPTPlugins.js): add support for chatGptLabel, promptPrefix, temperature, top_p, presence_penalty, and frequency_penalty in endpointOption feat(askGPTPlugins.js): add support for sending plugin and pluginend events feat(askGPTPlugins.js): add onAgentAction and onChainEnd callbacks to ChatAgent.sendMessage refactor(titleConvo.js): comment out unused imports refactor(validateTools.js): comment out console.log statement refactor(agent.js): change saveMessage to include unfinished property feat(agent.js): add endpoint property to saveConvo call in saveMessageToDatabase feat(askGPTPlugins.js): add validateTools import and use it to validate endpointOption.tools before passing to ChatAgent constructor feat(askGPTPlugins.js * refactor(MessageHeader.jsx): extract plugins section into a separate variable and add support for gptPlugins endpoint fix(MessageHeader.jsx): disable clicking on non-clickable endpoints * components for plugins in progress * feat(Plugin.jsx): add plugin prop to Plugin component and display plugin name feat(Plugin.jsx): add loading state and display loading spinner feat(Plugin.jsx): add Disclosure component to Plugin component feat(Plugin.jsx): add Disclosure.Panel to Plugin component to display team pricing information feat(Spinner.jsx): add classProp prop to Spinner component to allow for custom styling feat(Landing.jsx): add Plugin component to Landing page for testing testing gpt plugins feat(plugins): Milestone commit - Add formatAction function to format plugin actions. - Add prefix.js file to store the prefix message for ChatAgent. - Update ask function to include plugin object to store plugin data. - Update onAgentAction and onChainEnd functions to format plugin data and send intermediate messages. - Update response object to include plugin data. The `handlers.js` file now includes a `formatAction` function that formats the action object for display in the UI. The `createOnProgress` function now returns a `sendIntermediateMessage` function that sends intermediate messages to the client. feat (client): add support for plugins in messages This commit adds support for plugins in messages. It includes changes to the `handlers.js`, `index.jsx`, `CodeBlock.jsx`, `Message.jsx`, `MessageHeader.jsx`, and `Plugin.jsx` files. The `index.jsx` file now includes a `plugin` property in the `messageHandler` function. The `CodeBlock.jsx` file now includes a `plugin` property that determines the language of the code block. The `Message.jsx` file now includes a `Plugin` component that displays the plugin used in the message. The `MessageHeader.jsx` file now includes a `Plugins` component that displays the enabled plugins. feat(langchain): add OpenAICreateImage tool for generating images based on user prompts fix(langchain): update validateTools to include create-image tool fix(langchain): save plugin data to messageSchema fix(server/routes/askGPTPlugins.js): save userMessage and response to messageSchema feat(langchain): add SelfReflectionTool Add a new tool to the LangChain agent, SelfReflectionTool, which enhances the agent's self-awareness by reflecting on its thoughts before taking action. The tool provides a space for the agent to explore and organize its ideas in response to the user's message. Also, update the prefix message to reflect the changes in the agent's behavior and the way it should engage with the user. The prefix message now emphasizes the use of tools when necessary, and relying on the agent's knowledge for creative requests. It also provides clear instructions on how to use the 'Action' input and how to carry out tasks in the sequence written by the human. Finally, update the OpenAICreateImage tool to return the image URL in markdown format. The tool replaces newlines and spaces in the input text with hyphens to create a valid markdown link. Milestone commit: better error handling with custom output parser, dir and file re-org style(langchain): fix formatting and add comments to prefix.js fix(langchain): remove commented out code in test6.js feat(langchain): reduce maxAttempts from 3 to 2 in CustomChatAgent's buildPromptPrefix method feat(langchain): add null check for result.output in CustomChatAgent's buildPromptPrefix method style(langchain): improve consistency and readability of code This commit improves the consistency and readability of the code in the langchain directory. Specifically, it: - Changes the case of the "Thought" output in the CustomChatAgent class to match the "Thought" output in the SelfReflectionTool class. - Adds a currentDateString property to the CustomChatAgent class to avoid repeating the same code in multiple places. - Updates the prefix in the prefix.js file to match the current objectives of the ChatGPT model. - Changes the description of the OpenAICreateImage tool to request a description of the image to be generated. - Updates the tools used by the ChatAgent in the askGPTPlugins.js file to include the Google and Browser tools instead of the Calculator and Create-Image tools. feat: add wolfram, improve image creation, rename to dall-e * refactor(langchain): update language and formatting in various files - Update tool-based instructions to use proper Markdown syntax for image URLs - Adjust temperature for modelOptions in CustomChatAgent class - Comment out console.debug statement in CustomChatAgent class - Update prefix in initializeCustomAgent function to use proper line breaks - Update prefix in instructions.js to use proper line breaks and change "user" to "human" - Update input in test6.js to use Ezra Pound instead of Hemingway - Update return statement in OpenAICreateImage class to use "generated-image" as alt-text - Update description in SelfReflectionTool class to provide clearer instructions - Update tools in ask function in askGPTPlugins.js to use only the DALL-E tool and enable debug mode feat(ask): add support for DALL-E tool in formatAction function feat(ask): add support for self-reflection tool in formatAction function feat(Plugin.jsx): add support for self-reflection tool in Plugin component fix(Plugin.jsx): fix Plugin component to not display 'None' when latest is not available * docs(openaiCreateImage.js): update tool description to clarify usage * feat(agent.js): add message parameter to initialize function feat(agent.js): pass message parameter to SelfReflectionTool constructor feat(customAgent.js): add longestToolName variable to CustomOutputParser feat(openaiCreateImage.js): replace new lines with spaces in prompt parameter feat(selfReflection.js): add message parameter to SelfReflectionTool constructor feat(selfReflection.js): add placeholder response to selfReflect function * feat: frontend plugin selection * fix: agent updates, available tools via endpoint config * fix: improve frontend plugin selection * feat: further customize agent and bypass executor when no tools are provided * fix: key issue in multiselect and allow setting changes during convo in plugins endpoint * fix: convo will save modelOptions, fix persistent errors with agent * fix: add looser final answer parsing and edit action formatting * fix: handle edge case where stop token is not hit and causes long parsing error * feat: trying new prompt for image creation * fix: improvements based on gpt-3.5 * feat: allow setting model options throughout plugin conversation * fix: agent adjustments * improve final reply for gpt-4, gpt-3.5 needs a more stable approach * fix: better context output for gpt-3.5 * fix: added clarification for better context output for gpt-3.5 * feat(PluginsOptions): add advanced mode to show/hide options style(PluginsOptions): add styles for advanced mode and show/hide options * minor changes to styling * refactor(langchain): add support for custom GPT-4 agent This commit adds support for a custom GPT-4 agent in the langchain module. The `CustomGpt4Agent` class extends the `ZeroShotAgent` class and includes a new `createPrompt` method that generates a prompt template for the agent. The `initializeCustomAgent` function has been updated to use the `CustomGpt4Agent` class when the model is not GPT-3. The `instructions.js` file has also been updated to include new instructions for the GPT-4 agent. The `formatInstructions` method has been removed and replaced with `gpt4Instructions` and `prefix2` and `suffix2` have been added to include the new instructions. feat(langchain): add custom output parser for langchain agents This commit adds a custom output parser for langchain agents. The new parser is called CustomOutputParser and it extends ZeroShotAgentOutputParser. It takes a fields object as a parameter and sets the tools and longestToolName properties. It also sets the finishToolNameRegex property to match the final answer. The parse method of the CustomOutputParser class takes a text parameter and returns an object with returnValues, log, and toolInput properties. This commit also adds a Gpt4OutputParser class that extends ZeroShotAgentOutputParser. It takes a fields object as a parameter and sets the tools and longestToolName properties. It also sets the finishToolNameRegex property to match the final answer. The parse method of the Gpt4OutputParser class takes a text parameter and returns an object with returnValues, log, and toolInput properties. feat(langchain): add isGpt3 parameter to * Stable Diffusion Plugin (#204) * Added stable diffusion plugin * Added example prompt * Fixed naming * Removed brackets in the prompt * fix: improved agent for gpt-3.5 * fix: outparser, gpt3 instructions, and wolfram error handling * chore: update langchain to 0.0.71 * fix: long parsing action input fix * fix: make plugin select close on clicking label/button * fix: make plugin select close on clicking label/button * fix: wolfram input formatting and gpt-3 payload without plugins * chore(api): update axios package version to 1.3.4 feat(api): add requireJwtAuth middleware to askGPTPlugins endpoint fix(api): replace session user with user id in askGPTPlugins endpoint docs(LOCAL_INSTALL.md): update guide for local installation and testing This commit updates the guide for local installation and testing of the ChatGPT-Clone app. It includes instructions for locally running the app, updating the app version, and running tests. It also includes a new option for running the app using Docker. The commit also fixes some typos and formatting issues. * add reverseProxy to plugins client * chore(Dockerfile-app): add Dockerfile for building and running the app in a container docs: remove outdated guides on Google search and Bing jailbreak mode docs(LOCAL_INSTALL.md): remove outdated Windows installation instructions and update MeiliSearch configuration file * fix: handle n/a parsing error better, reduce token waste if no agentic behavior is needed * style: fix formatting and add parentheses around arrow function parameter style: change hover background color to white and dark hover background color to gray-700 * chore: re-organize agent dir and files * feat(ChatAgent.js): add support for PlanAndExecuteAgentExecutor feat(PlanAndExecuteAgentExecutor.js): add PlanAndExecuteAgentExecutor class feat(planExecutor.js): add demo for PlanAndExecuteAgentExecutor * feat: add azure support to plugins * refactor(utils): add basePath endpoint for genAzureEndpoint feat(api): add support for Azure OpenAI API in various modules and tools * feat: add plugin api for fetching available tools * feat: add data service for getting available plugins * feat: first iteration plugin store UI * refactor: rename files to follow proper naming convention * feat: Plugin store UI components * feat: create separate user routes, service, controller, and add plugins to user model * feat: create data service for adding and removing plugins per user * feat: UI for adding and removing plugins, displaying plugins in dropdown based on what user has installed * fix: merge conflicts from main * fix: fix plugin items titles * fix: tool.value -> tool.pluginKey * fix: testing returnDirect for self-reflection * fix: add browser tool to manifest * refactor(outputParser.js): remove commented out code feat(outputParser.js): add support for thought input when there is no action input * handling 'use tool' edge case * merge main to langchain * fix(User.js, auth.service.js, localStrategy.js): change deprecated Joi.validate() to schema.validate() method (#322) * fix(auth.service.js): fixes deprecated error callback in mongoose save method (#323) * chore: run formatting script with new rules * refactor: add requiresAuth to manifest, fix uninstall button * version with plugin auth as dialog modal * feat: Complete frontend for plugin auth * frontend styling updates * feat: api for plugin auth * feat: Add tooltip with field description to plugin auth form * fix: issue with plugin that has no auth * feat(tools): add support for user-specific API keys This commit adds support for user-specific API keys for the following tools: - Google Search API - Web Browser - SerpAPI - Zapier - DALL-E - Wolfram Alpha API It also adds support for OpenAI API key for the Web Browser tool. The `validateTools` function now takes a `user` parameter and checks for user-specific API keys before falling back to environment variables. The `loadTools` function now takes a `user` parameter and initializes the tools with user-specific API keys if available. The `manifest.json` file has been updated to include the new `authConfig` fields for the tools that support user-specific API keys. The `askGPTPlugins.js` file has been updated to use the `validateTools` function with the `user` parameter. refactor(ChatAgent.js): add user parameter to initialize function and pass it to loadTools function refactor(tools/index.js): set default value for tools parameter in validateTools function refactor(askGPTPlugins.js): remove duplicate user variable declaration and use the one from req object * refactor(ChatAgent.js): await validTool() before pushing to this.tools array refactor(tools/index.js): use Map instead of Set to store valid tools refactor(tools/index.js): filter availableTools to only validate tools passed in refactor(PluginController.js): filter out duplicate plugins by pluginKey refactor(crypto.js): use environment variables for encryption key and initialization vector feat(PluginService.js): add null check for pluginAuth in getUserPluginAuthValue() * feat(api): add credentials key and IV to .env.example for securely storing credentials * Adds testing for handling tools, introducing a test env to the backend Fixes bugs & optimizes code as revealed through testing, including: - wolfram.js: fixes bug where wolfram was not handling authentication - ChatAgent.js: ChatAgent modified to reflect 'handleTools' changes - handleTools.js: Moves logic out of index file - handleTools.js: loadTools: returns only requested tools - handleTools.js: validTools: correctly returns tools based on authentication * test(index.test.js): add test to validate a tool from an environment variable * test(tools): add test for initializing an authenticated tool through Environment Variables * refactor(ChatAgent.js): remove commented out code and unused imports * refactor(ChatAgent.js): move instructions to a separate file and import them fix(ChatAgent.js): replace hardcoded instructions with imported ones * refactor(ChatAgent.js): change import path for TextStream refactor(stream.js): remove unused TextStream class * chore(.gitignore): add .env.test to gitignore refactor(ChatAgent.js): rename CustomChatAgent to ChatAgent test(ChatAgent.test.js): add tests for ChatAgent class refactor(outputParser.js): remove OldOutputParser class refactor(outputParser.js): rename CustomOutputParser to OutputParser docs(.env.test.example): add comment explaining how to use OPENAI_API_KEY refactor(jestSetup.js): use dotenv to load environment variables from .env.test file * Various optimizations and config, add tests for PluginStoreDialog * test(ChatAgent.test.js): add test to check if chat history is returned correctly * test: unit tests for plugin store * test: add frontend-test script to root package.json * feat(ChatAgent.js, askGPTPlugins.js): add support for aborting chat requests (in progress) * test: add more client tests * feat(ChatAgent): allow plugin requests to be cancelled * feat(ChatAgent): allow message regeneration * feat(ChatAgent): remember last selected tools * Remove plugins we don't yet have from manifest.json * fix(ChatAgent.js): increase maxAttempts from 1 to 2 fix(ChatAgent.js): change error message to 'Cancelled.' if message was aborted mid-generation fix(openaiCreateImage.js): replace unwanted characters in input string fix(handlers.js): compare action.tool in lowercase to 'self-reflection' * fix(ChatAgent): Fix up plugin I/O formatting for n/a actions * refactor(Plugin.jsx): remove unused import statement feat(Plugin.jsx): add Plugin component with svg paths and styles * refactor: simplify credential encryption/decryption by using a single key and IV for all environments. Update crypto.js and .env.example files accordingly. * fix(ChatAgent.js): reduce maxAttempts from 2 to 1 feat(ChatAgent.js): add model information to responseMessage object feat(Message.js): add model field to messageSchema feat(Message.js): add model field to message object feat(Message.jsx): pass model information to getIcon function feat(getIcon.jsx): add Plugin component and handle plugin messages differently * feat(askGPTPlugins.js): add model property to the ask function response object feat(EndpointItem.jsx): add message property to the EndpointItem component feat(MessageHeader.jsx): add Plugin icon to the plugins section feat(MessageHeader.jsx): change alpha to beta in the plugins section feat(svg): add Plugin, GPTIcon, and BingIcon components to the svg folder refactor(EndpointItems.jsx): remove unused import statement * refactor(googleSearch.js, wolfram.js): change error handling to return a message instead of throwing an error * refactor(CustomAgent): remove commented code and change return object to include returnValues property * feat(CustomAgent.js): add currentDateString to createPrompt method options deps(api/package.json): update langchain to v0.0.81 * fix: do not show pagination if the maxPage is 1 * Add Zapier back to manifest (accidentally removed) * chore(api): update langchain dependency to version 0.0.84 * feat(DALL-E.js): add DALL-E tool for generating images using OpenAI's DALL-E API refactor(handleTools.js): update import for DALL-E tool refactor(index.test.js): update import for DALL-E tool refactor(stablediffusion.js): add check for image directory existence before saving image * refactor(CustomAgent): rename instructions prefix variable to gpt3 and add gpt4 instructions feat(CustomAgent): add support for gpt-4 model fix(initializeCustomAgent.js): pass model name to createPrompt method fix(outputParser.js): set selectedTool to 'self-reflection' when tool parsing fails * style(langchain/tools): update guidelines for image creation in DALL-E and StableDiffusion - Update guidelines for image creation in DALL-E and StableDiffusion tools - Emphasize the importance of "showing" and not "telling" the imagery in crafting input - Update formatting for the example prompt for generating a realistic portrait photo of a man - Generate images only once per human query unless explicitly requested by the user * docs(tools): update tool descriptions for DALL-E and Stable Diffusion - Update the description for DALL-E tool to indicate that it is exclusively for visual content and provide guidelines for generating images with a focus on visual attributes. - Update the description for Stable Diffusion tool to indicate that it is exclusively for visual content and provide guidelines for generating images with a focus on visual attributes. * chore(api): update "@waylaidwanderer/chatgpt-api" dependency to version "^1.36.3" * refactor(ChatAgent.js): use environment variable for reverse proxy url refactor(ChatAgent.js): use environment variable for openai base path refactor(instructions.js): update gpt3 and gpt3-v2 instructions refactor(outputParser.js): update finishToolNameRegex in CustomOutputParser class * refactor(DALL-E.js): change apiKey and azureKey fields to uppercase refactor(googleSearch.js): change cx and apiKey fields to uppercase feat(manifest.json): add authConfig field for Stable Diffusion WebUI API URL refactor(stablediffusion.js): add url field to constructor and change getServerURL() to this.url refactor(wolfram.js): change apiKey field to uppercase WOLFRAM_APP_ID * refactor(handleTools.js): simplify tool loading and add support for custom tool constructors and options * refactor(handleTools.js): remove commented out code and unused imports * refactor(handleTools.js, index.js): change file name from wolfram.js to Wolfram.js and selfReflection.js to SelfReflection.js to follow PascalCase convention * refactor(outputParser.js, askGPTPlugins.js): improve code readability and remove unnecessary comments * feat(GoogleSearch.js): add GoogleSearchAPI tool to allow agents to use the Google Custom Search API feat(SelfReflection.js): add SelfReflectionTool to allow agents to reflect on their thoughts and actions feat(StableDiffusion.js): add StableDiffusionAPI tool to allow agents to generate images using stable diffusion webui's api feat(Wolfram.js): add WolframAlphaAPI tool for computation, math, curated knowledge & real-time data through WolframAlpha. * testing openai specs * doc: fix link in .env.example * package-update * fix(MultiSelectDropDown.jsx): handle null or undefined values in availableValues array * refactor(DALL-E.js, StableDiffusion.js): remove 'dist/' from image path feat(docker-compose.yml): add comments for reverse proxy configuration * chore(.gitignore): ignore client/public/images/ fix(DALL-E.js, StableDiffusion.js): change image path from dist/ to public/ feat(index.js): add support for serving static files from client/public/ directory * fix: remove selected tool when uninstalled * plugin options in progress * fix: fix issue with uninstalling a plugin that is in use and typescript errors * feat(gptPlugins): add Preset support for GPT Plugins endpoint feat(ChatAgent.js): add support for agentOptions object feat(convoSchema.js): add agentOptions field to conversation schema feat(defaults.js): add agentOptions object to defaults feat(presetSchema.js): add agentOptions field to preset schema feat(askGPTPlugins.js): add support for agentOptions object in request body feat(EditPresetDialog.jsx): add support for showing/hiding GPT Plugins agent settings feat(EditPresetDialog.jsx): add support for setting GPT Plugins agent options fix(EndpointOptionsDialog.jsx): change endpoint name from 'gptPlugins' to 'Plugins' feat(AgentSettings.jsx): add AgentSettings component for GPT plugins configuration feat(client): add GPT Plugins settings component and endpoint to Settings component fix(client): remove unused imports in GoogleOptions component feat(PluginsOptions): add support for agent settings and refactor code feat(PluginsOptions): add GPTIcon to show/hide agent settings button feat(index.ts): export SVG components feat(GPTIcon.jsx): add className prop to GPTIcon component feat(GPTIcon.jsx): import cn function from utils feat(BingIcon.tsx): export BingIcon component feat(index.ts): export BingIcon component feat(index.ts): export MessagesSquared component refactor(cleanupPreset.js): add default values for agentOptions in gptPlugins endpoint feat(getDefaultConversation.js, handleSubmit.js): add agentOptions object to conversation object for GPT plugins endpoint. Update default temperature value to 0.8. Add chatGptLabel and promptPrefix properties to conversation object. * fix: set default convo back to null * refactor(ChatAgent.js, askGPTPlugins.js, AgentSettings.jsx): change variable names for better readability and remove redundant code * test: add RecoilRoot to layout-test-utils * refactor(askGPTPlugins.js): remove redundant code and use endpointOption directly feat(askGPTPlugins.js): add validation for tools in endpointOption before using it * chore(ChatAgent.js, Settings.jsx): add agentOptions to saveConvo function and adjust Settings component height The ChatAgent.js file was modified to include the agentOptions object in the saveConvo function. The Settings.jsx file was modified to adjust the height of the component to ensure that all content is visible. * refactor(ChatAgent.js): extract reverseProxyUrl option to a class property and add support for it feat(ChatAgent.js): add support for completionMode option in sendApiMessage method feat(ChatAgent.js): add support for user-provided promptPrefix in buildPrompt method * feat(plugins): allow preset change mid conversation * chore: update OPENAI_KEY to OPENAI_API_KEY in .github/playwright.yml and api/.env.example refactor(chatgpt-client.js): update OPENAI_KEY to OPENAI_API_KEY feat(langchain): add demo-aiplugin.js and demo-yaml.js, remove test2.js, test3.js, and test4.js chore: remove unused test files fix(titleConvo.js): fix typo in environment variable name fix(askGPTPlugins.js): fix typo in environment variable name fix(endpoints.js): fix typo in environment variable name docs: update installation guide to use OPENAI_API_KEY instead of OPENAI_KEY in .env file * fix(index.test.js): change import of GoogleSearchAPI to use uppercase G in GoogleSearch * chore(api): bump langchain version * feat(PluginController.js): authenticate plugins from environment variables if they are set feat(PluginStoreDialog.tsx): show plugin auth form only if plugin is not authenticated by env var and require authentication feat(types.ts): add authenticated field to TPlugin type definition * docs: update google_search.md and add stable_diffusion.md * Update stable_diffusion.md * refactor(Wolfram.js): remove newline characters from query before encoding docs(wolfram.md): add instructions for setting WOLFRAM_APP_ID in api.env to bypass prompt for AppID in plugin * refactor(Wolfram.js): replace deprecated replaceAll method with replace method * Update wolfram.md * fix(askGPTPlugins): error message will reference correct Parent Message * refactor(chatgpt-client.js, ChatAgent.js): simplify maxContextTokens calculation and add promptPrefix parameter to buildPrompt method * docs: initial draft of intro to plugins * Update introduction.md * Update introduction.md * Feature: User/Reg cleanup + Install / Upgrade script for langchain (#427) * test: login tests * test: finish login tests * test: initial tests for registration * test: registration specs * feature: Init a app config file - Simplifies the ENV vars too - Legacy fallbacks for older builds * refactor(auth): Refactor log in/out controllers - Moves both login and logout controllers to their own file * chore(jwt): Throw warning if secret is default * feature(frontend): Ability to disable registration * feature(env): Env in the root + version support ie .env.prod, .env.dev, .env.test * feature: Upgrade .env script for users * chore(config): Refactor and remove legacy env refs * feature(upgrade): Upgrade script for .env changes * feature: Install script and upgrade script * bugfix: Uncomment line to remove old .env file * chore: rename OPENAI_KEY to OPENAI_API_KEY * chore: Cleanup config changes/bugs * bugfix: Fix config and node env issues * bugfix: Config validation logic * bugfix: Handle unusual env configs gracefully * bugfix: Revert route changes and fix registration disable calling * bugfix: Fix env issues in frontend * bugfix: Fix login * bugfix: Fix frontend envs * bugfix: Fix frontend jest tests * bugfix: Fix upgrade scripts * bugfix: Allow install in non-tty envs * bugfix(windows): Use cross-env to set for windows * bugfix(env): Handle .env being incorrect to begin with for client domain * chore(merge-conflict): Update to LibreChat * chore(merge-conflict): Update to package-lock --------- Co-authored-by: Daniel D Orlando <dan@danorlando.com> * chore: comment out unused agent options * Update langchain plugins docs (#461) * Update: install docs (LibreChat) (#458) * Release: rename project from ChatGPT Clone to LibreChat Release: rename project from ChatGPT Clone to LibreChat * Release: rename project from ChatGPT Clone to LibreChat Release: rename project from ChatGPT Clone to LibreChat * Release: rename project from ChatGPT Clone to LibreChat Release: rename project from ChatGPT Clone to LibreChat * Release: rename project from ChatGPT Clone to LibreChat Release: rename project from ChatGPT Clone to LibreChat * Update documentation_guidelines.md * Update introduction.md add link to readme * Update stable_diffusion.md add link back to readme * Update wolfram.md add link back to readme * Update README.md add Plugins to ToC * feat(ChatAgent.js): add support for langchainProxy configuration option Add a new configuration option `langchainProxy` to the ChatAgent class. If the option is set, the `basePath` configuration option of the `ChatOpenAI` instance is set to the base path of `langchainProxy`. * bugfix(errors): Possible workaround for error flashing (#463) * Test/user auth system client tests (#462) * test: login tests * test: finish login tests * test: initial tests for registration * test: registration specs * chore(api): update langchain dependency to version 0.0.91 * Update introduction.md * Update introduction.md * Update introduction.md * fix: no longer renders html in markdown content fix: patch XSS vulnerability completely by handling cursor on the frontend without css/html * fix(Content.jsx): fix cursor logic so it never shows for static messages * bugfix(langchain): Upgrade script, docker, env and docs (#465) * bugfix(errors): Remove incorrect manual fix from misunderstanding * chore(env): Lets not make a .env.prod and use the prod values in the default root .env - .env.dev will still be created * chore(upgrade.js): Lets tell the user about .env.dev if we create it * bugfix(env): Move to full name environments for vite - .env.prod => .env.production - .env.dev => .env.development * chore(env-example): Explain how to get google login working in production * bugfix(oauth): Minor fix to point isProduction to a correct value * bugfix: Typo in public * chore(docs): Update docs to note the changes to .env * chore(docs): Include note on how to get google auth working in dev and how to disable registration * bugfix: Fix missing env changes * bugfix: Fix up docker to work with new env / npm changes * Update .env.example Cleanup the env of the palm2 instruction and fix to formating * chore(docker): Simplify Docker deployments - Needs work to support dev env/hotreload * bugfix: Remove volume map for client dir * chore(env-example): Change instructions to be more user centric --------- Co-authored-by: Fuegovic <32828263+fuegovic@users.noreply.github.com> * update: install docs (#466) * Add files via upload * Update apis-and-tokens.md * Update apis-and-tokens.md * Update docker_install.md * Update linux_install.md * Rename apis-and-tokens.md to apis_and_tokens.md * Update docker_install.md * Update linux_install.md * Update mac_install.md * Update linux_install.md * Update docker_install.md * Update windows_install.md * Update apis_and_tokens.md * Update mac_install.md * Update linux_install.md * Update docker_install.md * Update README.md * Update README.md : Breaking Changes --------- Co-authored-by: Danny Avila <110412045+danny-avila@users.noreply.github.com> * Update README.md (#468) add new API/Token docs to Toc * docs: guide on how to create your own plugin * Update make_your_own.md * Update make_your_own.md * feat(docker): add build args for frontend variables in Dockerfile feat(docker-compose): add build args for frontend variables in docker-compose.yml * Update docker_install.md * Update docker_install.md * Update docker_install.md * Update docker_install.md * docs: update (#469) * Update: make_your_own.md * Update README.md add `make_your_own.md` to ToC * Update linux_install.md * Update mac_install.md * Update windows_install.md * Update apis_and_tokens.md * Update docker_install.md * Update docker_install.md * Update linux_install.md * Update mac_install.md * Update windows_install.md * Update apis_and_tokens.md * Update user_auth_system.md * Update docker_install.md clean up of repeated information * Update docker_install.md * Update docker_install.md typo * fix: fix issue with pluginstore next and prev buttons going out of bounds * fix: add icon for web browser plugin * docs(GoogleSearch.js): update description of GoogleSearchAPI class to be more descriptive of its functionality * feat(ask/handlers.js): add cursor to indicate ongoing progress of a long-running task fix(Content.jsx): handle null content in the message stream by replacing it with an empty string (with a space so a text space is rendered) * Update README.md * Update README.md * fix: plugin option stacking order * update: web browser icon (#470) * Delete web-browser.png * update: web browser icon * Update readme (#472) * Update README.md Discord badge now displays the number of online users Project description has been updated to reflect current status Feature section has been updated to reflect current capabilities Sponsors section is now located just above the contributors section Roadmap has been removed as it was outdated. * Delete roadmap.md Roadmap has been removed to streamline document maintenance. * Update README.md * Update README.md * Delete CHANGELOG.md * fix: pluginstore in mobile view getting clipped and not scrolling * docs(linux_install.md): remove duplicate git clone command * chore(Dockerfile): comment out nginx-client build stage docs(README.md): update installation instructions and mention docker-compose changes docs(features/plugins/introduction.md): bold plugin names and add emphasis to notes * feat: add superscript and subscript support to markdown rendering refactor: support markdown citations for BingAI * refactor: support markdown citations for BingAI --------- Co-authored-by: David Shin <42793498+dncc89@users.noreply.github.com> Co-authored-by: Daniel D Orlando <dan@danorlando.com> Co-authored-by: LaraClara <2524209+ClaraLeigh@users.noreply.github.com> Co-authored-by: Fuegovic <32828263+fuegovic@users.noreply.github.com>
2023-06-10 19:10:03 -04:00
module.exports = {
✨ feat: Assistants API, General File Support, Side Panel, File Explorer (#1696) * feat: assistant name/icon in Landing & Header * feat: assistname in textarea placeholder, and use `Assistant` as default name * feat: display non-image files in user messages * fix: only render files if files.length is > 0 * refactor(config -> file-config): move file related configuration values to separate module, add excel types * chore: spreadsheet file rendering * fix(Landing): dark mode style for Assistant Name * refactor: move progress incrementing to own hook, start smaller, cap near limit \(1\) * refactor(useContentHandler): add empty Text part if last part was completed tool or image * chore: add accordion trigger border styling for dark mode * feat: Assistant Builder model selection * chore: use Spinner when Assistant is mutating * fix(get/assistants): return correct response object `AssistantListResponse` * refactor(Spinner): pass size as prop * refactor: make assistant crud mutations optimistic, add types for options * chore: remove assistants route and view * chore: move assistant builder components to separate directory * feat(ContextButton): delete Assistant via context button/dialog, add localization * refactor: conditionally show use and context menu buttons, add localization for create assistant * feat: save side panel states to localStorage * style(SidePanel): improve avatar menu and assistant select styling for dark mode * refactor: make NavToggle reusable for either side (left or right), add SidePanel Toggle with ability to close it completely * fix: resize handle and navToggle behavior * fix(/avatar/:assistant_id): await `deleteFile` and assign unique name to uploaded image * WIP: file UI components from PR #576 * refactor(OpenAIMinimalIcon): pass className * feat: formatDate helper fn * feat: DataTableColumnHeader * feat: add row selection, formatted row values, number of rows selected * WIP: add files to Side panel temporarily * feat: `LB_QueueAsyncCall`: Leaky Bucket queue for external APIs, use in `processDeleteRequest` * fix(TFile): correct `source` type with `FileSources` * fix(useFileHandling): use `continue` instead of return when iterating multiple files, add file type to extendedFile * chore: add generic setter type * refactor(processDeleteRequest): settle promises to prevent rejections from processing deletions, log errors * feat: `useFileDeletion` to reuse file deletion logic * refactor(useFileDeletion): make `setFiles` an optional param and use object as param * feat: useDeleteFilesFromTable * feat: use real `files` data and add deletion action to data table * fix(Table): make headers sticky * feat: add dynamic filtering for columns; only show to user Host or OpenAI storage type * style(DropdownMenu): replace `slate` with `gray` * style(DataTable): apply dark mode themes and other misc styling * style(Columns): add color to OpenAI Storage option * refactor(FileContainer): make file preview reusable * refactor(Images): make image preview reusable * refactor(FilePreview): make file prop optional for FileIcon and FilePreview, fix relative style * feat(Columns): add file/image previews, set a minimum size to show for file size in bytes * WIP: File Panel with real files and formatted * feat: open files dialog from panel * style: file data table mobile and general column styling fixes * refactor(api/files): return files sorted by the most recently updated * refactor: provide fileMap through context to prevent re-selecting files to map in different areas; remove unused imports commented out in PanelColumns * refactor(ExtendFile): make File type optional, add `attached` to prevent attached files from being deleted on remove, make Message.files a partial TFile type * feat: attach files through file panel * refactor(useFileHandling): move files to the start of cache list when uploaded * refactor(useDeleteFilesMutation): delete files from cache when successfully deleted from server * fix(FileRow): handle possible edge case of duplication due to attaching recently uploaded file * style(SidePanel): make resize grip border transparent, remove unnecessary styling on close sidepanel button * feat: action utilities and tests * refactor(actions): add `ValidationResult` type and change wording for no server URL found * refactor(actions): check for empty server URL * fix(data-provider): revert tsconfig to fix type issue resolution * feat(client): first pass of actions input for assistants * refactor(FunctionSignature): change method to output object instead of string * refactor(models/Assistant): add actions field to schema, use searchParams object for methods, and add `getAssistant` * feat: post actions input first pass - create new Action document - add actions to Assistant DB document - create /action/:assistant_id POST route - pass more props down from PanelSwitcher, derive assistant_id from switcher - move privacy policy to ActionInput - reset data on input change/validation - add `useUpdateAction` - conform FunctionSignature type to FunctionTool - add action, assistant doc, update hook related types * refactor: optimize assistant/actions relationship - past domain in metadata as hostname and not a URL - include domain in tool name - add `getActions` for actions retrieval by user - add `getAssistants` for assistant docs retrieval by user - add `assistant_id` to Action schema - move actions to own module as a subroute to `api/assistants` - add `useGetActionsQuery` and `useGetAssistantDocsQuery` hooks - fix Action type def * feat: show assistant actions in assistant builder * feat: switch to actions on action click, editing action styling * fix: add Assistant state for builder panel to allow immediate selection of newly created assistants as well as retaining the current assistant when switching to a different panel within the builder * refactor(SidePanel/NavToggle): offset less from right when SidePanel is completely collapsed * chore: rename `processActions` -> `processRequiredActions` * chore: rename Assistant API Action to RequiredAction * refactor(actions): avoid nesting actual API params under generic `requestBody` to optimize LLM token usage * fix(handleTools): avoid calling `validTool` if not defined, add optional param to skip the loading of specs, which throws an error in the context of assistants * WIP: working first pass of toolCalls generated from openapi specs * WIP: first pass ToolCall styling * feat: programmatic iv encryption/decryption helpers * fix: correct ActionAuth types/enums, and define type for AuthForm * feat: encryption/decryption helpers for Action AuthMetadata * refactor(getActions): remove sensitive fields from query response * refactor(POST/actions): encrypt and remove sensitive fields from mutation response * fix(ActionService): change ESM import to CJS * feat: frontend auth handling for actions + optimistic update on action update/creation * refactor(actions): use the correct variables and types for setAuth method * refactor: POST /:assistant_id action can now handle updating an existing action, add `saved_auth_fields` to determine when user explicitly saves new auth creds. only send auth metadata if user explicitly saved fields * refactor(createActionTool): catch errors and send back meaningful error message, add flag to `getActions` to determine whether to retrieve sensitive values or not * refactor(ToolService): add `action` property to ToolCall PartMetadata to determine if the tool call was an action, fix parsing function name issue with actionDelimiter * fix(ActionRequest): use URL class to correctly join endpoint parts for `execute` call * feat: delete assistant actions * refactor: conditionally show Available actions * refactor: show `retrieval` and `code_interpreter` as Capabilities, swap `Switch` for `Checkbox` * chore: remove shadow-stroke from messages * WIP: first pass of Assistants Knowledge attachments * refactor: remove AssistantsProvider in favor of FormProvider, fix selectedAssistant re-render bug, map Assistant file_ids to files via fileMap, initialize Knowledge component with mapped files if any exist * fix: prevent deleting files on assistant file upload * chore: remove console.log * refactor(useUploadFileMutation): update files and assistants cache on upload * chore: disable oauth option as not supported yet * feat: cancel assistant runs * refactor: initialize OpenAI client with helper function, resolve all related circular dependencies * fix(DALL-E): initialization * fix(process): openai client initialization * fix: select an existing Assistant when the active one is deleted * chore: allow attaching files for assistant endpoint, send back relevant OpenAI error message when uploading, deconstruct openAI initialization correctly, add `message_file` to formData when a file is attached to the message but not the assistant * fix: add assistant_id on newConvo * fix(initializeClient): import fix * chore: swap setAssistant for setOption in useEffect * fix(DALL-E): add processFileURL to loadTools call * chore: add customConfig to debug logs * feat: delete threads on convo delete * chore: replace Assistants icon * chore: remove console.dir() in `abortRun` * feat(AssistantService): accumulate text values from run in openai.responseText * feat: titling for assistants endpoint * chore: move panel file components to appropriate directory, add file checks for attaching files, change icon for Attach Files * refactor: add localizations to tools, plugins, add condition for adding/remove user plugins so tool selections don't affect this value * chore: disable `import from url` action for now * chore: remove textMimeTypes from default fileConfig for now * fix: catch tool errors and send as outputs with error messages * fix: React warning about button as descendant of button * style: retrieval and cancelled icon * WIP: pass isSubmitting to Parts, use InProgressCall to display cancelled tool calls correctly, show domain/function name * fix(meilisearch): fix `postSaveHook` issue where indexing expects a mongo document, and join all text content parts for meili indexing * ci: fix dall-e tests * ci: fix client tests * fix: button types in actions panel * fix: plugin auth form persisting across tool selections * fix(ci): update AppService spec with `loadAndFormatTools` * fix(clearConvos): add id check earlier on * refactor(AssistantAvatar): set previewURL dynamically when emtadata.avatar changes * feat(assistants): addTitle cache setting * fix(useSSE): resolve rebase conflicts * fix: delete mutation * style(SidePanel): make grip visible on active and hover, invisible otherwise * ci: add data-provider tests to workflow, also update eslint/tsconfig to recognize specs, and add `text/csv` to fileConfig * fix: handle edge case where auth object is undefined, and log errors * refactor(actions): resolve schemas, add tests for resolving refs, import specs from separate file for tests * chore: remove comment * fix(ActionsInput): re-render bug when initializing states with action fields * fix(patch/assistant): filter undefined tools * chore: add logging for errors in assistants routes * fix(updateAssistant): map actions to functions to avoid overwriting * fix(actions): properly handle GET paths * fix(convos): unhandled delete thread exception * refactor(AssistantService): pass both thread_id and conversationId when sending intermediate assistant messages, remove `mapMessagesToSteps` from AssistantService * refactor(useSSE): replace all messages with runMessages and pass latestMessageId to abortRun; fix(checkMessageGaps): include tool calls when syncing messages * refactor(assistants/chat): invoke `createOnTextProgress` after thread creation * chore: add typing * style: sidepanel styling * style: action tool call domain styling * feat(assistants): default models, limit retrieval to certain models, add env variables to to env.example * feat: assistants api key in EndpointService * refactor: set assistant model to conversation on assistant switch * refactor: set assistant model to conversation on assistant select from panel * fix(retrieveAndProcessFile): catch attempt to download file with `assistant` purpose which is not allowed; add logging * feat: retrieval styling, handling, and logging * chore: rename ASSISTANTS_REVERSE_PROXY to ASSISTANTS_BASE_URL * feat: FileContext for file metadata * feat: context file mgmt and filtering * style(Select): hover/rounded changes * refactor: explicit conversation switch, endpoint dependent, through `useSelectAssistant`, which does not create new chat if current endpoint is assistant endpoint * fix(AssistantAvatar): make empty previewURL if no avatar present * refactor: side panel mobile styling * style: merge tool and action section, optimize mobile styling for action/tool buttons * fix: localStorage issues * fix(useSelectAssistant): invoke react query hook directly in select hook as Map was not being updated in time * style: light mode fixes * fix: prevent sidepanel nav styling from shifting layout up * refactor: change default layout (collapsed by default) * style: mobile optimization of DataTable * style: datatable * feat: client-side hide right-side panel * chore(useNewConvo): add partial typing for preset * fix(useSelectAssistant): pass correct model name by using template as preset * WIP: assistant presets * refactor(ToolService): add native solution for `TavilySearchResults` and log tool output errors * refactor: organize imports and use native TavilySearchResults * fix(TavilySearchResults): stringify result * fix(ToolCall): show tool call outputs when not an action * chore: rename Prompt Prefix to custom instructions (in user facing text only) * refactor(EditPresetDialog): Optimize setting title by debouncing, reset preset on dialog close to avoid state mixture * feat: add `presetOverride` to overwrite active conversation settings when saving a Preset (relevant for client side updates only) * feat: Assistant preset settings (client-side) * fix(Switcher): only set assistant_id and model if current endpoint is Assistants * feat: use `useDebouncedInput` for updating conversation settings, starting with EditPresetDialog title setting and Assistant instructions setting * feat(Assistants): add instructions field to settings * feat(chat/assistants): pass conversation settings to run body * wip: begin localization and only allow actions if the assistant is created * refactor(AssistantsPanel): knowledge localization, allow tools on creation * feat: experimental: allow 'priming' values before assistant is created, that would normally require an assistant_id to be defined * chore: trim console logs and make more meaningful * chore: toast messages * fix(ci): date test * feat: create file when uploading Assistant Avatar * feat: file upload rate limiting from custom config with dynamic file route initialization * refactor: use file upload limiters on post routes only * refactor(fileConfig): add endpoints field for endpoint specific fileconfigs, add mergeConfig function, add tests * refactor: fileConfig route, dynamic multer instances used on all '/' and '/images' POST routes, data service and query hook * feat: supportedMimeTypesSchema, test for array of regex * feat: configurable file config limits * chore: clarify assistants file knowledge prereq. * chore(useTextarea): default to localized 'Assistant' if assistant name is empty * feat: configurable file limits and toggle file upload per endpoint * fix(useUploadFileMutation): prevent updating assistant.files cache if file upload is a message_file attachment * fix(AssistantSelect): set last selected assistant only when timeout successfully runs * refactor(queries): disable assistant queries if assistants endpoint is not enabled * chore(Switcher): add localization * chore: pluralize `assistant` for `EModelEndpoint key and value * feat: show/hide assistant UI components based on endpoint availability; librechat.yaml config for disabling builder section and setting polling/timeout intervals * fix(compactEndpointSchemas): use EModelEndpoint for schema access * feat(runAssistant): use configured values from `librechat.yaml` for `pollIntervalMs` and `timeout` * fix: naming issue * wip: revert landing * 🎉 happy birthday LibreChat (#1768) * happy birthday LibreChat * Refactor endpoint condition in Landing component * Update birthday message in Eng.tsx * fix(/config): avoid nesting ternaries * refactor(/config): check birthday --------- Co-authored-by: Danny Avila <messagedaniel@protonmail.com> * fix: landing * fix: landing * fix(useMessageHelpers): hardcoded check to use EModelEndpoint instead * fix(ci): convo test revert to main * fix(assistants/chat): fix issue where assistant_id was being saved as model for convo * chore: added logging, promises racing to prevent longer timeouts, explicit setting of maxRetries and timeouts, robust catching of invalid abortRun params * refactor: use recoil state for `showStopButton` and only show for assistants endpoint after syncing conversation data * refactor: optimize abortRun strategy using localStorage, refactor `abortConversation` to use async/await and await the result, refactor how the abortKey cache is set for runs * fix(checkMessageGaps): assign `assistant_id` to synced messages if defined; prevents UI from showing blank assistant for cancelled messages * refactor: re-order sequence of chat route, only allow aborting messages after run is created, cancel abortRun if there was a cancelling error (likely due already cancelled in chat route), and add extra logging * chore(typedefs): add httpAgent type to OpenAIClient * refactor: use custom implementation of retrieving run with axios to allow for timing out run query * fix(waitForRun): handle timed out run retrieval query * refactor: update preset conditions: - presets will retain settings when a different endpoint is selected; for existing convos, either when modular or is assistant switch - no longer use `navigateToConvo` on preset select * fix: temporary calculator hack as expects string input when invoked * fix: cancel abortRun only when cancelling error is a result of the run already being cancelled * chore: remove use of `fileMaxSizeMB` and total counterpart (redundant) * docs: custom config documentation update * docs: assistants api setup and dotenv, new custom config fields * refactor(Switcher): make Assistant switcher sticky in SidePanel * chore(useSSE): remove console log of data and message index * refactor(AssistantPanel): button styling and add secondary select button to bottom of panel * refactor(OpenAIClient): allow passing conversationId to RunManager through titleConvo and initializeLLM to properly record title context tokens used in cases where conversationId was not defined by the client * feat(assistants): token tracking for assistant runs * chore(spendTokens): improve logging * feat: support/exclude specific assistant Ids * chore: add update `librechat.example.yaml`, optimize `AppService` handling, new tests for `AppService`, optimize missing/outdate config logging * chore: mount docker logs to root of project * chore: condense axios errors * chore: bump vite * chore: vite hot reload fix using latest version * chore(getOpenAIModels): sort instruct models to the end of models list * fix(assistants): user provided key * fix(assistants): user provided key, invalidate more queries on revoke --------- Co-authored-by: Marco Beretta <81851188+Berry-13@users.noreply.github.com>
2024-02-13 20:42:27 -05:00
getAvailableTools,
getAvailablePluginsController,
feat: Plugins endpoint - Reverse Engineering of official Plugins features (#197) * components for plugins in progress * WIP: add langchain client implementation for tools/plugins feat(langchain): add loadHistory function for loading chat history from database feat(langchain): add saveMessageToDatabase function for saving chat messages to database * chore(Memory.js): remove Memory.js file from the project directory. * WIP: adding plugin functionality —————————————————— fix(eslintrc.js): change arrow-parens rule to always require parentheses refactor(agent.js): reorganize imports and add new imports feat(agent.js): add support for saving and loading chat history feat(agent.js): add support for saving messages to database feat(agent.js): add ChatAgent class with initialize and sendMessage methods fix(langchain): use getConvo and saveMessage functions from models.js instead of Conversation and Message models feat(langchain): add user parameter to loadHistory and saveMessageToDatabase functions chore(package.json): update langchain package version to 0.0.59 and add langchain script to run test2.js file —————————————————— * WIP: testing agent initialization * WIP: testing various agent methods feat(agent.js): add CustomChatAgent class and initializeAgentExecutorWithOptions method feat(customChatAgent.js): add CustomPromptTemplate and CustomOutputParser classes refactor(langchain): uncomment code for input2 and options feat(langchain): add input1 to read comments on a youtube video docs(langchain): remove commented code and add whitespace to package.json * WIP: feat: plugin endpoint, backend class working * feat(agent.js): add support for Zapier NLA API key feat(agent.js): add ZapierToolKit to tools if zapierApiKey is provided feat(customAgent.js): change prompt prefix and suffix to reflect new task-based prompt feat(test4.js): add test for new task-based prompt * style(langchain): improve readability and add comments to code feat(langchain): update prompt message for custom agent fix(langchain): update message format in test4.js * style(customAgent.js): remove unnecessary capitalization and rephrase some sentences test(langchain): add test2 and test3 scripts to package.json * chore(customAgent.js): fix typo in comment, change "an" to "identical" * WIP: gpt-4 testing * feat(langchain): add AIPluginTool and HumanTool classes fix(langchain): remove zapierApiKey option from ChatAgent constructor refactor(langchain): update langchain package to v0.0.64 misc(langchain): update test2, test3, and test4 scripts to use --inspect flag * feat(langchain): add GoogleSearchAPI tool for searching the web using Google Custom Search API * feat(askGPTPlugins.js): add support for progress callback in ask function fix(agent.js): pass progress callback to sendApiMessage function * refactor(agent.js): load tools from options and initialize them in constructor feat(agent.js): add support for environment variable SERPAPI_API_KEY feat(agent.js): add support for environment variable ZAPIER_NLA_API_KEY docs(agent.js): remove commented out code and add comments to clarify code * chore(langchain): remove unused files loadHistory.js and saveMessage.js * feat(validateTools.js): add function to validate API keys for supported tools * feat(langchain): update langchain package to version 0.0.66 feat(langchain): add support for GPT-4 model fix(server/index.js): fix uncaughtException handler to ignore 'fetch failed' errors * refactor(agent.js): remove FORMAT_INSTRUCTIONS and replace with a more concise message refactor(agent.js): remove unused variable 'errorMessage' refactor(agent.js): change 'result' variable initialization to an empty object instead of null refactor(agent.js): change error message when response generation fails refactor(agent.js): change output message when response generation fails refactor(agent.js): change output message when response generation succeeds * chore(langchain): comment out unused model in ChatAgent constructor feat(langchain): add test5 script to package.json for running test5.js script * refactor(agent.js): change response to answer and update message refactor(test3.js, test5.js): remove commented out code and add comments The changes in agent.js are to improve the message that is returned to the user. The word "response" has been changed to "answer" to better reflect the output of the chatbot. The message has also been updated to provide clearer instructions to the user. The changes in test3.js and test5.js are to remove commented out code and add comments to improve readability. * docs: update links to LOCAL_INSTALL.md and defaultSystemMessage.md fix: fix typo in BingAI/Settings.jsx feat: add Dockerfile for app containerization docs(google_search.md): add guide for setting up Google Custom Search API key and ID * docs: update link to system message guidelines in Bing AI Settings component docs: update link to system message guidelines in GOOGLE_SEARCH.md feat: add JAILBREAK_INFO.md guide for Bing AI jailbreak mode system message guidelines * style(api): remove unnecessary quotes and empty values from .env.example style(agent.js): refactor getActions method to accept an input parameter feat(agent.js): add handleChainEnd method to CustomChatAgent class style(customAgent.js): add a new line to the end of the file style(test5.js): comment out unused variable and update input1 variable style(googleSearch.js): change tool name to kebab-case * chore(langchain): comment out handleChainEnd method in agent.js feat(langchain): add browser tool to ChatAgent in test2.js feat(langchain): add modelOptions to ChatAgent in test2.js feat(langchain): change question in input1 and request article review summary in test5.js * fix(askGPTPlugins.js): fix syntax error by removing extra comma in parentMessageId field feat(askGPTPlugins.js): add default value of null to parentMessageId parameter in ask function * fix(askGPTPlugins.js): change endpoint string from 'GPTPlugins' to 'gptPlugins' feat(endpoints.js): add support for gptPlugins endpoint feat(PresetItem.jsx): add support for gptPlugins endpoint feat(HoverButtons.jsx): add support for gptPlugins endpoint feat(createPayload.ts): add support for gptPlugins endpoint feat(types.ts): add gptPlugins endpoint to EModelEndpoint enum feat(endpoints.js): add gptPlugins endpoint to availableEndpoints selector feat(cleanupPreset.js): add support for gptPlugins endpoint feat(getDefaultConversation.js): add support for gptPlugins endpoint feat(getIcon.jsx): add support for gptPlugins endpoint feat(handleSubmit.js): add support for gptPlugins endpoint * refactor(agent.js): remove debug option from options object refactor(agent.js): change tool name from 'google-search' to 'google' refactor(agent.js): update description for 'google' tool feat(agent.js): add support for citing sources when using web links in response message fix(agent.js): update error message to not mention error to user feat(agent.js): add unique message ids for user message and response message feat(agent.js): limit number of search results to 5 in 'google' tool refactor(validateTools.js): add console log to show valid tools * feat(askGPTPlugins.js): add support for GPT-3.5-turbo model and validate model option refactor(askGPTPlugins.js): remove unused imports and variables refactor(askGPTPlugins.js): remove commented code refactor(askGPTPlugins.js): remove unused parameters in ask function feat(ask/index.js): add askGPTPlugins route to router * feat(NewConversationMenu): add alpha tag to gptPlugins endpoint and rename it to Plugins * refactor(askGPTPlugins.js): remove commented code and unused imports feat(askGPTPlugins.js): add support for debug option in endpointOption feat(askGPTPlugins.js): add support for chatGptLabel, promptPrefix, temperature, top_p, presence_penalty, and frequency_penalty in endpointOption feat(askGPTPlugins.js): add support for sending plugin and pluginend events feat(askGPTPlugins.js): add onAgentAction and onChainEnd callbacks to ChatAgent.sendMessage refactor(titleConvo.js): comment out unused imports refactor(validateTools.js): comment out console.log statement refactor(agent.js): change saveMessage to include unfinished property feat(agent.js): add endpoint property to saveConvo call in saveMessageToDatabase feat(askGPTPlugins.js): add validateTools import and use it to validate endpointOption.tools before passing to ChatAgent constructor feat(askGPTPlugins.js * refactor(MessageHeader.jsx): extract plugins section into a separate variable and add support for gptPlugins endpoint fix(MessageHeader.jsx): disable clicking on non-clickable endpoints * components for plugins in progress * feat(Plugin.jsx): add plugin prop to Plugin component and display plugin name feat(Plugin.jsx): add loading state and display loading spinner feat(Plugin.jsx): add Disclosure component to Plugin component feat(Plugin.jsx): add Disclosure.Panel to Plugin component to display team pricing information feat(Spinner.jsx): add classProp prop to Spinner component to allow for custom styling feat(Landing.jsx): add Plugin component to Landing page for testing testing gpt plugins feat(plugins): Milestone commit - Add formatAction function to format plugin actions. - Add prefix.js file to store the prefix message for ChatAgent. - Update ask function to include plugin object to store plugin data. - Update onAgentAction and onChainEnd functions to format plugin data and send intermediate messages. - Update response object to include plugin data. The `handlers.js` file now includes a `formatAction` function that formats the action object for display in the UI. The `createOnProgress` function now returns a `sendIntermediateMessage` function that sends intermediate messages to the client. feat (client): add support for plugins in messages This commit adds support for plugins in messages. It includes changes to the `handlers.js`, `index.jsx`, `CodeBlock.jsx`, `Message.jsx`, `MessageHeader.jsx`, and `Plugin.jsx` files. The `index.jsx` file now includes a `plugin` property in the `messageHandler` function. The `CodeBlock.jsx` file now includes a `plugin` property that determines the language of the code block. The `Message.jsx` file now includes a `Plugin` component that displays the plugin used in the message. The `MessageHeader.jsx` file now includes a `Plugins` component that displays the enabled plugins. feat(langchain): add OpenAICreateImage tool for generating images based on user prompts fix(langchain): update validateTools to include create-image tool fix(langchain): save plugin data to messageSchema fix(server/routes/askGPTPlugins.js): save userMessage and response to messageSchema feat(langchain): add SelfReflectionTool Add a new tool to the LangChain agent, SelfReflectionTool, which enhances the agent's self-awareness by reflecting on its thoughts before taking action. The tool provides a space for the agent to explore and organize its ideas in response to the user's message. Also, update the prefix message to reflect the changes in the agent's behavior and the way it should engage with the user. The prefix message now emphasizes the use of tools when necessary, and relying on the agent's knowledge for creative requests. It also provides clear instructions on how to use the 'Action' input and how to carry out tasks in the sequence written by the human. Finally, update the OpenAICreateImage tool to return the image URL in markdown format. The tool replaces newlines and spaces in the input text with hyphens to create a valid markdown link. Milestone commit: better error handling with custom output parser, dir and file re-org style(langchain): fix formatting and add comments to prefix.js fix(langchain): remove commented out code in test6.js feat(langchain): reduce maxAttempts from 3 to 2 in CustomChatAgent's buildPromptPrefix method feat(langchain): add null check for result.output in CustomChatAgent's buildPromptPrefix method style(langchain): improve consistency and readability of code This commit improves the consistency and readability of the code in the langchain directory. Specifically, it: - Changes the case of the "Thought" output in the CustomChatAgent class to match the "Thought" output in the SelfReflectionTool class. - Adds a currentDateString property to the CustomChatAgent class to avoid repeating the same code in multiple places. - Updates the prefix in the prefix.js file to match the current objectives of the ChatGPT model. - Changes the description of the OpenAICreateImage tool to request a description of the image to be generated. - Updates the tools used by the ChatAgent in the askGPTPlugins.js file to include the Google and Browser tools instead of the Calculator and Create-Image tools. feat: add wolfram, improve image creation, rename to dall-e * refactor(langchain): update language and formatting in various files - Update tool-based instructions to use proper Markdown syntax for image URLs - Adjust temperature for modelOptions in CustomChatAgent class - Comment out console.debug statement in CustomChatAgent class - Update prefix in initializeCustomAgent function to use proper line breaks - Update prefix in instructions.js to use proper line breaks and change "user" to "human" - Update input in test6.js to use Ezra Pound instead of Hemingway - Update return statement in OpenAICreateImage class to use "generated-image" as alt-text - Update description in SelfReflectionTool class to provide clearer instructions - Update tools in ask function in askGPTPlugins.js to use only the DALL-E tool and enable debug mode feat(ask): add support for DALL-E tool in formatAction function feat(ask): add support for self-reflection tool in formatAction function feat(Plugin.jsx): add support for self-reflection tool in Plugin component fix(Plugin.jsx): fix Plugin component to not display 'None' when latest is not available * docs(openaiCreateImage.js): update tool description to clarify usage * feat(agent.js): add message parameter to initialize function feat(agent.js): pass message parameter to SelfReflectionTool constructor feat(customAgent.js): add longestToolName variable to CustomOutputParser feat(openaiCreateImage.js): replace new lines with spaces in prompt parameter feat(selfReflection.js): add message parameter to SelfReflectionTool constructor feat(selfReflection.js): add placeholder response to selfReflect function * feat: frontend plugin selection * fix: agent updates, available tools via endpoint config * fix: improve frontend plugin selection * feat: further customize agent and bypass executor when no tools are provided * fix: key issue in multiselect and allow setting changes during convo in plugins endpoint * fix: convo will save modelOptions, fix persistent errors with agent * fix: add looser final answer parsing and edit action formatting * fix: handle edge case where stop token is not hit and causes long parsing error * feat: trying new prompt for image creation * fix: improvements based on gpt-3.5 * feat: allow setting model options throughout plugin conversation * fix: agent adjustments * improve final reply for gpt-4, gpt-3.5 needs a more stable approach * fix: better context output for gpt-3.5 * fix: added clarification for better context output for gpt-3.5 * feat(PluginsOptions): add advanced mode to show/hide options style(PluginsOptions): add styles for advanced mode and show/hide options * minor changes to styling * refactor(langchain): add support for custom GPT-4 agent This commit adds support for a custom GPT-4 agent in the langchain module. The `CustomGpt4Agent` class extends the `ZeroShotAgent` class and includes a new `createPrompt` method that generates a prompt template for the agent. The `initializeCustomAgent` function has been updated to use the `CustomGpt4Agent` class when the model is not GPT-3. The `instructions.js` file has also been updated to include new instructions for the GPT-4 agent. The `formatInstructions` method has been removed and replaced with `gpt4Instructions` and `prefix2` and `suffix2` have been added to include the new instructions. feat(langchain): add custom output parser for langchain agents This commit adds a custom output parser for langchain agents. The new parser is called CustomOutputParser and it extends ZeroShotAgentOutputParser. It takes a fields object as a parameter and sets the tools and longestToolName properties. It also sets the finishToolNameRegex property to match the final answer. The parse method of the CustomOutputParser class takes a text parameter and returns an object with returnValues, log, and toolInput properties. This commit also adds a Gpt4OutputParser class that extends ZeroShotAgentOutputParser. It takes a fields object as a parameter and sets the tools and longestToolName properties. It also sets the finishToolNameRegex property to match the final answer. The parse method of the Gpt4OutputParser class takes a text parameter and returns an object with returnValues, log, and toolInput properties. feat(langchain): add isGpt3 parameter to * Stable Diffusion Plugin (#204) * Added stable diffusion plugin * Added example prompt * Fixed naming * Removed brackets in the prompt * fix: improved agent for gpt-3.5 * fix: outparser, gpt3 instructions, and wolfram error handling * chore: update langchain to 0.0.71 * fix: long parsing action input fix * fix: make plugin select close on clicking label/button * fix: make plugin select close on clicking label/button * fix: wolfram input formatting and gpt-3 payload without plugins * chore(api): update axios package version to 1.3.4 feat(api): add requireJwtAuth middleware to askGPTPlugins endpoint fix(api): replace session user with user id in askGPTPlugins endpoint docs(LOCAL_INSTALL.md): update guide for local installation and testing This commit updates the guide for local installation and testing of the ChatGPT-Clone app. It includes instructions for locally running the app, updating the app version, and running tests. It also includes a new option for running the app using Docker. The commit also fixes some typos and formatting issues. * add reverseProxy to plugins client * chore(Dockerfile-app): add Dockerfile for building and running the app in a container docs: remove outdated guides on Google search and Bing jailbreak mode docs(LOCAL_INSTALL.md): remove outdated Windows installation instructions and update MeiliSearch configuration file * fix: handle n/a parsing error better, reduce token waste if no agentic behavior is needed * style: fix formatting and add parentheses around arrow function parameter style: change hover background color to white and dark hover background color to gray-700 * chore: re-organize agent dir and files * feat(ChatAgent.js): add support for PlanAndExecuteAgentExecutor feat(PlanAndExecuteAgentExecutor.js): add PlanAndExecuteAgentExecutor class feat(planExecutor.js): add demo for PlanAndExecuteAgentExecutor * feat: add azure support to plugins * refactor(utils): add basePath endpoint for genAzureEndpoint feat(api): add support for Azure OpenAI API in various modules and tools * feat: add plugin api for fetching available tools * feat: add data service for getting available plugins * feat: first iteration plugin store UI * refactor: rename files to follow proper naming convention * feat: Plugin store UI components * feat: create separate user routes, service, controller, and add plugins to user model * feat: create data service for adding and removing plugins per user * feat: UI for adding and removing plugins, displaying plugins in dropdown based on what user has installed * fix: merge conflicts from main * fix: fix plugin items titles * fix: tool.value -> tool.pluginKey * fix: testing returnDirect for self-reflection * fix: add browser tool to manifest * refactor(outputParser.js): remove commented out code feat(outputParser.js): add support for thought input when there is no action input * handling 'use tool' edge case * merge main to langchain * fix(User.js, auth.service.js, localStrategy.js): change deprecated Joi.validate() to schema.validate() method (#322) * fix(auth.service.js): fixes deprecated error callback in mongoose save method (#323) * chore: run formatting script with new rules * refactor: add requiresAuth to manifest, fix uninstall button * version with plugin auth as dialog modal * feat: Complete frontend for plugin auth * frontend styling updates * feat: api for plugin auth * feat: Add tooltip with field description to plugin auth form * fix: issue with plugin that has no auth * feat(tools): add support for user-specific API keys This commit adds support for user-specific API keys for the following tools: - Google Search API - Web Browser - SerpAPI - Zapier - DALL-E - Wolfram Alpha API It also adds support for OpenAI API key for the Web Browser tool. The `validateTools` function now takes a `user` parameter and checks for user-specific API keys before falling back to environment variables. The `loadTools` function now takes a `user` parameter and initializes the tools with user-specific API keys if available. The `manifest.json` file has been updated to include the new `authConfig` fields for the tools that support user-specific API keys. The `askGPTPlugins.js` file has been updated to use the `validateTools` function with the `user` parameter. refactor(ChatAgent.js): add user parameter to initialize function and pass it to loadTools function refactor(tools/index.js): set default value for tools parameter in validateTools function refactor(askGPTPlugins.js): remove duplicate user variable declaration and use the one from req object * refactor(ChatAgent.js): await validTool() before pushing to this.tools array refactor(tools/index.js): use Map instead of Set to store valid tools refactor(tools/index.js): filter availableTools to only validate tools passed in refactor(PluginController.js): filter out duplicate plugins by pluginKey refactor(crypto.js): use environment variables for encryption key and initialization vector feat(PluginService.js): add null check for pluginAuth in getUserPluginAuthValue() * feat(api): add credentials key and IV to .env.example for securely storing credentials * Adds testing for handling tools, introducing a test env to the backend Fixes bugs & optimizes code as revealed through testing, including: - wolfram.js: fixes bug where wolfram was not handling authentication - ChatAgent.js: ChatAgent modified to reflect 'handleTools' changes - handleTools.js: Moves logic out of index file - handleTools.js: loadTools: returns only requested tools - handleTools.js: validTools: correctly returns tools based on authentication * test(index.test.js): add test to validate a tool from an environment variable * test(tools): add test for initializing an authenticated tool through Environment Variables * refactor(ChatAgent.js): remove commented out code and unused imports * refactor(ChatAgent.js): move instructions to a separate file and import them fix(ChatAgent.js): replace hardcoded instructions with imported ones * refactor(ChatAgent.js): change import path for TextStream refactor(stream.js): remove unused TextStream class * chore(.gitignore): add .env.test to gitignore refactor(ChatAgent.js): rename CustomChatAgent to ChatAgent test(ChatAgent.test.js): add tests for ChatAgent class refactor(outputParser.js): remove OldOutputParser class refactor(outputParser.js): rename CustomOutputParser to OutputParser docs(.env.test.example): add comment explaining how to use OPENAI_API_KEY refactor(jestSetup.js): use dotenv to load environment variables from .env.test file * Various optimizations and config, add tests for PluginStoreDialog * test(ChatAgent.test.js): add test to check if chat history is returned correctly * test: unit tests for plugin store * test: add frontend-test script to root package.json * feat(ChatAgent.js, askGPTPlugins.js): add support for aborting chat requests (in progress) * test: add more client tests * feat(ChatAgent): allow plugin requests to be cancelled * feat(ChatAgent): allow message regeneration * feat(ChatAgent): remember last selected tools * Remove plugins we don't yet have from manifest.json * fix(ChatAgent.js): increase maxAttempts from 1 to 2 fix(ChatAgent.js): change error message to 'Cancelled.' if message was aborted mid-generation fix(openaiCreateImage.js): replace unwanted characters in input string fix(handlers.js): compare action.tool in lowercase to 'self-reflection' * fix(ChatAgent): Fix up plugin I/O formatting for n/a actions * refactor(Plugin.jsx): remove unused import statement feat(Plugin.jsx): add Plugin component with svg paths and styles * refactor: simplify credential encryption/decryption by using a single key and IV for all environments. Update crypto.js and .env.example files accordingly. * fix(ChatAgent.js): reduce maxAttempts from 2 to 1 feat(ChatAgent.js): add model information to responseMessage object feat(Message.js): add model field to messageSchema feat(Message.js): add model field to message object feat(Message.jsx): pass model information to getIcon function feat(getIcon.jsx): add Plugin component and handle plugin messages differently * feat(askGPTPlugins.js): add model property to the ask function response object feat(EndpointItem.jsx): add message property to the EndpointItem component feat(MessageHeader.jsx): add Plugin icon to the plugins section feat(MessageHeader.jsx): change alpha to beta in the plugins section feat(svg): add Plugin, GPTIcon, and BingIcon components to the svg folder refactor(EndpointItems.jsx): remove unused import statement * refactor(googleSearch.js, wolfram.js): change error handling to return a message instead of throwing an error * refactor(CustomAgent): remove commented code and change return object to include returnValues property * feat(CustomAgent.js): add currentDateString to createPrompt method options deps(api/package.json): update langchain to v0.0.81 * fix: do not show pagination if the maxPage is 1 * Add Zapier back to manifest (accidentally removed) * chore(api): update langchain dependency to version 0.0.84 * feat(DALL-E.js): add DALL-E tool for generating images using OpenAI's DALL-E API refactor(handleTools.js): update import for DALL-E tool refactor(index.test.js): update import for DALL-E tool refactor(stablediffusion.js): add check for image directory existence before saving image * refactor(CustomAgent): rename instructions prefix variable to gpt3 and add gpt4 instructions feat(CustomAgent): add support for gpt-4 model fix(initializeCustomAgent.js): pass model name to createPrompt method fix(outputParser.js): set selectedTool to 'self-reflection' when tool parsing fails * style(langchain/tools): update guidelines for image creation in DALL-E and StableDiffusion - Update guidelines for image creation in DALL-E and StableDiffusion tools - Emphasize the importance of "showing" and not "telling" the imagery in crafting input - Update formatting for the example prompt for generating a realistic portrait photo of a man - Generate images only once per human query unless explicitly requested by the user * docs(tools): update tool descriptions for DALL-E and Stable Diffusion - Update the description for DALL-E tool to indicate that it is exclusively for visual content and provide guidelines for generating images with a focus on visual attributes. - Update the description for Stable Diffusion tool to indicate that it is exclusively for visual content and provide guidelines for generating images with a focus on visual attributes. * chore(api): update "@waylaidwanderer/chatgpt-api" dependency to version "^1.36.3" * refactor(ChatAgent.js): use environment variable for reverse proxy url refactor(ChatAgent.js): use environment variable for openai base path refactor(instructions.js): update gpt3 and gpt3-v2 instructions refactor(outputParser.js): update finishToolNameRegex in CustomOutputParser class * refactor(DALL-E.js): change apiKey and azureKey fields to uppercase refactor(googleSearch.js): change cx and apiKey fields to uppercase feat(manifest.json): add authConfig field for Stable Diffusion WebUI API URL refactor(stablediffusion.js): add url field to constructor and change getServerURL() to this.url refactor(wolfram.js): change apiKey field to uppercase WOLFRAM_APP_ID * refactor(handleTools.js): simplify tool loading and add support for custom tool constructors and options * refactor(handleTools.js): remove commented out code and unused imports * refactor(handleTools.js, index.js): change file name from wolfram.js to Wolfram.js and selfReflection.js to SelfReflection.js to follow PascalCase convention * refactor(outputParser.js, askGPTPlugins.js): improve code readability and remove unnecessary comments * feat(GoogleSearch.js): add GoogleSearchAPI tool to allow agents to use the Google Custom Search API feat(SelfReflection.js): add SelfReflectionTool to allow agents to reflect on their thoughts and actions feat(StableDiffusion.js): add StableDiffusionAPI tool to allow agents to generate images using stable diffusion webui's api feat(Wolfram.js): add WolframAlphaAPI tool for computation, math, curated knowledge & real-time data through WolframAlpha. * testing openai specs * doc: fix link in .env.example * package-update * fix(MultiSelectDropDown.jsx): handle null or undefined values in availableValues array * refactor(DALL-E.js, StableDiffusion.js): remove 'dist/' from image path feat(docker-compose.yml): add comments for reverse proxy configuration * chore(.gitignore): ignore client/public/images/ fix(DALL-E.js, StableDiffusion.js): change image path from dist/ to public/ feat(index.js): add support for serving static files from client/public/ directory * fix: remove selected tool when uninstalled * plugin options in progress * fix: fix issue with uninstalling a plugin that is in use and typescript errors * feat(gptPlugins): add Preset support for GPT Plugins endpoint feat(ChatAgent.js): add support for agentOptions object feat(convoSchema.js): add agentOptions field to conversation schema feat(defaults.js): add agentOptions object to defaults feat(presetSchema.js): add agentOptions field to preset schema feat(askGPTPlugins.js): add support for agentOptions object in request body feat(EditPresetDialog.jsx): add support for showing/hiding GPT Plugins agent settings feat(EditPresetDialog.jsx): add support for setting GPT Plugins agent options fix(EndpointOptionsDialog.jsx): change endpoint name from 'gptPlugins' to 'Plugins' feat(AgentSettings.jsx): add AgentSettings component for GPT plugins configuration feat(client): add GPT Plugins settings component and endpoint to Settings component fix(client): remove unused imports in GoogleOptions component feat(PluginsOptions): add support for agent settings and refactor code feat(PluginsOptions): add GPTIcon to show/hide agent settings button feat(index.ts): export SVG components feat(GPTIcon.jsx): add className prop to GPTIcon component feat(GPTIcon.jsx): import cn function from utils feat(BingIcon.tsx): export BingIcon component feat(index.ts): export BingIcon component feat(index.ts): export MessagesSquared component refactor(cleanupPreset.js): add default values for agentOptions in gptPlugins endpoint feat(getDefaultConversation.js, handleSubmit.js): add agentOptions object to conversation object for GPT plugins endpoint. Update default temperature value to 0.8. Add chatGptLabel and promptPrefix properties to conversation object. * fix: set default convo back to null * refactor(ChatAgent.js, askGPTPlugins.js, AgentSettings.jsx): change variable names for better readability and remove redundant code * test: add RecoilRoot to layout-test-utils * refactor(askGPTPlugins.js): remove redundant code and use endpointOption directly feat(askGPTPlugins.js): add validation for tools in endpointOption before using it * chore(ChatAgent.js, Settings.jsx): add agentOptions to saveConvo function and adjust Settings component height The ChatAgent.js file was modified to include the agentOptions object in the saveConvo function. The Settings.jsx file was modified to adjust the height of the component to ensure that all content is visible. * refactor(ChatAgent.js): extract reverseProxyUrl option to a class property and add support for it feat(ChatAgent.js): add support for completionMode option in sendApiMessage method feat(ChatAgent.js): add support for user-provided promptPrefix in buildPrompt method * feat(plugins): allow preset change mid conversation * chore: update OPENAI_KEY to OPENAI_API_KEY in .github/playwright.yml and api/.env.example refactor(chatgpt-client.js): update OPENAI_KEY to OPENAI_API_KEY feat(langchain): add demo-aiplugin.js and demo-yaml.js, remove test2.js, test3.js, and test4.js chore: remove unused test files fix(titleConvo.js): fix typo in environment variable name fix(askGPTPlugins.js): fix typo in environment variable name fix(endpoints.js): fix typo in environment variable name docs: update installation guide to use OPENAI_API_KEY instead of OPENAI_KEY in .env file * fix(index.test.js): change import of GoogleSearchAPI to use uppercase G in GoogleSearch * chore(api): bump langchain version * feat(PluginController.js): authenticate plugins from environment variables if they are set feat(PluginStoreDialog.tsx): show plugin auth form only if plugin is not authenticated by env var and require authentication feat(types.ts): add authenticated field to TPlugin type definition * docs: update google_search.md and add stable_diffusion.md * Update stable_diffusion.md * refactor(Wolfram.js): remove newline characters from query before encoding docs(wolfram.md): add instructions for setting WOLFRAM_APP_ID in api.env to bypass prompt for AppID in plugin * refactor(Wolfram.js): replace deprecated replaceAll method with replace method * Update wolfram.md * fix(askGPTPlugins): error message will reference correct Parent Message * refactor(chatgpt-client.js, ChatAgent.js): simplify maxContextTokens calculation and add promptPrefix parameter to buildPrompt method * docs: initial draft of intro to plugins * Update introduction.md * Update introduction.md * Feature: User/Reg cleanup + Install / Upgrade script for langchain (#427) * test: login tests * test: finish login tests * test: initial tests for registration * test: registration specs * feature: Init a app config file - Simplifies the ENV vars too - Legacy fallbacks for older builds * refactor(auth): Refactor log in/out controllers - Moves both login and logout controllers to their own file * chore(jwt): Throw warning if secret is default * feature(frontend): Ability to disable registration * feature(env): Env in the root + version support ie .env.prod, .env.dev, .env.test * feature: Upgrade .env script for users * chore(config): Refactor and remove legacy env refs * feature(upgrade): Upgrade script for .env changes * feature: Install script and upgrade script * bugfix: Uncomment line to remove old .env file * chore: rename OPENAI_KEY to OPENAI_API_KEY * chore: Cleanup config changes/bugs * bugfix: Fix config and node env issues * bugfix: Config validation logic * bugfix: Handle unusual env configs gracefully * bugfix: Revert route changes and fix registration disable calling * bugfix: Fix env issues in frontend * bugfix: Fix login * bugfix: Fix frontend envs * bugfix: Fix frontend jest tests * bugfix: Fix upgrade scripts * bugfix: Allow install in non-tty envs * bugfix(windows): Use cross-env to set for windows * bugfix(env): Handle .env being incorrect to begin with for client domain * chore(merge-conflict): Update to LibreChat * chore(merge-conflict): Update to package-lock --------- Co-authored-by: Daniel D Orlando <dan@danorlando.com> * chore: comment out unused agent options * Update langchain plugins docs (#461) * Update: install docs (LibreChat) (#458) * Release: rename project from ChatGPT Clone to LibreChat Release: rename project from ChatGPT Clone to LibreChat * Release: rename project from ChatGPT Clone to LibreChat Release: rename project from ChatGPT Clone to LibreChat * Release: rename project from ChatGPT Clone to LibreChat Release: rename project from ChatGPT Clone to LibreChat * Release: rename project from ChatGPT Clone to LibreChat Release: rename project from ChatGPT Clone to LibreChat * Update documentation_guidelines.md * Update introduction.md add link to readme * Update stable_diffusion.md add link back to readme * Update wolfram.md add link back to readme * Update README.md add Plugins to ToC * feat(ChatAgent.js): add support for langchainProxy configuration option Add a new configuration option `langchainProxy` to the ChatAgent class. If the option is set, the `basePath` configuration option of the `ChatOpenAI` instance is set to the base path of `langchainProxy`. * bugfix(errors): Possible workaround for error flashing (#463) * Test/user auth system client tests (#462) * test: login tests * test: finish login tests * test: initial tests for registration * test: registration specs * chore(api): update langchain dependency to version 0.0.91 * Update introduction.md * Update introduction.md * Update introduction.md * fix: no longer renders html in markdown content fix: patch XSS vulnerability completely by handling cursor on the frontend without css/html * fix(Content.jsx): fix cursor logic so it never shows for static messages * bugfix(langchain): Upgrade script, docker, env and docs (#465) * bugfix(errors): Remove incorrect manual fix from misunderstanding * chore(env): Lets not make a .env.prod and use the prod values in the default root .env - .env.dev will still be created * chore(upgrade.js): Lets tell the user about .env.dev if we create it * bugfix(env): Move to full name environments for vite - .env.prod => .env.production - .env.dev => .env.development * chore(env-example): Explain how to get google login working in production * bugfix(oauth): Minor fix to point isProduction to a correct value * bugfix: Typo in public * chore(docs): Update docs to note the changes to .env * chore(docs): Include note on how to get google auth working in dev and how to disable registration * bugfix: Fix missing env changes * bugfix: Fix up docker to work with new env / npm changes * Update .env.example Cleanup the env of the palm2 instruction and fix to formating * chore(docker): Simplify Docker deployments - Needs work to support dev env/hotreload * bugfix: Remove volume map for client dir * chore(env-example): Change instructions to be more user centric --------- Co-authored-by: Fuegovic <32828263+fuegovic@users.noreply.github.com> * update: install docs (#466) * Add files via upload * Update apis-and-tokens.md * Update apis-and-tokens.md * Update docker_install.md * Update linux_install.md * Rename apis-and-tokens.md to apis_and_tokens.md * Update docker_install.md * Update linux_install.md * Update mac_install.md * Update linux_install.md * Update docker_install.md * Update windows_install.md * Update apis_and_tokens.md * Update mac_install.md * Update linux_install.md * Update docker_install.md * Update README.md * Update README.md : Breaking Changes --------- Co-authored-by: Danny Avila <110412045+danny-avila@users.noreply.github.com> * Update README.md (#468) add new API/Token docs to Toc * docs: guide on how to create your own plugin * Update make_your_own.md * Update make_your_own.md * feat(docker): add build args for frontend variables in Dockerfile feat(docker-compose): add build args for frontend variables in docker-compose.yml * Update docker_install.md * Update docker_install.md * Update docker_install.md * Update docker_install.md * docs: update (#469) * Update: make_your_own.md * Update README.md add `make_your_own.md` to ToC * Update linux_install.md * Update mac_install.md * Update windows_install.md * Update apis_and_tokens.md * Update docker_install.md * Update docker_install.md * Update linux_install.md * Update mac_install.md * Update windows_install.md * Update apis_and_tokens.md * Update user_auth_system.md * Update docker_install.md clean up of repeated information * Update docker_install.md * Update docker_install.md typo * fix: fix issue with pluginstore next and prev buttons going out of bounds * fix: add icon for web browser plugin * docs(GoogleSearch.js): update description of GoogleSearchAPI class to be more descriptive of its functionality * feat(ask/handlers.js): add cursor to indicate ongoing progress of a long-running task fix(Content.jsx): handle null content in the message stream by replacing it with an empty string (with a space so a text space is rendered) * Update README.md * Update README.md * fix: plugin option stacking order * update: web browser icon (#470) * Delete web-browser.png * update: web browser icon * Update readme (#472) * Update README.md Discord badge now displays the number of online users Project description has been updated to reflect current status Feature section has been updated to reflect current capabilities Sponsors section is now located just above the contributors section Roadmap has been removed as it was outdated. * Delete roadmap.md Roadmap has been removed to streamline document maintenance. * Update README.md * Update README.md * Delete CHANGELOG.md * fix: pluginstore in mobile view getting clipped and not scrolling * docs(linux_install.md): remove duplicate git clone command * chore(Dockerfile): comment out nginx-client build stage docs(README.md): update installation instructions and mention docker-compose changes docs(features/plugins/introduction.md): bold plugin names and add emphasis to notes * feat: add superscript and subscript support to markdown rendering refactor: support markdown citations for BingAI * refactor: support markdown citations for BingAI --------- Co-authored-by: David Shin <42793498+dncc89@users.noreply.github.com> Co-authored-by: Daniel D Orlando <dan@danorlando.com> Co-authored-by: LaraClara <2524209+ClaraLeigh@users.noreply.github.com> Co-authored-by: Fuegovic <32828263+fuegovic@users.noreply.github.com>
2023-06-10 19:10:03 -04:00
};