mirror of
https://github.com/Youzini-afk/ST-Bionic-Memory-Ecology.git
synced 2026-06-13 18:31:16 +08:00
refactor(runtime): extract recall input/intent state factory (Phase 4a)
This commit is contained in:
197
index.js
197
index.js
@@ -160,6 +160,7 @@ import {
|
||||
consumeRerollRecallReuseMarker,
|
||||
createRerollRecallReuseMarker,
|
||||
} from "./runtime/reroll-transaction-boundary.js";
|
||||
import { createRecallInputState } from "./runtime/recall-input-state.js";
|
||||
import {
|
||||
extractMemories,
|
||||
generateReflection,
|
||||
@@ -1349,7 +1350,31 @@ let pendingRecallSendIntent = createRecallInputRecord();
|
||||
let lastRecallSentUserMessage = createRecallInputRecord();
|
||||
let pendingHostGenerationInputSnapshot = createRecallInputRecord();
|
||||
let pendingRerollRecallReuse = null;
|
||||
let currentGenerationTrivialSkip = null;
|
||||
const recallInputState = createRecallInputState({
|
||||
createRecallInputRecord,
|
||||
getCurrentChatId,
|
||||
getLastRecallSentUserMessage: () => lastRecallSentUserMessage,
|
||||
getPendingHostGenerationInputSnapshot: () => pendingHostGenerationInputSnapshot,
|
||||
getPendingRecallSendIntent: () => pendingRecallSendIntent,
|
||||
hashRecallInput,
|
||||
isFreshRecallInputRecord,
|
||||
normalizeChatIdCandidate,
|
||||
normalizeRecallInputText,
|
||||
recordMessageTraceSnapshot: (patch) => recordMessageTraceSnapshot(patch),
|
||||
setLastRecallSentUserMessage: (record) => {
|
||||
lastRecallSentUserMessage = record;
|
||||
},
|
||||
setPendingHostGenerationInputSnapshot: (record) => {
|
||||
pendingHostGenerationInputSnapshot = record;
|
||||
},
|
||||
setPendingRecallSendIntent: (record) => {
|
||||
pendingRecallSendIntent = record;
|
||||
},
|
||||
clearPendingRerollRecallReuse: (...args) => clearPendingRerollRecallReuse(...args),
|
||||
clearPlannerRecallHandoffsForChat: (...args) =>
|
||||
clearPlannerRecallHandoffsForChat(...args),
|
||||
TRIVIAL_GENERATION_SKIP_TTL_MS,
|
||||
});
|
||||
let coreEventBindingState = {
|
||||
registered: false,
|
||||
cleanups: [],
|
||||
@@ -5138,18 +5163,8 @@ function restoreRecallUiStateFromPersistence(chat = getContext()?.chat) {
|
||||
}
|
||||
|
||||
function clearRecallInputTracking() {
|
||||
clearPendingRecallSendIntent();
|
||||
lastRecallSentUserMessage = createRecallInputRecord();
|
||||
clearPendingHostGenerationInputSnapshot();
|
||||
clearPendingRerollRecallReuse("recall-input-tracking-cleared");
|
||||
if (typeof recordMessageTraceSnapshot === "function") {
|
||||
recordMessageTraceSnapshot({
|
||||
lastSentUserMessage: null,
|
||||
});
|
||||
}
|
||||
clearPlannerRecallHandoffsForChat("", { clearAll: true });
|
||||
return recallInputState.clearRecallInputTracking();
|
||||
}
|
||||
|
||||
function getCoreEventBindingState() {
|
||||
return coreEventBindingState;
|
||||
}
|
||||
@@ -5189,74 +5204,30 @@ function freezeHostGenerationInputSnapshot(
|
||||
text,
|
||||
source = "host-generation-lifecycle",
|
||||
) {
|
||||
const normalized = normalizeRecallInputText(text);
|
||||
if (!normalized) return null;
|
||||
|
||||
pendingHostGenerationInputSnapshot = createRecallInputRecord({
|
||||
text: normalized,
|
||||
hash: hashRecallInput(normalized),
|
||||
source,
|
||||
at: Date.now(),
|
||||
});
|
||||
return pendingHostGenerationInputSnapshot;
|
||||
return recallInputState.freezeHostGenerationInputSnapshot(text, source);
|
||||
}
|
||||
|
||||
function consumeHostGenerationInputSnapshot(options = {}) {
|
||||
const { preserve = false } = options;
|
||||
if (!isFreshRecallInputRecord(pendingHostGenerationInputSnapshot)) {
|
||||
if (!preserve) {
|
||||
pendingHostGenerationInputSnapshot = createRecallInputRecord();
|
||||
}
|
||||
return createRecallInputRecord();
|
||||
}
|
||||
|
||||
const snapshot = createRecallInputRecord({
|
||||
...pendingHostGenerationInputSnapshot,
|
||||
});
|
||||
if (!preserve) {
|
||||
pendingHostGenerationInputSnapshot = createRecallInputRecord();
|
||||
}
|
||||
return snapshot;
|
||||
return recallInputState.consumeHostGenerationInputSnapshot(options);
|
||||
}
|
||||
|
||||
function getPendingHostGenerationInputSnapshot() {
|
||||
return pendingHostGenerationInputSnapshot;
|
||||
return recallInputState.getPendingHostGenerationInputSnapshot();
|
||||
}
|
||||
|
||||
function clearPendingRecallSendIntent() {
|
||||
pendingRecallSendIntent = createRecallInputRecord();
|
||||
return pendingRecallSendIntent;
|
||||
return recallInputState.clearPendingRecallSendIntent();
|
||||
}
|
||||
|
||||
function clearPendingHostGenerationInputSnapshot() {
|
||||
pendingHostGenerationInputSnapshot = createRecallInputRecord();
|
||||
return pendingHostGenerationInputSnapshot;
|
||||
return recallInputState.clearPendingHostGenerationInputSnapshot();
|
||||
}
|
||||
|
||||
function getCurrentGenerationTrivialSkip(
|
||||
chatId = getCurrentChatId(),
|
||||
now = Date.now(),
|
||||
) {
|
||||
if (!currentGenerationTrivialSkip) return null;
|
||||
|
||||
const setAtMs = Number(currentGenerationTrivialSkip.setAtMs) || 0;
|
||||
if (
|
||||
!setAtMs ||
|
||||
now - setAtMs > TRIVIAL_GENERATION_SKIP_TTL_MS
|
||||
) {
|
||||
currentGenerationTrivialSkip = null;
|
||||
return null;
|
||||
}
|
||||
|
||||
const normalizedChatId = normalizeChatIdCandidate(chatId);
|
||||
const activeChatId = normalizeChatIdCandidate(
|
||||
currentGenerationTrivialSkip.chatId,
|
||||
);
|
||||
if (normalizedChatId && activeChatId && normalizedChatId !== activeChatId) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return currentGenerationTrivialSkip;
|
||||
return recallInputState.getCurrentGenerationTrivialSkip(chatId, now);
|
||||
}
|
||||
|
||||
function markCurrentGenerationTrivialSkip({
|
||||
@@ -5264,22 +5235,15 @@ function markCurrentGenerationTrivialSkip({
|
||||
chatId = getCurrentChatId(),
|
||||
chatLength = 0,
|
||||
} = {}) {
|
||||
currentGenerationTrivialSkip = {
|
||||
chatId: normalizeChatIdCandidate(chatId),
|
||||
setAtMs: Date.now(),
|
||||
reason: String(reason || ""),
|
||||
generationStartMinChatIndex: Math.max(
|
||||
0,
|
||||
Math.floor(Number(chatLength) || 0),
|
||||
),
|
||||
};
|
||||
return currentGenerationTrivialSkip;
|
||||
return recallInputState.markCurrentGenerationTrivialSkip({
|
||||
reason,
|
||||
chatId,
|
||||
chatLength,
|
||||
});
|
||||
}
|
||||
|
||||
function clearCurrentGenerationTrivialSkip(_reason = "") {
|
||||
const previous = currentGenerationTrivialSkip;
|
||||
currentGenerationTrivialSkip = null;
|
||||
return previous;
|
||||
return recallInputState.clearCurrentGenerationTrivialSkip(_reason);
|
||||
}
|
||||
|
||||
function consumeCurrentGenerationTrivialSkip(
|
||||
@@ -5287,89 +5251,20 @@ function consumeCurrentGenerationTrivialSkip(
|
||||
chatId = getCurrentChatId(),
|
||||
now = Date.now(),
|
||||
) {
|
||||
const activeSkip = getCurrentGenerationTrivialSkip(chatId, now);
|
||||
if (!activeSkip) return false;
|
||||
|
||||
const normalizedTargetIndex = Number.isFinite(Number(targetMessageIndex))
|
||||
? Math.floor(Number(targetMessageIndex))
|
||||
: null;
|
||||
if (!Number.isFinite(normalizedTargetIndex)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (
|
||||
normalizedTargetIndex <
|
||||
Math.max(0, Math.floor(Number(activeSkip.generationStartMinChatIndex) || 0))
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
currentGenerationTrivialSkip = null;
|
||||
return true;
|
||||
return recallInputState.consumeCurrentGenerationTrivialSkip(
|
||||
targetMessageIndex,
|
||||
chatId,
|
||||
now,
|
||||
);
|
||||
}
|
||||
|
||||
function recordRecallSendIntent(text, source = "dom-intent") {
|
||||
const normalized = normalizeRecallInputText(text);
|
||||
if (!normalized) return createRecallInputRecord();
|
||||
|
||||
const hash = hashRecallInput(normalized);
|
||||
const previousRecord = isFreshRecallInputRecord(pendingRecallSendIntent)
|
||||
? pendingRecallSendIntent
|
||||
: null;
|
||||
const previousHash = String(previousRecord?.hash || "");
|
||||
const previousText = String(previousRecord?.text || "");
|
||||
|
||||
if (previousHash && previousHash === hash && previousText === normalized) {
|
||||
pendingRecallSendIntent = createRecallInputRecord({
|
||||
...previousRecord,
|
||||
at: Date.now(),
|
||||
source: String(source || previousRecord.source || "dom-intent"),
|
||||
});
|
||||
return pendingRecallSendIntent;
|
||||
}
|
||||
|
||||
pendingRecallSendIntent = createRecallInputRecord({
|
||||
text: normalized,
|
||||
hash,
|
||||
source,
|
||||
at: Date.now(),
|
||||
});
|
||||
return pendingRecallSendIntent;
|
||||
return recallInputState.recordRecallSendIntent(text, source);
|
||||
}
|
||||
|
||||
function recordRecallSentUserMessage(messageId, text, source = "message-sent") {
|
||||
const normalized = normalizeRecallInputText(text);
|
||||
if (!normalized) return createRecallInputRecord();
|
||||
|
||||
const hash = hashRecallInput(normalized);
|
||||
lastRecallSentUserMessage = createRecallInputRecord({
|
||||
text: normalized,
|
||||
hash,
|
||||
messageId: Number.isFinite(messageId) ? messageId : null,
|
||||
source,
|
||||
at: Date.now(),
|
||||
});
|
||||
if (typeof recordMessageTraceSnapshot === "function") {
|
||||
recordMessageTraceSnapshot({
|
||||
lastSentUserMessage: {
|
||||
text: normalized,
|
||||
hash,
|
||||
messageId: Number.isFinite(messageId) ? messageId : null,
|
||||
source,
|
||||
updatedAt: new Date().toISOString(),
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
// 注意:不再在 MESSAGE_SENT 阶段清空 pendingRecallSendIntent /
|
||||
// pendingHostGenerationInputSnapshot / transactions。
|
||||
// 这些数据在 GENERATION_AFTER_COMMANDS 中被消费;MESSAGE_SENT 先于
|
||||
// GENERATION_AFTER_COMMANDS 触发,提前清空会导致召回拿不到用户输入。
|
||||
// 真正的消费发生在 recall 执行后(runRecallController 内部)。
|
||||
|
||||
return lastRecallSentUserMessage;
|
||||
return recallInputState.recordRecallSentUserMessage(messageId, text, source);
|
||||
}
|
||||
|
||||
function getMessageRecallRecord(messageIndex) {
|
||||
const chat = getContext()?.chat;
|
||||
return readPersistedRecallFromUserMessage(chat, messageIndex);
|
||||
|
||||
259
runtime/recall-input-state.js
Normal file
259
runtime/recall-input-state.js
Normal file
@@ -0,0 +1,259 @@
|
||||
export function createRecallInputState(deps = {}) {
|
||||
let currentGenerationTrivialSkip = null;
|
||||
|
||||
const getPendingRecallSendIntent = () =>
|
||||
deps.getPendingRecallSendIntent?.() ?? deps.createRecallInputRecord?.();
|
||||
const setPendingRecallSendIntent = (record) => {
|
||||
deps.setPendingRecallSendIntent?.(record);
|
||||
return record;
|
||||
};
|
||||
const getPendingHostGenerationInputSnapshot = () =>
|
||||
deps.getPendingHostGenerationInputSnapshot?.() ?? deps.createRecallInputRecord?.();
|
||||
const setPendingHostGenerationInputSnapshot = (record) => {
|
||||
deps.setPendingHostGenerationInputSnapshot?.(record);
|
||||
return record;
|
||||
};
|
||||
const getLastRecallSentUserMessage = () =>
|
||||
deps.getLastRecallSentUserMessage?.() ?? deps.createRecallInputRecord?.();
|
||||
const setLastRecallSentUserMessage = (record) => {
|
||||
deps.setLastRecallSentUserMessage?.(record);
|
||||
return record;
|
||||
};
|
||||
const getCurrentChatId = (...args) => deps.getCurrentChatId?.(...args);
|
||||
const normalizeChatIdCandidate = (value = "") =>
|
||||
deps.normalizeChatIdCandidate?.(value) ?? String(value ?? "").trim();
|
||||
const normalizeRecallInputText = (value = "") =>
|
||||
deps.normalizeRecallInputText?.(value) ?? String(value || "").trim();
|
||||
const createRecallInputRecord = (record = {}) =>
|
||||
deps.createRecallInputRecord?.(record) ?? { ...(record || {}) };
|
||||
const hashRecallInput = (value = "") => deps.hashRecallInput?.(value) ?? "";
|
||||
const isFreshRecallInputRecord = (record) =>
|
||||
deps.isFreshRecallInputRecord?.(record) ?? Boolean(record?.text);
|
||||
const getTrivialGenerationSkipTtlMs = () =>
|
||||
Number.isFinite(Number(deps.TRIVIAL_GENERATION_SKIP_TTL_MS))
|
||||
? Number(deps.TRIVIAL_GENERATION_SKIP_TTL_MS)
|
||||
: 60000;
|
||||
|
||||
function freezeHostGenerationInputSnapshot(
|
||||
text,
|
||||
source = "host-generation-lifecycle",
|
||||
) {
|
||||
const normalized = normalizeRecallInputText(text);
|
||||
if (!normalized) return null;
|
||||
|
||||
const nextSnapshot = createRecallInputRecord({
|
||||
text: normalized,
|
||||
hash: hashRecallInput(normalized),
|
||||
source,
|
||||
at: Date.now(),
|
||||
});
|
||||
setPendingHostGenerationInputSnapshot(nextSnapshot);
|
||||
return nextSnapshot;
|
||||
}
|
||||
|
||||
function consumeHostGenerationInputSnapshot(options = {}) {
|
||||
const { preserve = false } = options;
|
||||
const pendingHostGenerationInputSnapshot = getPendingHostGenerationInputSnapshot();
|
||||
if (!isFreshRecallInputRecord(pendingHostGenerationInputSnapshot)) {
|
||||
if (!preserve) {
|
||||
setPendingHostGenerationInputSnapshot(createRecallInputRecord());
|
||||
}
|
||||
return createRecallInputRecord();
|
||||
}
|
||||
|
||||
const snapshot = createRecallInputRecord({
|
||||
...pendingHostGenerationInputSnapshot,
|
||||
});
|
||||
if (!preserve) {
|
||||
setPendingHostGenerationInputSnapshot(createRecallInputRecord());
|
||||
}
|
||||
return snapshot;
|
||||
}
|
||||
|
||||
function readPendingHostGenerationInputSnapshot() {
|
||||
return getPendingHostGenerationInputSnapshot();
|
||||
}
|
||||
|
||||
function clearPendingRecallSendIntent() {
|
||||
const nextRecord = createRecallInputRecord();
|
||||
setPendingRecallSendIntent(nextRecord);
|
||||
return nextRecord;
|
||||
}
|
||||
|
||||
function clearPendingHostGenerationInputSnapshot() {
|
||||
const nextSnapshot = createRecallInputRecord();
|
||||
setPendingHostGenerationInputSnapshot(nextSnapshot);
|
||||
return nextSnapshot;
|
||||
}
|
||||
|
||||
function getCurrentGenerationTrivialSkip(
|
||||
chatId = getCurrentChatId(),
|
||||
now = Date.now(),
|
||||
) {
|
||||
if (!currentGenerationTrivialSkip) return null;
|
||||
|
||||
const setAtMs = Number(currentGenerationTrivialSkip.setAtMs) || 0;
|
||||
if (
|
||||
!setAtMs ||
|
||||
now - setAtMs > getTrivialGenerationSkipTtlMs()
|
||||
) {
|
||||
currentGenerationTrivialSkip = null;
|
||||
return null;
|
||||
}
|
||||
|
||||
const normalizedChatId = normalizeChatIdCandidate(chatId);
|
||||
const activeChatId = normalizeChatIdCandidate(
|
||||
currentGenerationTrivialSkip.chatId,
|
||||
);
|
||||
if (normalizedChatId && activeChatId && normalizedChatId !== activeChatId) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return currentGenerationTrivialSkip;
|
||||
}
|
||||
|
||||
function markCurrentGenerationTrivialSkip({
|
||||
reason = "",
|
||||
chatId = getCurrentChatId(),
|
||||
chatLength = 0,
|
||||
} = {}) {
|
||||
currentGenerationTrivialSkip = {
|
||||
chatId: normalizeChatIdCandidate(chatId),
|
||||
setAtMs: Date.now(),
|
||||
reason: String(reason || ""),
|
||||
generationStartMinChatIndex: Math.max(
|
||||
0,
|
||||
Math.floor(Number(chatLength) || 0),
|
||||
),
|
||||
};
|
||||
return currentGenerationTrivialSkip;
|
||||
}
|
||||
|
||||
function clearCurrentGenerationTrivialSkip(_reason = "") {
|
||||
const previous = currentGenerationTrivialSkip;
|
||||
currentGenerationTrivialSkip = null;
|
||||
return previous;
|
||||
}
|
||||
|
||||
function consumeCurrentGenerationTrivialSkip(
|
||||
targetMessageIndex,
|
||||
chatId = getCurrentChatId(),
|
||||
now = Date.now(),
|
||||
) {
|
||||
const activeSkip = getCurrentGenerationTrivialSkip(chatId, now);
|
||||
if (!activeSkip) return false;
|
||||
|
||||
const normalizedTargetIndex = Number.isFinite(Number(targetMessageIndex))
|
||||
? Math.floor(Number(targetMessageIndex))
|
||||
: null;
|
||||
if (!Number.isFinite(normalizedTargetIndex)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (
|
||||
normalizedTargetIndex <
|
||||
Math.max(0, Math.floor(Number(activeSkip.generationStartMinChatIndex) || 0))
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
currentGenerationTrivialSkip = null;
|
||||
return true;
|
||||
}
|
||||
|
||||
function recordRecallSendIntent(text, source = "dom-intent") {
|
||||
const normalized = normalizeRecallInputText(text);
|
||||
if (!normalized) return createRecallInputRecord();
|
||||
|
||||
const hash = hashRecallInput(normalized);
|
||||
const pendingRecallSendIntent = getPendingRecallSendIntent();
|
||||
const previousRecord = isFreshRecallInputRecord(pendingRecallSendIntent)
|
||||
? pendingRecallSendIntent
|
||||
: null;
|
||||
const previousHash = String(previousRecord?.hash || "");
|
||||
const previousText = String(previousRecord?.text || "");
|
||||
|
||||
if (previousHash && previousHash === hash && previousText === normalized) {
|
||||
const nextRecord = createRecallInputRecord({
|
||||
...previousRecord,
|
||||
at: Date.now(),
|
||||
source: String(source || previousRecord.source || "dom-intent"),
|
||||
});
|
||||
setPendingRecallSendIntent(nextRecord);
|
||||
return nextRecord;
|
||||
}
|
||||
|
||||
const nextRecord = createRecallInputRecord({
|
||||
text: normalized,
|
||||
hash,
|
||||
source,
|
||||
at: Date.now(),
|
||||
});
|
||||
setPendingRecallSendIntent(nextRecord);
|
||||
return nextRecord;
|
||||
}
|
||||
|
||||
function recordRecallSentUserMessage(messageId, text, source = "message-sent") {
|
||||
const normalized = normalizeRecallInputText(text);
|
||||
if (!normalized) return createRecallInputRecord();
|
||||
|
||||
const hash = hashRecallInput(normalized);
|
||||
const nextRecord = createRecallInputRecord({
|
||||
text: normalized,
|
||||
hash,
|
||||
messageId: Number.isFinite(messageId) ? messageId : null,
|
||||
source,
|
||||
at: Date.now(),
|
||||
});
|
||||
setLastRecallSentUserMessage(nextRecord);
|
||||
if (typeof deps.recordMessageTraceSnapshot === "function") {
|
||||
deps.recordMessageTraceSnapshot({
|
||||
lastSentUserMessage: {
|
||||
text: normalized,
|
||||
hash,
|
||||
messageId: Number.isFinite(messageId) ? messageId : null,
|
||||
source,
|
||||
updatedAt: new Date().toISOString(),
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
// 注意:不再在 MESSAGE_SENT 阶段清空 pendingRecallSendIntent /
|
||||
// pendingHostGenerationInputSnapshot / transactions。
|
||||
// 这些数据在 GENERATION_AFTER_COMMANDS 中被消费;MESSAGE_SENT 先于
|
||||
// GENERATION_AFTER_COMMANDS 触发,提前清空会导致召回拿不到用户输入。
|
||||
// 真正的消费发生在 recall 执行后(runRecallController 内部)。
|
||||
|
||||
return nextRecord;
|
||||
}
|
||||
|
||||
function clearRecallInputTracking() {
|
||||
clearPendingRecallSendIntent();
|
||||
setLastRecallSentUserMessage(createRecallInputRecord());
|
||||
clearPendingHostGenerationInputSnapshot();
|
||||
deps.clearPendingRerollRecallReuse?.("recall-input-tracking-cleared");
|
||||
if (typeof deps.recordMessageTraceSnapshot === "function") {
|
||||
deps.recordMessageTraceSnapshot({
|
||||
lastSentUserMessage: null,
|
||||
});
|
||||
}
|
||||
deps.clearPlannerRecallHandoffsForChat?.("", { clearAll: true });
|
||||
}
|
||||
|
||||
return {
|
||||
freezeHostGenerationInputSnapshot,
|
||||
consumeHostGenerationInputSnapshot,
|
||||
getPendingHostGenerationInputSnapshot: readPendingHostGenerationInputSnapshot,
|
||||
clearPendingHostGenerationInputSnapshot,
|
||||
recordRecallSendIntent,
|
||||
clearPendingRecallSendIntent,
|
||||
recordRecallSentUserMessage,
|
||||
getCurrentGenerationTrivialSkip,
|
||||
markCurrentGenerationTrivialSkip,
|
||||
clearCurrentGenerationTrivialSkip,
|
||||
consumeCurrentGenerationTrivialSkip,
|
||||
clearRecallInputTracking,
|
||||
getLastRecallSentUserMessage,
|
||||
getPendingRecallSendIntent,
|
||||
};
|
||||
}
|
||||
@@ -160,6 +160,7 @@ import {
|
||||
normalizeRecallInputText,
|
||||
normalizeStageNoticeLevel,
|
||||
} from "../ui/ui-status.js";
|
||||
import { createRecallInputState } from "../runtime/recall-input-state.js";
|
||||
|
||||
const moduleDir = path.dirname(fileURLToPath(import.meta.url));
|
||||
const indexPath = path.resolve(moduleDir, "../index.js");
|
||||
@@ -781,6 +782,7 @@ async function createGraphPersistenceHarness({
|
||||
return null;
|
||||
},
|
||||
},
|
||||
createRecallInputState,
|
||||
createRecallMessageUiController() {
|
||||
return {
|
||||
refreshPersistedRecallMessageUi: () => ({
|
||||
|
||||
@@ -62,6 +62,7 @@ import {
|
||||
consumeRerollRecallReuseMarker,
|
||||
createRerollRecallReuseMarker,
|
||||
} from "../../runtime/reroll-transaction-boundary.js";
|
||||
import { createRecallInputState } from "../../runtime/recall-input-state.js";
|
||||
|
||||
const moduleDir = path.dirname(fileURLToPath(import.meta.url));
|
||||
const indexPath = path.resolve(moduleDir, "../../index.js");
|
||||
@@ -102,6 +103,9 @@ export function createGenerationRecallHarness(options = {}) {
|
||||
},
|
||||
result: null,
|
||||
currentGraph: {},
|
||||
pendingRecallSendIntent: createRecallInputRecord(),
|
||||
lastRecallSentUserMessage: createRecallInputRecord(),
|
||||
pendingHostGenerationInputSnapshot: createRecallInputRecord(),
|
||||
_panelModule: null,
|
||||
defaultSettings,
|
||||
mergePersistedSettings,
|
||||
@@ -115,6 +119,7 @@ export function createGenerationRecallHarness(options = {}) {
|
||||
recordAuthorityAcceptedRevision,
|
||||
consumeRerollRecallReuseMarker,
|
||||
createRerollRecallReuseMarker,
|
||||
createRecallInputState,
|
||||
settings: {},
|
||||
graphPersistenceState: createGraphPersistenceState(),
|
||||
extension_settings: { [MODULE_NAME]: {} },
|
||||
@@ -273,6 +278,7 @@ export function createGenerationRecallHarness(options = {}) {
|
||||
recordInjectionSnapshot: (_kind, snapshot = {}) => {
|
||||
context.recordedInjectionSnapshots.push({ ...snapshot });
|
||||
},
|
||||
recordMessageTraceSnapshot() {},
|
||||
schedulePersistedRecallMessageUiRefresh: () => {
|
||||
context.recallUiRefreshCalls += 1;
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user