feat: integrate mempalace
This commit is contained in:
@@ -31405,6 +31405,11 @@ var ChatView = class extends import_obsidian.ItemView {
|
|||||||
...additionalFiles
|
...additionalFiles
|
||||||
].filter((f, i, arr) => arr.findIndex((x) => x.path === f.path) === i);
|
].filter((f, i, arr) => arr.findIndex((x) => x.path === f.path) === i);
|
||||||
const contextNotes = contextFiles.map((f) => f.path);
|
const contextNotes = contextFiles.map((f) => f.path);
|
||||||
|
let mpContext = "";
|
||||||
|
if (this.plugin.settings.useMempalace && query.trim()) {
|
||||||
|
this.setStatus("MemPalace wird abgefragt\u2026");
|
||||||
|
mpContext = await this.queryMempalace(query);
|
||||||
|
}
|
||||||
let contextText = "";
|
let contextText = "";
|
||||||
if (contextFiles.length > 0) {
|
if (contextFiles.length > 0) {
|
||||||
this.setStatus(`Lade ${contextFiles.length} Notizen\u2026`);
|
this.setStatus(`Lade ${contextFiles.length} Notizen\u2026`);
|
||||||
@@ -31417,6 +31422,8 @@ ${content}`;
|
|||||||
);
|
);
|
||||||
contextText = "\n\n---\nKontext aus dem Vault:\n\n" + contents.join("\n\n");
|
contextText = "\n\n---\nKontext aus dem Vault:\n\n" + contents.join("\n\n");
|
||||||
}
|
}
|
||||||
|
if (mpContext)
|
||||||
|
contextText = mpContext + contextText;
|
||||||
const userMsg = {
|
const userMsg = {
|
||||||
role: "user",
|
role: "user",
|
||||||
content: query,
|
content: query,
|
||||||
@@ -32045,6 +32052,29 @@ tags: [chat]
|
|||||||
this.renderHistoryList(listEl);
|
this.renderHistoryList(listEl);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/** Query the MemPalace CLI and return formatted context, or "" on error/timeout/not-installed. */
|
||||||
|
async queryMempalace(query) {
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
const { execFile } = require("child_process");
|
||||||
|
const { existsSync } = require("fs");
|
||||||
|
if (!existsSync("/usr/local/bin/mempalace")) {
|
||||||
|
resolve("");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
execFile(
|
||||||
|
"/usr/local/bin/mempalace",
|
||||||
|
["search", query, "--results", String(this.plugin.settings.mempalaceResults ?? 3)],
|
||||||
|
{ timeout: 1e4 },
|
||||||
|
(err, stdout) => {
|
||||||
|
if (err || !stdout?.trim()) {
|
||||||
|
resolve("");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
resolve("\n\n---\nMemPalace (Wissens-Archiv):\n\n" + stdout.trim());
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
renderHistoryList(listEl) {
|
renderHistoryList(listEl) {
|
||||||
listEl.empty();
|
listEl.empty();
|
||||||
if (this.historyThreads.length === 0) {
|
if (this.historyThreads.length === 0) {
|
||||||
@@ -32894,6 +32924,8 @@ Wenn du Fragen beantwortest:
|
|||||||
useEmbeddings: false,
|
useEmbeddings: false,
|
||||||
embeddingModel: "TaylorAI/bge-micro-v2",
|
embeddingModel: "TaylorAI/bge-micro-v2",
|
||||||
embedExcludeFolders: [],
|
embedExcludeFolders: [],
|
||||||
|
useMempalace: false,
|
||||||
|
mempalaceResults: 3,
|
||||||
promptButtons: [
|
promptButtons: [
|
||||||
{
|
{
|
||||||
label: "Draft Check",
|
label: "Draft Check",
|
||||||
@@ -33077,6 +33109,23 @@ var MemexChatSettingsTab = class extends import_obsidian3.PluginSettingTab {
|
|||||||
addExclFolder(exclInput.value);
|
addExclFolder(exclInput.value);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
containerEl.createEl("h3", { text: "MemPalace" });
|
||||||
|
containerEl.createEl("p", {
|
||||||
|
text: "Reichert jeden Chat mit Ergebnissen aus dem MemPalace-Wissensarchiv an (ben\xF6tigt /usr/local/bin/mempalace).",
|
||||||
|
cls: "setting-item-description"
|
||||||
|
});
|
||||||
|
new import_obsidian3.Setting(containerEl).setName("MemPalace aktivieren").setDesc("F\xFChrt bei jeder Nachricht eine MemPalace-Suche durch und f\xFCgt die Ergebnisse als Kontext ein.").addToggle(
|
||||||
|
(toggle) => toggle.setValue(this.plugin.settings.useMempalace).onChange(async (value) => {
|
||||||
|
this.plugin.settings.useMempalace = value;
|
||||||
|
await this.plugin.saveSettings();
|
||||||
|
})
|
||||||
|
);
|
||||||
|
new import_obsidian3.Setting(containerEl).setName("Anzahl MemPalace-Ergebnisse").setDesc("Wie viele Treffer aus dem MemPalace-Archiv pro Anfrage eingebunden werden (1\u201310).").addSlider(
|
||||||
|
(slider) => slider.setLimits(1, 10, 1).setValue(this.plugin.settings.mempalaceResults).setDynamicTooltip().onChange(async (value) => {
|
||||||
|
this.plugin.settings.mempalaceResults = value;
|
||||||
|
await this.plugin.saveSettings();
|
||||||
|
})
|
||||||
|
);
|
||||||
containerEl.createEl("h3", { text: "Kontext-Einstellungen" });
|
containerEl.createEl("h3", { text: "Kontext-Einstellungen" });
|
||||||
new import_obsidian3.Setting(containerEl).setName("Max. Kontext-Notizen").setDesc("Wie viele Notizen werden automatisch als Kontext hinzugef\xFCgt? (1\u201315)").addSlider(
|
new import_obsidian3.Setting(containerEl).setName("Max. Kontext-Notizen").setDesc("Wie viele Notizen werden automatisch als Kontext hinzugef\xFCgt? (1\u201315)").addSlider(
|
||||||
(slider) => slider.setLimits(1, 15, 1).setValue(this.plugin.settings.maxContextNotes).setDynamicTooltip().onChange(async (value) => {
|
(slider) => slider.setLimits(1, 15, 1).setValue(this.plugin.settings.maxContextNotes).setDynamicTooltip().onChange(async (value) => {
|
||||||
|
|||||||
+31
-1
@@ -357,7 +357,14 @@ export class ChatView extends ItemView {
|
|||||||
|
|
||||||
const contextNotes = contextFiles.map((f) => f.path);
|
const contextNotes = contextFiles.map((f) => f.path);
|
||||||
|
|
||||||
// Build context text
|
// MemPalace context (queried first — prepended so it appears closest to the query)
|
||||||
|
let mpContext = "";
|
||||||
|
if (this.plugin.settings.useMempalace && query.trim()) {
|
||||||
|
this.setStatus("MemPalace wird abgefragt…");
|
||||||
|
mpContext = await this.queryMempalace(query);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build vault context text
|
||||||
let contextText = "";
|
let contextText = "";
|
||||||
if (contextFiles.length > 0) {
|
if (contextFiles.length > 0) {
|
||||||
this.setStatus(`Lade ${contextFiles.length} Notizen…`);
|
this.setStatus(`Lade ${contextFiles.length} Notizen…`);
|
||||||
@@ -370,6 +377,9 @@ export class ChatView extends ItemView {
|
|||||||
contextText = "\n\n---\nKontext aus dem Vault:\n\n" + contents.join("\n\n");
|
contextText = "\n\n---\nKontext aus dem Vault:\n\n" + contents.join("\n\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MemPalace results precede vault notes (higher priority = closer to the query)
|
||||||
|
if (mpContext) contextText = mpContext + contextText;
|
||||||
|
|
||||||
// Add user message
|
// Add user message
|
||||||
const userMsg: ChatMessage = {
|
const userMsg: ChatMessage = {
|
||||||
role: "user",
|
role: "user",
|
||||||
@@ -1087,6 +1097,26 @@ export class ChatView extends ItemView {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Query the MemPalace CLI and return formatted context, or "" on error/timeout/not-installed. */
|
||||||
|
private async queryMempalace(query: string): Promise<string> {
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||||
|
const { execFile } = require("child_process") as typeof import("child_process");
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||||
|
const { existsSync } = require("fs") as typeof import("fs");
|
||||||
|
if (!existsSync("/usr/local/bin/mempalace")) { resolve(""); return; }
|
||||||
|
execFile(
|
||||||
|
"/usr/local/bin/mempalace",
|
||||||
|
["search", query, "--results", String(this.plugin.settings.mempalaceResults ?? 3)],
|
||||||
|
{ timeout: 10_000 },
|
||||||
|
(err: Error | null, stdout: string) => {
|
||||||
|
if (err || !stdout?.trim()) { resolve(""); return; }
|
||||||
|
resolve("\n\n---\nMemPalace (Wissens-Archiv):\n\n" + stdout.trim());
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
private renderHistoryList(listEl: HTMLElement): void {
|
private renderHistoryList(listEl: HTMLElement): void {
|
||||||
listEl.empty();
|
listEl.empty();
|
||||||
if (this.historyThreads.length === 0) {
|
if (this.historyThreads.length === 0) {
|
||||||
|
|||||||
@@ -28,6 +28,8 @@ export interface MemexChatSettings {
|
|||||||
useEmbeddings: boolean; // use local embedding model instead of TF-IDF
|
useEmbeddings: boolean; // use local embedding model instead of TF-IDF
|
||||||
embeddingModel: string; // HuggingFace model ID
|
embeddingModel: string; // HuggingFace model ID
|
||||||
embedExcludeFolders: string[]; // vault folders to skip during embedding
|
embedExcludeFolders: string[]; // vault folders to skip during embedding
|
||||||
|
useMempalace: boolean; // inject MemPalace search results as additional context
|
||||||
|
mempalaceResults: number; // number of MemPalace results to include
|
||||||
}
|
}
|
||||||
|
|
||||||
export const DEFAULT_SETTINGS: MemexChatSettings = {
|
export const DEFAULT_SETTINGS: MemexChatSettings = {
|
||||||
@@ -54,6 +56,8 @@ Wenn du Fragen beantwortest:
|
|||||||
useEmbeddings: false,
|
useEmbeddings: false,
|
||||||
embeddingModel: "TaylorAI/bge-micro-v2",
|
embeddingModel: "TaylorAI/bge-micro-v2",
|
||||||
embedExcludeFolders: [],
|
embedExcludeFolders: [],
|
||||||
|
useMempalace: false,
|
||||||
|
mempalaceResults: 3,
|
||||||
promptButtons: [
|
promptButtons: [
|
||||||
{
|
{
|
||||||
label: "Draft Check",
|
label: "Draft Check",
|
||||||
@@ -284,6 +288,37 @@ export class MemexChatSettingsTab extends PluginSettingTab {
|
|||||||
if (e.key === "Enter") { e.preventDefault(); addExclFolder(exclInput.value); }
|
if (e.key === "Enter") { e.preventDefault(); addExclFolder(exclInput.value); }
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// --- MemPalace ---
|
||||||
|
containerEl.createEl("h3", { text: "MemPalace" });
|
||||||
|
containerEl.createEl("p", {
|
||||||
|
text: "Reichert jeden Chat mit Ergebnissen aus dem MemPalace-Wissensarchiv an (benötigt /usr/local/bin/mempalace).",
|
||||||
|
cls: "setting-item-description",
|
||||||
|
});
|
||||||
|
|
||||||
|
new Setting(containerEl)
|
||||||
|
.setName("MemPalace aktivieren")
|
||||||
|
.setDesc("Führt bei jeder Nachricht eine MemPalace-Suche durch und fügt die Ergebnisse als Kontext ein.")
|
||||||
|
.addToggle((toggle) =>
|
||||||
|
toggle.setValue(this.plugin.settings.useMempalace).onChange(async (value) => {
|
||||||
|
this.plugin.settings.useMempalace = value;
|
||||||
|
await this.plugin.saveSettings();
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
new Setting(containerEl)
|
||||||
|
.setName("Anzahl MemPalace-Ergebnisse")
|
||||||
|
.setDesc("Wie viele Treffer aus dem MemPalace-Archiv pro Anfrage eingebunden werden (1–10).")
|
||||||
|
.addSlider((slider) =>
|
||||||
|
slider
|
||||||
|
.setLimits(1, 10, 1)
|
||||||
|
.setValue(this.plugin.settings.mempalaceResults)
|
||||||
|
.setDynamicTooltip()
|
||||||
|
.onChange(async (value) => {
|
||||||
|
this.plugin.settings.mempalaceResults = value;
|
||||||
|
await this.plugin.saveSettings();
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
// --- Context ---
|
// --- Context ---
|
||||||
containerEl.createEl("h3", { text: "Kontext-Einstellungen" });
|
containerEl.createEl("h3", { text: "Kontext-Einstellungen" });
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user