fix(memory): initialize candidates and enforce lifecycle rollout
Memind CI / Test, build, and release guards (push) Successful in 3m29s
Memind CI / Test, build, and release guards (push) Successful in 3m29s
This commit is contained in:
+34
-9
@@ -5,7 +5,10 @@ import { createLegacyMemoryBackend, createMemoryV2, resolveMemoryV2Policy } from
|
||||
import { createLettaHttpClient, createLettaMemoryBackend } from './memory-v2-letta.mjs';
|
||||
import { createMemoryV2PluginBackends } from './memory-v2-plugin-backends.mjs';
|
||||
import { createPersonalMemoryShadowPipeline } from './memory-v2-personal-shadow.mjs';
|
||||
import { createPersonalMemoryCandidateStore } from './memory-v2-personal-store.mjs';
|
||||
import {
|
||||
createPersonalMemoryCandidateStore,
|
||||
ensurePersonalMemoryCandidateSchema,
|
||||
} from './memory-v2-personal-store.mjs';
|
||||
import { createMem0HttpClient, createMem0MemoryBackend } from './memory-v2-mem0.mjs';
|
||||
import { createNeo4jHttpClient, createNeo4jMemoryBackend } from './memory-v2-neo4j.mjs';
|
||||
import { createPgvectorMemoryBackend } from './memory-v2-pgvector.mjs';
|
||||
@@ -13,7 +16,10 @@ import { backfillLegacyMemoriesToPgvector } from './memory-v2-pgvector-backfill.
|
||||
import { createQdrantHttpClient, createQdrantMemoryBackend } from './memory-v2-qdrant.mjs';
|
||||
import { createRedisStreamsClient, createRedisStreamsMemoryBackend } from './memory-v2-redis-streams.mjs';
|
||||
import { createWeaviateHttpClient, createWeaviateMemoryBackend } from './memory-v2-weaviate.mjs';
|
||||
import { createMemoryV2LifecycleService } from './memory-v2-lifecycle.mjs';
|
||||
import {
|
||||
createMemoryV2LifecycleService,
|
||||
resolveMemoryV2LifecycleWorkerScopes,
|
||||
} from './memory-v2-lifecycle.mjs';
|
||||
|
||||
const DEFAULT_PGVECTOR_URL_ENV = 'MEMORY_PGVECTOR_DATABASE_URL';
|
||||
|
||||
@@ -403,9 +409,17 @@ export async function createMemoryV2Runtime({
|
||||
],
|
||||
}));
|
||||
|
||||
const personalCandidateStore = readFlag(env, 'MEMORY_CANDIDATE_PERSISTENCE_ENABLED', false)
|
||||
? createPersonalMemoryCandidateStore(mysqlPool)
|
||||
: null;
|
||||
let personalCandidateStore = null;
|
||||
if (readFlag(env, 'MEMORY_CANDIDATE_PERSISTENCE_ENABLED', false) && mysqlPool?.query) {
|
||||
try {
|
||||
await ensurePersonalMemoryCandidateSchema(mysqlPool);
|
||||
personalCandidateStore = createPersonalMemoryCandidateStore(mysqlPool);
|
||||
} catch (err) {
|
||||
logger?.warn?.(
|
||||
`[memory-v2] candidate persistence unavailable: ${err instanceof Error ? err.message : err}`,
|
||||
);
|
||||
}
|
||||
}
|
||||
const personalShadowPipeline = createPersonalMemoryShadowPipeline({
|
||||
env,
|
||||
store: personalCandidateStore,
|
||||
@@ -420,11 +434,22 @@ export async function createMemoryV2Runtime({
|
||||
const lifecycle = createMemoryV2LifecycleService({ pool: mysqlPool, env, logger });
|
||||
let lifecycleTimer = null;
|
||||
const lifecycleWorkerEnabled = readFlag(env, 'MEMORY_LIFECYCLE_WORKER_ENABLED', false);
|
||||
if (lifecycleWorkerEnabled && mysqlPool?.query) {
|
||||
const lifecycleWorkerScopes = resolveMemoryV2LifecycleWorkerScopes(lifecycle.policy);
|
||||
if (lifecycleWorkerEnabled && mysqlPool?.query && lifecycleWorkerScopes.length > 0) {
|
||||
const intervalMs = Math.max(60_000, Number(lifecycle.policy.compactIntervalHours ?? 24) * 3_600_000);
|
||||
const runLifecycle = () => lifecycle.expire().then(() => lifecycle.compact()).then(() => lifecycle.promote()).then(() => lifecycle.reflect()).catch((err) => {
|
||||
logger?.warn?.(`[memory-v2] lifecycle worker skipped: ${err instanceof Error ? err.message : err}`);
|
||||
});
|
||||
const runLifecycle = async () => {
|
||||
try {
|
||||
for (const userId of lifecycleWorkerScopes) {
|
||||
const input = userId == null ? {} : { userId };
|
||||
await lifecycle.expire(input);
|
||||
await lifecycle.compact(input);
|
||||
await lifecycle.promote(input);
|
||||
await lifecycle.reflect(input);
|
||||
}
|
||||
} catch (err) {
|
||||
logger?.warn?.(`[memory-v2] lifecycle worker skipped: ${err instanceof Error ? err.message : err}`);
|
||||
}
|
||||
};
|
||||
lifecycleTimer = setInterval(runLifecycle, intervalMs);
|
||||
lifecycleTimer.unref?.();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user