mirror of
https://github.com/Youzini-afk/ST-Bionic-Memory-Ecology.git
synced 2026-05-15 22:30:38 +08:00
Fix graph metadata readiness detection
This commit is contained in:
126
index.js
126
index.js
@@ -1174,11 +1174,13 @@ function hasLikelySelectedChatContext(context = getContext()) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const hasChatMetadata =
|
const hasMeaningfulChatMetadata =
|
||||||
context.chatMetadata &&
|
context.chatMetadata &&
|
||||||
typeof context.chatMetadata === "object" &&
|
typeof context.chatMetadata === "object" &&
|
||||||
!Array.isArray(context.chatMetadata);
|
!Array.isArray(context.chatMetadata) &&
|
||||||
const hasChatMessages = Array.isArray(context.chat);
|
Object.keys(context.chatMetadata).length > 0;
|
||||||
|
const hasChatMessages =
|
||||||
|
Array.isArray(context.chat) && context.chat.length > 0;
|
||||||
const hasCharacterId =
|
const hasCharacterId =
|
||||||
context.characterId !== undefined &&
|
context.characterId !== undefined &&
|
||||||
context.characterId !== null &&
|
context.characterId !== null &&
|
||||||
@@ -1188,7 +1190,30 @@ function hasLikelySelectedChatContext(context = getContext()) {
|
|||||||
context.groupId !== null &&
|
context.groupId !== null &&
|
||||||
String(context.groupId).trim() !== "";
|
String(context.groupId).trim() !== "";
|
||||||
|
|
||||||
return hasChatMetadata || hasChatMessages || hasCharacterId || hasGroupId;
|
return (
|
||||||
|
hasMeaningfulChatMetadata ||
|
||||||
|
hasChatMessages ||
|
||||||
|
hasCharacterId ||
|
||||||
|
hasGroupId
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function isHostChatMetadataReady(context = getContext()) {
|
||||||
|
if (
|
||||||
|
!context?.chatMetadata ||
|
||||||
|
typeof context.chatMetadata !== "object" ||
|
||||||
|
Array.isArray(context.chatMetadata)
|
||||||
|
) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const metadata = context.chatMetadata;
|
||||||
|
// SillyTavern 在 CHAT_CHANGED 之前会为已加载聊天补上 integrity。
|
||||||
|
if (normalizeChatIdCandidate(metadata.integrity)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Object.keys(metadata).length > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
function resolveCurrentChatIdentity(context = getContext()) {
|
function resolveCurrentChatIdentity(context = getContext()) {
|
||||||
@@ -2324,6 +2349,7 @@ function loadGraphFromChat(options = {}) {
|
|||||||
context?.chatMetadata &&
|
context?.chatMetadata &&
|
||||||
typeof context.chatMetadata === "object" &&
|
typeof context.chatMetadata === "object" &&
|
||||||
!Array.isArray(context.chatMetadata);
|
!Array.isArray(context.chatMetadata);
|
||||||
|
const metadataReady = isHostChatMetadataReady(context);
|
||||||
const savedData = hasChatMetadata
|
const savedData = hasChatMetadata
|
||||||
? context.chatMetadata[GRAPH_METADATA_KEY]
|
? context.chatMetadata[GRAPH_METADATA_KEY]
|
||||||
: undefined;
|
: undefined;
|
||||||
@@ -2432,7 +2458,7 @@ function loadGraphFromChat(options = {}) {
|
|||||||
"warning",
|
"warning",
|
||||||
);
|
);
|
||||||
|
|
||||||
if (hasChatMetadata && !shouldRetry) {
|
if (metadataReady) {
|
||||||
applyGraphLoadState(GRAPH_LOAD_STATES.LOADED, {
|
applyGraphLoadState(GRAPH_LOAD_STATES.LOADED, {
|
||||||
chatId,
|
chatId,
|
||||||
reason: "shadow-snapshot-promoted",
|
reason: "shadow-snapshot-promoted",
|
||||||
@@ -2508,32 +2534,40 @@ function loadGraphFromChat(options = {}) {
|
|||||||
lastRecalledItems = [];
|
lastRecalledItems = [];
|
||||||
lastInjectionContent = "";
|
lastInjectionContent = "";
|
||||||
|
|
||||||
if (shouldRetry) {
|
if (!metadataReady) {
|
||||||
runtimeStatus = createUiStatus(
|
runtimeStatus = createUiStatus(
|
||||||
"待命",
|
"待命",
|
||||||
"正在加载当前聊天图谱,暂不写回图谱元数据",
|
shouldRetry
|
||||||
"idle",
|
? "正在加载当前聊天图谱,暂不写回图谱元数据"
|
||||||
|
: "聊天元数据未就绪,已暂停图谱写回",
|
||||||
|
shouldRetry ? "idle" : "warning",
|
||||||
);
|
);
|
||||||
lastExtractionStatus = createUiStatus(
|
lastExtractionStatus = createUiStatus(
|
||||||
"待命",
|
"待命",
|
||||||
"正在等待聊天图谱元数据加载",
|
shouldRetry ? "正在等待聊天图谱元数据加载" : "聊天元数据未就绪,暂不允许修改图谱",
|
||||||
"idle",
|
shouldRetry ? "idle" : "warning",
|
||||||
);
|
);
|
||||||
lastVectorStatus = createUiStatus(
|
lastVectorStatus = createUiStatus(
|
||||||
"待命",
|
"待命",
|
||||||
"正在等待聊天图谱元数据加载",
|
shouldRetry ? "正在等待聊天图谱元数据加载" : "聊天元数据未就绪,暂不允许修改图谱",
|
||||||
"idle",
|
shouldRetry ? "idle" : "warning",
|
||||||
);
|
);
|
||||||
lastRecallStatus = createUiStatus(
|
lastRecallStatus = createUiStatus(
|
||||||
"待命",
|
"待命",
|
||||||
"正在等待聊天图谱元数据加载",
|
shouldRetry ? "正在等待聊天图谱元数据加载" : "聊天元数据未就绪,图谱处于保护状态",
|
||||||
"idle",
|
shouldRetry ? "idle" : "warning",
|
||||||
);
|
);
|
||||||
applyGraphLoadState(GRAPH_LOAD_STATES.LOADING, {
|
applyGraphLoadState(
|
||||||
|
shouldRetry ? GRAPH_LOAD_STATES.LOADING : GRAPH_LOAD_STATES.BLOCKED,
|
||||||
|
{
|
||||||
chatId,
|
chatId,
|
||||||
reason: hasChatMetadata
|
reason: hasChatMetadata
|
||||||
? "graph-metadata-missing"
|
? shouldRetry
|
||||||
: "chat-metadata-missing",
|
? "graph-metadata-missing"
|
||||||
|
: "graph-metadata-timeout"
|
||||||
|
: shouldRetry
|
||||||
|
? "chat-metadata-missing"
|
||||||
|
: "chat-metadata-timeout",
|
||||||
attemptIndex,
|
attemptIndex,
|
||||||
revision: 0,
|
revision: 0,
|
||||||
lastPersistedRevision: 0,
|
lastPersistedRevision: 0,
|
||||||
@@ -2544,17 +2578,24 @@ function loadGraphFromChat(options = {}) {
|
|||||||
shadowSnapshotUpdatedAt: "",
|
shadowSnapshotUpdatedAt: "",
|
||||||
shadowSnapshotReason: "",
|
shadowSnapshotReason: "",
|
||||||
writesBlocked: true,
|
writesBlocked: true,
|
||||||
});
|
},
|
||||||
scheduleGraphLoadRetry(
|
|
||||||
chatId,
|
|
||||||
hasChatMetadata ? "graph-metadata-missing" : "chat-metadata-missing",
|
|
||||||
attemptIndex,
|
|
||||||
);
|
);
|
||||||
|
if (shouldRetry) {
|
||||||
|
scheduleGraphLoadRetry(
|
||||||
|
chatId,
|
||||||
|
hasChatMetadata ? "graph-metadata-missing" : "chat-metadata-missing",
|
||||||
|
attemptIndex,
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
clearPendingGraphLoadRetry();
|
||||||
|
}
|
||||||
refreshPanelLiveState();
|
refreshPanelLiveState();
|
||||||
return {
|
return {
|
||||||
success: false,
|
success: false,
|
||||||
loaded: false,
|
loaded: false,
|
||||||
loadState: GRAPH_LOAD_STATES.LOADING,
|
loadState: shouldRetry
|
||||||
|
? GRAPH_LOAD_STATES.LOADING
|
||||||
|
: GRAPH_LOAD_STATES.BLOCKED,
|
||||||
reason: graphPersistenceState.reason,
|
reason: graphPersistenceState.reason,
|
||||||
chatId,
|
chatId,
|
||||||
attemptIndex,
|
attemptIndex,
|
||||||
@@ -2563,43 +2604,30 @@ function loadGraphFromChat(options = {}) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
clearPendingGraphLoadRetry();
|
clearPendingGraphLoadRetry();
|
||||||
const confirmedState = hasChatMetadata
|
const confirmedState = GRAPH_LOAD_STATES.EMPTY_CONFIRMED;
|
||||||
? GRAPH_LOAD_STATES.EMPTY_CONFIRMED
|
|
||||||
: GRAPH_LOAD_STATES.BLOCKED;
|
|
||||||
runtimeStatus = createUiStatus(
|
runtimeStatus = createUiStatus(
|
||||||
"待命",
|
"待命",
|
||||||
confirmedState === GRAPH_LOAD_STATES.EMPTY_CONFIRMED
|
"当前聊天还没有图谱",
|
||||||
? "当前聊天还没有图谱"
|
"idle",
|
||||||
: "聊天元数据未就绪,已暂停图谱写回",
|
|
||||||
confirmedState === GRAPH_LOAD_STATES.EMPTY_CONFIRMED ? "idle" : "warning",
|
|
||||||
);
|
);
|
||||||
lastExtractionStatus = createUiStatus(
|
lastExtractionStatus = createUiStatus(
|
||||||
"待命",
|
"待命",
|
||||||
confirmedState === GRAPH_LOAD_STATES.EMPTY_CONFIRMED
|
"当前聊天尚未执行提取",
|
||||||
? "当前聊天尚未执行提取"
|
"idle",
|
||||||
: "聊天元数据未就绪,暂不允许修改图谱",
|
|
||||||
confirmedState === GRAPH_LOAD_STATES.EMPTY_CONFIRMED ? "idle" : "warning",
|
|
||||||
);
|
);
|
||||||
lastVectorStatus = createUiStatus(
|
lastVectorStatus = createUiStatus(
|
||||||
"待命",
|
"待命",
|
||||||
confirmedState === GRAPH_LOAD_STATES.EMPTY_CONFIRMED
|
"当前聊天尚未执行向量任务",
|
||||||
? "当前聊天尚未执行向量任务"
|
"idle",
|
||||||
: "聊天元数据未就绪,暂不允许修改图谱",
|
|
||||||
confirmedState === GRAPH_LOAD_STATES.EMPTY_CONFIRMED ? "idle" : "warning",
|
|
||||||
);
|
);
|
||||||
lastRecallStatus = createUiStatus(
|
lastRecallStatus = createUiStatus(
|
||||||
"待命",
|
"待命",
|
||||||
confirmedState === GRAPH_LOAD_STATES.EMPTY_CONFIRMED
|
"当前聊天尚未建立记忆图谱",
|
||||||
? "当前聊天尚未建立记忆图谱"
|
"idle",
|
||||||
: "聊天元数据未就绪,图谱处于保护状态",
|
|
||||||
confirmedState === GRAPH_LOAD_STATES.EMPTY_CONFIRMED ? "idle" : "warning",
|
|
||||||
);
|
);
|
||||||
applyGraphLoadState(confirmedState, {
|
applyGraphLoadState(confirmedState, {
|
||||||
chatId,
|
chatId,
|
||||||
reason:
|
reason: "metadata-confirmed-empty",
|
||||||
confirmedState === GRAPH_LOAD_STATES.EMPTY_CONFIRMED
|
|
||||||
? "metadata-confirmed-empty"
|
|
||||||
: "chat-metadata-timeout",
|
|
||||||
attemptIndex,
|
attemptIndex,
|
||||||
revision: 0,
|
revision: 0,
|
||||||
lastPersistedRevision: 0,
|
lastPersistedRevision: 0,
|
||||||
@@ -2609,11 +2637,9 @@ function loadGraphFromChat(options = {}) {
|
|||||||
shadowSnapshotRevision: 0,
|
shadowSnapshotRevision: 0,
|
||||||
shadowSnapshotUpdatedAt: "",
|
shadowSnapshotUpdatedAt: "",
|
||||||
shadowSnapshotReason: "",
|
shadowSnapshotReason: "",
|
||||||
writesBlocked: confirmedState !== GRAPH_LOAD_STATES.EMPTY_CONFIRMED,
|
writesBlocked: false,
|
||||||
});
|
});
|
||||||
if (confirmedState === GRAPH_LOAD_STATES.EMPTY_CONFIRMED) {
|
removeGraphShadowSnapshot(chatId);
|
||||||
removeGraphShadowSnapshot(chatId);
|
|
||||||
}
|
|
||||||
refreshPanelLiveState();
|
refreshPanelLiveState();
|
||||||
return {
|
return {
|
||||||
success: false,
|
success: false,
|
||||||
|
|||||||
@@ -267,6 +267,26 @@ result = {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
const harness = await createGraphPersistenceHarness({
|
||||||
|
chatId: "",
|
||||||
|
globalChatId: "",
|
||||||
|
chatMetadata: {},
|
||||||
|
characterId: "",
|
||||||
|
groupId: null,
|
||||||
|
chat: [],
|
||||||
|
});
|
||||||
|
const result = harness.api.loadGraphFromChat({
|
||||||
|
attemptIndex: 0,
|
||||||
|
source: "no-chat-empty-host-state",
|
||||||
|
});
|
||||||
|
const live = harness.api.getGraphPersistenceLiveState();
|
||||||
|
|
||||||
|
assert.equal(result.loadState, "no-chat");
|
||||||
|
assert.equal(live.loadState, "no-chat");
|
||||||
|
assert.equal(live.writesBlocked, true);
|
||||||
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
const harness = await createGraphPersistenceHarness({
|
const harness = await createGraphPersistenceHarness({
|
||||||
chatId: "",
|
chatId: "",
|
||||||
@@ -466,11 +486,13 @@ result = {
|
|||||||
{
|
{
|
||||||
const harness = await createGraphPersistenceHarness({
|
const harness = await createGraphPersistenceHarness({
|
||||||
chatId: "chat-empty-confirmed",
|
chatId: "chat-empty-confirmed",
|
||||||
chatMetadata: {},
|
chatMetadata: {
|
||||||
|
integrity: "meta-ready-empty",
|
||||||
|
},
|
||||||
});
|
});
|
||||||
const result = harness.api.loadGraphFromChat({
|
const result = harness.api.loadGraphFromChat({
|
||||||
attemptIndex: harness.api.GRAPH_LOAD_RETRY_DELAYS_MS.length,
|
attemptIndex: 0,
|
||||||
source: "timeout-empty",
|
source: "ready-empty",
|
||||||
});
|
});
|
||||||
const live = harness.api.getGraphPersistenceLiveState();
|
const live = harness.api.getGraphPersistenceLiveState();
|
||||||
|
|
||||||
@@ -499,12 +521,14 @@ result = {
|
|||||||
|
|
||||||
const reader = await createGraphPersistenceHarness({
|
const reader = await createGraphPersistenceHarness({
|
||||||
chatId: "chat-promote",
|
chatId: "chat-promote",
|
||||||
chatMetadata: {},
|
chatMetadata: {
|
||||||
|
integrity: "meta-ready-promote",
|
||||||
|
},
|
||||||
sessionStore: sharedSession,
|
sessionStore: sharedSession,
|
||||||
});
|
});
|
||||||
const result = reader.api.loadGraphFromChat({
|
const result = reader.api.loadGraphFromChat({
|
||||||
attemptIndex: reader.api.GRAPH_LOAD_RETRY_DELAYS_MS.length,
|
attemptIndex: 0,
|
||||||
source: "promote-after-timeout",
|
source: "promote-when-metadata-ready",
|
||||||
});
|
});
|
||||||
const live = reader.api.getGraphPersistenceLiveState();
|
const live = reader.api.getGraphPersistenceLiveState();
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user