@joshuaswarren/openclaw-engram 9.0.98 → 9.0.99

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,76 @@ 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
+ if (globalThis[ENGRAM_INIT_PROMISE]) {
13984
+ await globalThis[ENGRAM_INIT_PROMISE];
13985
+ if (globalThis[ENGRAM_SERVICE_STARTED]) return;
13993
13986
  }
13994
- if (cfg.agentAccessHttp.enabled) {
13987
+ if (globalThis[ENGRAM_SERVICE_STARTED]) {
13988
+ log.debug("openclaw-engram: service.start() called again \u2014 skipping duplicate init");
13989
+ return;
13990
+ }
13991
+ didCountStart = true;
13992
+ const initPromise = (async () => {
13995
13993
  try {
13996
- const status = await accessHttpServer.start();
13997
- log.info(`engram access HTTP ready at http://${status.host}:${status.port}`);
13994
+ log.info("initializing engram memory system...");
13995
+ await orchestrator.initialize();
13996
+ if (!didCountStart) return;
13997
+ activeOpikExporter = createOpikExporter({}, log);
13998
+ if (activeOpikExporter) activeOpikExporter.subscribe();
13999
+ if (orchestrator.config.transcriptEnabled) {
14000
+ await orchestrator.transcript.cleanup(orchestrator.config.transcriptRetentionDays);
14001
+ if (!didCountStart) return;
14002
+ }
14003
+ if (orchestrator.config.hourlySummariesEnabled && orchestrator.config.hourlySummaryCronAutoRegister) {
14004
+ await ensureHourlySummaryCron(api);
14005
+ if (!didCountStart) return;
14006
+ } else if (orchestrator.config.hourlySummariesEnabled) {
14007
+ log.info(
14008
+ "hourly summaries enabled; cron auto-register is disabled. To schedule summaries, create an isolated/agentTurn cron job that calls `memory_summarize_hourly`."
14009
+ );
14010
+ }
14011
+ if (cfg.agentAccessHttp.enabled) {
14012
+ if (!didCountStart) return;
14013
+ try {
14014
+ const status = await accessHttpServer.start();
14015
+ log.info(`engram access HTTP ready at http://${status.host}:${status.port}`);
14016
+ } catch (err) {
14017
+ log.error("failed to start engram access HTTP server", err);
14018
+ }
14019
+ }
14020
+ if (!didCountStart) return;
14021
+ log.info("engram memory system ready");
13998
14022
  } catch (err) {
13999
- log.error("failed to start engram access HTTP server", err);
14023
+ try {
14024
+ activeOpikExporter?.unsubscribe();
14025
+ } catch {
14026
+ }
14027
+ activeOpikExporter = null;
14028
+ didCountStart = false;
14029
+ globalThis[ENGRAM_SERVICE_STARTED] = false;
14030
+ throw err;
14000
14031
  }
14032
+ })();
14033
+ globalThis[ENGRAM_INIT_PROMISE] = initPromise;
14034
+ globalThis[ENGRAM_SERVICE_STARTED] = true;
14035
+ try {
14036
+ await initPromise;
14037
+ } finally {
14038
+ globalThis[ENGRAM_INIT_PROMISE] = null;
14001
14039
  }
14002
- log.info("engram memory system ready");
14003
14040
  },
14004
14041
  stop: async () => {
14005
- activeOpikExporter?.unsubscribe();
14042
+ if (!didCountStart) return;
14043
+ didCountStart = false;
14044
+ try {
14045
+ activeOpikExporter?.unsubscribe();
14046
+ } catch (err) {
14047
+ log.debug(`engram opik exporter unsubscribe failed: ${err}`);
14048
+ }
14006
14049
  activeOpikExporter = null;
14007
14050
  try {
14008
14051
  await accessHttpServer.stop();
@@ -14013,6 +14056,7 @@ Use this context naturally when relevant. Never quote or expose this memory cont
14013
14056
  delete globalThis[ENGRAM_ACCESS_SERVICE];
14014
14057
  globalThis[ENGRAM_REGISTERED_GUARD] = false;
14015
14058
  globalThis[ENGRAM_HOOK_APIS] = /* @__PURE__ */ new WeakSet();
14059
+ globalThis[ENGRAM_SERVICE_STARTED] = false;
14016
14060
  log.info("stopped");
14017
14061
  }
14018
14062
  });