mirror of
https://github.com/danny-avila/LibreChat.git
synced 2025-12-17 00:40:14 +01:00
⌚ feat: Add Current Datetime to Assistants (v1/v2) (#4952)
* Feature: Added ability to send current date and time to v1 and v2 assistants * remove date_feature.patch * fix: rename append_today_date to append_current_datetime * feat: Refactor time handling in chatV1 and chatV2, add date and time utility functions * fix: Add warning log and response for missing run values in abortRun middleware --------- Co-authored-by: Max Sanna <max@maxsanna.com>
This commit is contained in:
parent
b5c9144127
commit
1dbe6ee75d
38 changed files with 378 additions and 67 deletions
|
|
@ -1,5 +1,6 @@
|
|||
const { v4 } = require('uuid');
|
||||
const {
|
||||
Time,
|
||||
Constants,
|
||||
RunStatus,
|
||||
CacheKeys,
|
||||
|
|
@ -24,6 +25,7 @@ const validateAuthor = require('~/server/middleware/assistants/validateAuthor');
|
|||
const { formatMessage, createVisionPrompt } = require('~/app/clients/prompts');
|
||||
const { createRun, StreamRunManager } = require('~/server/services/Runs');
|
||||
const { addTitle } = require('~/server/services/Endpoints/assistants');
|
||||
const { createRunBody } = require('~/server/services/createRunBody');
|
||||
const { getTransactions } = require('~/models/Transaction');
|
||||
const checkBalance = require('~/models/checkBalance');
|
||||
const { getConvo } = require('~/models/Conversation');
|
||||
|
|
@ -32,8 +34,6 @@ const { getModelMaxTokens } = require('~/utils');
|
|||
const { getOpenAIClient } = require('./helpers');
|
||||
const { logger } = require('~/config');
|
||||
|
||||
const ten_minutes = 1000 * 60 * 10;
|
||||
|
||||
/**
|
||||
* @route POST /
|
||||
* @desc Chat with an assistant
|
||||
|
|
@ -59,6 +59,7 @@ const chatV1 = async (req, res) => {
|
|||
messageId: _messageId,
|
||||
conversationId: convoId,
|
||||
parentMessageId: _parentId = Constants.NO_PARENT,
|
||||
clientTimestamp,
|
||||
} = req.body;
|
||||
|
||||
/** @type {OpenAIClient} */
|
||||
|
|
@ -304,24 +305,14 @@ const chatV1 = async (req, res) => {
|
|||
};
|
||||
|
||||
/** @type {CreateRunBody | undefined} */
|
||||
const body = {
|
||||
const body = createRunBody({
|
||||
assistant_id,
|
||||
model,
|
||||
};
|
||||
|
||||
if (promptPrefix) {
|
||||
body.additional_instructions = promptPrefix;
|
||||
}
|
||||
|
||||
if (typeof endpointOption.artifactsPrompt === 'string' && endpointOption.artifactsPrompt) {
|
||||
body.additional_instructions = `${body.additional_instructions ?? ''}\n${
|
||||
endpointOption.artifactsPrompt
|
||||
}`.trim();
|
||||
}
|
||||
|
||||
if (instructions) {
|
||||
body.instructions = instructions;
|
||||
}
|
||||
promptPrefix,
|
||||
instructions,
|
||||
endpointOption,
|
||||
clientTimestamp,
|
||||
});
|
||||
|
||||
const getRequestFileIds = async () => {
|
||||
let thread_file_ids = [];
|
||||
|
|
@ -518,7 +509,7 @@ const chatV1 = async (req, res) => {
|
|||
});
|
||||
|
||||
run_id = run.id;
|
||||
await cache.set(cacheKey, `${thread_id}:${run_id}`, ten_minutes);
|
||||
await cache.set(cacheKey, `${thread_id}:${run_id}`, Time.TEN_MINUTES);
|
||||
sendInitialResponse();
|
||||
|
||||
// todo: retry logic
|
||||
|
|
@ -529,7 +520,7 @@ const chatV1 = async (req, res) => {
|
|||
/** @type {{[AssistantStreamEvents.ThreadRunCreated]: (event: ThreadRunCreated) => Promise<void>}} */
|
||||
const handlers = {
|
||||
[AssistantStreamEvents.ThreadRunCreated]: async (event) => {
|
||||
await cache.set(cacheKey, `${thread_id}:${event.data.id}`, ten_minutes);
|
||||
await cache.set(cacheKey, `${thread_id}:${event.data.id}`, Time.TEN_MINUTES);
|
||||
run_id = event.data.id;
|
||||
sendInitialResponse();
|
||||
},
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ const { createErrorHandler } = require('~/server/controllers/assistants/errors')
|
|||
const validateAuthor = require('~/server/middleware/assistants/validateAuthor');
|
||||
const { createRun, StreamRunManager } = require('~/server/services/Runs');
|
||||
const { addTitle } = require('~/server/services/Endpoints/assistants');
|
||||
const { createRunBody } = require('~/server/services/createRunBody');
|
||||
const { getTransactions } = require('~/models/Transaction');
|
||||
const checkBalance = require('~/models/checkBalance');
|
||||
const { getConvo } = require('~/models/Conversation');
|
||||
|
|
@ -31,8 +32,6 @@ const { getModelMaxTokens } = require('~/utils');
|
|||
const { getOpenAIClient } = require('./helpers');
|
||||
const { logger } = require('~/config');
|
||||
|
||||
const ten_minutes = 1000 * 60 * 10;
|
||||
|
||||
/**
|
||||
* @route POST /
|
||||
* @desc Chat with an assistant
|
||||
|
|
@ -58,6 +57,7 @@ const chatV2 = async (req, res) => {
|
|||
messageId: _messageId,
|
||||
conversationId: convoId,
|
||||
parentMessageId: _parentId = Constants.NO_PARENT,
|
||||
clientTimestamp,
|
||||
} = req.body;
|
||||
|
||||
/** @type {OpenAIClient} */
|
||||
|
|
@ -186,22 +186,14 @@ const chatV2 = async (req, res) => {
|
|||
};
|
||||
|
||||
/** @type {CreateRunBody | undefined} */
|
||||
const body = {
|
||||
const body = createRunBody({
|
||||
assistant_id,
|
||||
model,
|
||||
};
|
||||
|
||||
if (promptPrefix) {
|
||||
body.additional_instructions = promptPrefix;
|
||||
}
|
||||
|
||||
if (typeof endpointOption.artifactsPrompt === 'string' && endpointOption.artifactsPrompt) {
|
||||
body.additional_instructions = `${body.additional_instructions ?? ''}\n${endpointOption.artifactsPrompt}`.trim();
|
||||
}
|
||||
|
||||
if (instructions) {
|
||||
body.instructions = instructions;
|
||||
}
|
||||
promptPrefix,
|
||||
instructions,
|
||||
endpointOption,
|
||||
clientTimestamp,
|
||||
});
|
||||
|
||||
const getRequestFileIds = async () => {
|
||||
let thread_file_ids = [];
|
||||
|
|
@ -361,7 +353,7 @@ const chatV2 = async (req, res) => {
|
|||
});
|
||||
|
||||
run_id = run.id;
|
||||
await cache.set(cacheKey, `${thread_id}:${run_id}`, ten_minutes);
|
||||
await cache.set(cacheKey, `${thread_id}:${run_id}`, Time.TEN_MINUTES);
|
||||
sendInitialResponse();
|
||||
|
||||
// todo: retry logic
|
||||
|
|
@ -372,7 +364,7 @@ const chatV2 = async (req, res) => {
|
|||
/** @type {{[AssistantStreamEvents.ThreadRunCreated]: (event: ThreadRunCreated) => Promise<void>}} */
|
||||
const handlers = {
|
||||
[AssistantStreamEvents.ThreadRunCreated]: async (event) => {
|
||||
await cache.set(cacheKey, `${thread_id}:${event.data.id}`, ten_minutes);
|
||||
await cache.set(cacheKey, `${thread_id}:${event.data.id}`, Time.TEN_MINUTES);
|
||||
run_id = event.data.id;
|
||||
sendInitialResponse();
|
||||
},
|
||||
|
|
|
|||
|
|
@ -19,8 +19,15 @@ const createAssistant = async (req, res) => {
|
|||
try {
|
||||
const { openai } = await getOpenAIClient({ req, res });
|
||||
|
||||
const { tools = [], endpoint, conversation_starters, ...assistantData } = req.body;
|
||||
const {
|
||||
tools = [],
|
||||
endpoint,
|
||||
conversation_starters,
|
||||
append_current_datetime,
|
||||
...assistantData
|
||||
} = req.body;
|
||||
delete assistantData.conversation_starters;
|
||||
delete assistantData.append_current_datetime;
|
||||
|
||||
assistantData.tools = tools
|
||||
.map((tool) => {
|
||||
|
|
@ -49,6 +56,9 @@ const createAssistant = async (req, res) => {
|
|||
if (conversation_starters) {
|
||||
createData.conversation_starters = conversation_starters;
|
||||
}
|
||||
if (append_current_datetime !== undefined) {
|
||||
createData.append_current_datetime = append_current_datetime;
|
||||
}
|
||||
|
||||
const document = await updateAssistantDoc({ assistant_id: assistant.id }, createData);
|
||||
|
||||
|
|
@ -60,6 +70,10 @@ const createAssistant = async (req, res) => {
|
|||
assistant.conversation_starters = document.conversation_starters;
|
||||
}
|
||||
|
||||
if (append_current_datetime !== undefined) {
|
||||
assistant.append_current_datetime = append_current_datetime;
|
||||
}
|
||||
|
||||
logger.debug('/assistants/', assistant);
|
||||
res.status(201).json(assistant);
|
||||
} catch (error) {
|
||||
|
|
@ -102,7 +116,12 @@ const patchAssistant = async (req, res) => {
|
|||
await validateAuthor({ req, openai });
|
||||
|
||||
const assistant_id = req.params.id;
|
||||
const { endpoint: _e, conversation_starters, ...updateData } = req.body;
|
||||
const {
|
||||
endpoint: _e,
|
||||
conversation_starters,
|
||||
append_current_datetime,
|
||||
...updateData
|
||||
} = req.body;
|
||||
updateData.tools = (updateData.tools ?? [])
|
||||
.map((tool) => {
|
||||
if (typeof tool !== 'string') {
|
||||
|
|
@ -127,6 +146,11 @@ const patchAssistant = async (req, res) => {
|
|||
updatedAssistant.conversation_starters = conversationStartersUpdate.conversation_starters;
|
||||
}
|
||||
|
||||
if (append_current_datetime !== undefined) {
|
||||
await updateAssistantDoc({ assistant_id }, { append_current_datetime });
|
||||
updatedAssistant.append_current_datetime = append_current_datetime;
|
||||
}
|
||||
|
||||
res.json(updatedAssistant);
|
||||
} catch (error) {
|
||||
logger.error('[/assistants/:id] Error updating assistant', error);
|
||||
|
|
@ -219,6 +243,7 @@ const getAssistantDocuments = async (req, res) => {
|
|||
conversation_starters: 1,
|
||||
createdAt: 1,
|
||||
updatedAt: 1,
|
||||
append_current_datetime: 1,
|
||||
},
|
||||
);
|
||||
|
||||
|
|
|
|||
|
|
@ -16,8 +16,15 @@ const createAssistant = async (req, res) => {
|
|||
/** @type {{ openai: OpenAIClient }} */
|
||||
const { openai } = await getOpenAIClient({ req, res });
|
||||
|
||||
const { tools = [], endpoint, conversation_starters, ...assistantData } = req.body;
|
||||
const {
|
||||
tools = [],
|
||||
endpoint,
|
||||
conversation_starters,
|
||||
append_current_datetime,
|
||||
...assistantData
|
||||
} = req.body;
|
||||
delete assistantData.conversation_starters;
|
||||
delete assistantData.append_current_datetime;
|
||||
|
||||
assistantData.tools = tools
|
||||
.map((tool) => {
|
||||
|
|
@ -46,6 +53,9 @@ const createAssistant = async (req, res) => {
|
|||
if (conversation_starters) {
|
||||
createData.conversation_starters = conversation_starters;
|
||||
}
|
||||
if (append_current_datetime !== undefined) {
|
||||
createData.append_current_datetime = append_current_datetime;
|
||||
}
|
||||
|
||||
const document = await updateAssistantDoc({ assistant_id: assistant.id }, createData);
|
||||
|
||||
|
|
@ -56,6 +66,9 @@ const createAssistant = async (req, res) => {
|
|||
if (document.conversation_starters) {
|
||||
assistant.conversation_starters = document.conversation_starters;
|
||||
}
|
||||
if (append_current_datetime !== undefined) {
|
||||
assistant.append_current_datetime = append_current_datetime;
|
||||
}
|
||||
|
||||
logger.debug('/assistants/', assistant);
|
||||
res.status(201).json(assistant);
|
||||
|
|
@ -89,6 +102,14 @@ const updateAssistant = async ({ req, openai, assistant_id, updateData }) => {
|
|||
delete updateData.conversation_starters;
|
||||
}
|
||||
|
||||
if (updateData?.append_current_datetime !== undefined) {
|
||||
await updateAssistantDoc(
|
||||
{ assistant_id: assistant_id },
|
||||
{ append_current_datetime: updateData.append_current_datetime },
|
||||
);
|
||||
delete updateData.append_current_datetime;
|
||||
}
|
||||
|
||||
let hasFileSearch = false;
|
||||
for (const tool of updateData.tools ?? []) {
|
||||
let actualTool = typeof tool === 'string' ? req.app.locals.availableTools[tool] : tool;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue