mirror of
https://github.com/Youzini-afk/ST-Bionic-Memory-Ecology.git
synced 2026-05-15 22:30:38 +08:00
fix: freeze recall input from host lifecycle
This commit is contained in:
@@ -8,7 +8,10 @@ export function registerBeforeCombinePromptsController(runtime, listener) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
runtime.console.warn("[ST-BME] eventMakeFirst 不可用,回退到普通事件注册");
|
runtime.console.warn("[ST-BME] eventMakeFirst 不可用,回退到普通事件注册");
|
||||||
runtime.eventSource.on(runtime.eventTypes.GENERATE_BEFORE_COMBINE_PROMPTS, listener);
|
runtime.eventSource.on(
|
||||||
|
runtime.eventTypes.GENERATE_BEFORE_COMBINE_PROMPTS,
|
||||||
|
listener,
|
||||||
|
);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -21,7 +24,10 @@ export function registerGenerationAfterCommandsController(runtime, listener) {
|
|||||||
runtime.console.warn(
|
runtime.console.warn(
|
||||||
"[ST-BME] eventMakeFirst 不可用,GENERATION_AFTER_COMMANDS 回退到普通事件注册",
|
"[ST-BME] eventMakeFirst 不可用,GENERATION_AFTER_COMMANDS 回退到普通事件注册",
|
||||||
);
|
);
|
||||||
runtime.eventSource.on(runtime.eventTypes.GENERATION_AFTER_COMMANDS, listener);
|
runtime.eventSource.on(
|
||||||
|
runtime.eventTypes.GENERATION_AFTER_COMMANDS,
|
||||||
|
listener,
|
||||||
|
);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -48,7 +54,10 @@ export function installSendIntentHooksController(runtime) {
|
|||||||
|
|
||||||
if (sendButton) {
|
if (sendButton) {
|
||||||
const captureSendIntent = () => {
|
const captureSendIntent = () => {
|
||||||
runtime.recordRecallSendIntent(runtime.getSendTextareaValue(), "send-button");
|
runtime.recordRecallSendIntent(
|
||||||
|
runtime.getSendTextareaValue(),
|
||||||
|
"send-button",
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
sendButton.addEventListener("click", captureSendIntent, true);
|
sendButton.addEventListener("click", captureSendIntent, true);
|
||||||
@@ -182,25 +191,36 @@ export async function onGenerationAfterCommandsController(
|
|||||||
) {
|
) {
|
||||||
if (dryRun) return;
|
if (dryRun) return;
|
||||||
|
|
||||||
|
const generationType = String(type || "normal").trim() || "normal";
|
||||||
|
const frozenInputSnapshot =
|
||||||
|
generationType === "normal"
|
||||||
|
? runtime.consumeHostGenerationInputSnapshot?.({ preserve: true }) ||
|
||||||
|
runtime.consumeHostGenerationInputSnapshot?.()
|
||||||
|
: null;
|
||||||
|
|
||||||
const context = runtime.getContext();
|
const context = runtime.getContext();
|
||||||
const chat = context?.chat;
|
const chat = context?.chat;
|
||||||
const recallOptions = runtime.buildGenerationAfterCommandsRecallInput(
|
const recallOptions = runtime.buildGenerationAfterCommandsRecallInput(
|
||||||
type,
|
type,
|
||||||
params,
|
{
|
||||||
|
...params,
|
||||||
|
frozenInputSnapshot,
|
||||||
|
},
|
||||||
chat,
|
chat,
|
||||||
);
|
);
|
||||||
if (!recallOptions) return;
|
if (!recallOptions) return;
|
||||||
|
|
||||||
const recallContext = runtime.createGenerationRecallContext({
|
const recallContext = runtime.createGenerationRecallContext({
|
||||||
hookName: "GENERATION_AFTER_COMMANDS",
|
hookName: "GENERATION_AFTER_COMMANDS",
|
||||||
generationType: String(type || "normal").trim() || "normal",
|
generationType,
|
||||||
recallOptions,
|
recallOptions,
|
||||||
});
|
});
|
||||||
if (!recallContext.shouldRun) {
|
if (!recallContext.shouldRun) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const runtimeRecallOptions = recallContext.recallOptions || recallOptions || {};
|
const runtimeRecallOptions =
|
||||||
|
recallContext.recallOptions || recallOptions || {};
|
||||||
runtime.markGenerationRecallTransactionHookState(
|
runtime.markGenerationRecallTransactionHookState(
|
||||||
recallContext.transaction,
|
recallContext.transaction,
|
||||||
recallContext.hookName,
|
recallContext.hookName,
|
||||||
@@ -226,10 +246,17 @@ export async function onGenerationAfterCommandsController(
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function onBeforeCombinePromptsController(runtime) {
|
export async function onBeforeCombinePromptsController(runtime) {
|
||||||
|
const frozenInputSnapshot =
|
||||||
|
runtime.consumeHostGenerationInputSnapshot?.() ||
|
||||||
|
runtime.getPendingHostGenerationInputSnapshot?.() ||
|
||||||
|
runtime.createRecallInputRecord?.() ||
|
||||||
|
{};
|
||||||
const context = runtime.getContext();
|
const context = runtime.getContext();
|
||||||
const chat = context?.chat;
|
const chat = context?.chat;
|
||||||
const recallOptions =
|
const recallOptions =
|
||||||
runtime.buildNormalGenerationRecallInput(chat) ||
|
runtime.buildNormalGenerationRecallInput(chat, {
|
||||||
|
frozenInputSnapshot,
|
||||||
|
}) ||
|
||||||
runtime.buildHistoryGenerationRecallInput(chat) ||
|
runtime.buildHistoryGenerationRecallInput(chat) ||
|
||||||
{};
|
{};
|
||||||
const recallContext = runtime.createGenerationRecallContext({
|
const recallContext = runtime.createGenerationRecallContext({
|
||||||
@@ -241,7 +268,8 @@ export async function onBeforeCombinePromptsController(runtime) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const runtimeRecallOptions = recallContext.recallOptions || recallOptions || {};
|
const runtimeRecallOptions =
|
||||||
|
recallContext.recallOptions || recallOptions || {};
|
||||||
runtime.markGenerationRecallTransactionHookState(
|
runtime.markGenerationRecallTransactionHookState(
|
||||||
recallContext.transaction,
|
recallContext.transaction,
|
||||||
recallContext.hookName,
|
recallContext.hookName,
|
||||||
@@ -268,7 +296,8 @@ export function onMessageReceivedController(runtime) {
|
|||||||
const persistenceState = runtime.getGraphPersistenceState?.() || {};
|
const persistenceState = runtime.getGraphPersistenceState?.() || {};
|
||||||
const loadState = persistenceState.loadState || "";
|
const loadState = persistenceState.loadState || "";
|
||||||
const dbReady =
|
const dbReady =
|
||||||
persistenceState.dbReady ?? (loadState === "loaded" || loadState === "empty-confirmed");
|
persistenceState.dbReady ??
|
||||||
|
(loadState === "loaded" || loadState === "empty-confirmed");
|
||||||
if (
|
if (
|
||||||
!dbReady ||
|
!dbReady ||
|
||||||
loadState === "loading" ||
|
loadState === "loading" ||
|
||||||
|
|||||||
84
index.js
84
index.js
@@ -446,6 +446,7 @@ let graphPersistenceState = createGraphPersistenceState();
|
|||||||
const lastStatusToastAt = {};
|
const lastStatusToastAt = {};
|
||||||
let pendingRecallSendIntent = createRecallInputRecord();
|
let pendingRecallSendIntent = createRecallInputRecord();
|
||||||
let lastRecallSentUserMessage = createRecallInputRecord();
|
let lastRecallSentUserMessage = createRecallInputRecord();
|
||||||
|
let pendingHostGenerationInputSnapshot = createRecallInputRecord();
|
||||||
let sendIntentHookCleanup = [];
|
let sendIntentHookCleanup = [];
|
||||||
let sendIntentHookRetryTimer = null;
|
let sendIntentHookRetryTimer = null;
|
||||||
let pendingHistoryRecoveryTimer = null;
|
let pendingHistoryRecoveryTimer = null;
|
||||||
@@ -1027,6 +1028,45 @@ function updateLastRecalledItems(nodeIds = []) {
|
|||||||
function clearRecallInputTracking() {
|
function clearRecallInputTracking() {
|
||||||
pendingRecallSendIntent = createRecallInputRecord();
|
pendingRecallSendIntent = createRecallInputRecord();
|
||||||
lastRecallSentUserMessage = createRecallInputRecord();
|
lastRecallSentUserMessage = createRecallInputRecord();
|
||||||
|
pendingHostGenerationInputSnapshot = createRecallInputRecord();
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getPendingHostGenerationInputSnapshot() {
|
||||||
|
return pendingHostGenerationInputSnapshot;
|
||||||
}
|
}
|
||||||
|
|
||||||
function recordRecallSendIntent(text, source = "dom-intent") {
|
function recordRecallSendIntent(text, source = "dom-intent") {
|
||||||
@@ -1057,6 +1097,12 @@ function recordRecallSentUserMessage(messageId, text, source = "message-sent") {
|
|||||||
if (pendingRecallSendIntent.hash && pendingRecallSendIntent.hash === hash) {
|
if (pendingRecallSendIntent.hash && pendingRecallSendIntent.hash === hash) {
|
||||||
pendingRecallSendIntent = createRecallInputRecord();
|
pendingRecallSendIntent = createRecallInputRecord();
|
||||||
}
|
}
|
||||||
|
if (
|
||||||
|
pendingHostGenerationInputSnapshot.hash &&
|
||||||
|
pendingHostGenerationInputSnapshot.hash === hash
|
||||||
|
) {
|
||||||
|
pendingHostGenerationInputSnapshot = createRecallInputRecord();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getMessageRecallRecord(messageIndex) {
|
function getMessageRecallRecord(messageIndex) {
|
||||||
@@ -4830,10 +4876,12 @@ function buildGenerationAfterCommandsRecallInput(type, params = {}, chat) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
return buildNormalGenerationRecallInput(chat);
|
return buildNormalGenerationRecallInput(chat, {
|
||||||
|
frozenInputSnapshot: params?.frozenInputSnapshot,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function buildNormalGenerationRecallInput(chat) {
|
function buildNormalGenerationRecallInput(chat, options = {}) {
|
||||||
const lastNonSystemMessage = getLastNonSystemChatMessage(chat);
|
const lastNonSystemMessage = getLastNonSystemChatMessage(chat);
|
||||||
const tailUserText = lastNonSystemMessage?.is_user
|
const tailUserText = lastNonSystemMessage?.is_user
|
||||||
? normalizeRecallInputText(lastNonSystemMessage?.mes || "")
|
? normalizeRecallInputText(lastNonSystemMessage?.mes || "")
|
||||||
@@ -4841,18 +4889,38 @@ function buildNormalGenerationRecallInput(chat) {
|
|||||||
const targetUserMessageIndex = resolveGenerationTargetUserMessageIndex(chat, {
|
const targetUserMessageIndex = resolveGenerationTargetUserMessageIndex(chat, {
|
||||||
generationType: "normal",
|
generationType: "normal",
|
||||||
});
|
});
|
||||||
|
const frozenInputSnapshot = isFreshRecallInputRecord(
|
||||||
|
options?.frozenInputSnapshot,
|
||||||
|
)
|
||||||
|
? options.frozenInputSnapshot
|
||||||
|
: null;
|
||||||
|
const hostSnapshotText = normalizeRecallInputText(
|
||||||
|
frozenInputSnapshot?.text || "",
|
||||||
|
);
|
||||||
const textareaText = normalizeRecallInputText(
|
const textareaText = normalizeRecallInputText(
|
||||||
pendingRecallSendIntent.text || getSendTextareaValue(),
|
pendingRecallSendIntent.text || getSendTextareaValue(),
|
||||||
);
|
);
|
||||||
const userMessage = tailUserText || textareaText;
|
const userMessage = tailUserText || hostSnapshotText || textareaText;
|
||||||
if (!userMessage) return null;
|
if (!userMessage) return null;
|
||||||
|
|
||||||
|
let overrideSource = "send-intent";
|
||||||
|
let overrideSourceLabel = "发送意图";
|
||||||
|
if (tailUserText) {
|
||||||
|
overrideSource = "chat-tail-user";
|
||||||
|
overrideSourceLabel = "当前用户楼层";
|
||||||
|
} else if (hostSnapshotText) {
|
||||||
|
overrideSource = String(
|
||||||
|
frozenInputSnapshot?.source || "host-generation-lifecycle",
|
||||||
|
);
|
||||||
|
overrideSourceLabel = "宿主发送快照";
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
overrideUserMessage: userMessage,
|
overrideUserMessage: userMessage,
|
||||||
generationType: "normal",
|
generationType: "normal",
|
||||||
targetUserMessageIndex,
|
targetUserMessageIndex,
|
||||||
overrideSource: tailUserText ? "chat-tail-user" : "send-intent",
|
overrideSource,
|
||||||
overrideSourceLabel: tailUserText ? "当前用户楼层" : "发送意图",
|
overrideSourceLabel,
|
||||||
includeSyntheticUserMessage: !tailUserText,
|
includeSyntheticUserMessage: !tailUserText,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -6514,6 +6582,7 @@ async function onGenerationAfterCommands(type, params = {}, dryRun = false) {
|
|||||||
{
|
{
|
||||||
applyFinalRecallInjectionForGeneration,
|
applyFinalRecallInjectionForGeneration,
|
||||||
buildGenerationAfterCommandsRecallInput,
|
buildGenerationAfterCommandsRecallInput,
|
||||||
|
consumeHostGenerationInputSnapshot,
|
||||||
createGenerationRecallContext,
|
createGenerationRecallContext,
|
||||||
getContext,
|
getContext,
|
||||||
getGenerationRecallHookStateFromResult,
|
getGenerationRecallHookStateFromResult,
|
||||||
@@ -6531,6 +6600,7 @@ async function onBeforeCombinePrompts() {
|
|||||||
applyFinalRecallInjectionForGeneration,
|
applyFinalRecallInjectionForGeneration,
|
||||||
buildHistoryGenerationRecallInput,
|
buildHistoryGenerationRecallInput,
|
||||||
buildNormalGenerationRecallInput,
|
buildNormalGenerationRecallInput,
|
||||||
|
consumeHostGenerationInputSnapshot,
|
||||||
createGenerationRecallContext,
|
createGenerationRecallContext,
|
||||||
getContext,
|
getContext,
|
||||||
getGenerationRecallHookStateFromResult,
|
getGenerationRecallHookStateFromResult,
|
||||||
@@ -6546,6 +6616,7 @@ function onMessageReceived() {
|
|||||||
getContext,
|
getContext,
|
||||||
getCurrentGraph: () => currentGraph,
|
getCurrentGraph: () => currentGraph,
|
||||||
getGraphPersistenceState: () => graphPersistenceState,
|
getGraphPersistenceState: () => graphPersistenceState,
|
||||||
|
getPendingHostGenerationInputSnapshot,
|
||||||
getPendingRecallSendIntent: () => pendingRecallSendIntent,
|
getPendingRecallSendIntent: () => pendingRecallSendIntent,
|
||||||
isAssistantChatMessage,
|
isAssistantChatMessage,
|
||||||
isFreshRecallInputRecord,
|
isFreshRecallInputRecord,
|
||||||
@@ -6557,6 +6628,9 @@ function onMessageReceived() {
|
|||||||
queueMicrotask,
|
queueMicrotask,
|
||||||
runExtraction,
|
runExtraction,
|
||||||
refreshPersistedRecallMessageUi: schedulePersistedRecallMessageUiRefresh,
|
refreshPersistedRecallMessageUi: schedulePersistedRecallMessageUiRefresh,
|
||||||
|
setPendingHostGenerationInputSnapshot: (record) => {
|
||||||
|
pendingHostGenerationInputSnapshot = record;
|
||||||
|
},
|
||||||
setPendingRecallSendIntent: (record) => {
|
setPendingRecallSendIntent: (record) => {
|
||||||
pendingRecallSendIntent = record;
|
pendingRecallSendIntent = record;
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -270,6 +270,7 @@ function createGenerationRecallHarness() {
|
|||||||
getCurrentChatId: () => "chat-main",
|
getCurrentChatId: () => "chat-main",
|
||||||
normalizeRecallInputText: (text = "") => String(text || "").trim(),
|
normalizeRecallInputText: (text = "") => String(text || "").trim(),
|
||||||
pendingRecallSendIntent: { text: "", hash: "", at: 0 },
|
pendingRecallSendIntent: { text: "", hash: "", at: 0 },
|
||||||
|
pendingHostGenerationInputSnapshot: { text: "", hash: "", at: 0 },
|
||||||
lastRecallSentUserMessage: { text: "", hash: "", at: 0 },
|
lastRecallSentUserMessage: { text: "", hash: "", at: 0 },
|
||||||
getLatestUserChatMessage: (chat = []) =>
|
getLatestUserChatMessage: (chat = []) =>
|
||||||
[...chat].reverse().find((message) => message?.is_user) || null,
|
[...chat].reverse().find((message) => message?.is_user) || null,
|
||||||
@@ -341,7 +342,7 @@ function createGenerationRecallHarness() {
|
|||||||
};
|
};
|
||||||
vm.createContext(context);
|
vm.createContext(context);
|
||||||
vm.runInContext(
|
vm.runInContext(
|
||||||
`${snippet}\nresult = { hashRecallInput, buildPreGenerationRecallKey, buildGenerationAfterCommandsRecallInput, cleanupGenerationRecallTransactions, buildGenerationRecallTransactionId, beginGenerationRecallTransaction, markGenerationRecallTransactionHookState, shouldRunRecallForTransaction, createGenerationRecallContext, onGenerationAfterCommands, onBeforeCombinePrompts, generationRecallTransactions };`,
|
`${snippet}\nresult = { hashRecallInput, buildPreGenerationRecallKey, buildGenerationAfterCommandsRecallInput, cleanupGenerationRecallTransactions, buildGenerationRecallTransactionId, beginGenerationRecallTransaction, markGenerationRecallTransactionHookState, shouldRunRecallForTransaction, createGenerationRecallContext, onGenerationAfterCommands, onBeforeCombinePrompts, generationRecallTransactions, freezeHostGenerationInputSnapshot, consumeHostGenerationInputSnapshot, getPendingHostGenerationInputSnapshot };`,
|
||||||
context,
|
context,
|
||||||
{ filename: indexPath },
|
{ filename: indexPath },
|
||||||
);
|
);
|
||||||
@@ -2264,6 +2265,40 @@ async function testGenerationRecallBeforeCombineCanUseProvisionalSendIntentBindi
|
|||||||
assert.equal(harness.runRecallCalls[0].targetUserMessageIndex, null);
|
assert.equal(harness.runRecallCalls[0].targetUserMessageIndex, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function testGenerationRecallHostLifecycleSnapshotSurvivesTextareaClearWithoutDomIntent() {
|
||||||
|
const harness = await createGenerationRecallHarness();
|
||||||
|
harness.chat = [{ is_user: false, mes: "assistant-tail" }];
|
||||||
|
harness.__sendTextareaValue = "宿主冻结输入";
|
||||||
|
|
||||||
|
const frozenSnapshot = harness.result.freezeHostGenerationInputSnapshot(
|
||||||
|
harness.__sendTextareaValue,
|
||||||
|
);
|
||||||
|
harness.__sendTextareaValue = "";
|
||||||
|
|
||||||
|
await harness.result.onGenerationAfterCommands(
|
||||||
|
"normal",
|
||||||
|
{ frozenInputSnapshot: frozenSnapshot },
|
||||||
|
false,
|
||||||
|
);
|
||||||
|
await harness.result.onBeforeCombinePrompts();
|
||||||
|
|
||||||
|
assert.equal(harness.runRecallCalls.length, 1);
|
||||||
|
assert.equal(
|
||||||
|
harness.runRecallCalls[0].hookName,
|
||||||
|
"GENERATE_BEFORE_COMBINE_PROMPTS",
|
||||||
|
);
|
||||||
|
assert.equal(harness.runRecallCalls[0].overrideUserMessage, "宿主冻结输入");
|
||||||
|
assert.equal(harness.runRecallCalls[0].overrideSourceLabel, "宿主发送快照");
|
||||||
|
assert.equal(harness.runRecallCalls[0].targetUserMessageIndex, null);
|
||||||
|
assert.deepEqual(harness.result.getPendingHostGenerationInputSnapshot(), {
|
||||||
|
text: "",
|
||||||
|
hash: "",
|
||||||
|
at: 0,
|
||||||
|
source: "",
|
||||||
|
messageId: null,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
async function testGenerationRecallAfterCommandsStillSkipsWithoutStableUserFloor() {
|
async function testGenerationRecallAfterCommandsStillSkipsWithoutStableUserFloor() {
|
||||||
const harness = await createGenerationRecallHarness();
|
const harness = await createGenerationRecallHarness();
|
||||||
harness.chat = [{ is_user: false, mes: "assistant-tail" }];
|
harness.chat = [{ is_user: false, mes: "assistant-tail" }];
|
||||||
@@ -3016,6 +3051,7 @@ await testGenerationRecallHistoryModesUseSameBindingAcrossHooks();
|
|||||||
await testGenerationRecallFrozenBindingSurvivesCrossHookInputDrift();
|
await testGenerationRecallFrozenBindingSurvivesCrossHookInputDrift();
|
||||||
await testGenerationRecallSkipsUntilTargetUserFloorAvailable();
|
await testGenerationRecallSkipsUntilTargetUserFloorAvailable();
|
||||||
await testGenerationRecallBeforeCombineCanUseProvisionalSendIntentBinding();
|
await testGenerationRecallBeforeCombineCanUseProvisionalSendIntentBinding();
|
||||||
|
await testGenerationRecallHostLifecycleSnapshotSurvivesTextareaClearWithoutDomIntent();
|
||||||
await testGenerationRecallAfterCommandsStillSkipsWithoutStableUserFloor();
|
await testGenerationRecallAfterCommandsStillSkipsWithoutStableUserFloor();
|
||||||
await testGenerationRecallSameKeyCanRunAgainImmediatelyAsNewGeneration();
|
await testGenerationRecallSameKeyCanRunAgainImmediatelyAsNewGeneration();
|
||||||
await testGenerationRecallSameKeyCanRunAgainAfterBridgeWindow();
|
await testGenerationRecallSameKeyCanRunAgainAfterBridgeWindow();
|
||||||
|
|||||||
Reference in New Issue
Block a user