Files
oh-my-pi/packages/mnemopi/test/recall-feature-flags.test.ts
T
Wolfgang Schoenberger 8eb8ec4b74 fix(mnemopi): make proactive linking configurable from host settings
Proactive linking (ingesting new memories into the episodic graph as they
are stored) could only be toggled through the MNEMOPI_PROACTIVE_LINKING
environment variable, unlike its sibling recall features polyphonicRecall
and enhancedRecall, which hosts drive through configureRecallFeatures() and
the coding-agent mnemopi.polyphonicRecall / mnemopi.enhancedRecall
config.yml settings. The write-path gate in store.ts read process.env
directly and the existing env-only proactiveLinkingEnabled() helper was
dead code, so host configuration never reached it.

- Add proactiveLinking to RecallFeatureFlags / configureRecallFeatures()
  and rewrite proactiveLinkingEnabled() to fall back to the configured
  default, matching the polyphonic/enhanced resolvers. The
  MNEMOPI_PROACTIVE_LINKING env var still takes precedence when set.
- Route the store.ts proactiveLinkIfEnabled gate through
  proactiveLinkingEnabled() instead of reading process.env directly.
- Add the mnemopi.proactiveLinking coding-agent config.yml setting (off by
  default, /settings -> Memory -> Mnemopi) and wire it through
  loadMnemopiConfig and createScopedResources.

Closes #2440

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-18 13:29:03 -07:00

64 lines
3.0 KiB
TypeScript

import { afterEach, describe, expect, it } from "bun:test";
import {
configureRecallFeatures,
enhancedRecallEnabled,
polyphonicRecallEnabled,
proactiveLinkingEnabled,
} from "@oh-my-pi/pi-mnemopi/config";
import { polyphonicRecallIsEnabled } from "@oh-my-pi/pi-mnemopi/core/polyphonic-recall";
import { isEnhancedRecallEnabled, isQueryCacheEnabled } from "@oh-my-pi/pi-mnemopi/core/query-cache";
afterEach(() => {
configureRecallFeatures({ polyphonicRecall: false, enhancedRecall: false, proactiveLinking: false });
});
describe("configureRecallFeatures", () => {
it("keeps all recall gates off by default", () => {
expect(polyphonicRecallEnabled({})).toBe(false);
expect(enhancedRecallEnabled({})).toBe(false);
expect(proactiveLinkingEnabled({})).toBe(false);
expect(isEnhancedRecallEnabled({})).toBe(false);
expect(isQueryCacheEnabled(true, {})).toBe(false);
});
it("enables the gates from host configuration when the env vars are unset", () => {
configureRecallFeatures({ polyphonicRecall: true, enhancedRecall: true, proactiveLinking: true });
expect(polyphonicRecallEnabled({})).toBe(true);
expect(polyphonicRecallIsEnabled({})).toBe(true);
expect(enhancedRecallEnabled({})).toBe(true);
expect(proactiveLinkingEnabled({})).toBe(true);
expect(isEnhancedRecallEnabled({})).toBe(true);
expect(isQueryCacheEnabled(true, {})).toBe(true);
expect(isQueryCacheEnabled(false, {})).toBe(false);
});
it("lets the env vars override the configured value in both directions", () => {
configureRecallFeatures({ polyphonicRecall: true, enhancedRecall: true, proactiveLinking: true });
expect(polyphonicRecallEnabled({ MNEMOPI_POLYPHONIC_RECALL: "0" })).toBe(false);
expect(enhancedRecallEnabled({ MNEMOPI_ENHANCED_RECALL: "0" })).toBe(false);
expect(proactiveLinkingEnabled({ MNEMOPI_PROACTIVE_LINKING: "0" })).toBe(false);
expect(isQueryCacheEnabled(true, { MNEMOPI_ENHANCED_RECALL: "0" })).toBe(false);
configureRecallFeatures({ polyphonicRecall: false, enhancedRecall: false, proactiveLinking: false });
expect(polyphonicRecallEnabled({ MNEMOPI_POLYPHONIC_RECALL: "1" })).toBe(true);
expect(enhancedRecallEnabled({ MNEMOPI_ENHANCED_RECALL: "1" })).toBe(true);
expect(proactiveLinkingEnabled({ MNEMOPI_PROACTIVE_LINKING: "1" })).toBe(true);
expect(isQueryCacheEnabled(true, { MNEMOPI_ENHANCED_RECALL: "1" })).toBe(true);
});
it("updates only the flags that are present", () => {
configureRecallFeatures({ polyphonicRecall: true });
expect(polyphonicRecallEnabled({})).toBe(true);
expect(enhancedRecallEnabled({})).toBe(false);
expect(proactiveLinkingEnabled({})).toBe(false);
configureRecallFeatures({ enhancedRecall: true });
expect(polyphonicRecallEnabled({})).toBe(true);
expect(enhancedRecallEnabled({})).toBe(true);
expect(proactiveLinkingEnabled({})).toBe(false);
configureRecallFeatures({ proactiveLinking: true });
expect(polyphonicRecallEnabled({})).toBe(true);
expect(enhancedRecallEnabled({})).toBe(true);
expect(proactiveLinkingEnabled({})).toBe(true);
});
});