@remnic/plugin-openclaw 9.25.7 → 9.27.0

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
@@ -5275,6 +5275,7 @@ function resolveRemnicOpenClawPluginEntry(raw, preferredId) {
5275
5275
  import path4 from "path";
5276
5276
  import { renderMemoryContextPrompt } from "@remnic/core";
5277
5277
  import { log as log2 } from "@remnic/core/logger";
5278
+ import { SESSION_NAMESPACE_BINDING_MAX_ENTRIES, SESSION_NAMESPACE_BINDING_MAX_NAMESPACES, SESSION_NAMESPACE_BINDING_MAX_NAMESPACE_LENGTH, createFileSessionNamespaceBindingStore } from "@remnic/core/session-namespace-bindings";
5278
5279
  import { createFileToggleStore } from "@remnic/core/session-toggles";
5279
5280
 
5280
5281
  // src/bridge.ts
@@ -5605,6 +5606,7 @@ function extractTextContent(msg) {
5605
5606
  }
5606
5607
 
5607
5608
  // src/delegate-runtime.ts
5609
+ var DELEGATE_BATCH_FLUSH_CACHE_TTL_MS = 3e4;
5608
5610
  var DEFAULT_DELEGATE_AUTHORIZATION_OPERATIONS = [
5609
5611
  "recall",
5610
5612
  "observe",
@@ -5668,6 +5670,30 @@ async function postJson(target, serviceId, pathname, body, timeoutMs) {
5668
5670
  const parsed = await res.json().catch(() => null);
5669
5671
  return typeof parsed === "object" && parsed !== null ? parsed : null;
5670
5672
  }
5673
+ async function getJson(target, serviceId, pathname, timeoutMs) {
5674
+ const headers = {};
5675
+ const auth = target.resolveAuthToken();
5676
+ if (auth.token) headers.Authorization = `Bearer ${auth.token}`;
5677
+ const res = await fetch(daemonUrl(target, pathname), {
5678
+ headers,
5679
+ signal: AbortSignal.timeout(timeoutMs)
5680
+ });
5681
+ if (!res.ok) {
5682
+ if (res.status === 401 || res.status === 403) {
5683
+ const status = res.status === 401 ? 401 : 403;
5684
+ await res.body?.cancel();
5685
+ reportDaemonAuthorizationFailure(serviceId, pathname, status, auth.source);
5686
+ return { status: res.status, body: null };
5687
+ }
5688
+ await res.body?.cancel();
5689
+ return { status: res.status, body: null };
5690
+ }
5691
+ const parsed = await res.json().catch(() => null);
5692
+ return {
5693
+ status: res.status,
5694
+ body: typeof parsed === "object" && parsed !== null ? parsed : null
5695
+ };
5696
+ }
5671
5697
  function sessionKeyFrom(event, ctx) {
5672
5698
  const fromCtx = ctx?.sessionKey;
5673
5699
  if (typeof fromCtx === "string" && fromCtx.length > 0) return fromCtx;
@@ -5675,6 +5701,13 @@ function sessionKeyFrom(event, ctx) {
5675
5701
  if (typeof fromEvent === "string" && fromEvent.length > 0) return fromEvent;
5676
5702
  return "default";
5677
5703
  }
5704
+ function lifecycleSessionKeyFrom(event, ctx) {
5705
+ const fromEvent = event?.sessionKey;
5706
+ if (fromEvent !== void 0) {
5707
+ return typeof fromEvent === "string" && fromEvent.length > 0 ? fromEvent : void 0;
5708
+ }
5709
+ return sessionKeyFrom(event, ctx);
5710
+ }
5678
5711
  function recallQueryFrom(event) {
5679
5712
  let prompt = typeof event.prompt === "string" ? event.prompt : void 0;
5680
5713
  if ((!prompt || prompt.length < 5) && Array.isArray(event.messages)) {
@@ -5699,7 +5732,67 @@ function cwdFrom(event, ctx, fallback) {
5699
5732
  return fallback;
5700
5733
  }
5701
5734
  function withNamespace(namespace, body) {
5702
- return namespace.length > 0 ? { ...body, namespace } : body;
5735
+ return namespace ? { ...body, namespace } : body;
5736
+ }
5737
+ function explicitSessionNamespaceFrom(sessionKey, event, ctx) {
5738
+ const eventSessionKey = typeof event.sessionKey === "string" ? event.sessionKey : void 0;
5739
+ const ctxSessionKey = typeof ctx.sessionKey === "string" ? ctx.sessionKey : void 0;
5740
+ const sources = eventSessionKey === sessionKey ? [event, ctx] : ctxSessionKey === sessionKey ? [ctx, event] : [ctx, event];
5741
+ for (const source of sources) {
5742
+ const sourceSessionKey = typeof source.sessionKey === "string" ? source.sessionKey : void 0;
5743
+ if (sourceSessionKey !== sessionKey) continue;
5744
+ const runtime = source.runtime;
5745
+ if (typeof runtime !== "object" || runtime === null) continue;
5746
+ const agent = runtime.agent;
5747
+ if (typeof agent !== "object" || agent === null) continue;
5748
+ const session = agent.session;
5749
+ if (typeof session !== "object" || session === null) continue;
5750
+ const namespace = session.namespace;
5751
+ if (namespace !== void 0 && typeof namespace !== "string") {
5752
+ throw new Error("delegate session namespace metadata must be a string");
5753
+ }
5754
+ return { namespace: typeof namespace === "string" ? namespace.trim() || void 0 : void 0 };
5755
+ }
5756
+ return void 0;
5757
+ }
5758
+ async function rememberedNamespacesFor(sessionKey, namespaceBindings) {
5759
+ return namespaceBindings.namespacesFor(sessionKey);
5760
+ }
5761
+ async function rememberNamespace(sessionKey, namespace, namespaceBindings) {
5762
+ if (namespace.length > SESSION_NAMESPACE_BINDING_MAX_NAMESPACE_LENGTH) {
5763
+ throw new Error(
5764
+ `delegate session namespace exceeds the daemon limit of ${SESSION_NAMESPACE_BINDING_MAX_NAMESPACE_LENGTH} characters`
5765
+ );
5766
+ }
5767
+ try {
5768
+ await namespaceBindings.remember(sessionKey, namespace);
5769
+ } catch (err) {
5770
+ log2.warn(`delegate namespace binding persistence failed: ${String(err)}`);
5771
+ throw err;
5772
+ }
5773
+ }
5774
+ async function sessionNamespaceFrom(sessionKey, event, ctx, fallback, namespaceBindings) {
5775
+ const explicit = explicitSessionNamespaceFrom(sessionKey, event, ctx);
5776
+ if (explicit !== void 0) {
5777
+ await rememberNamespace(sessionKey, explicit.namespace ?? "", namespaceBindings);
5778
+ return explicit.namespace;
5779
+ }
5780
+ const remembered = await rememberedNamespacesFor(sessionKey, namespaceBindings);
5781
+ return remembered.length > 0 ? remembered.at(-1) || void 0 : fallback.trim() || void 0;
5782
+ }
5783
+ async function lifecycleSessionNamespacesFrom(sessionKey, event, ctx, fallback, namespaceBindings) {
5784
+ const explicit = explicitSessionNamespaceFrom(sessionKey, event, ctx);
5785
+ if (explicit !== void 0) {
5786
+ await rememberNamespace(sessionKey, explicit.namespace ?? "", namespaceBindings);
5787
+ }
5788
+ const remembered = await rememberedNamespacesFor(sessionKey, namespaceBindings);
5789
+ if (explicit !== void 0) {
5790
+ const explicitNamespace = explicit.namespace ?? "";
5791
+ const namespaces = remembered.includes(explicitNamespace) ? remembered : [...remembered, explicitNamespace];
5792
+ return namespaces.map((namespace) => namespace || void 0);
5793
+ }
5794
+ if (remembered.length > 0) return remembered.map((namespace) => namespace || void 0);
5795
+ return [fallback.trim() || void 0];
5703
5796
  }
5704
5797
  function readContextComposition(response, fallbackContext) {
5705
5798
  const candidate = response.contextComposition;
@@ -5712,7 +5805,8 @@ function readContextComposition(response, fallbackContext) {
5712
5805
  return { context: candidate.context };
5713
5806
  }
5714
5807
  function registerDelegateRuntime(api, options) {
5715
- const { target, namespace } = options;
5808
+ const { target, namespace, namespaceBindings } = options;
5809
+ const now = options.now ?? Date.now;
5716
5810
  if (options.passive) {
5717
5811
  log2.info(
5718
5812
  `[${options.serviceId}] bridge mode delegate: memory slot not owned \u2014 passive, no hooks registered`
@@ -5739,11 +5833,18 @@ function registerDelegateRuntime(api, options) {
5739
5833
  return void 0;
5740
5834
  }
5741
5835
  const cwd = cwdFrom(event, ctx, options.cwd);
5836
+ const scopedNamespace = await sessionNamespaceFrom(
5837
+ sessionKey,
5838
+ event,
5839
+ ctx,
5840
+ namespace,
5841
+ namespaceBindings
5842
+ );
5742
5843
  const response = await postJson(
5743
5844
  target,
5744
5845
  options.serviceId,
5745
5846
  "/engram/v1/recall",
5746
- withNamespace(namespace, {
5847
+ withNamespace(scopedNamespace, {
5747
5848
  query,
5748
5849
  sessionKey,
5749
5850
  mode: "auto",
@@ -5815,11 +5916,18 @@ function registerDelegateRuntime(api, options) {
5815
5916
  if (turn.length === 0) return;
5816
5917
  try {
5817
5918
  const cwd = cwdFrom(event, ctx, options.cwd);
5919
+ const scopedNamespace = await sessionNamespaceFrom(
5920
+ sessionKey,
5921
+ event,
5922
+ ctx,
5923
+ namespace,
5924
+ namespaceBindings
5925
+ );
5818
5926
  await postJson(
5819
5927
  target,
5820
5928
  options.serviceId,
5821
5929
  "/engram/v1/observe",
5822
- withNamespace(namespace, {
5930
+ withNamespace(scopedNamespace, {
5823
5931
  sessionKey,
5824
5932
  messages: turn,
5825
5933
  ...cwd ? { cwd } : {},
@@ -5831,25 +5939,129 @@ function registerDelegateRuntime(api, options) {
5831
5939
  log2.warn(`delegate observe failed: ${String(err)}`);
5832
5940
  }
5833
5941
  });
5942
+ let cachedBatchFlushSupport;
5943
+ let cachedBatchFlushSupportExpiresAt = 0;
5944
+ let supportsBatchFlushPromise;
5945
+ const invalidateCachedBatchFlushSupport = () => {
5946
+ cachedBatchFlushSupport = void 0;
5947
+ cachedBatchFlushSupportExpiresAt = 0;
5948
+ };
5949
+ const cacheBatchFlushSupport = (supported) => {
5950
+ cachedBatchFlushSupport = supported;
5951
+ cachedBatchFlushSupportExpiresAt = now() + DELEGATE_BATCH_FLUSH_CACHE_TTL_MS;
5952
+ };
5953
+ const supportsBatchFlush = (timeoutMs) => {
5954
+ if (cachedBatchFlushSupport !== void 0) {
5955
+ if (now() < cachedBatchFlushSupportExpiresAt) {
5956
+ return Promise.resolve(cachedBatchFlushSupport);
5957
+ }
5958
+ invalidateCachedBatchFlushSupport();
5959
+ }
5960
+ if (supportsBatchFlushPromise !== void 0) return supportsBatchFlushPromise;
5961
+ const probe = getJson(
5962
+ target,
5963
+ options.serviceId,
5964
+ "/engram/v1/capabilities",
5965
+ timeoutMs
5966
+ ).then((response) => {
5967
+ const isSuccessfulResponse = response.status >= 200 && response.status < 300;
5968
+ if (isSuccessfulResponse && response.body !== null) {
5969
+ const batchFlushSupport = response.body.lcmCompactionFlushBatch;
5970
+ if (typeof batchFlushSupport === "boolean") {
5971
+ cacheBatchFlushSupport(batchFlushSupport);
5972
+ return batchFlushSupport;
5973
+ }
5974
+ return false;
5975
+ }
5976
+ if (response.status === 204 || response.status === 404 || response.status === 405 || response.status === 501) {
5977
+ cacheBatchFlushSupport(false);
5978
+ }
5979
+ return false;
5980
+ }).catch(() => false);
5981
+ supportsBatchFlushPromise = probe.finally(() => {
5982
+ supportsBatchFlushPromise = void 0;
5983
+ });
5984
+ return supportsBatchFlushPromise;
5985
+ };
5834
5986
  const flushHandler = async (event, ctx) => {
5835
- const fromEvent = event?.sessionKey;
5836
- const sessionKey = typeof fromEvent === "string" && fromEvent.length > 0 ? fromEvent : sessionKeyFrom(event, ctx);
5837
5987
  try {
5838
- await postJson(
5988
+ const deadline = Date.now() + options.flushTimeoutMs;
5989
+ const remainingTimeout = () => Math.max(1, deadline - Date.now());
5990
+ const sessionKey = lifecycleSessionKeyFrom(event, ctx);
5991
+ if (sessionKey === void 0) {
5992
+ log2.warn("delegate flush skipped: lifecycle event has malformed session key");
5993
+ return false;
5994
+ }
5995
+ const namespaces = await lifecycleSessionNamespacesFrom(
5996
+ sessionKey,
5997
+ event,
5998
+ ctx,
5999
+ namespace,
6000
+ namespaceBindings
6001
+ );
6002
+ const flushNamespace = (sessionNamespace) => postJson(
5839
6003
  target,
5840
6004
  options.serviceId,
5841
6005
  "/engram/v1/lcm/compaction/flush",
5842
- withNamespace(namespace, { sessionKey }),
5843
- options.flushTimeoutMs
6006
+ withNamespace(sessionNamespace, { sessionKey }),
6007
+ remainingTimeout()
5844
6008
  );
6009
+ const flushIndividually = async () => {
6010
+ const outcomes = await Promise.allSettled(namespaces.map(flushNamespace));
6011
+ return outcomes.every(
6012
+ (outcome) => outcome.status === "fulfilled" && outcome.value !== null && outcome.value.flushed === true
6013
+ );
6014
+ };
6015
+ if (namespaces.length <= 1 || await supportsBatchFlush(remainingTimeout())) {
6016
+ if (namespaces.length <= 1) {
6017
+ const response = await flushNamespace(namespaces[0]);
6018
+ return response !== null && response.flushed === true;
6019
+ }
6020
+ try {
6021
+ const response = await postJson(
6022
+ target,
6023
+ options.serviceId,
6024
+ "/engram/v1/lcm/compaction/flush",
6025
+ {
6026
+ sessionKey,
6027
+ namespaces: namespaces.map((sessionNamespace) => sessionNamespace ?? "")
6028
+ },
6029
+ remainingTimeout()
6030
+ );
6031
+ if (response === null) {
6032
+ invalidateCachedBatchFlushSupport();
6033
+ return flushIndividually();
6034
+ }
6035
+ const responseNamespaces = response.namespaces;
6036
+ const responseResults = response.results;
6037
+ const isBatchResponse = Array.isArray(responseNamespaces) && Array.isArray(responseResults) && responseNamespaces.length === namespaces.length && responseNamespaces.every(
6038
+ (responseNamespace, index) => responseNamespace === (namespaces[index] ?? "")
6039
+ ) && responseResults.length === namespaces.length;
6040
+ if (!isBatchResponse) {
6041
+ invalidateCachedBatchFlushSupport();
6042
+ return flushIndividually();
6043
+ }
6044
+ if (response.flushed !== true) {
6045
+ invalidateCachedBatchFlushSupport();
6046
+ return false;
6047
+ }
6048
+ return true;
6049
+ } catch {
6050
+ invalidateCachedBatchFlushSupport();
6051
+ return flushIndividually();
6052
+ }
6053
+ }
6054
+ return flushIndividually();
5845
6055
  } catch (err) {
5846
6056
  log2.warn(`delegate flush failed: ${String(err)}`);
6057
+ return false;
5847
6058
  }
5848
6059
  };
5849
6060
  api.on("before_compaction", flushHandler);
5850
6061
  if (options.flushOnResetEnabled) {
5851
- api.on("before_reset", flushHandler);
5852
- api.on("session_end", flushHandler);
6062
+ const flushEndedSession = async (event, ctx) => flushHandler(event, ctx);
6063
+ api.on("before_reset", flushEndedSession);
6064
+ api.on("session_end", flushEndedSession);
5853
6065
  }
5854
6066
  log2.info(
5855
6067
  `[${options.serviceId}] bridge mode delegate: memory loop backed by daemon at ${target.host}:${target.port} (embedded orchestrator skipped; tools/CLI/surfaces stay daemon-side)`
@@ -5858,7 +6070,130 @@ function registerDelegateRuntime(api, options) {
5858
6070
  function activeDelegateAuthorizationOperations(options) {
5859
6071
  return options.allowPromptInjection && options.recallBudgetChars !== 0 ? DEFAULT_DELEGATE_AUTHORIZATION_OPERATIONS : DEFAULT_DELEGATE_AUTHORIZATION_OPERATIONS.slice(1);
5860
6072
  }
6073
+ var delegateNamespaceMigrationChains = /* @__PURE__ */ new Map();
6074
+ var queueDelegateNamespaceMigration = (bindingPath, sessionKey, operation) => {
6075
+ let sessionChains = delegateNamespaceMigrationChains.get(bindingPath);
6076
+ if (sessionChains === void 0) {
6077
+ sessionChains = /* @__PURE__ */ new Map();
6078
+ delegateNamespaceMigrationChains.set(bindingPath, sessionChains);
6079
+ }
6080
+ const prior = sessionChains.get(sessionKey) ?? Promise.resolve();
6081
+ const run = prior.catch(() => void 0).then(operation);
6082
+ const settled = run.then(
6083
+ () => void 0,
6084
+ () => void 0
6085
+ );
6086
+ sessionChains.set(sessionKey, settled);
6087
+ void settled.then(() => {
6088
+ if (sessionChains?.get(sessionKey) !== settled) return;
6089
+ sessionChains.delete(sessionKey);
6090
+ if (sessionChains.size === 0 && delegateNamespaceMigrationChains.get(bindingPath) === sessionChains) {
6091
+ delegateNamespaceMigrationChains.delete(bindingPath);
6092
+ }
6093
+ });
6094
+ return run;
6095
+ };
6096
+ function createDelegateNamespaceBindingStore(memoryDir, serviceId, isLegacyAdapterActive) {
6097
+ const bindingPath = (pluginId) => path4.join(memoryDir, "state", "plugins", pluginId, "session-namespace-bindings.json");
6098
+ const primaryPath = bindingPath(serviceId);
6099
+ const primary = createFileSessionNamespaceBindingStore(primaryPath);
6100
+ if (serviceId !== REMNIC_OPENCLAW_PLUGIN_ID) return primary;
6101
+ const legacy = createFileSessionNamespaceBindingStore(
6102
+ bindingPath(REMNIC_OPENCLAW_LEGACY_PLUGIN_ID)
6103
+ );
6104
+ const migratedLegacySessions = /* @__PURE__ */ new Set();
6105
+ const rememberMigratedLegacySession = (sessionKey) => {
6106
+ if (migratedLegacySessions.has(sessionKey)) return;
6107
+ migratedLegacySessions.add(sessionKey);
6108
+ while (migratedLegacySessions.size > SESSION_NAMESPACE_BINDING_MAX_ENTRIES) {
6109
+ const oldest = migratedLegacySessions.values().next().value;
6110
+ if (oldest === void 0) return;
6111
+ migratedLegacySessions.delete(oldest);
6112
+ }
6113
+ };
6114
+ const queueSessionMigration = (sessionKey, operation) => queueDelegateNamespaceMigration(primaryPath, sessionKey, operation);
6115
+ const readLegacyNamespaces = async (sessionKey, current) => {
6116
+ if (!isLegacyAdapterActive() && migratedLegacySessions.has(sessionKey)) return [];
6117
+ try {
6118
+ const previous = await legacy.namespacesFor(sessionKey);
6119
+ if (previous.length === 0) rememberMigratedLegacySession(sessionKey);
6120
+ return previous;
6121
+ } catch (err) {
6122
+ if (current.length > 0) {
6123
+ log2.warn(
6124
+ `[${serviceId}] delegate legacy namespace read failed; using canonical bindings: ${String(err)}`
6125
+ );
6126
+ return [];
6127
+ }
6128
+ throw err;
6129
+ }
6130
+ };
6131
+ const mergeNamespaceHistory = (current, previous) => {
6132
+ const merged = [];
6133
+ for (const remembered of [...previous, ...current]) {
6134
+ const existing = merged.indexOf(remembered);
6135
+ if (existing >= 0) merged.splice(existing, 1);
6136
+ merged.push(remembered);
6137
+ }
6138
+ return merged.slice(-SESSION_NAMESPACE_BINDING_MAX_NAMESPACES);
6139
+ };
6140
+ const persistNamespaceHistory = async (store, sessionKey, namespaces) => {
6141
+ if (store.replace !== void 0) {
6142
+ await store.replace(sessionKey, namespaces);
6143
+ return;
6144
+ }
6145
+ for (const namespace of namespaces) {
6146
+ await store.remember(sessionKey, namespace);
6147
+ }
6148
+ };
6149
+ const completeLegacyMigration = async (sessionKey) => {
6150
+ if (!isLegacyAdapterActive()) {
6151
+ try {
6152
+ await legacy.replace?.(sessionKey, []);
6153
+ } catch (err) {
6154
+ log2.warn(`[${serviceId}] delegate legacy namespace cleanup failed: ${String(err)}`);
6155
+ }
6156
+ }
6157
+ rememberMigratedLegacySession(sessionKey);
6158
+ };
6159
+ return {
6160
+ async namespacesFor(sessionKey) {
6161
+ return queueSessionMigration(sessionKey, async () => {
6162
+ const current = await primary.namespacesFor(sessionKey);
6163
+ const previous = await readLegacyNamespaces(sessionKey, current);
6164
+ if (previous.length === 0) return current;
6165
+ const merged = mergeNamespaceHistory(current, previous);
6166
+ const hasMissingLegacy = previous.some((remembered) => !current.includes(remembered));
6167
+ if (!hasMissingLegacy) {
6168
+ await completeLegacyMigration(sessionKey);
6169
+ return current;
6170
+ }
6171
+ try {
6172
+ await persistNamespaceHistory(primary, sessionKey, merged);
6173
+ await completeLegacyMigration(sessionKey);
6174
+ } catch (err) {
6175
+ log2.warn(`[${serviceId}] delegate namespace migration failed: ${String(err)}`);
6176
+ }
6177
+ return merged;
6178
+ });
6179
+ },
6180
+ async remember(sessionKey, namespace) {
6181
+ return queueSessionMigration(sessionKey, async () => {
6182
+ const current = await primary.namespacesFor(sessionKey);
6183
+ const previous = await readLegacyNamespaces(sessionKey, current);
6184
+ if (previous.length === 0) {
6185
+ await primary.remember(sessionKey, namespace);
6186
+ return;
6187
+ }
6188
+ const merged = mergeNamespaceHistory([...current, namespace], previous);
6189
+ await persistNamespaceHistory(primary, sessionKey, merged);
6190
+ await completeLegacyMigration(sessionKey);
6191
+ });
6192
+ }
6193
+ };
6194
+ }
5861
6195
  var delegateHookApiServices = /* @__PURE__ */ new WeakMap();
6196
+ var delegateActiveServiceIds = /* @__PURE__ */ new Set();
5862
6197
  var delegateEmbeddedFallbackApis = /* @__PURE__ */ new WeakSet();
5863
6198
  var delegateAuthorizationPreflightServices = /* @__PURE__ */ new WeakMap();
5864
6199
  function maybeRegisterDelegateRuntime(api, options, deps = { checkHealth: checkDaemonHealthSync }) {
@@ -5898,6 +6233,7 @@ function maybeRegisterDelegateRuntime(api, options, deps = { checkHealth: checkD
5898
6233
  (boundServices ?? delegateHookApiServices.set(api, /* @__PURE__ */ new Set()).get(api))?.add(
5899
6234
  options.serviceId
5900
6235
  );
6236
+ delegateActiveServiceIds.add(options.serviceId);
5901
6237
  }
5902
6238
  const toggleStore = options.sessionTogglesEnabled ? createFileToggleStore(
5903
6239
  path4.join(options.memoryDir, "state", "plugins", options.serviceId, "session-toggles.json"),
@@ -5914,6 +6250,11 @@ function maybeRegisterDelegateRuntime(api, options, deps = { checkHealth: checkD
5914
6250
  serviceId: options.serviceId,
5915
6251
  target,
5916
6252
  namespace: "",
6253
+ namespaceBindings: createDelegateNamespaceBindingStore(
6254
+ options.memoryDir,
6255
+ options.serviceId,
6256
+ () => delegateActiveServiceIds.has(REMNIC_OPENCLAW_LEGACY_PLUGIN_ID)
6257
+ ),
5917
6258
  allowPromptInjection: options.allowPromptInjection,
5918
6259
  passive: options.passive,
5919
6260
  gateHeartbeatTurns: options.gateHeartbeatTurns,