* Powerpoint File Creation (#5278) * wip * download card * UI for downloading * move to fs system with endpoint to pull files * refactor UI * final-pass * remove save-file-browser skill and refactor * remove fileDownload event * reset * reset file * reset timeout * persist toggle * Txt creation (#5279) * wip * download card * UI for downloading * move to fs system with endpoint to pull files * refactor UI * final-pass * remove save-file-browser skill and refactor * remove fileDownload event * reset * reset file * reset timeout * wip * persist toggle * add arbitrary text creation file * Add PDF document generation with markdown formatting (#5283) add support for branding in bottom right corner refactor core utils and frontend rendering * Xlsx document creation (#5284) add Excel doc & sheet creation * Basic docx creation (#5285) * Basic docx creation * add test theme support + styling and title pages * simplify skill selection * handle TG attachments * send documents over tg * lazy import * pin deps * fix lock * i18n for file creation (#5286) i18n for file-creation connect #5280 * theme overhaul * Add PPTX subagent for better results * forgot files * Add PPTX subagent for better results (#5287) * Add PPTX subagent for better results * forgot files * make sub-agent use proper tool calling if it can and better UI hints
110 lines
3.9 KiB
JavaScript
110 lines
3.9 KiB
JavaScript
const { WorkspaceChats } = require("../../../../models/workspaceChats");
|
|
|
|
/**
|
|
* Plugin to save chat history to AnythingLLM DB.
|
|
*/
|
|
const chatHistory = {
|
|
name: "chat-history",
|
|
startupConfig: {
|
|
params: {},
|
|
},
|
|
plugin: function () {
|
|
return {
|
|
name: this.name,
|
|
setup: function (aibitat) {
|
|
aibitat.onMessage(async () => {
|
|
try {
|
|
const lastResponses = aibitat.chats.slice(-2);
|
|
if (lastResponses.length !== 2) return;
|
|
const [prev, last] = lastResponses;
|
|
|
|
// We need a full conversation reply with prev being from
|
|
// the USER and the last being from anyone other than the user.
|
|
if (prev.from !== "USER" || last.from === "USER") return;
|
|
|
|
// Extract attachments from user message if present
|
|
const attachments = prev.attachments || [];
|
|
|
|
// If we have a post-reply flow we should save the chat using this special flow
|
|
// so that post save cleanup and other unique properties can be run as opposed to regular chat.
|
|
if (aibitat.hasOwnProperty("_replySpecialAttributes")) {
|
|
await this._storeSpecial(aibitat, {
|
|
prompt: prev.content,
|
|
response: last.content,
|
|
attachments,
|
|
options: aibitat._replySpecialAttributes,
|
|
});
|
|
delete aibitat._replySpecialAttributes;
|
|
return;
|
|
}
|
|
|
|
await this._store(aibitat, {
|
|
prompt: prev.content,
|
|
response: last.content,
|
|
attachments,
|
|
});
|
|
} catch {}
|
|
});
|
|
},
|
|
_store: async function (
|
|
aibitat,
|
|
{ prompt, response, attachments = [] } = {}
|
|
) {
|
|
const invocation = aibitat.handlerProps.invocation;
|
|
const metrics = aibitat.provider?.getUsage?.() ?? {};
|
|
const citations = aibitat._pendingCitations ?? [];
|
|
const outputs = aibitat._pendingOutputs ?? [];
|
|
await WorkspaceChats.new({
|
|
workspaceId: Number(invocation.workspace_id),
|
|
prompt,
|
|
response: {
|
|
text: response,
|
|
sources: citations,
|
|
type: "chat",
|
|
attachments,
|
|
metrics,
|
|
...(outputs.length > 0 ? { outputs } : {}),
|
|
},
|
|
user: { id: invocation?.user_id || null },
|
|
threadId: invocation?.thread_id || null,
|
|
});
|
|
aibitat.clearCitations?.();
|
|
aibitat._pendingOutputs = [];
|
|
},
|
|
_storeSpecial: async function (
|
|
aibitat,
|
|
{ prompt, response, attachments = [], options = {} } = {}
|
|
) {
|
|
const invocation = aibitat.handlerProps.invocation;
|
|
const metrics = aibitat.provider?.getUsage?.() ?? {};
|
|
const citations = aibitat._pendingCitations ?? [];
|
|
const outputs = aibitat._pendingOutputs ?? [];
|
|
const existingSources = options?.sources ?? [];
|
|
await WorkspaceChats.new({
|
|
workspaceId: Number(invocation.workspace_id),
|
|
prompt,
|
|
response: {
|
|
sources: [...existingSources, ...citations],
|
|
// when we have a _storeSpecial called the options param can include a storedResponse() function
|
|
// that will override the text property to store extra information in, depending on the special type of chat.
|
|
text: options.hasOwnProperty("storedResponse")
|
|
? options.storedResponse(response)
|
|
: response,
|
|
type: options?.saveAsType ?? "chat",
|
|
attachments,
|
|
metrics,
|
|
...(outputs.length > 0 ? { outputs } : {}),
|
|
},
|
|
user: { id: invocation?.user_id || null },
|
|
threadId: invocation?.thread_id || null,
|
|
});
|
|
aibitat.clearCitations?.();
|
|
aibitat._pendingOutputs = [];
|
|
options?.postSave();
|
|
},
|
|
};
|
|
},
|
|
};
|
|
|
|
module.exports = { chatHistory };
|