mirror of
https://github.com/Youzini-afk/ST-Bionic-Memory-Ecology.git
synced 2026-06-13 18:31:16 +08:00
Fix recall card refresh after rendered messages
This commit is contained in:
@@ -175,6 +175,15 @@ export function registerCoreEventHooksController(runtime) {
|
||||
if (eventTypes.MESSAGE_UPDATED) {
|
||||
bind(eventTypes.MESSAGE_UPDATED, handlers.onMessageEdited);
|
||||
}
|
||||
if (eventTypes.USER_MESSAGE_RENDERED) {
|
||||
bind(eventTypes.USER_MESSAGE_RENDERED, handlers.onUserMessageRendered);
|
||||
}
|
||||
if (eventTypes.CHARACTER_MESSAGE_RENDERED) {
|
||||
bind(
|
||||
eventTypes.CHARACTER_MESSAGE_RENDERED,
|
||||
handlers.onCharacterMessageRendered,
|
||||
);
|
||||
}
|
||||
|
||||
const nextState = {
|
||||
registered: true,
|
||||
@@ -248,6 +257,31 @@ export function onMessageSentController(runtime, messageId) {
|
||||
runtime.refreshPersistedRecallMessageUi?.();
|
||||
}
|
||||
|
||||
export function onUserMessageRenderedController(runtime, messageId = null) {
|
||||
// MESSAGE_SENT 早于实际 DOM 挂载;这里等宿主确认 user 楼层渲染完成后,
|
||||
// 再补一次 Recall Card 刷新,避免“当前楼层没卡片,下一楼才补出来”。
|
||||
runtime.refreshPersistedRecallMessageUi?.(40);
|
||||
return {
|
||||
messageId: Number.isFinite(Number(messageId)) ? Number(messageId) : null,
|
||||
refreshed: true,
|
||||
source: "user-message-rendered",
|
||||
};
|
||||
}
|
||||
|
||||
export function onCharacterMessageRenderedController(
|
||||
runtime,
|
||||
messageId = null,
|
||||
type = "",
|
||||
) {
|
||||
runtime.refreshPersistedRecallMessageUi?.(80);
|
||||
return {
|
||||
messageId: Number.isFinite(Number(messageId)) ? Number(messageId) : null,
|
||||
type: String(type || ""),
|
||||
refreshed: true,
|
||||
source: "character-message-rendered",
|
||||
};
|
||||
}
|
||||
|
||||
export function onGenerationStartedController(
|
||||
runtime,
|
||||
type,
|
||||
|
||||
23
index.js
23
index.js
@@ -50,6 +50,7 @@ import {
|
||||
import {
|
||||
installSendIntentHooksController,
|
||||
onBeforeCombinePromptsController,
|
||||
onCharacterMessageRenderedController,
|
||||
onChatChangedController,
|
||||
onChatLoadedController,
|
||||
onGenerationAfterCommandsController,
|
||||
@@ -59,6 +60,7 @@ import {
|
||||
onMessageReceivedController,
|
||||
onMessageSentController,
|
||||
onMessageSwipedController,
|
||||
onUserMessageRenderedController,
|
||||
registerBeforeCombinePromptsController,
|
||||
registerCoreEventHooksController,
|
||||
registerGenerationAfterCommandsController,
|
||||
@@ -9099,6 +9101,25 @@ function onMessageSent(messageId) {
|
||||
return result;
|
||||
}
|
||||
|
||||
function onUserMessageRendered(messageId = null) {
|
||||
return onUserMessageRenderedController(
|
||||
{
|
||||
refreshPersistedRecallMessageUi: schedulePersistedRecallMessageUiRefresh,
|
||||
},
|
||||
messageId,
|
||||
);
|
||||
}
|
||||
|
||||
function onCharacterMessageRendered(messageId = null, type = "") {
|
||||
return onCharacterMessageRenderedController(
|
||||
{
|
||||
refreshPersistedRecallMessageUi: schedulePersistedRecallMessageUiRefresh,
|
||||
},
|
||||
messageId,
|
||||
type,
|
||||
);
|
||||
}
|
||||
|
||||
function onMessageDeleted(chatLengthOrMessageId, meta = null) {
|
||||
const result = onMessageDeletedController(
|
||||
{
|
||||
@@ -9574,6 +9595,7 @@ async function onReembedDirect() {
|
||||
getCoreEventBindingState,
|
||||
handlers: {
|
||||
onBeforeCombinePrompts,
|
||||
onCharacterMessageRendered,
|
||||
onChatChanged,
|
||||
onChatLoaded,
|
||||
onGenerationAfterCommands,
|
||||
@@ -9584,6 +9606,7 @@ async function onReembedDirect() {
|
||||
onMessageReceived,
|
||||
onMessageSent,
|
||||
onMessageSwiped,
|
||||
onUserMessageRendered,
|
||||
},
|
||||
registerBeforeCombinePrompts,
|
||||
registerGenerationAfterCommands,
|
||||
|
||||
@@ -7,12 +7,14 @@ import vm from "node:vm";
|
||||
import { pruneProcessedMessageHashesFromFloor } from "../chat-history.js";
|
||||
import {
|
||||
onBeforeCombinePromptsController,
|
||||
onCharacterMessageRenderedController,
|
||||
onChatChangedController,
|
||||
onGenerationAfterCommandsController,
|
||||
onGenerationStartedController,
|
||||
onMessageSentController,
|
||||
onMessageReceivedController,
|
||||
onMessageSwipedController,
|
||||
onUserMessageRenderedController,
|
||||
registerCoreEventHooksController,
|
||||
} from "../event-binding.js";
|
||||
import {
|
||||
@@ -3580,23 +3582,29 @@ async function testRegisterCoreEventHooksIsIdempotent() {
|
||||
CHAT_LOADED: "chat-loaded",
|
||||
MESSAGE_SENT: "message-sent",
|
||||
GENERATION_STARTED: "generation-started",
|
||||
GENERATION_ENDED: "generation-ended",
|
||||
MESSAGE_RECEIVED: "message-received",
|
||||
MESSAGE_DELETED: "message-deleted",
|
||||
MESSAGE_EDITED: "message-edited",
|
||||
MESSAGE_SWIPED: "message-swiped",
|
||||
MESSAGE_UPDATED: "message-updated",
|
||||
USER_MESSAGE_RENDERED: "user-message-rendered",
|
||||
CHARACTER_MESSAGE_RENDERED: "character-message-rendered",
|
||||
},
|
||||
handlers: {
|
||||
onChatChanged() {},
|
||||
onChatLoaded() {},
|
||||
onMessageSent() {},
|
||||
onGenerationStarted() {},
|
||||
onGenerationEnded() {},
|
||||
onGenerationAfterCommands() {},
|
||||
onBeforeCombinePrompts() {},
|
||||
onMessageReceived() {},
|
||||
onMessageDeleted() {},
|
||||
onMessageEdited() {},
|
||||
onMessageSwiped() {},
|
||||
onUserMessageRendered() {},
|
||||
onCharacterMessageRendered() {},
|
||||
},
|
||||
registerGenerationAfterCommands(listener) {
|
||||
makeFirstRegistrations.push({ hook: "after", listener });
|
||||
@@ -3620,7 +3628,7 @@ async function testRegisterCoreEventHooksIsIdempotent() {
|
||||
registerCoreEventHooksController(runtime);
|
||||
registerCoreEventHooksController(runtime);
|
||||
|
||||
assert.equal(eventRegistrations.length, 9);
|
||||
assert.equal(eventRegistrations.length, 12);
|
||||
assert.equal(makeFirstRegistrations.length, 2);
|
||||
assert.equal(bindingState.registered, true);
|
||||
}
|
||||
@@ -3743,6 +3751,42 @@ async function testMessageSentFallsBackToLatestUserWhenHostMessageIdInvalid() {
|
||||
assert.equal(refreshCalls, 1);
|
||||
}
|
||||
|
||||
async function testUserMessageRenderedRefreshesRecallUiAfterRealDomRender() {
|
||||
const refreshCalls = [];
|
||||
|
||||
const result = onUserMessageRenderedController(
|
||||
{
|
||||
refreshPersistedRecallMessageUi(delayMs = 0) {
|
||||
refreshCalls.push(delayMs);
|
||||
},
|
||||
},
|
||||
7,
|
||||
);
|
||||
|
||||
assert.deepEqual(refreshCalls, [40]);
|
||||
assert.equal(result.messageId, 7);
|
||||
assert.equal(result.source, "user-message-rendered");
|
||||
}
|
||||
|
||||
async function testCharacterMessageRenderedRefreshesRecallUiAfterAssistantRender() {
|
||||
const refreshCalls = [];
|
||||
|
||||
const result = onCharacterMessageRenderedController(
|
||||
{
|
||||
refreshPersistedRecallMessageUi(delayMs = 0) {
|
||||
refreshCalls.push(delayMs);
|
||||
},
|
||||
},
|
||||
8,
|
||||
"normal",
|
||||
);
|
||||
|
||||
assert.deepEqual(refreshCalls, [80]);
|
||||
assert.equal(result.messageId, 8);
|
||||
assert.equal(result.type, "normal");
|
||||
assert.equal(result.source, "character-message-rendered");
|
||||
}
|
||||
|
||||
async function testMessageReceivedQueuesExtractionWithoutRuntimeQueueMicrotask() {
|
||||
let runExtractionCalls = 0;
|
||||
let refreshCalls = 0;
|
||||
@@ -5275,6 +5319,8 @@ await testRegisterCoreEventHooksIsIdempotent();
|
||||
await testChatChangedDoesNotClearCoreEventBindings();
|
||||
await testSwipeRoutesToRerollWithoutHistoryRecoveryFallback();
|
||||
await testMessageSentFallsBackToLatestUserWhenHostMessageIdInvalid();
|
||||
await testUserMessageRenderedRefreshesRecallUiAfterRealDomRender();
|
||||
await testCharacterMessageRenderedRefreshesRecallUiAfterAssistantRender();
|
||||
await testMessageReceivedQueuesExtractionWithoutRuntimeQueueMicrotask();
|
||||
await testAutoExtractionDefersWhenGraphNotReady();
|
||||
await testAutoExtractionDefersWhenAlreadyExtracting();
|
||||
|
||||
Reference in New Issue
Block a user