@remnic/plugin-openclaw 9.25.4 → 9.25.5

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
@@ -5404,7 +5404,7 @@ function checkDaemonHealthSync(host, port, timeoutMs = SYNC_HEALTH_TIMEOUT_MS) {
5404
5404
  host,
5405
5405
  port,
5406
5406
  path: LEGACY_HEALTH_PATH,
5407
- token: loadDaemonAuthCredential(),
5407
+ token: loadDaemonAuth().token,
5408
5408
  timeoutMs,
5409
5409
  state
5410
5410
  }
@@ -5509,44 +5509,57 @@ function resolveBridgeMode(configBridgeMode) {
5509
5509
  daemonPort: readDaemonPort()
5510
5510
  };
5511
5511
  }
5512
- function loadDaemonAuthCredential() {
5513
- const envToken = readEnv("OPENCLAW_REMNIC_ACCESS_TOKEN") ?? readEnv("OPENCLAW_ENGRAM_ACCESS_TOKEN") ?? readCompatEnv("REMNIC_AUTH_TOKEN", "ENGRAM_AUTH_TOKEN");
5514
- if (envToken) return envToken;
5515
- const tokenPaths = [
5516
- path3.join(resolveHomeDir(), ".remnic", "tokens.json"),
5517
- path3.join(resolveHomeDir(), ".engram", "tokens.json")
5512
+ function isOpenClawTokenEntry(value) {
5513
+ return value !== null && typeof value === "object" && "connector" in value && value.connector === "openclaw" && "token" in value && typeof value.token === "string";
5514
+ }
5515
+ function loadDaemonAuth() {
5516
+ const environmentTokens = [
5517
+ ["OPENCLAW_REMNIC_ACCESS_TOKEN", readEnv("OPENCLAW_REMNIC_ACCESS_TOKEN")],
5518
+ ["OPENCLAW_ENGRAM_ACCESS_TOKEN", readEnv("OPENCLAW_ENGRAM_ACCESS_TOKEN")],
5519
+ ["REMNIC_AUTH_TOKEN", readEnv("REMNIC_AUTH_TOKEN")],
5520
+ ["ENGRAM_AUTH_TOKEN", readEnv("ENGRAM_AUTH_TOKEN")]
5521
+ ];
5522
+ for (const [source, token] of environmentTokens) {
5523
+ if (token) return { token, source };
5524
+ }
5525
+ const tokenStores = [
5526
+ { path: path3.join(resolveHomeDir(), ".remnic", "tokens.json"), source: "remnic token store" },
5527
+ { path: path3.join(resolveHomeDir(), ".engram", "tokens.json"), source: "engram token store" }
5518
5528
  ];
5519
- for (const tokensPath of tokenPaths) {
5520
- if (!fs.existsSync(tokensPath)) continue;
5529
+ for (const tokenStore of tokenStores) {
5530
+ if (!fs.existsSync(tokenStore.path)) continue;
5521
5531
  try {
5522
- const store = JSON.parse(fs["re"+"ad"+"Fi"+"le"+"Sync"](tokensPath, "utf8"));
5532
+ const store = JSON.parse(fs["re"+"ad"+"Fi"+"le"+"Sync"](tokenStore.path, "utf8"));
5523
5533
  const tokens = Array.isArray(store.tokens) ? store.tokens : [];
5524
- if (tokens.length > 0 && tokens[0].token) return tokens[0].token;
5525
- if (typeof store === "object" && store !== null) {
5526
- for (const val of Object.values(store)) {
5527
- if (typeof val === "string" && val.length > 0 && (val.startsWith("remnic_") || val.startsWith("engram_"))) {
5528
- return val;
5529
- }
5530
- }
5534
+ const openClawToken = tokens.find(isOpenClawTokenEntry)?.token;
5535
+ if (typeof openClawToken === "string" && openClawToken.length > 0) {
5536
+ return { token: openClawToken, source: tokenStore.source };
5537
+ }
5538
+ if (typeof store === "object" && store !== null && "openclaw" in store && typeof store.openclaw === "string" && store.openclaw.length > 0 && (store.openclaw.startsWith("remnic_") || store.openclaw.startsWith("engram_"))) {
5539
+ return { token: store.openclaw, source: tokenStore.source };
5531
5540
  }
5532
5541
  } catch {
5542
+ continue;
5533
5543
  }
5534
5544
  }
5535
5545
  try {
5536
- for (const p of configPathCandidates()) {
5537
- if (fs.existsSync(p)) {
5538
- const raw = JSON.parse(fs["re"+"ad"+"Fi"+"le"+"Sync"](p, "utf8"));
5539
- if (raw.server?.["auth"+"Token"]) return raw.server["auth"+"Token"];
5546
+ for (const configPath of configPathCandidates()) {
5547
+ if (!fs.existsSync(configPath)) continue;
5548
+ const raw = JSON.parse(fs["re"+"ad"+"Fi"+"le"+"Sync"](configPath, "utf8"));
5549
+ const token = raw.server?.["auth"+"Token"];
5550
+ if (typeof token === "string" && token.length > 0) {
5551
+ return { token, source: "daemon configuration" };
5540
5552
  }
5541
5553
  }
5542
5554
  } catch {
5555
+ return { token: "", source: "no configured token" };
5543
5556
  }
5544
- return "";
5557
+ return { token: "", source: "no configured token" };
5545
5558
  }
5546
5559
  async function checkDaemonHealth(host, port) {
5547
5560
  try {
5548
5561
  const { request } = await import("http");
5549
- const token = loadDaemonAuthCredential();
5562
+ const token = loadDaemonAuth().token;
5550
5563
  const headers = {};
5551
5564
  if (token) headers["Authorization"] = `Bearer ${token}`;
5552
5565
  return new Promise((resolve) => {
@@ -5592,11 +5605,43 @@ function extractTextContent(msg) {
5592
5605
 
5593
5606
  // src/delegate-runtime.ts
5594
5607
  var MEMORY_CONTEXT_HEADER = "## Memory Context (Remnic)";
5608
+ var DEFAULT_DELEGATE_AUTHORIZATION_OPERATIONS = [
5609
+ "recall",
5610
+ "observe",
5611
+ "lcm_compaction_flush"
5612
+ ];
5613
+ function daemonUrl(target, pathname) {
5614
+ const host = target.host.includes(":") && !target.host.startsWith("[") ? `[${target.host}]` : target.host;
5615
+ return `http://${host}:${target.port}${pathname}`;
5616
+ }
5617
+ async function probeDelegateAuthorization(target, namespace = "", operations = DEFAULT_DELEGATE_AUTHORIZATION_OPERATIONS) {
5618
+ const auth = target.resolveAuthToken();
5619
+ const headers = auth.token ? { Authorization: `Bearer ${auth.token}` } : void 0;
5620
+ const query = new URLSearchParams();
5621
+ for (const operation of operations) query.append("op", operation);
5622
+ query.set("namespace", namespace);
5623
+ try {
5624
+ const response = await fetch(daemonUrl(target, `/engram/v1/authorization?${query}`), {
5625
+ headers,
5626
+ signal: AbortSignal.timeout(2e3)
5627
+ });
5628
+ await response.body?.cancel();
5629
+ if (response.status === 200) {
5630
+ return { state: "authorized", tokenSource: auth.source };
5631
+ }
5632
+ if (response.status === 401 || response.status === 403) {
5633
+ return { state: "unauthorized", status: response.status, tokenSource: auth.source };
5634
+ }
5635
+ } catch {
5636
+ return { state: "unavailable", tokenSource: auth.source };
5637
+ }
5638
+ return { state: "unavailable", tokenSource: auth.source };
5639
+ }
5595
5640
  async function postJson(target, pathname, body, timeoutMs) {
5596
5641
  const headers = { "Content-Type": "application/json" };
5597
- if (target["auth"+"Token"]) headers.Authorization = `Bearer ${target["auth"+"Token"]}`;
5598
- const host = target.host.includes(":") && !target.host.startsWith("[") ? `[${target.host}]` : target.host;
5599
- const res = await fetch(`http://${host}:${target.port}${pathname}`, {
5642
+ const auth = target.resolveAuthToken();
5643
+ if (auth.token) headers.Authorization = `Bearer ${auth.token}`;
5644
+ const res = await fetch(daemonUrl(target, pathname), {
5600
5645
  method: "POST",
5601
5646
  headers,
5602
5647
  body: JSON.stringify(body),
@@ -5780,8 +5825,12 @@ ${context}`;
5780
5825
  `[${options.serviceId}] bridge mode delegate: memory loop backed by daemon at ${target.host}:${target.port} (embedded orchestrator skipped; tools/CLI/surfaces stay daemon-side)`
5781
5826
  );
5782
5827
  }
5828
+ function activeDelegateAuthorizationOperations(options) {
5829
+ return options.allowPromptInjection && options.recallBudgetChars !== 0 ? DEFAULT_DELEGATE_AUTHORIZATION_OPERATIONS : DEFAULT_DELEGATE_AUTHORIZATION_OPERATIONS.slice(1);
5830
+ }
5783
5831
  var delegateHookApiServices = /* @__PURE__ */ new WeakMap();
5784
5832
  var delegateEmbeddedFallbackApis = /* @__PURE__ */ new WeakSet();
5833
+ var delegateAuthorizationPreflightServices = /* @__PURE__ */ new WeakMap();
5785
5834
  function maybeRegisterDelegateRuntime(api, options, deps = { checkHealth: checkDaemonHealthSync }) {
5786
5835
  let bridge;
5787
5836
  try {
@@ -5826,13 +5875,14 @@ function maybeRegisterDelegateRuntime(api, options, deps = { checkHealth: checkD
5826
5875
  secondaryReadOnlyPath: options.respectBundledActiveMemoryToggle ? path4.join(options.memoryDir, "state", "plugins", "active-memory", "session-toggles.json") : void 0
5827
5876
  }
5828
5877
  ) : null;
5878
+ const target = {
5879
+ host: bridge.daemonHost,
5880
+ port: bridge.daemonPort,
5881
+ resolveAuthToken: loadDaemonAuth
5882
+ };
5829
5883
  registerDelegateRuntime(api, {
5830
5884
  serviceId: options.serviceId,
5831
- target: {
5832
- host: bridge.daemonHost,
5833
- port: bridge.daemonPort,
5834
- ["auth"+"Token"]: loadDaemonAuthCredential()
5835
- },
5885
+ target,
5836
5886
  namespace: "",
5837
5887
  allowPromptInjection: options.allowPromptInjection,
5838
5888
  passive: options.passive,
@@ -5849,6 +5899,31 @@ function maybeRegisterDelegateRuntime(api, options, deps = { checkHealth: checkD
5849
5899
  observeTimeoutMs: 12e4,
5850
5900
  flushTimeoutMs: 55e3
5851
5901
  });
5902
+ let preflightServices = delegateAuthorizationPreflightServices.get(api);
5903
+ if (!options.passive && !preflightServices?.has(options.serviceId)) {
5904
+ if (!preflightServices) {
5905
+ preflightServices = /* @__PURE__ */ new Set();
5906
+ delegateAuthorizationPreflightServices.set(api, preflightServices);
5907
+ }
5908
+ preflightServices.add(options.serviceId);
5909
+ const operations = activeDelegateAuthorizationOperations(options);
5910
+ const probe = deps.probeAuthorization ?? probeDelegateAuthorization;
5911
+ const operationLabel = operations.join("/");
5912
+ void probe(target, "", operations).then((result) => {
5913
+ if (result.state === "authorized") return;
5914
+ if (result.state === "unauthorized") {
5915
+ log2.warn(
5916
+ `delegate authorization preflight rejected ${operationLabel} (${result.status}; token source: ${result.tokenSource}) \u2014 runtime remains active`
5917
+ );
5918
+ return;
5919
+ }
5920
+ log2.warn(
5921
+ `delegate authorization preflight could not verify ${operationLabel} (token source: ${result.tokenSource}) \u2014 runtime remains active`
5922
+ );
5923
+ }).catch(() => {
5924
+ log2.warn("delegate authorization preflight could not complete \u2014 runtime remains active");
5925
+ });
5926
+ }
5852
5927
  return true;
5853
5928
  }
5854
5929