export async function runPlannerRecallForEnaController(runtime = {}, { rawUserInput, signal = undefined, disableLlmRecall = false, } = {}) { const userMessage = runtime.normalizeRecallInputText(rawUserInput || ""); const trivialInputResult = runtime.isTrivialUserInput(userMessage); if (trivialInputResult.trivial) { runtime.console.info?.( `[ST-BME] trivial-input skip: reason=${trivialInputResult.reason} len=${trivialInputResult.normalizedText.length} hook=ena-planner`, ); return { ok: false, reason: `trivial-user-input:${trivialInputResult.reason}`, memoryBlock: "", recentMessages: [], result: null, }; } const settings = runtime.getSettings(); if (!settings.enabled || !settings.recallEnabled) { return { ok: false, reason: "recall-disabled", memoryBlock: "", recentMessages: [], result: null, }; } if (signal?.aborted) { throw signal.reason instanceof Error ? signal.reason : runtime.createAbortError("Ena Planner recall aborted"); } const currentGraph = runtime.getCurrentGraph(); if (!currentGraph || !runtime.isGraphReadableForRecall()) { return { ok: false, reason: "graph-not-readable", memoryBlock: "", recentMessages: [], result: null, }; } if ( !Array.isArray(currentGraph.nodes) || currentGraph.nodes.length === 0 ) { return { ok: false, reason: "graph-empty", memoryBlock: "", recentMessages: [], result: null, }; } if (runtime.isGraphMetadataWriteAllowed()) { const recovered = await runtime.recoverHistoryIfNeeded("pre-ena-planner-recall"); if (!recovered) { return { ok: false, reason: "history-recovery-not-ready", memoryBlock: "", recentMessages: [], result: null, }; } } if (signal?.aborted) { throw signal.reason instanceof Error ? signal.reason : runtime.createAbortError("Ena Planner recall aborted"); } await runtime.ensureVectorReadyIfNeeded("pre-ena-planner-recall", signal); const context = runtime.getContext(); const chat = context?.chat ?? []; const recentMessages = runtime.buildRecallRecentMessages( chat, runtime.clampInt(settings.recallLlmContextMessages, 4, 0, 20), userMessage, ); const schema = runtime.getSchema(); const baseOptions = runtime.buildRecallRetrieveOptions(settings, context); const options = { ...baseOptions, enableLLMRecall: disableLlmRecall ? false : baseOptions.enableLLMRecall, }; const result = await runtime.retrieve({ graph: currentGraph, userMessage, recentMessages, embeddingConfig: runtime.getEmbeddingConfig(), schema, settings, signal, options, }); const memoryBlock = runtime.formatInjection(result, schema).trim(); return { ok: Boolean(memoryBlock), reason: memoryBlock ? "completed" : "empty-memory-block", memoryBlock, recentMessages, result, }; }