mirror of
https://github.com/zadam/trilium.git
synced 2026-06-27 18:07:51 +02:00
feat(llm): API to create LLM notes similar to search
This commit is contained in:
@@ -84,6 +84,14 @@ async function createSearchNote(opts = {}) {
|
||||
return await froca.getNote(note.noteId);
|
||||
}
|
||||
|
||||
async function createLlmChat() {
|
||||
const note = await server.post<FNoteRow>("special-notes/llm-chat");
|
||||
|
||||
await ws.waitForMaxKnownEntityChangeId();
|
||||
|
||||
return await froca.getNote(note.noteId);
|
||||
}
|
||||
|
||||
export default {
|
||||
getInboxNote,
|
||||
getTodayNote,
|
||||
@@ -94,5 +102,6 @@ export default {
|
||||
getMonthNote,
|
||||
getYearNote,
|
||||
createSqlConsole,
|
||||
createSearchNote
|
||||
createSearchNote,
|
||||
createLlmChat
|
||||
};
|
||||
|
||||
@@ -297,7 +297,8 @@
|
||||
},
|
||||
"quarterNumber": "Quarter {quarterNumber}",
|
||||
"special_notes": {
|
||||
"search_prefix": "Search:"
|
||||
"search_prefix": "Search:",
|
||||
"llm_chat_prefix": "Chat:"
|
||||
},
|
||||
"test_sync": {
|
||||
"not-configured": "Sync server host is not configured. Please configure sync first.",
|
||||
@@ -308,6 +309,7 @@
|
||||
"search-history-title": "Search History",
|
||||
"note-map-title": "Note Map",
|
||||
"sql-console-history-title": "SQL Console History",
|
||||
"llm-chat-history-title": "AI Chat History",
|
||||
"shared-notes-title": "Shared Notes",
|
||||
"bulk-action-title": "Bulk Action",
|
||||
"backend-log-title": "Backend Log",
|
||||
|
||||
@@ -86,6 +86,14 @@ function createSearchNote(req: Request) {
|
||||
return specialNotesService.createSearchNote(searchString, ancestorNoteId);
|
||||
}
|
||||
|
||||
function createLlmChat() {
|
||||
return specialNotesService.createLlmChat();
|
||||
}
|
||||
|
||||
function saveLlmChat(req: Request) {
|
||||
return specialNotesService.saveLlmChat(req.body.llmChatNoteId);
|
||||
}
|
||||
|
||||
function getHoistedNote() {
|
||||
return becca.getNote(cls.getHoistedNoteId());
|
||||
}
|
||||
@@ -119,6 +127,8 @@ export default {
|
||||
saveSqlConsole,
|
||||
createSearchNote,
|
||||
saveSearchNote,
|
||||
createLlmChat,
|
||||
saveLlmChat,
|
||||
createLauncher,
|
||||
resetLauncher,
|
||||
createOrUpdateScriptLauncherFromApi
|
||||
|
||||
@@ -292,6 +292,8 @@ function register(app: express.Application) {
|
||||
asyncApiRoute(PST, "/api/special-notes/save-sql-console", specialNotesRoute.saveSqlConsole);
|
||||
apiRoute(PST, "/api/special-notes/search-note", specialNotesRoute.createSearchNote);
|
||||
apiRoute(PST, "/api/special-notes/save-search-note", specialNotesRoute.saveSearchNote);
|
||||
apiRoute(PST, "/api/special-notes/llm-chat", specialNotesRoute.createLlmChat);
|
||||
apiRoute(PST, "/api/special-notes/save-llm-chat", specialNotesRoute.saveLlmChat);
|
||||
apiRoute(PST, "/api/special-notes/launchers/:noteId/reset", specialNotesRoute.resetLauncher);
|
||||
apiRoute(PST, "/api/special-notes/launchers/:parentNoteId/:launcherType", specialNotesRoute.createLauncher);
|
||||
apiRoute(PUT, "/api/special-notes/api-script-launcher", specialNotesRoute.createOrUpdateScriptLauncherFromApi);
|
||||
|
||||
@@ -66,6 +66,12 @@ function buildHiddenSubtreeDefinition(helpSubtree: HiddenSubtreeItem[]): HiddenS
|
||||
type: "doc",
|
||||
icon: "bx-data"
|
||||
},
|
||||
{
|
||||
id: "_llmChat",
|
||||
title: t("hidden-subtree.llm-chat-history-title"),
|
||||
type: "doc",
|
||||
icon: "bx-message-square-dots"
|
||||
},
|
||||
{
|
||||
id: "_share",
|
||||
title: t("hidden-subtree.shared-notes-title"),
|
||||
|
||||
@@ -10,7 +10,7 @@ import SearchContext from "./search/search_context.js";
|
||||
import { LBTPL_NOTE_LAUNCHER, LBTPL_CUSTOM_WIDGET, LBTPL_SPACER, LBTPL_SCRIPT } from "./hidden_subtree.js";
|
||||
import { t } from "i18next";
|
||||
import BNote from '../becca/entities/bnote.js';
|
||||
import { SaveSearchNoteResponse, SaveSqlConsoleResponse } from "@triliumnext/commons";
|
||||
import { SaveSearchNoteResponse, SaveSqlConsoleResponse, SaveLlmChatResponse } from "@triliumnext/commons";
|
||||
|
||||
function getInboxNote(date: string) {
|
||||
const workspaceNote = hoistedNoteService.getWorkspaceNote();
|
||||
@@ -123,6 +123,58 @@ function saveSearchNote(searchNoteId: string) {
|
||||
return result satisfies SaveSearchNoteResponse;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
} else {
|
||||
const today = dateUtils.localNowDate();
|
||||
|
||||
return workspaceNote.searchNoteInSubtree("#llmChatHome") || dateNoteService.getDayNote(today);
|
||||
}
|
||||
}
|
||||
|
||||
function saveLlmChat(llmChatNoteId: string) {
|
||||
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`;
|
||||
@@ -282,6 +334,8 @@ export default {
|
||||
saveSqlConsole,
|
||||
createSearchNote,
|
||||
saveSearchNote,
|
||||
createLlmChat,
|
||||
saveLlmChat,
|
||||
createLauncher,
|
||||
resetLauncher,
|
||||
createOrUpdateScriptLauncherFromApi
|
||||
|
||||
@@ -214,6 +214,8 @@ export interface ConvertAttachmentToNoteResponse {
|
||||
|
||||
export type SaveSqlConsoleResponse = CloneResponse;
|
||||
|
||||
export type SaveLlmChatResponse = CloneResponse;
|
||||
|
||||
export interface BacklinkCountResponse {
|
||||
count: number;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user