2023-12-14 07:49:27 -05:00
|
|
|
const _ = require('lodash');
|
2023-03-22 19:52:38 -04:00
|
|
|
const mongoose = require('mongoose');
|
2023-03-22 01:31:01 -04:00
|
|
|
const { MeiliSearch } = require('meilisearch');
|
2023-12-14 07:49:27 -05:00
|
|
|
const { cleanUpPrimaryKeyValue } = require('~/lib/utils/misc');
|
|
|
|
const logger = require('~/config/meiliLogger');
|
|
|
|
|
2023-07-08 11:41:51 -04:00
|
|
|
const searchEnabled = process.env.SEARCH && process.env.SEARCH.toLowerCase() === 'true';
|
|
|
|
const meiliEnabled = process.env.MEILI_HOST && process.env.MEILI_MASTER_KEY && searchEnabled;
|
2023-03-22 01:31:01 -04:00
|
|
|
|
|
|
|
const validateOptions = function (options) {
|
|
|
|
const requiredKeys = ['host', 'apiKey', 'indexName'];
|
|
|
|
requiredKeys.forEach((key) => {
|
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
|
|
|
if (!options[key]) {
|
|
|
|
throw new Error(`Missing mongoMeili Option: ${key}`);
|
|
|
|
}
|
2023-03-22 01:31:01 -04:00
|
|
|
});
|
|
|
|
};
|
|
|
|
|
2023-07-28 11:46:15 -04:00
|
|
|
// const createMeiliMongooseModel = function ({ index, indexName, client, attributesToIndex }) {
|
|
|
|
const createMeiliMongooseModel = function ({ index, attributesToIndex }) {
|
2023-03-22 01:31:01 -04:00
|
|
|
const primaryKey = attributesToIndex[0];
|
|
|
|
// MeiliMongooseModel is of type Mongoose.Model
|
|
|
|
class MeiliMongooseModel {
|
2023-07-28 11:46:15 -04:00
|
|
|
/**
|
|
|
|
* `syncWithMeili`: synchronizes the data between a MongoDB collection and a MeiliSearch index,
|
|
|
|
* only triggered if there's ever a discrepancy determined by `api\lib\db\indexSync.js`.
|
|
|
|
*
|
|
|
|
* 1. Fetches all documents from the MongoDB collection and the MeiliSearch index.
|
|
|
|
* 2. Compares the documents from both sources.
|
|
|
|
* 3. If a document exists in MeiliSearch but not in MongoDB, it's deleted from MeiliSearch.
|
|
|
|
* 4. If a document exists in MongoDB but not in MeiliSearch, it's added to MeiliSearch.
|
|
|
|
* 5. If a document exists in both but has different `text` or `title` fields (depending on the `primaryKey`), it's updated in MeiliSearch.
|
|
|
|
* 6. After all operations, it updates the `_meiliIndex` field in MongoDB to indicate whether the document is indexed in MeiliSearch.
|
|
|
|
*
|
|
|
|
* Note: This strategy does not use batch operations for Meilisearch as the `index.addDocuments` will discard
|
|
|
|
* the entire batch if there's an error with one document, and will not throw an error if there's an issue.
|
|
|
|
* Also, `index.getDocuments` needs an exact limit on the amount of documents to return, so we build the map in batches.
|
|
|
|
*
|
|
|
|
* @returns {Promise} A promise that resolves when the synchronization is complete.
|
|
|
|
*
|
|
|
|
* @throws {Error} Throws an error if there's an issue with adding a document to MeiliSearch.
|
|
|
|
*/
|
2023-03-22 01:31:01 -04:00
|
|
|
static async syncWithMeili() {
|
2023-07-08 11:20:57 +09:00
|
|
|
try {
|
2023-07-28 11:46:15 -04:00
|
|
|
let moreDocuments = true;
|
|
|
|
const mongoDocuments = await this.find().lean();
|
|
|
|
const format = (doc) => _.pick(doc, attributesToIndex);
|
|
|
|
|
|
|
|
// Prepare for comparison
|
|
|
|
const mongoMap = new Map(mongoDocuments.map((doc) => [doc[primaryKey], format(doc)]));
|
|
|
|
const indexMap = new Map();
|
|
|
|
let offset = 0;
|
|
|
|
const batchSize = 1000;
|
|
|
|
|
|
|
|
while (moreDocuments) {
|
|
|
|
const batch = await index.getDocuments({ limit: batchSize, offset });
|
|
|
|
|
|
|
|
if (batch.results.length === 0) {
|
|
|
|
moreDocuments = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (const doc of batch.results) {
|
|
|
|
indexMap.set(doc[primaryKey], format(doc));
|
|
|
|
}
|
|
|
|
|
|
|
|
offset += batchSize;
|
|
|
|
}
|
|
|
|
|
2023-12-14 07:49:27 -05:00
|
|
|
logger.debug('[syncWithMeili]', { indexMap: indexMap.size, mongoMap: mongoMap.size });
|
2023-07-28 11:46:15 -04:00
|
|
|
|
|
|
|
const updateOps = [];
|
|
|
|
|
|
|
|
// Iterate over Meili index documents
|
|
|
|
for (const [id, doc] of indexMap) {
|
|
|
|
const update = {};
|
|
|
|
update[primaryKey] = id;
|
|
|
|
if (mongoMap.has(id)) {
|
|
|
|
// Case: Update
|
|
|
|
// If document also exists in MongoDB, would be update case
|
|
|
|
if (
|
|
|
|
(doc.text && doc.text !== mongoMap.get(id).text) ||
|
|
|
|
(doc.title && doc.title !== mongoMap.get(id).title)
|
|
|
|
) {
|
2023-12-14 07:49:27 -05:00
|
|
|
logger.debug(
|
|
|
|
`[syncWithMeili] ${id} had document discrepancy in ${
|
|
|
|
doc.text ? 'text' : 'title'
|
|
|
|
} field`,
|
|
|
|
);
|
2023-07-28 11:46:15 -04:00
|
|
|
updateOps.push({
|
|
|
|
updateOne: { filter: update, update: { $set: { _meiliIndex: true } } },
|
|
|
|
});
|
|
|
|
await index.addDocuments([doc]);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
// Case: Delete
|
|
|
|
// If document does not exist in MongoDB, its a delete case from meili index
|
|
|
|
await index.deleteDocument(id);
|
|
|
|
updateOps.push({
|
|
|
|
updateOne: { filter: update, update: { $set: { _meiliIndex: false } } },
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Iterate over MongoDB documents
|
|
|
|
for (const [id, doc] of mongoMap) {
|
|
|
|
const update = {};
|
|
|
|
update[primaryKey] = id;
|
|
|
|
// Case: Insert
|
|
|
|
// If document does not exist in Meili Index, Its an insert case
|
|
|
|
if (!indexMap.has(id)) {
|
|
|
|
await index.addDocuments([doc]);
|
|
|
|
updateOps.push({
|
|
|
|
updateOne: { filter: update, update: { $set: { _meiliIndex: true } } },
|
|
|
|
});
|
|
|
|
} else if (doc._meiliIndex === false) {
|
|
|
|
updateOps.push({
|
|
|
|
updateOne: { filter: update, update: { $set: { _meiliIndex: true } } },
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (updateOps.length > 0) {
|
|
|
|
await this.collection.bulkWrite(updateOps);
|
2023-12-14 07:49:27 -05:00
|
|
|
logger.debug(
|
|
|
|
`[syncWithMeili] Finished indexing ${
|
2023-07-28 12:13:16 -04:00
|
|
|
primaryKey === 'messageId' ? 'messages' : 'conversations'
|
|
|
|
}`,
|
2023-07-28 11:46:15 -04:00
|
|
|
);
|
|
|
|
}
|
2023-07-08 11:20:57 +09:00
|
|
|
} catch (error) {
|
2023-12-14 07:49:27 -05:00
|
|
|
logger.error('[syncWithMeili] Error adding document to Meili', error);
|
2023-07-08 11:20:57 +09:00
|
|
|
}
|
2023-03-22 01:31:01 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
// Set one or more settings of the meili index
|
|
|
|
static async setMeiliIndexSettings(settings) {
|
|
|
|
return await index.updateSettings(settings);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Search the index
|
|
|
|
static async meiliSearch(q, params, populate) {
|
|
|
|
const data = await index.search(q, params);
|
|
|
|
|
|
|
|
// Populate hits with content from mongodb
|
|
|
|
if (populate) {
|
|
|
|
// Find objects into mongodb matching `objectID` from Meili search
|
|
|
|
const query = {};
|
|
|
|
// query[primaryKey] = { $in: _.map(data.hits, primaryKey) };
|
2023-05-18 11:44:07 -07:00
|
|
|
query[primaryKey] = _.map(data.hits, (hit) => cleanUpPrimaryKeyValue(hit[primaryKey]));
|
2023-12-14 07:49:27 -05:00
|
|
|
// logger.debug('query', query);
|
2023-03-22 01:31:01 -04:00
|
|
|
const hitsFromMongoose = await this.find(
|
|
|
|
query,
|
|
|
|
_.reduce(
|
|
|
|
this.schema.obj,
|
|
|
|
function (results, value, key) {
|
|
|
|
return { ...results, [key]: 1 };
|
|
|
|
},
|
2023-07-14 09:36:49 -04:00
|
|
|
{ _id: 1 },
|
|
|
|
),
|
2023-07-28 13:16:41 -04:00
|
|
|
).lean();
|
2023-03-22 01:31:01 -04:00
|
|
|
|
|
|
|
// Add additional data from mongodb into Meili search hits
|
|
|
|
const populatedHits = data.hits.map(function (hit) {
|
|
|
|
const query = {};
|
|
|
|
query[primaryKey] = hit[primaryKey];
|
|
|
|
const originalHit = _.find(hitsFromMongoose, query);
|
|
|
|
|
|
|
|
return {
|
2023-07-28 13:16:41 -04:00
|
|
|
...(originalHit ?? {}),
|
2023-07-14 09:36:49 -04:00
|
|
|
...hit,
|
2023-03-22 01:31:01 -04:00
|
|
|
};
|
|
|
|
});
|
|
|
|
data.hits = populatedHits;
|
|
|
|
}
|
|
|
|
|
|
|
|
return data;
|
|
|
|
}
|
|
|
|
|
2023-07-08 11:20:57 +09:00
|
|
|
preprocessObjectForIndex() {
|
2023-03-22 01:31:01 -04:00
|
|
|
const object = _.pick(this.toJSON(), attributesToIndex);
|
|
|
|
// NOTE: MeiliSearch does not allow | in primary key, so we replace it with - for Bing convoIds
|
|
|
|
// object.conversationId = object.conversationId.replace(/\|/g, '-');
|
|
|
|
if (object.conversationId && object.conversationId.includes('|')) {
|
|
|
|
object.conversationId = object.conversationId.replace(/\|/g, '--');
|
|
|
|
}
|
✨ 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
|
|
|
|
|
|
|
if (object.content && Array.isArray(object.content)) {
|
|
|
|
object.text = object.content
|
|
|
|
.filter((item) => item.type === 'text' && item.text && item.text.value)
|
|
|
|
.map((item) => item.text.value)
|
|
|
|
.join(' ');
|
|
|
|
delete object.content;
|
|
|
|
}
|
|
|
|
|
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
|
|
|
return object;
|
2023-07-08 11:20:57 +09:00
|
|
|
}
|
2023-03-22 01:31:01 -04:00
|
|
|
|
2023-07-08 11:20:57 +09:00
|
|
|
// Push new document to Meili
|
|
|
|
async addObjectToMeili() {
|
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
|
|
|
const object = this.preprocessObjectForIndex();
|
2023-03-22 01:31:01 -04:00
|
|
|
try {
|
2023-12-14 07:49:27 -05:00
|
|
|
// logger.debug('Adding document to Meili', object);
|
2023-03-22 01:31:01 -04:00
|
|
|
await index.addDocuments([object]);
|
|
|
|
} catch (error) {
|
2023-12-14 07:49:27 -05:00
|
|
|
// logger.debug('Error adding document to Meili');
|
|
|
|
// logger.error(error);
|
2023-03-22 01:31:01 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
await this.collection.updateMany({ _id: this._id }, { $set: { _meiliIndex: true } });
|
|
|
|
}
|
|
|
|
|
|
|
|
// Update an existing document in Meili
|
|
|
|
async updateObjectToMeili() {
|
|
|
|
const object = _.pick(this.toJSON(), attributesToIndex);
|
|
|
|
await index.updateDocuments([object]);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Delete a document from Meili
|
|
|
|
async deleteObjectFromMeili() {
|
|
|
|
await index.deleteDocument(this._id);
|
|
|
|
}
|
|
|
|
|
|
|
|
// * schema.post('save')
|
|
|
|
postSaveHook() {
|
|
|
|
if (this._meiliIndex) {
|
|
|
|
this.updateObjectToMeili();
|
|
|
|
} else {
|
|
|
|
this.addObjectToMeili();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// * schema.post('update')
|
|
|
|
postUpdateHook() {
|
|
|
|
if (this._meiliIndex) {
|
|
|
|
this.updateObjectToMeili();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// * schema.post('remove')
|
|
|
|
postRemoveHook() {
|
|
|
|
if (this._meiliIndex) {
|
|
|
|
this.deleteObjectFromMeili();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return MeiliMongooseModel;
|
|
|
|
};
|
|
|
|
|
|
|
|
module.exports = function mongoMeili(schema, options) {
|
|
|
|
// Vaidate Options for mongoMeili
|
|
|
|
validateOptions(options);
|
|
|
|
|
|
|
|
// Add meiliIndex to schema
|
|
|
|
schema.add({
|
|
|
|
_meiliIndex: {
|
|
|
|
type: Boolean,
|
|
|
|
required: false,
|
|
|
|
select: false,
|
2023-07-14 09:36:49 -04:00
|
|
|
default: false,
|
|
|
|
},
|
2023-03-22 01:31:01 -04:00
|
|
|
});
|
|
|
|
|
|
|
|
const { host, apiKey, indexName, primaryKey } = options;
|
|
|
|
|
|
|
|
// Setup MeiliSearch Client
|
|
|
|
const client = new MeiliSearch({ host, apiKey });
|
|
|
|
|
|
|
|
// Asynchronously create the index
|
|
|
|
client.createIndex(indexName, { primaryKey });
|
|
|
|
|
|
|
|
// Setup the index to search for this schema
|
|
|
|
const index = client.index(indexName);
|
|
|
|
|
|
|
|
const attributesToIndex = [
|
|
|
|
..._.reduce(
|
|
|
|
schema.obj,
|
|
|
|
function (results, value, key) {
|
|
|
|
return value.meiliIndex ? [...results, key] : results;
|
|
|
|
// }, []), '_id'];
|
|
|
|
},
|
2023-07-14 09:36:49 -04:00
|
|
|
[],
|
|
|
|
),
|
2023-03-22 01:31:01 -04:00
|
|
|
];
|
|
|
|
|
|
|
|
schema.loadClass(createMeiliMongooseModel({ index, indexName, client, attributesToIndex }));
|
|
|
|
|
|
|
|
// Register hooks
|
|
|
|
schema.post('save', function (doc) {
|
|
|
|
doc.postSaveHook();
|
|
|
|
});
|
|
|
|
schema.post('update', function (doc) {
|
|
|
|
doc.postUpdateHook();
|
|
|
|
});
|
|
|
|
schema.post('remove', function (doc) {
|
|
|
|
doc.postRemoveHook();
|
|
|
|
});
|
2023-05-18 11:09:31 -07:00
|
|
|
|
2023-07-07 02:03:23 -04:00
|
|
|
schema.pre('deleteMany', async function (next) {
|
2023-07-08 11:41:51 -04:00
|
|
|
if (!meiliEnabled) {
|
|
|
|
next();
|
|
|
|
}
|
|
|
|
|
2023-07-07 02:03:23 -04:00
|
|
|
try {
|
|
|
|
if (Object.prototype.hasOwnProperty.call(schema.obj, 'messages')) {
|
|
|
|
const convoIndex = client.index('convos');
|
|
|
|
const deletedConvos = await mongoose.model('Conversation').find(this._conditions).lean();
|
|
|
|
let promises = [];
|
|
|
|
for (const convo of deletedConvos) {
|
|
|
|
promises.push(convoIndex.deleteDocument(convo.conversationId));
|
|
|
|
}
|
|
|
|
await Promise.all(promises);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (Object.prototype.hasOwnProperty.call(schema.obj, 'messageId')) {
|
|
|
|
const messageIndex = client.index('messages');
|
|
|
|
const deletedMessages = await mongoose.model('Message').find(this._conditions).lean();
|
|
|
|
let promises = [];
|
|
|
|
for (const message of deletedMessages) {
|
|
|
|
promises.push(messageIndex.deleteDocument(message.messageId));
|
|
|
|
}
|
|
|
|
await Promise.all(promises);
|
|
|
|
}
|
|
|
|
return next();
|
|
|
|
} catch (error) {
|
2023-07-08 11:41:51 -04:00
|
|
|
if (meiliEnabled) {
|
2023-12-14 07:49:27 -05:00
|
|
|
logger.error(
|
|
|
|
'[MeiliMongooseModel.deleteMany] There was an issue deleting conversation indexes upon deletion, next startup may be slow due to syncing',
|
|
|
|
error,
|
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
|
|
|
);
|
2023-07-08 11:41:51 -04:00
|
|
|
}
|
|
|
|
return next();
|
2023-03-22 19:52:38 -04:00
|
|
|
}
|
|
|
|
});
|
2023-07-07 02:03:23 -04:00
|
|
|
|
|
|
|
schema.post('findOneAndUpdate', async function (doc) {
|
2023-07-08 11:41:51 -04:00
|
|
|
if (!meiliEnabled) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2023-07-07 02:03:23 -04:00
|
|
|
if (doc.unfinished) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
let meiliDoc;
|
|
|
|
// Doc is a Conversation
|
|
|
|
if (doc.messages) {
|
|
|
|
try {
|
|
|
|
meiliDoc = await client.index('convos').getDocument(doc.conversationId);
|
|
|
|
} catch (error) {
|
2023-12-14 07:49:27 -05:00
|
|
|
logger.error(
|
|
|
|
'[MeiliMongooseModel.findOneAndUpdate] Convo not found in MeiliSearch and will index ' +
|
|
|
|
doc.conversationId,
|
|
|
|
error,
|
|
|
|
);
|
2023-07-07 02:03:23 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (meiliDoc && meiliDoc.title === doc.title) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2023-03-22 01:31:01 -04:00
|
|
|
doc.postSaveHook();
|
|
|
|
});
|
|
|
|
};
|