UNPKG

openclaw

Version:

Multi-channel AI gateway with extensible messaging integrations

537 lines (536 loc) 24.6 kB
import { a as normalizeLowercaseStringOrEmpty } from "./string-coerce-mnp54Vah.js"; import { i as formatErrorMessage } from "./errors-BXgSefBE.js"; import { _ as uniqueStrings } from "./string-normalization-WNUDCpXX.js"; import { B as MANAGED_MEMORY_DREAMING_CRON_TAG, G as resolveMemoryDeepDreamingConfig, V as MEMORY_DREAMING_SYSTEM_EVENT_TEXT, W as resolveMemoryCorePluginConfig, Y as resolveMemoryDreamingWorkspaces, z as MANAGED_MEMORY_DREAMING_CRON_NAME } from "./dreaming-SqhFI2Et.js"; import { c as peekSystemEventEntries } from "./system-events-C5WI3S5a.js"; import "./string-coerce-runtime-CEGJWkQ_.js"; import "./system-event-runtime-D80J5tzu.js"; import "./memory-core-host-status-DVjlVr90.js"; import { n as normalizeTrimmedString, t as includesSystemEventToken } from "./dreaming-shared-BChAYuyu.js"; //#region extensions/memory-core/src/dreaming.ts const RUNTIME_CRON_RECONCILE_INTERVAL_MS = 6e4; const STARTUP_CRON_RETRY_DELAY_MS = 5e3; const STARTUP_CRON_RETRY_MAX_ATTEMPTS = 12; const HEARTBEAT_ISOLATED_SESSION_SUFFIX = ":heartbeat"; function formatRepairSummary(repair) { const actions = []; if (repair.rewroteStore) { const removedOverflowEntries = repair.removedOverflowEntries ?? 0; const details = [repair.removedInvalidEntries > 0 ? `-${repair.removedInvalidEntries} invalid` : null, removedOverflowEntries > 0 ? `-${removedOverflowEntries} overflow` : null].filter(Boolean).join(", "); actions.push(`rewrote recall store${details ? ` (${details})` : ""}`); } if (repair.removedStaleLock) actions.push("removed stale promotion lock"); return actions.join(", "); } function resolveManagedCronDescription(config) { const recencyHalfLifeDays = config.recencyHalfLifeDays ?? 14; return `${MANAGED_MEMORY_DREAMING_CRON_TAG} Promote weighted short-term recalls into MEMORY.md (limit=${config.limit}, minScore=${config.minScore.toFixed(3)}, minRecallCount=${config.minRecallCount}, minUniqueQueries=${config.minUniqueQueries}, recencyHalfLifeDays=${recencyHalfLifeDays}, maxAgeDays=${config.maxAgeDays ?? "none"}).`; } function buildManagedDreamingCronJob(config) { return { name: MANAGED_MEMORY_DREAMING_CRON_NAME, description: resolveManagedCronDescription(config), enabled: true, schedule: { kind: "cron", expr: config.cron, ...config.timezone ? { tz: config.timezone } : {} }, sessionTarget: "isolated", wakeMode: "now", payload: { kind: "agentTurn", message: MEMORY_DREAMING_SYSTEM_EVENT_TEXT, lightContext: true }, delivery: { mode: "none" } }; } function resolveManagedDreamingPayloadToken(payload) { const payloadKind = normalizeLowercaseStringOrEmpty(normalizeTrimmedString(payload?.kind)); if (payloadKind === "systemevent") return normalizeTrimmedString(payload?.text); if (payloadKind === "agentturn") return normalizeTrimmedString(payload?.message); } function isManagedDreamingJob(job) { if (normalizeTrimmedString(job.description)?.includes("[managed-by=memory-core.short-term-promotion]")) return true; const name = normalizeTrimmedString(job.name); const payloadToken = resolveManagedDreamingPayloadToken(job.payload); return name === "Memory Dreaming Promotion" && payloadToken === "__openclaw_memory_core_short_term_promotion_dream__"; } function isLegacyPhaseDreamingJob(job) { const description = normalizeTrimmedString(job.description); if (description?.includes("[managed-by=memory-core.dreaming.light]") || description?.includes("[managed-by=memory-core.dreaming.rem]")) return true; const name = normalizeTrimmedString(job.name); const payloadText = normalizeTrimmedString(job.payload?.text); if (name === "Memory Light Dreaming" && payloadText === "__openclaw_memory_core_light_sleep__") return true; return name === "Memory REM Dreaming" && payloadText === "__openclaw_memory_core_rem_sleep__"; } function compareOptionalStrings(a, b) { return a === b; } async function migrateLegacyPhaseDreamingCronJobs(params) { let migrated = 0; for (const job of params.legacyJobs) try { if ((await params.cron.remove(job.id)).removed === true) migrated += 1; } catch (err) { params.logger.warn(`memory-core: failed to migrate legacy phase dreaming cron job ${job.id}: ${formatErrorMessage(err)}`); } if (migrated > 0) if (params.mode === "enabled") params.logger.info(`memory-core: migrated ${migrated} legacy phase dreaming cron job(s) to the unified dreaming controller.`); else params.logger.info(`memory-core: completed legacy phase dreaming cron migration while unified dreaming is disabled (${migrated} job(s) removed).`); return migrated; } function buildManagedDreamingPatch(job, desired) { const patch = {}; if (!compareOptionalStrings(normalizeTrimmedString(job.name), desired.name)) patch.name = desired.name; if (!compareOptionalStrings(normalizeTrimmedString(job.description), desired.description)) patch.description = desired.description; if (job.enabled !== true) patch.enabled = true; const scheduleKind = normalizeLowercaseStringOrEmpty(normalizeTrimmedString(job.schedule?.kind)); const scheduleExpr = normalizeTrimmedString(job.schedule?.expr); const scheduleTz = normalizeTrimmedString(job.schedule?.tz); if (scheduleKind !== "cron" || !compareOptionalStrings(scheduleExpr, desired.schedule.expr) || !compareOptionalStrings(scheduleTz, desired.schedule.tz)) patch.schedule = desired.schedule; if (normalizeLowercaseStringOrEmpty(normalizeTrimmedString(job.sessionTarget)) !== desired.sessionTarget) patch.sessionTarget = desired.sessionTarget; if (normalizeLowercaseStringOrEmpty(normalizeTrimmedString(job.wakeMode)) !== "now") patch.wakeMode = "now"; const payloadKind = normalizeLowercaseStringOrEmpty(normalizeTrimmedString(job.payload?.kind)); const payloadToken = resolveManagedDreamingPayloadToken(job.payload); const desiredPayloadToken = desired.payload.kind === "systemEvent" ? desired.payload.text : desired.payload.message; if (payloadKind !== normalizeLowercaseStringOrEmpty(desired.payload.kind) || !compareOptionalStrings(payloadToken, desiredPayloadToken) || desired.payload.kind === "agentTurn" && job.payload?.lightContext !== desired.payload.lightContext) patch.payload = desired.payload; if (normalizeLowercaseStringOrEmpty(normalizeTrimmedString(job.delivery?.mode)) !== "none") patch.delivery = desired.delivery; return Object.keys(patch).length > 0 ? patch : null; } function sortManagedJobs(managed) { return managed.toSorted((a, b) => { const aCreated = typeof a.createdAtMs === "number" && Number.isFinite(a.createdAtMs) ? a.createdAtMs : Number.MAX_SAFE_INTEGER; const bCreated = typeof b.createdAtMs === "number" && Number.isFinite(b.createdAtMs) ? b.createdAtMs : Number.MAX_SAFE_INTEGER; if (aCreated !== bCreated) return aCreated - bCreated; return a.id.localeCompare(b.id); }); } function resolveCronServiceFromCandidate(candidate) { if (!candidate || typeof candidate !== "object") return null; const cron = candidate; if (typeof cron.list !== "function" || typeof cron.add !== "function" || typeof cron.update !== "function" || typeof cron.remove !== "function") return null; return cron; } function resolveCronServiceFromGatewayContext(context) { return resolveCronServiceFromCandidate(context?.getCron?.()); } function resolveDreamingTriggerSessionKeys(sessionKey) { const normalized = normalizeTrimmedString(sessionKey); if (!normalized) return []; const keys = [normalized]; if (normalized.endsWith(HEARTBEAT_ISOLATED_SESSION_SUFFIX)) { const baseSessionKey = normalized.slice(0, -10).trim(); if (baseSessionKey) keys.push(baseSessionKey); } return uniqueStrings(keys); } function hasPendingManagedDreamingCronEvent(sessionKey) { return resolveDreamingTriggerSessionKeys(sessionKey).some((candidateSessionKey) => peekSystemEventEntries(candidateSessionKey).some((event) => event.contextKey?.startsWith("cron:") === true && normalizeTrimmedString(event.text) === "__openclaw_memory_core_short_term_promotion_dream__")); } function resolveShortTermPromotionDreamingConfig(params) { const resolved = resolveMemoryDeepDreamingConfig(params); return { enabled: resolved.enabled, cron: resolved.cron, ...resolved.timezone ? { timezone: resolved.timezone } : {}, limit: resolved.limit, minScore: resolved.minScore, minRecallCount: resolved.minRecallCount, minUniqueQueries: resolved.minUniqueQueries, recencyHalfLifeDays: resolved.recencyHalfLifeDays, ...typeof resolved.maxAgeDays === "number" ? { maxAgeDays: resolved.maxAgeDays } : {}, maxPromotedSnippetTokens: resolved.maxPromotedSnippetTokens ?? 160, verboseLogging: resolved.verboseLogging, storage: resolved.storage, ...resolved.execution.model ? { execution: { model: resolved.execution.model } } : {} }; } async function reconcileShortTermDreamingCronJob(params) { const cron = params.cron; if (!cron) return { status: "unavailable", removed: 0 }; const allJobs = await cron.list({ includeDisabled: true }); const managed = allJobs.filter(isManagedDreamingJob); const legacyPhaseJobs = allJobs.filter(isLegacyPhaseDreamingJob); if (!params.config.enabled) { let removed = await migrateLegacyPhaseDreamingCronJobs({ cron, legacyJobs: legacyPhaseJobs, logger: params.logger, mode: "disabled" }); for (const job of managed) try { if ((await cron.remove(job.id)).removed === true) removed += 1; } catch (err) { params.logger.warn(`memory-core: failed to remove managed dreaming cron job ${job.id}: ${formatErrorMessage(err)}`); } if (removed > 0) params.logger.info(`memory-core: removed ${removed} managed dreaming cron job(s).`); return { status: "disabled", removed }; } const desired = buildManagedDreamingCronJob(params.config); if (managed.length === 0) { await cron.add(desired); const migratedLegacy = await migrateLegacyPhaseDreamingCronJobs({ cron, legacyJobs: legacyPhaseJobs, logger: params.logger, mode: "enabled" }); params.logger.info("memory-core: created managed dreaming cron job."); return { status: "added", removed: migratedLegacy }; } const [primary, ...duplicates] = sortManagedJobs(managed); let removed = await migrateLegacyPhaseDreamingCronJobs({ cron, legacyJobs: legacyPhaseJobs, logger: params.logger, mode: "enabled" }); for (const duplicate of duplicates) try { if ((await cron.remove(duplicate.id)).removed === true) removed += 1; } catch (err) { params.logger.warn(`memory-core: failed to prune duplicate managed dreaming cron job ${duplicate.id}: ${formatErrorMessage(err)}`); } const patch = buildManagedDreamingPatch(primary, desired); if (!patch) { if (removed > 0) params.logger.info("memory-core: pruned duplicate managed dreaming cron jobs."); return { status: "noop", removed }; } await cron.update(primary.id, patch); params.logger.info("memory-core: updated managed dreaming cron job."); return { status: "updated", removed }; } async function runShortTermDreamingPromotionIfTriggered(params) { if (params.trigger !== "heartbeat" && params.trigger !== "cron") return; if (!includesSystemEventToken(params.cleanedBody, "__openclaw_memory_core_short_term_promotion_dream__")) return; if (!params.config.enabled) return { handled: true, reason: "memory-core: short-term dreaming disabled" }; const recencyHalfLifeDays = params.config.recencyHalfLifeDays ?? 14; const fallbackWorkspaceDir = normalizeTrimmedString(params.workspaceDir); const workspaceCandidates = params.cfg ? resolveMemoryDreamingWorkspaces(params.cfg, { primaryWorkspaceDir: fallbackWorkspaceDir, primaryAgentId: "main" }).map((entry) => entry.workspaceDir) : []; const seenWorkspaces = /* @__PURE__ */ new Set(); const workspaces = workspaceCandidates.filter((workspaceDir) => { if (seenWorkspaces.has(workspaceDir)) return false; seenWorkspaces.add(workspaceDir); return true; }); if (workspaces.length === 0 && fallbackWorkspaceDir) workspaces.push(fallbackWorkspaceDir); if (workspaces.length === 0) { params.logger.warn("memory-core: dreaming promotion skipped because no memory workspace is available."); return { handled: true, reason: "memory-core: short-term dreaming missing workspace" }; } if (params.config.limit === 0) { params.logger.info("memory-core: dreaming promotion skipped because limit=0."); return { handled: true, reason: "memory-core: short-term dreaming disabled by limit" }; } if (params.config.verboseLogging) params.logger.info(`memory-core: dreaming verbose enabled (cron=${params.config.cron}, limit=${params.config.limit}, minScore=${params.config.minScore.toFixed(3)}, minRecallCount=${params.config.minRecallCount}, minUniqueQueries=${params.config.minUniqueQueries}, recencyHalfLifeDays=${recencyHalfLifeDays}, maxAgeDays=${params.config.maxAgeDays ?? "none"}, workspaces=${workspaces.length}).`); let totalCandidates = 0; let totalApplied = 0; let failedWorkspaces = 0; const pluginConfig = params.cfg ? resolveMemoryCorePluginConfig(params.cfg) : void 0; const detachNarratives = params.trigger === "cron"; const [{ writeDeepDreamingReport }, { appendFallbackNarrativeEntry, generateAndAppendDreamNarrative, runDetachedDreamNarrative }, { runDreamingSweepPhases }, { applyShortTermPromotions, repairShortTermPromotionArtifacts, rankShortTermPromotionCandidates }] = await Promise.all([ import("./dreaming-markdown-BHSC9aNz.js"), import("./dreaming-narrative-Bdg-vPO_.js"), import("./dreaming-phases-E8TN4rSj.js"), import("./short-term-promotion-dT5KFZ8a.js") ]); for (const workspaceDir of workspaces) try { const sweepNowMs = Date.now(); await runDreamingSweepPhases({ workspaceDir, pluginConfig, cfg: params.cfg, logger: params.logger, subagent: params.subagent, detachNarratives, nowMs: sweepNowMs }); const reportLines = []; const repair = await repairShortTermPromotionArtifacts({ workspaceDir }); if (repair.changed) { params.logger.info(`memory-core: normalized recall artifacts before dreaming (${formatRepairSummary(repair)}) [workspace=${workspaceDir}].`); reportLines.push(`- Repaired recall artifacts: ${formatRepairSummary(repair)}.`); } const candidates = await rankShortTermPromotionCandidates({ workspaceDir, limit: params.config.limit, minScore: params.config.minScore, minRecallCount: params.config.minRecallCount, minUniqueQueries: params.config.minUniqueQueries, recencyHalfLifeDays, maxAgeDays: params.config.maxAgeDays, nowMs: sweepNowMs }); totalCandidates += candidates.length; reportLines.push(`- Ranked ${candidates.length} candidate(s) for durable promotion.`); if (params.config.verboseLogging) { const candidateSummary = candidates.length > 0 ? candidates.map((candidate) => `${candidate.path}:${candidate.startLine}-${candidate.endLine} score=${candidate.score.toFixed(3)} recalls=${candidate.recallCount} queries=${candidate.uniqueQueries} components={freq=${candidate.components.frequency.toFixed(3)},rel=${candidate.components.relevance.toFixed(3)},div=${candidate.components.diversity.toFixed(3)},rec=${candidate.components.recency.toFixed(3)},cons=${candidate.components.consolidation.toFixed(3)},concept=${candidate.components.conceptual.toFixed(3)}}`).join(" | ") : "none"; params.logger.info(`memory-core: dreaming candidate details [workspace=${workspaceDir}] ${candidateSummary}`); } const applied = await applyShortTermPromotions({ workspaceDir, candidates, limit: params.config.limit, minScore: params.config.minScore, minRecallCount: params.config.minRecallCount, minUniqueQueries: params.config.minUniqueQueries, maxAgeDays: params.config.maxAgeDays, maxPromotedSnippetTokens: params.config.maxPromotedSnippetTokens, timezone: params.config.timezone, nowMs: sweepNowMs }); totalApplied += applied.applied; reportLines.push(`- Promoted ${applied.applied} candidate(s) into MEMORY.md.`); if (params.config.verboseLogging) { const appliedSummary = applied.appliedCandidates.length > 0 ? applied.appliedCandidates.map((candidate) => `${candidate.path}:${candidate.startLine}-${candidate.endLine} score=${candidate.score.toFixed(3)} recalls=${candidate.recallCount}`).join(" | ") : "none"; params.logger.info(`memory-core: dreaming applied details [workspace=${workspaceDir}] ${appliedSummary}`); } await writeDeepDreamingReport({ workspaceDir, bodyLines: reportLines, nowMs: sweepNowMs, timezone: params.config.timezone, storage: params.config.storage ?? { mode: "separate", separateReports: false } }); if (candidates.length > 0 || applied.applied > 0) { const data = { phase: "deep", snippets: candidates.map((c) => c.snippet).filter(Boolean), promotions: applied.appliedCandidates.map((c) => c.snippet).filter(Boolean) }; if (!params.subagent) await appendFallbackNarrativeEntry({ workspaceDir, data, nowMs: sweepNowMs, timezone: params.config.timezone, logger: params.logger, reason: "subagent runtime is unavailable" }); else if (detachNarratives) runDetachedDreamNarrative({ subagent: params.subagent, workspaceDir, data, nowMs: sweepNowMs, timezone: params.config.timezone, model: params.config.execution?.model, logger: params.logger }); else await generateAndAppendDreamNarrative({ subagent: params.subagent, workspaceDir, data, nowMs: sweepNowMs, timezone: params.config.timezone, model: params.config.execution?.model, logger: params.logger }); } } catch (err) { failedWorkspaces += 1; params.logger.error(`memory-core: dreaming promotion failed for workspace ${workspaceDir}: ${formatErrorMessage(err)}`); } params.logger.info(`memory-core: dreaming promotion complete (workspaces=${workspaces.length}, candidates=${totalCandidates}, applied=${totalApplied}, failed=${failedWorkspaces}).`); return { handled: true, reason: "memory-core: short-term dreaming processed" }; } function registerShortTermPromotionDreaming(api) { let resolveStartupCron = null; let gatewayContext = null; let unavailableCronWarningEmitted = false; let lastRuntimeReconcileAtMs = 0; let lastRuntimeConfigKey = null; let lastRuntimeCronRef = null; let startupCronRetryTimer = null; let runtimeCronReconcileTimer = null; let startupCronRetryAttempts = 0; let disposed = false; const resolveCurrentConfig = () => api.runtime.config?.current?.() ?? api.config; const clearStartupCronRetry = () => { if (startupCronRetryTimer) { clearTimeout(startupCronRetryTimer); startupCronRetryTimer = null; } startupCronRetryAttempts = 0; }; const hasStartupCron = () => { try { return Boolean(resolveStartupCron?.()); } catch { return false; } }; const hasCronManagementContext = () => Boolean(resolveStartupCron || gatewayContext?.getCron); const disposeStartupCronRetry = () => { disposed = true; clearStartupCronRetry(); if (runtimeCronReconcileTimer) { clearInterval(runtimeCronReconcileTimer); runtimeCronReconcileTimer = null; } gatewayContext = null; resolveStartupCron = null; }; const runtimeConfigKey = (config) => [ config.enabled ? "enabled" : "disabled", config.cron, config.timezone ?? "", String(config.limit), String(config.minScore), String(config.minRecallCount), String(config.minUniqueQueries), String(config.recencyHalfLifeDays ?? ""), String(config.maxAgeDays ?? ""), config.verboseLogging ? "verbose" : "quiet", config.storage?.mode ?? "", config.storage?.separateReports ? "separate" : "inline" ].join("|"); const reconcileManagedDreamingCron = async (params) => { const startupCfg = params.reason === "startup" ? params.startupConfig ?? api.config : resolveCurrentConfig(); const config = resolveShortTermPromotionDreamingConfig({ pluginConfig: params.reason === "startup" ? resolveMemoryCorePluginConfig(startupCfg) ?? resolveMemoryCorePluginConfig(api.config) ?? api.pluginConfig : resolveMemoryCorePluginConfig(startupCfg), cfg: startupCfg }); if (params.reason === "startup") resolveStartupCron = params.startupCron ?? null; let cron = resolveStartupCron?.() ?? null; if (!cron && params.reason !== "startup" && gatewayContext) try { cron = resolveCronServiceFromGatewayContext(gatewayContext); if (cron) resolveStartupCron = () => cron; } catch {} const configKey = runtimeConfigKey(config); if (!cron && config.enabled && !unavailableCronWarningEmitted) if (params.reason === "startup" || params.reason === "startup_retry") api.logger.debug?.("memory-core: cron service not yet available at gateway_start; deferring to runtime reconciliation."); else { api.logger.warn("memory-core: managed dreaming cron could not be reconciled (cron service unavailable)."); unavailableCronWarningEmitted = true; } if (cron) { unavailableCronWarningEmitted = false; clearStartupCronRetry(); } if (!cron && params.reason === "startup_retry") return config; if (params.reason === "runtime") { const now = Date.now(); if (now - lastRuntimeReconcileAtMs < RUNTIME_CRON_RECONCILE_INTERVAL_MS && lastRuntimeConfigKey === configKey && lastRuntimeCronRef === cron) return config; lastRuntimeReconcileAtMs = now; lastRuntimeConfigKey = configKey; lastRuntimeCronRef = cron; } await reconcileShortTermDreamingCronJob({ cron, config, logger: api.logger }); return config; }; const scheduleStartupCronRetry = () => { if (disposed || hasStartupCron()) { clearStartupCronRetry(); return; } if (startupCronRetryTimer || startupCronRetryAttempts >= STARTUP_CRON_RETRY_MAX_ATTEMPTS) return; startupCronRetryTimer = setTimeout(() => { startupCronRetryTimer = null; if (disposed) return; startupCronRetryAttempts += 1; reconcileManagedDreamingCron({ reason: "startup_retry" }).then(async () => { if (disposed || hasStartupCron()) { clearStartupCronRetry(); return; } if (startupCronRetryAttempts >= STARTUP_CRON_RETRY_MAX_ATTEMPTS) { await reconcileManagedDreamingCron({ reason: "runtime" }); return; } scheduleStartupCronRetry(); }).catch((err) => { if (disposed) return; api.logger.error(`memory-core: deferred dreaming cron retry failed: ${formatErrorMessage(err)}`); scheduleStartupCronRetry(); }); }, STARTUP_CRON_RETRY_DELAY_MS); }; const startRuntimeCronReconcileTimer = () => { if (runtimeCronReconcileTimer) return; runtimeCronReconcileTimer = setInterval(() => { reconcileManagedDreamingCron({ reason: "runtime" }).catch((err) => { api.logger.error(`memory-core: dreaming cron reconcile failed: ${formatErrorMessage(err)}`); }); }, RUNTIME_CRON_RECONCILE_INTERVAL_MS); runtimeCronReconcileTimer.unref?.(); }; api.on("gateway_start", async (_event, ctx) => { disposed = false; gatewayContext = ctx; try { await reconcileManagedDreamingCron({ reason: "startup", startupConfig: ctx.config, startupCron: () => resolveCronServiceFromGatewayContext(ctx) }); startRuntimeCronReconcileTimer(); scheduleStartupCronRetry(); } catch (err) { api.logger.error(`memory-core: dreaming startup reconciliation failed: ${formatErrorMessage(err)}`); } }); api.on("gateway_stop", () => { disposeStartupCronRetry(); }); api.on("before_agent_reply", async (event, ctx) => { try { if (ctx.trigger !== "heartbeat" && ctx.trigger !== "cron") return; const currentConfig = resolveCurrentConfig(); const hasManagedDreamingToken = includesSystemEventToken(event.cleanedBody, MEMORY_DREAMING_SYSTEM_EVENT_TEXT); const isManagedHeartbeatTrigger = ctx.trigger === "heartbeat" && hasPendingManagedDreamingCronEvent(ctx.sessionKey); const isManagedCronTrigger = ctx.trigger === "cron"; const shouldHandleManagedDreaming = hasManagedDreamingToken && (isManagedHeartbeatTrigger || isManagedCronTrigger); if (!shouldHandleManagedDreaming && !hasCronManagementContext()) return; const config = await reconcileManagedDreamingCron({ reason: "runtime" }); if (!shouldHandleManagedDreaming) return; return await runShortTermDreamingPromotionIfTriggered({ cleanedBody: event.cleanedBody, trigger: ctx.trigger, workspaceDir: ctx.workspaceDir, cfg: currentConfig, config, logger: api.logger, subagent: config.enabled ? api.runtime?.subagent : void 0 }); } catch (err) { api.logger.error(`memory-core: dreaming trigger failed: ${formatErrorMessage(err)}`); return; } }); } //#endregion export { resolveShortTermPromotionDreamingConfig as n, registerShortTermPromotionDreaming as t };