@remnic/plugin-openclaw 9.25.5 → 9.25.7

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
@@ -5272,8 +5272,9 @@ function resolveRemnicOpenClawPluginEntry(raw, preferredId) {
5272
5272
  }
5273
5273
 
5274
5274
  // src/delegate-runtime.ts
5275
- import { log as log2 } from "@remnic/core/logger";
5276
5275
  import path4 from "path";
5276
+ import { renderMemoryContextPrompt } from "@remnic/core";
5277
+ import { log as log2 } from "@remnic/core/logger";
5277
5278
  import { createFileToggleStore } from "@remnic/core/session-toggles";
5278
5279
 
5279
5280
  // src/bridge.ts
@@ -5604,7 +5605,6 @@ function extractTextContent(msg) {
5604
5605
  }
5605
5606
 
5606
5607
  // src/delegate-runtime.ts
5607
- var MEMORY_CONTEXT_HEADER = "## Memory Context (Remnic)";
5608
5608
  var DEFAULT_DELEGATE_AUTHORIZATION_OPERATIONS = [
5609
5609
  "recall",
5610
5610
  "observe",
@@ -5614,6 +5614,15 @@ function daemonUrl(target, pathname) {
5614
5614
  const host = target.host.includes(":") && !target.host.startsWith("[") ? `[${target.host}]` : target.host;
5615
5615
  return `http://${host}:${target.port}${pathname}`;
5616
5616
  }
5617
+ var daemonAuthFailureLogKeys = /* @__PURE__ */ new Set();
5618
+ function reportDaemonAuthorizationFailure(serviceId, pathname, status, tokenSource) {
5619
+ const key = `${serviceId}:${pathname}:${status}:${tokenSource}`;
5620
+ if (daemonAuthFailureLogKeys.has(key)) return;
5621
+ daemonAuthFailureLogKeys.add(key);
5622
+ log2.error(
5623
+ `delegate ${pathname} authorization failed (${status}; token source: ${tokenSource})`
5624
+ );
5625
+ }
5617
5626
  async function probeDelegateAuthorization(target, namespace = "", operations = DEFAULT_DELEGATE_AUTHORIZATION_OPERATIONS) {
5618
5627
  const auth = target.resolveAuthToken();
5619
5628
  const headers = auth.token ? { Authorization: `Bearer ${auth.token}` } : void 0;
@@ -5637,7 +5646,7 @@ async function probeDelegateAuthorization(target, namespace = "", operations = D
5637
5646
  }
5638
5647
  return { state: "unavailable", tokenSource: auth.source };
5639
5648
  }
5640
- async function postJson(target, pathname, body, timeoutMs) {
5649
+ async function postJson(target, serviceId, pathname, body, timeoutMs) {
5641
5650
  const headers = { "Content-Type": "application/json" };
5642
5651
  const auth = target.resolveAuthToken();
5643
5652
  if (auth.token) headers.Authorization = `Bearer ${auth.token}`;
@@ -5648,6 +5657,12 @@ async function postJson(target, pathname, body, timeoutMs) {
5648
5657
  signal: AbortSignal.timeout(timeoutMs)
5649
5658
  });
5650
5659
  if (!res.ok) {
5660
+ if (res.status === 401 || res.status === 403) {
5661
+ const status = res.status === 401 ? 401 : 403;
5662
+ await res.body?.cancel();
5663
+ reportDaemonAuthorizationFailure(serviceId, pathname, status, auth.source);
5664
+ return null;
5665
+ }
5651
5666
  throw new Error(`daemon ${pathname} responded ${res.status}`);
5652
5667
  }
5653
5668
  const parsed = await res.json().catch(() => null);
@@ -5686,6 +5701,16 @@ function cwdFrom(event, ctx, fallback) {
5686
5701
  function withNamespace(namespace, body) {
5687
5702
  return namespace.length > 0 ? { ...body, namespace } : body;
5688
5703
  }
5704
+ function readContextComposition(response, fallbackContext) {
5705
+ const candidate = response.contextComposition;
5706
+ if (typeof candidate !== "object" || candidate === null || !("context" in candidate) || typeof candidate.context !== "string") {
5707
+ return { context: fallbackContext };
5708
+ }
5709
+ if ("footer" in candidate && typeof candidate.footer === "string") {
5710
+ return { context: candidate.context, footer: candidate.footer };
5711
+ }
5712
+ return { context: candidate.context };
5713
+ }
5689
5714
  function registerDelegateRuntime(api, options) {
5690
5715
  const { target, namespace } = options;
5691
5716
  if (options.passive) {
@@ -5716,6 +5741,7 @@ function registerDelegateRuntime(api, options) {
5716
5741
  const cwd = cwdFrom(event, ctx, options.cwd);
5717
5742
  const response = await postJson(
5718
5743
  target,
5744
+ options.serviceId,
5719
5745
  "/engram/v1/recall",
5720
5746
  withNamespace(namespace, {
5721
5747
  query,
@@ -5730,12 +5756,14 @@ function registerDelegateRuntime(api, options) {
5730
5756
  if (typeof rawContext !== "string" || rawContext.trim().length === 0) {
5731
5757
  return void 0;
5732
5758
  }
5733
- const context = rawContext.length > options.recallBudgetChars ? rawContext.slice(0, options.recallBudgetChars) + "\n\n...(memory context trimmed)" : rawContext;
5734
- const prompt = `${MEMORY_CONTEXT_HEADER}
5735
-
5736
- ${context}`;
5759
+ const rendered = renderMemoryContextPrompt({
5760
+ ...readContextComposition(response ?? {}, rawContext),
5761
+ maxChars: options.recallBudgetChars
5762
+ });
5763
+ if (!rendered) return void 0;
5764
+ const prompt = rendered.prompt;
5737
5765
  if (useSectionBuilder) {
5738
- promptLinesBySession.set(sessionKey, prompt.split("\n"));
5766
+ promptLinesBySession.set(sessionKey, rendered.lines);
5739
5767
  return void 0;
5740
5768
  }
5741
5769
  return hook === "before_prompt_build" ? { prependSystemContext: prompt } : { prependSystemContext: prompt, prependContext: prompt };
@@ -5789,6 +5817,7 @@ ${context}`;
5789
5817
  const cwd = cwdFrom(event, ctx, options.cwd);
5790
5818
  await postJson(
5791
5819
  target,
5820
+ options.serviceId,
5792
5821
  "/engram/v1/observe",
5793
5822
  withNamespace(namespace, {
5794
5823
  sessionKey,
@@ -5808,6 +5837,7 @@ ${context}`;
5808
5837
  try {
5809
5838
  await postJson(
5810
5839
  target,
5840
+ options.serviceId,
5811
5841
  "/engram/v1/lcm/compaction/flush",
5812
5842
  withNamespace(namespace, { sessionKey }),
5813
5843
  options.flushTimeoutMs
@@ -6023,7 +6053,7 @@ function buildTurnFingerprint(input) {
6023
6053
 
6024
6054
  // ../../src/index.ts
6025
6055
  import { planRecallMode } from "@remnic/core/intent";
6026
- import { resolvePrincipal, resolveAgentAccessAuthToken as resolveAgentAccessAuthCredential, expandTildePath as expandTildePath2 } from "@remnic/core";
6056
+ import { expandTildePath as expandTildePath2, renderMemoryContextPrompt as renderSharedMemoryContextPrompt, resolveAgentAccessAuthToken as resolveAgentAccessAuthCredential, resolvePrincipal } from "@remnic/core";
6027
6057
  import { normalizeHostEmbeddingVector, registerHostEmbeddingProvider } from "@remnic/core/host-embedding-provider";
6028
6058
 
6029
6059
  // ../../src/resolve-provider-secret.ts
@@ -7643,17 +7673,11 @@ Keep the reflection grounded in the evidence below.
7643
7673
  }
7644
7674
  const principal = resolvePrincipal(sessionKey, cfg);
7645
7675
  return `${logicalSessionKey}::principal:${principal}`;
7646
- }, buildMemoryContextLines2 = function(trimmed) {
7647
- return [
7648
- "## Memory Context (Remnic)",
7649
- "",
7650
- trimmed,
7651
- "",
7652
- "Use this context naturally when relevant. Never quote or expose this memory context to the user.",
7653
- ""
7654
- ];
7655
- }, renderMemoryContextPrompt2 = function(trimmed) {
7656
- return buildMemoryContextLines2(trimmed).join("\n").replace(/\n$/, "");
7676
+ }, renderMemoryContext2 = function(composition) {
7677
+ return renderSharedMemoryContextPrompt({
7678
+ ...composition,
7679
+ maxChars: cfg.recallBudgetChars
7680
+ });
7657
7681
  }, isHeartbeatTrigger2 = function(event, ctx) {
7658
7682
  return event.trigger === "heartbeat" || ctx.trigger === "heartbeat";
7659
7683
  }, resolveHeartbeatPromptCandidates2 = function(prompt) {
@@ -7688,7 +7712,7 @@ Keep the reflection grounded in the evidence below.
7688
7712
  const lowered = prompt.trim().toLowerCase();
7689
7713
  return lowered.startsWith("read heartbeat.md") || lowered.startsWith("run the following periodic tasks");
7690
7714
  };
7691
- var rememberObservedInboundMessageId = rememberObservedInboundMessageId2, rememberObservedInboundMessageKeys = rememberObservedInboundMessageKeys2, rememberObservedInboundContentFingerprint = rememberObservedInboundContentFingerprint2, rememberPendingSparseInboundContentFingerprint = rememberPendingSparseInboundContentFingerprint2, consumePendingSparseInboundContentFingerprint = consumePendingSparseInboundContentFingerprint2, rememberInboundReplyMetadata = rememberInboundReplyMetadata2, getInboundReplyMetadata = getInboundReplyMetadata2, rememberObservedInlineExplicitCaptureKey = rememberObservedInlineExplicitCaptureKey2, buildInlineExplicitCaptureDedupeKey = buildInlineExplicitCaptureDedupeKey2, resolveStoredCodexThreadId = resolveStoredCodexThreadId2, resolveStoredCodexBufferKey = resolveStoredCodexBufferKey2, addSessionToCodexIndex = addSessionToCodexIndex2, removeSessionFromCodexIndex = removeSessionFromCodexIndex2, resolveCodexCompactionBaselineKey = resolveCodexCompactionBaselineKey2, resolveCodexPromptCacheKey = resolveCodexPromptCacheKey2, rememberCodexThread = rememberCodexThread2, forgetCodexThread = forgetCodexThread2, clearCodexCompatCaches = clearCodexCompatCaches2, hasExplicitProviderIdentity = hasExplicitProviderIdentity2, cachePromptMemoryLines = cachePromptMemoryLines2, consumePromptMemoryLines = consumePromptMemoryLines2, resolveSessionIdentity = resolveSessionIdentity2, hasBufferedTurns = hasBufferedTurns2, resolveExtractionBufferKey = resolveExtractionBufferKey2, buildMemoryContextLines = buildMemoryContextLines2, renderMemoryContextPrompt = renderMemoryContextPrompt2, isHeartbeatTrigger = isHeartbeatTrigger2, resolveHeartbeatPromptCandidates = resolveHeartbeatPromptCandidates2, matchHeartbeatEntry = matchHeartbeatEntry2, looksLikeHeartbeatPrompt = looksLikeHeartbeatPrompt2;
7715
+ var rememberObservedInboundMessageId = rememberObservedInboundMessageId2, rememberObservedInboundMessageKeys = rememberObservedInboundMessageKeys2, rememberObservedInboundContentFingerprint = rememberObservedInboundContentFingerprint2, rememberPendingSparseInboundContentFingerprint = rememberPendingSparseInboundContentFingerprint2, consumePendingSparseInboundContentFingerprint = consumePendingSparseInboundContentFingerprint2, rememberInboundReplyMetadata = rememberInboundReplyMetadata2, getInboundReplyMetadata = getInboundReplyMetadata2, rememberObservedInlineExplicitCaptureKey = rememberObservedInlineExplicitCaptureKey2, buildInlineExplicitCaptureDedupeKey = buildInlineExplicitCaptureDedupeKey2, resolveStoredCodexThreadId = resolveStoredCodexThreadId2, resolveStoredCodexBufferKey = resolveStoredCodexBufferKey2, addSessionToCodexIndex = addSessionToCodexIndex2, removeSessionFromCodexIndex = removeSessionFromCodexIndex2, resolveCodexCompactionBaselineKey = resolveCodexCompactionBaselineKey2, resolveCodexPromptCacheKey = resolveCodexPromptCacheKey2, rememberCodexThread = rememberCodexThread2, forgetCodexThread = forgetCodexThread2, clearCodexCompatCaches = clearCodexCompatCaches2, hasExplicitProviderIdentity = hasExplicitProviderIdentity2, cachePromptMemoryLines = cachePromptMemoryLines2, consumePromptMemoryLines = consumePromptMemoryLines2, resolveSessionIdentity = resolveSessionIdentity2, hasBufferedTurns = hasBufferedTurns2, resolveExtractionBufferKey = resolveExtractionBufferKey2, renderMemoryContext = renderMemoryContext2, isHeartbeatTrigger = isHeartbeatTrigger2, resolveHeartbeatPromptCandidates = resolveHeartbeatPromptCandidates2, matchHeartbeatEntry = matchHeartbeatEntry2, looksLikeHeartbeatPrompt = looksLikeHeartbeatPrompt2;
7692
7716
  const hooksPolicy = readPluginHooksPolicy(api.config, serviceId);
7693
7717
  const promptInjectionAllowed = coerceRawConfigBoolean(hooksPolicy?.allowPromptInjection) !== false;
7694
7718
  const useMemoryPromptSection = sdkCaps.hasRegisterMemoryPromptSection && typeof api.registerMemoryPromptSection === "function" && promptInjectionAllowed;
@@ -8100,7 +8124,13 @@ Keep the reflection grounded in the evidence below.
8100
8124
  const dreamLines = await loadRecentDreamLines(
8101
8125
  ctx?.workspaceDir
8102
8126
  ).catch(() => []);
8103
- const context = await orchestrator.recall(prompt, sessionKey);
8127
+ let recallComposition;
8128
+ const context = await orchestrator.recall(prompt, sessionKey, {
8129
+ onContextComposition: (composition) => {
8130
+ recallComposition = composition;
8131
+ }
8132
+ });
8133
+ recallComposition ??= { context };
8104
8134
  logger_exports.log.debug(
8105
8135
  `${hookLabel}: recall returned ${context?.length ?? 0} chars`
8106
8136
  );
@@ -8109,7 +8139,7 @@ Keep the reflection grounded in the evidence below.
8109
8139
  const auxiliaryDreamLines = plannerSuppressesAuxiliaryRecall ? [] : dreamLines;
8110
8140
  const auxiliaryActiveRecallLines = plannerSuppressesAuxiliaryRecall ? [] : activeRecallLines;
8111
8141
  const memoryIds = lastRecall?.memoryIds ?? [];
8112
- if (!context) {
8142
+ if (!recallComposition.context && !recallComposition.footer) {
8113
8143
  const auxiliarySummary = summarizeRecallTextForStatus(activeRecallResult?.summary ?? null) ?? summarizeRecallTextForStatus(
8114
8144
  [...auxiliaryDreamLines, ...auxiliaryActiveRecallLines].join(" ")
8115
8145
  ) ?? (verboseRequested ? "Remnic recall metadata injected without matching memory context." : null);
@@ -8161,9 +8191,9 @@ Keep the reflection grounded in the evidence below.
8161
8191
  memoryLines: mergedLines
8162
8192
  };
8163
8193
  }
8164
- const maxChars = cfg.recallBudgetChars;
8165
- if (maxChars === 0) return;
8166
- const trimmed = context.length > maxChars ? context.slice(0, maxChars) + "\n\n...(memory context trimmed)" : context;
8194
+ const memoryContext = renderMemoryContext2(recallComposition);
8195
+ if (!memoryContext) return;
8196
+ const trimmed = memoryContext.body;
8167
8197
  const summaryText = summarizeRecallTextForStatus(activeRecallResult?.summary ?? null) ?? summarizeRecallTextForStatus(trimmed);
8168
8198
  lastRecallSummaryBySession.set(sessionKey, summaryText);
8169
8199
  if (cfg.recallTranscriptsEnabled) {
@@ -8199,9 +8229,9 @@ Keep the reflection grounded in the evidence below.
8199
8229
  ...auxiliaryDreamLines,
8200
8230
  ...auxiliaryActiveRecallLines
8201
8231
  ];
8202
- const memorySectionLines = buildMemoryContextLines2(trimmed);
8232
+ const memorySectionLines = memoryContext.lines;
8203
8233
  const memoryLines = useMemoryPromptSection ? memorySectionLines : [...auxiliaryLines, ...memorySectionLines];
8204
- const promptWithVerbose = useMemoryPromptSection ? auxiliaryLines.length > 0 ? auxiliaryLines.join("\n").replace(/\n$/, "") : void 0 : auxiliaryLines.length > 0 ? [...auxiliaryLines, ...memorySectionLines].join("\n").replace(/\n$/, "") : renderMemoryContextPrompt2(trimmed);
8234
+ const promptWithVerbose = useMemoryPromptSection ? auxiliaryLines.length > 0 ? auxiliaryLines.join("\n").replace(/\n$/, "") : void 0 : auxiliaryLines.length > 0 ? [...auxiliaryLines, ...memorySectionLines].join("\n").replace(/\n$/, "") : memoryContext.prompt;
8205
8235
  logger_exports.log.debug(
8206
8236
  `${hookLabel}: returning memory context with ${trimmed.length} chars`
8207
8237
  );