@joshuaswarren/openclaw-engram 9.0.98 → 9.0.100

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -13509,6 +13509,8 @@ var ENGRAM_REGISTERED_GUARD = "__openclawEngramRegistered";
13509
13509
  var ENGRAM_HOOK_APIS = "__openclawEngramHookApis";
13510
13510
  var ENGRAM_ACCESS_SERVICE = "__openclawEngramAccessService";
13511
13511
  var ENGRAM_ACCESS_HTTP_SERVER = "__openclawEngramAccessHttpServer";
13512
+ var ENGRAM_SERVICE_STARTED = "__openclawEngramServiceStarted";
13513
+ var ENGRAM_INIT_PROMISE = "__openclawEngramInitPromise";
13512
13514
  function loadPluginConfigFromFile() {
13513
13515
  try {
13514
13516
  const explicitConfigPath = process.env.OPENCLAW_ENGRAM_CONFIG_PATH || process.env.OPENCLAW_CONFIG_PATH;
@@ -13974,35 +13976,83 @@ Use this context naturally when relevant. Never quote or expose this memory cont
13974
13976
  registerCli(api, orchestrator);
13975
13977
  }
13976
13978
  let activeOpikExporter = null;
13977
- if (isFirstRegistration) api.registerService({
13979
+ let didCountStart = false;
13980
+ api.registerService({
13978
13981
  id: "openclaw-engram",
13979
13982
  start: async () => {
13980
- log.info("initializing engram memory system...");
13981
- await orchestrator.initialize();
13982
- activeOpikExporter = createOpikExporter({}, log);
13983
- if (activeOpikExporter) activeOpikExporter.subscribe();
13984
- if (orchestrator.config.transcriptEnabled) {
13985
- await orchestrator.transcript.cleanup(orchestrator.config.transcriptRetentionDays);
13986
- }
13987
- if (orchestrator.config.hourlySummariesEnabled && orchestrator.config.hourlySummaryCronAutoRegister) {
13988
- await ensureHourlySummaryCron(api);
13989
- } else if (orchestrator.config.hourlySummariesEnabled) {
13990
- log.info(
13991
- "hourly summaries enabled; cron auto-register is disabled. To schedule summaries, create an isolated/agentTurn cron job that calls `memory_summarize_hourly`."
13992
- );
13983
+ for (; ; ) {
13984
+ while (globalThis[ENGRAM_INIT_PROMISE]) {
13985
+ try {
13986
+ await globalThis[ENGRAM_INIT_PROMISE];
13987
+ } catch {
13988
+ }
13989
+ if (globalThis[ENGRAM_SERVICE_STARTED]) return;
13990
+ }
13991
+ if (globalThis[ENGRAM_SERVICE_STARTED]) {
13992
+ log.debug("openclaw-engram: service.start() called again \u2014 skipping duplicate init");
13993
+ return;
13994
+ }
13995
+ if (globalThis[ENGRAM_INIT_PROMISE]) continue;
13996
+ break;
13993
13997
  }
13994
- if (cfg.agentAccessHttp.enabled) {
13998
+ didCountStart = true;
13999
+ const initPromise = (async () => {
13995
14000
  try {
13996
- const status = await accessHttpServer.start();
13997
- log.info(`engram access HTTP ready at http://${status.host}:${status.port}`);
14001
+ log.info("initializing engram memory system...");
14002
+ await orchestrator.initialize();
14003
+ if (!didCountStart) return;
14004
+ activeOpikExporter = createOpikExporter({}, log);
14005
+ if (activeOpikExporter) activeOpikExporter.subscribe();
14006
+ if (orchestrator.config.transcriptEnabled) {
14007
+ await orchestrator.transcript.cleanup(orchestrator.config.transcriptRetentionDays);
14008
+ if (!didCountStart) return;
14009
+ }
14010
+ if (orchestrator.config.hourlySummariesEnabled && orchestrator.config.hourlySummaryCronAutoRegister) {
14011
+ await ensureHourlySummaryCron(api);
14012
+ if (!didCountStart) return;
14013
+ } else if (orchestrator.config.hourlySummariesEnabled) {
14014
+ log.info(
14015
+ "hourly summaries enabled; cron auto-register is disabled. To schedule summaries, create an isolated/agentTurn cron job that calls `memory_summarize_hourly`."
14016
+ );
14017
+ }
14018
+ if (cfg.agentAccessHttp.enabled) {
14019
+ if (!didCountStart) return;
14020
+ try {
14021
+ const status = await accessHttpServer.start();
14022
+ log.info(`engram access HTTP ready at http://${status.host}:${status.port}`);
14023
+ } catch (err) {
14024
+ log.error("failed to start engram access HTTP server", err);
14025
+ }
14026
+ }
14027
+ if (!didCountStart) return;
14028
+ globalThis[ENGRAM_SERVICE_STARTED] = true;
14029
+ log.info("engram memory system ready");
13998
14030
  } catch (err) {
13999
- log.error("failed to start engram access HTTP server", err);
14031
+ try {
14032
+ activeOpikExporter?.unsubscribe();
14033
+ } catch {
14034
+ }
14035
+ activeOpikExporter = null;
14036
+ didCountStart = false;
14037
+ globalThis[ENGRAM_SERVICE_STARTED] = false;
14038
+ throw err;
14000
14039
  }
14040
+ })();
14041
+ globalThis[ENGRAM_INIT_PROMISE] = initPromise;
14042
+ try {
14043
+ await initPromise;
14044
+ } finally {
14045
+ globalThis[ENGRAM_INIT_PROMISE] = null;
14001
14046
  }
14002
- log.info("engram memory system ready");
14003
14047
  },
14004
14048
  stop: async () => {
14005
- activeOpikExporter?.unsubscribe();
14049
+ if (!didCountStart) return;
14050
+ didCountStart = false;
14051
+ try {
14052
+ activeOpikExporter?.unsubscribe();
14053
+ } catch (err) {
14054
+ log.debug(`engram opik exporter unsubscribe failed: ${err}`);
14055
+ }
14006
14056
  activeOpikExporter = null;
14007
14057
  try {
14008
14058
  await accessHttpServer.stop();
@@ -14011,8 +14061,26 @@ Use this context naturally when relevant. Never quote or expose this memory cont
14011
14061
  }
14012
14062
  delete globalThis[ENGRAM_ACCESS_HTTP_SERVER];
14013
14063
  delete globalThis[ENGRAM_ACCESS_SERVICE];
14014
- globalThis[ENGRAM_REGISTERED_GUARD] = false;
14015
- globalThis[ENGRAM_HOOK_APIS] = /* @__PURE__ */ new WeakSet();
14064
+ const currentInitPromise = globalThis[ENGRAM_INIT_PROMISE];
14065
+ let secondaryTookOver = false;
14066
+ if (!currentInitPromise) {
14067
+ globalThis[ENGRAM_REGISTERED_GUARD] = false;
14068
+ } else {
14069
+ try {
14070
+ await currentInitPromise;
14071
+ } catch {
14072
+ }
14073
+ await new Promise((resolve) => queueMicrotask(resolve));
14074
+ if (globalThis[ENGRAM_INIT_PROMISE] || globalThis[ENGRAM_SERVICE_STARTED]) {
14075
+ secondaryTookOver = true;
14076
+ }
14077
+ }
14078
+ if (!secondaryTookOver) {
14079
+ globalThis[ENGRAM_HOOK_APIS] = /* @__PURE__ */ new WeakSet();
14080
+ }
14081
+ if (!secondaryTookOver) {
14082
+ globalThis[ENGRAM_SERVICE_STARTED] = false;
14083
+ }
14016
14084
  log.info("stopped");
14017
14085
  }
14018
14086
  });