mirror of
https://github.com/Youzini-afk/ST-Bionic-Memory-Ecology.git
synced 2026-05-15 22:30:38 +08:00
refactor: move graph import flow into ui actions controller
This commit is contained in:
99
index.js
99
index.js
@@ -79,6 +79,7 @@ import {
|
||||
onFetchEmbeddingModelsController,
|
||||
onFetchMemoryLLMModelsController,
|
||||
onExportGraphController,
|
||||
onImportGraphController,
|
||||
onManualCompressController,
|
||||
onRebuildController,
|
||||
onTestEmbeddingController,
|
||||
@@ -4545,82 +4546,28 @@ async function onExportGraph() {
|
||||
}
|
||||
|
||||
async function onImportGraph() {
|
||||
if (!ensureGraphMutationReady("导入图谱")) {
|
||||
return { cancelled: true };
|
||||
}
|
||||
const input = document.createElement("input");
|
||||
input.type = "file";
|
||||
input.accept = ".json";
|
||||
return await new Promise((resolve, reject) => {
|
||||
let settled = false;
|
||||
let focusTimer = null;
|
||||
|
||||
const cleanup = () => {
|
||||
if (focusTimer) {
|
||||
clearTimeout(focusTimer);
|
||||
focusTimer = null;
|
||||
}
|
||||
input.onchange = null;
|
||||
window.removeEventListener("focus", onWindowFocus, true);
|
||||
};
|
||||
|
||||
const finish = (value, isError = false) => {
|
||||
if (settled) return;
|
||||
settled = true;
|
||||
cleanup();
|
||||
if (isError) {
|
||||
reject(value);
|
||||
} else {
|
||||
resolve(value);
|
||||
}
|
||||
};
|
||||
|
||||
const onWindowFocus = () => {
|
||||
focusTimer = setTimeout(() => {
|
||||
if (!settled) {
|
||||
finish({ cancelled: true });
|
||||
}
|
||||
}, 180);
|
||||
};
|
||||
|
||||
window.addEventListener("focus", onWindowFocus, true);
|
||||
input.addEventListener(
|
||||
"cancel",
|
||||
() => {
|
||||
finish({ cancelled: true });
|
||||
},
|
||||
{ once: true },
|
||||
);
|
||||
input.onchange = async (e) => {
|
||||
const file = e.target.files?.[0];
|
||||
if (!file) {
|
||||
finish({ cancelled: true });
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const text = await file.text();
|
||||
currentGraph = normalizeGraphRuntimeState(
|
||||
importGraph(text),
|
||||
getCurrentChatId(),
|
||||
);
|
||||
markVectorStateDirty("导入图谱后需要重建向量索引");
|
||||
extractionCount = 0;
|
||||
lastExtractedItems = [];
|
||||
updateLastRecalledItems(currentGraph.lastRecallResult || []);
|
||||
clearInjectionState();
|
||||
saveGraphToChat({ reason: "graph-import-complete" });
|
||||
toastr.success("图谱已导入");
|
||||
finish({ imported: true, handledToast: true });
|
||||
} catch (err) {
|
||||
const error =
|
||||
err instanceof Error ? err : new Error(String(err || "导入失败"));
|
||||
toastr.error(`导入失败: ${error.message}`);
|
||||
error._stBmeToastHandled = true;
|
||||
finish(error, true);
|
||||
}
|
||||
};
|
||||
input.click();
|
||||
return await onImportGraphController({
|
||||
clearInjectionState,
|
||||
clearTimeout,
|
||||
document,
|
||||
ensureGraphMutationReady,
|
||||
getCurrentChatId,
|
||||
importGraph,
|
||||
markVectorStateDirty,
|
||||
normalizeGraphRuntimeState,
|
||||
saveGraphToChat,
|
||||
setCurrentGraph: (graph) => {
|
||||
currentGraph = graph;
|
||||
},
|
||||
setExtractionCount: (value) => {
|
||||
extractionCount = value;
|
||||
},
|
||||
setLastExtractedItems: (items) => {
|
||||
lastExtractedItems = items;
|
||||
},
|
||||
toastr,
|
||||
updateLastRecalledItems,
|
||||
window,
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -245,3 +245,88 @@ export async function onRebuildController(runtime) {
|
||||
runtime.refreshPanelLiveState();
|
||||
}
|
||||
}
|
||||
|
||||
export async function onImportGraphController(runtime) {
|
||||
if (!runtime.ensureGraphMutationReady("导入图谱")) {
|
||||
return { cancelled: true };
|
||||
}
|
||||
|
||||
const input = runtime.document.createElement("input");
|
||||
input.type = "file";
|
||||
input.accept = ".json";
|
||||
|
||||
return await new Promise((resolve, reject) => {
|
||||
let settled = false;
|
||||
let focusTimer = null;
|
||||
|
||||
const cleanup = () => {
|
||||
if (focusTimer) {
|
||||
runtime.clearTimeout(focusTimer);
|
||||
focusTimer = null;
|
||||
}
|
||||
input.onchange = null;
|
||||
runtime.window.removeEventListener("focus", onWindowFocus, true);
|
||||
};
|
||||
|
||||
const finish = (value, isError = false) => {
|
||||
if (settled) return;
|
||||
settled = true;
|
||||
cleanup();
|
||||
if (isError) {
|
||||
reject(value);
|
||||
} else {
|
||||
resolve(value);
|
||||
}
|
||||
};
|
||||
|
||||
const onWindowFocus = () => {
|
||||
focusTimer = setTimeout(() => {
|
||||
if (!settled) {
|
||||
finish({ cancelled: true });
|
||||
}
|
||||
}, 180);
|
||||
};
|
||||
|
||||
runtime.window.addEventListener("focus", onWindowFocus, true);
|
||||
input.addEventListener(
|
||||
"cancel",
|
||||
() => {
|
||||
finish({ cancelled: true });
|
||||
},
|
||||
{ once: true },
|
||||
);
|
||||
|
||||
input.onchange = async (event) => {
|
||||
const file = event.target.files?.[0];
|
||||
if (!file) {
|
||||
finish({ cancelled: true });
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const text = await file.text();
|
||||
const importedGraph = runtime.normalizeGraphRuntimeState(
|
||||
runtime.importGraph(text),
|
||||
runtime.getCurrentChatId(),
|
||||
);
|
||||
runtime.setCurrentGraph(importedGraph);
|
||||
runtime.markVectorStateDirty("导入图谱后需要重建向量索引");
|
||||
runtime.setExtractionCount(0);
|
||||
runtime.setLastExtractedItems([]);
|
||||
runtime.updateLastRecalledItems(importedGraph.lastRecallResult || []);
|
||||
runtime.clearInjectionState();
|
||||
runtime.saveGraphToChat({ reason: "graph-import-complete" });
|
||||
runtime.toastr.success("图谱已导入");
|
||||
finish({ imported: true, handledToast: true });
|
||||
} catch (err) {
|
||||
const error =
|
||||
err instanceof Error ? err : new Error(String(err || "导入失败"));
|
||||
runtime.toastr.error(`导入失败: ${error.message}`);
|
||||
error._stBmeToastHandled = true;
|
||||
finish(error, true);
|
||||
}
|
||||
};
|
||||
|
||||
input.click();
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user