mirror of
https://github.com/zadam/trilium.git
synced 2026-06-26 02:00:06 +02:00
148 lines
4.1 KiB
TypeScript
148 lines
4.1 KiB
TypeScript
import { SaveLlmChatResponse } from "@triliumnext/commons";
|
|
import { t } from "i18next";
|
|
|
|
import becca from "../becca/becca.js";
|
|
import dateNoteService from "./date_notes.js";
|
|
import dateUtils from "./date_utils.js";
|
|
import hoistedNoteService from "./hoisted_note.js";
|
|
import noteService from "./notes.js";
|
|
import SearchContext from "./search/search_context.js";
|
|
import searchService from "./search/services/search.js";
|
|
|
|
function createLlmChat() {
|
|
const { note } = noteService.createNewNote({
|
|
parentNoteId: getMonthlyParentNoteId("_llmChat", "llmChat"),
|
|
title: `${t("special_notes.llm_chat_prefix")} ${dateUtils.localNowDateTime()}`,
|
|
content: JSON.stringify({
|
|
version: 1,
|
|
messages: []
|
|
}),
|
|
type: "llmChat",
|
|
mime: "application/json"
|
|
});
|
|
|
|
note.setLabel("iconClass", "bx bx-message-square-dots");
|
|
note.setLabel("keepCurrentHoisting");
|
|
|
|
return note;
|
|
}
|
|
|
|
/**
|
|
* Gets the most recently modified LLM chat note.
|
|
* Used by sidebar chat to persist conversation across page refreshes.
|
|
* Returns null if no chat exists.
|
|
*/
|
|
function getMostRecentLlmChat() {
|
|
// Search for all llmChat notes and return the most recently modified
|
|
const results = searchService.searchNotes(
|
|
"note.type = llmChat",
|
|
new SearchContext({
|
|
ancestorNoteId: "_llmChat",
|
|
limit: 1,
|
|
orderBy: "utcDateModified",
|
|
orderDirection: "desc"
|
|
})
|
|
);
|
|
|
|
return results.length > 0 ? results[0] : null;
|
|
}
|
|
|
|
/**
|
|
* Gets the most recent LLM chat or creates a new one if none exists.
|
|
* Used by sidebar chat for persistent conversations.
|
|
*/
|
|
function getOrCreateLlmChat() {
|
|
const existingChat = getMostRecentLlmChat();
|
|
|
|
if (existingChat) {
|
|
return existingChat;
|
|
}
|
|
|
|
return createLlmChat();
|
|
}
|
|
|
|
/**
|
|
* Gets a list of recent LLM chat notes.
|
|
* Used by sidebar chat history popup.
|
|
*/
|
|
function getRecentLlmChats(limit: number = 10) {
|
|
const results = searchService.searchNotes(
|
|
"note.type = llmChat",
|
|
new SearchContext({
|
|
ancestorNoteId: "_llmChat",
|
|
limit,
|
|
orderBy: "utcDateModified",
|
|
orderDirection: "desc"
|
|
})
|
|
);
|
|
|
|
return results.map(note => ({
|
|
noteId: note.noteId,
|
|
title: note.title,
|
|
dateModified: note.utcDateModified
|
|
}));
|
|
}
|
|
|
|
function getLlmChatHome() {
|
|
const workspaceNote = hoistedNoteService.getWorkspaceNote();
|
|
if (!workspaceNote) {
|
|
throw new Error("Unable to find workspace note");
|
|
}
|
|
|
|
if (!workspaceNote.isRoot()) {
|
|
return workspaceNote.searchNoteInSubtree("#workspaceLlmChatHome") || workspaceNote.searchNoteInSubtree("#llmChatHome") || workspaceNote;
|
|
}
|
|
const today = dateUtils.localNowDate();
|
|
|
|
return workspaceNote.searchNoteInSubtree("#llmChatHome") || dateNoteService.getDayNote(today);
|
|
|
|
}
|
|
|
|
function saveLlmChat(llmChatNoteId: string | null) {
|
|
const llmChatNote = becca.getNote(llmChatNoteId);
|
|
if (!llmChatNote) {
|
|
throw new Error(`Unable to find LLM chat note ID: ${llmChatNoteId}`);
|
|
}
|
|
|
|
const llmChatHome = getLlmChatHome();
|
|
|
|
const result = llmChatNote.cloneTo(llmChatHome.noteId);
|
|
|
|
for (const parentBranch of llmChatNote.getParentBranches()) {
|
|
if (parentBranch.parentNote?.hasAncestor("_hidden")) {
|
|
parentBranch.markAsDeleted();
|
|
}
|
|
}
|
|
|
|
return result satisfies SaveLlmChatResponse;
|
|
}
|
|
|
|
function getMonthlyParentNoteId(rootNoteId: string, prefix: string) {
|
|
const month = dateUtils.localNowDate().substring(0, 7);
|
|
const labelName = `${prefix}MonthNote`;
|
|
|
|
let monthNote = searchService.findFirstNoteWithQuery(`#${labelName}="${month}"`, new SearchContext({ ancestorNoteId: rootNoteId }));
|
|
|
|
if (!monthNote) {
|
|
monthNote = noteService.createNewNote({
|
|
parentNoteId: rootNoteId,
|
|
title: month,
|
|
content: "",
|
|
isProtected: false,
|
|
type: "book"
|
|
}).note;
|
|
|
|
monthNote.addLabel(labelName, month);
|
|
}
|
|
|
|
return monthNote.noteId;
|
|
}
|
|
|
|
export default {
|
|
createLlmChat,
|
|
getMostRecentLlmChat,
|
|
getOrCreateLlmChat,
|
|
getRecentLlmChats,
|
|
saveLlmChat,
|
|
};
|