feat(memory): add gated agent recall and lifecycle controls
This commit is contained in:
@@ -67,10 +67,39 @@ export function resolveMemoryV2Policy({ env = process.env, overrides = {} } = {}
|
||||
vectorEnabled: readFlag(env, 'MEMORY_VECTOR_ENABLED', false),
|
||||
backend: String(env?.MEMORY_BACKEND ?? 'legacy').trim() || 'legacy',
|
||||
failOpen: readFlag(env, 'MEMORY_FAIL_OPEN', true),
|
||||
agentResolveEnabled: readFlag(env, 'MEMORY_AGENT_RESOLVE_ENABLED', false),
|
||||
agentInjectionMode: normalizeAgentInjectionMode(env?.MEMORY_AGENT_INJECTION_MODE),
|
||||
agentCanaryUserIds: normalizeUserIdList(env?.MEMORY_AGENT_CANARY_USER_IDS),
|
||||
agentResolveLimit: resolveBoundedNumber(env?.MEMORY_AGENT_RESOLVE_LIMIT, 3, 1, 50),
|
||||
agentResolveTimeoutMs: resolveBoundedNumber(env?.MEMORY_AGENT_RESOLVE_TIMEOUT_MS, 1200, 0, 30000),
|
||||
promotionEnabled: readFlag(env, 'MEMORY_PROMOTION_ENABLED', false),
|
||||
compactionV2Enabled: readFlag(env, 'MEMORY_COMPACTION_V2_ENABLED', false),
|
||||
reflectionEnabled: readFlag(env, 'MEMORY_REFLECTION_ENABLED', false),
|
||||
lifecycleWorkerEnabled: readFlag(env, 'MEMORY_LIFECYCLE_WORKER_ENABLED', false),
|
||||
lifecycleRolloutMode: String(env?.MEMORY_LIFECYCLE_ROLLOUT_MODE ?? 'off').trim().toLowerCase() || 'off',
|
||||
lifecycleRolloutUserIds: normalizeUserIdList(env?.MEMORY_LIFECYCLE_ROLLOUT_USER_IDS),
|
||||
...overrides,
|
||||
};
|
||||
}
|
||||
|
||||
function resolveBoundedNumber(value, fallback, min, max) {
|
||||
const parsed = Number(value);
|
||||
if (!Number.isFinite(parsed)) return fallback;
|
||||
return Math.min(max, Math.max(min, parsed));
|
||||
}
|
||||
|
||||
function normalizeAgentInjectionMode(value) {
|
||||
const mode = String(value ?? 'off').trim().toLowerCase();
|
||||
return ['off', 'shadow', 'canary', 'active'].includes(mode) ? mode : 'off';
|
||||
}
|
||||
|
||||
function normalizeUserIdList(value) {
|
||||
return [...new Set(String(value ?? '')
|
||||
.split(/[\s,]+/u)
|
||||
.map((item) => item.trim())
|
||||
.filter(Boolean))].slice(0, 1000);
|
||||
}
|
||||
|
||||
export function createLegacyMemoryBackend(conversationMemoryService) {
|
||||
return {
|
||||
name: 'legacy-conversation-memory',
|
||||
@@ -373,6 +402,19 @@ export function createMemoryV2({
|
||||
eventLogEnabled: Boolean(resolvedPolicy.eventLogEnabled),
|
||||
vectorEnabled: Boolean(resolvedPolicy.vectorEnabled),
|
||||
failOpen: Boolean(resolvedPolicy.failOpen),
|
||||
runtimeControl: {
|
||||
agentResolveEnabled: Boolean(resolvedPolicy.agentResolveEnabled),
|
||||
agentInjectionMode: resolvedPolicy.agentInjectionMode,
|
||||
agentCanaryUserIds: resolvedPolicy.agentCanaryUserIds,
|
||||
agentResolveLimit: Number(resolvedPolicy.agentResolveLimit),
|
||||
agentResolveTimeoutMs: Number(resolvedPolicy.agentResolveTimeoutMs),
|
||||
promotionEnabled: Boolean(resolvedPolicy.promotionEnabled),
|
||||
compactionV2Enabled: Boolean(resolvedPolicy.compactionV2Enabled),
|
||||
reflectionEnabled: Boolean(resolvedPolicy.reflectionEnabled),
|
||||
lifecycleWorkerEnabled: Boolean(resolvedPolicy.lifecycleWorkerEnabled),
|
||||
lifecycleRolloutMode: resolvedPolicy.lifecycleRolloutMode,
|
||||
lifecycleRolloutUserIds: resolvedPolicy.lifecycleRolloutUserIds,
|
||||
},
|
||||
backends,
|
||||
};
|
||||
if (shadowPipeline?.config?.enabled) {
|
||||
|
||||
Reference in New Issue
Block a user