🔀 refactor: Conditional Mapping Support for Multi-Convo (Parallel) Messages (#11180)
Some checks are pending
Docker Dev Branch Images Build / build (Dockerfile, lc-dev, node) (push) Waiting to run
Docker Dev Branch Images Build / build (Dockerfile.multi, lc-dev-api, api-build) (push) Waiting to run
Docker Dev Images Build / build (Dockerfile, librechat-dev, node) (push) Waiting to run
Docker Dev Images Build / build (Dockerfile.multi, librechat-dev-api, api-build) (push) Waiting to run
Sync Locize Translations & Create Translation PR / Sync Translation Keys with Locize (push) Waiting to run
Sync Locize Translations & Create Translation PR / Create Translation PR on Version Published (push) Blocked by required conditions

* refactor: message handling with addedConvo support

- Introduced `addedConvo` property in message schema to track conversation additions.
- Updated `BaseClient` to conditionally include `addedConvo` in saved messages based on request body.
- Enhanced `AgentClient` to apply mapping logic for messages with the `addedConvo` flag, improving message processing.
- Updated documentation to reflect new optional `mapCondition` parameter for message mapping functions, enhancing flexibility in message handling.

* test: Add comprehensive tests for getMessagesForConversation method

- Introduced a suite of tests for the `getMessagesForConversation` method in the `AgentClient` to validate mapping logic based on `mapMethod` and `mapCondition`.
- Covered various scenarios including applying mapping to all messages, conditional mapping based on `addedConvo`, handling of empty messages, and preserving message order.
- Ensured robust handling of edge cases such as null `mapMethod` and undefined `mapCondition`, enhancing overall test coverage and reliability of message processing.
This commit is contained in:
Danny Avila 2026-01-02 19:42:54 -05:00 committed by GitHub
parent b94388ce9d
commit e452c1a8d9
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 235 additions and 11 deletions

View file

@ -938,6 +938,7 @@ class BaseClient {
throw new Error('User mismatch.');
}
const hasAddedConvo = this.options?.req?.body?.addedConvo != null;
const savedMessage = await saveMessage(
this.options?.req,
{
@ -945,6 +946,7 @@ class BaseClient {
endpoint: this.options.endpoint,
unfinished: false,
user,
...(hasAddedConvo && { addedConvo: true }),
},
{ context: 'api/app/clients/BaseClient.js - saveMessageToDatabase #saveMessage' },
);
@ -1025,7 +1027,8 @@ class BaseClient {
* @param {Object} options - The options for the function.
* @param {TMessage[]} options.messages - An array of message objects. Each object should have either an 'id' or 'messageId' property, and may have a 'parentMessageId' property.
* @param {string} options.parentMessageId - The ID of the parent message to start the traversal from.
* @param {Function} [options.mapMethod] - An optional function to map over the ordered messages. If provided, it will be applied to each message in the resulting array.
* @param {Function} [options.mapMethod] - An optional function to map over the ordered messages. Applied conditionally based on mapCondition.
* @param {(message: TMessage) => boolean} [options.mapCondition] - An optional function to determine whether mapMethod should be applied to a given message. If not provided and mapMethod is set, mapMethod applies to all messages.
* @param {boolean} [options.summary=false] - If set to true, the traversal modifies messages with 'summary' and 'summaryTokenCount' properties and stops at the message with a 'summary' property.
* @returns {TMessage[]} An array containing the messages in the order they should be displayed, starting with the most recent message with a 'summary' property if the 'summary' option is true, and ending with the message identified by 'parentMessageId'.
*/
@ -1033,6 +1036,7 @@ class BaseClient {
messages,
parentMessageId,
mapMethod = null,
mapCondition = null,
summary = false,
}) {
if (!messages || messages.length === 0) {
@ -1067,7 +1071,9 @@ class BaseClient {
message.tokenCount = message.summaryTokenCount;
}
orderedMessages.push(message);
const shouldMap = mapMethod != null && (mapCondition != null ? mapCondition(message) : true);
const processedMessage = shouldMap ? mapMethod(message) : message;
orderedMessages.push(processedMessage);
if (summary && message.summary) {
break;
@ -1078,11 +1084,6 @@ class BaseClient {
}
orderedMessages.reverse();
if (mapMethod) {
return orderedMessages.map(mapMethod);
}
return orderedMessages;
}