@remnic/plugin-openclaw 9.29.1 → 9.30.1

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
@@ -72,7 +72,16 @@ import { clearIndexes, clearIndexesAsync, deindexMemory, deindexMemoryAsync, ext
72
72
  import * as temporal_index_star from "@remnic/core/temporal-index";
73
73
 
74
74
  // ../../src/explicit-capture.ts
75
- import { hasInlineExplicitCaptureMarkup, parseInlineExplicitCaptureNotes, persistExplicitCapture, queueExplicitCaptureForReview, shouldProcessInlineExplicitCapture, shouldSkipImplicitExtraction, stripInlineExplicitCaptureNotes, validateExplicitCaptureInput } from "@remnic/core/explicit-capture";
75
+ import { InlineExplicitCaptureProcessor, hasInlineExplicitCaptureMarkup, parseInlineExplicitCaptureNotes, persistExplicitCapture, queueExplicitCaptureForReview, shouldProcessInlineExplicitCapture, shouldSkipImplicitExtraction, stripInlineExplicitCaptureNotes, validateExplicitCaptureInput } from "@remnic/core/explicit-capture";
76
+ function mergeInlineCaptureDedupeKeys(messageKeys, fallbackDedupeKeys = []) {
77
+ const dedupeKeys = new Set(messageKeys ?? []);
78
+ if (dedupeKeys.size === 0) {
79
+ for (const key of fallbackDedupeKeys) {
80
+ if (key) dedupeKeys.add(key);
81
+ }
82
+ }
83
+ return [...dedupeKeys];
84
+ }
76
85
 
77
86
  // ../../src/tools.ts
78
87
  import { composeSalvagedEnvelope as composeSalvagedEnvelope2 } from "@remnic/core/salvage-envelope";
@@ -6980,7 +6989,6 @@ function tryDefinePluginEntry(def) {
6980
6989
  }
6981
6990
  }
6982
6991
  var MAX_OBSERVED_INBOUND_MESSAGE_IDS = 1024;
6983
- var MAX_OBSERVED_INLINE_EXPLICIT_CAPTURE_KEYS = 1024;
6984
6992
  function requireOpenClawSdkSubpath(subpath) {
6985
6993
  try {
6986
6994
  const _require = createRequire(import.meta.url);
@@ -7724,6 +7732,16 @@ Keep the reflection grounded in the evidence below.
7724
7732
  const expired = observedInboundContentFingerprintOrder.shift();
7725
7733
  if (expired) observedInboundContentFingerprints.delete(expired);
7726
7734
  }
7735
+ }, rememberObservedInboundCaptureContentFingerprint2 = function(contentFingerprint) {
7736
+ if (!contentFingerprint) return;
7737
+ if (!observedInboundCaptureContentFingerprints.has(contentFingerprint)) {
7738
+ observedInboundCaptureContentFingerprints.add(contentFingerprint);
7739
+ observedInboundCaptureContentFingerprintOrder.push(contentFingerprint);
7740
+ }
7741
+ while (observedInboundCaptureContentFingerprintOrder.length > MAX_OBSERVED_INBOUND_MESSAGE_IDS) {
7742
+ const expired = observedInboundCaptureContentFingerprintOrder.shift();
7743
+ if (expired) observedInboundCaptureContentFingerprints.delete(expired);
7744
+ }
7727
7745
  }, rememberPendingSparseInboundContentFingerprint2 = function(contentFingerprint) {
7728
7746
  if (!contentFingerprint) return;
7729
7747
  if (!pendingSparseInboundContentFingerprints.has(contentFingerprint)) {
@@ -7762,18 +7780,6 @@ Keep the reflection grounded in the evidence below.
7762
7780
  if (metadata?.replyToBody?.trim()) return metadata;
7763
7781
  }
7764
7782
  return null;
7765
- }, rememberObservedInlineExplicitCaptureKey2 = function(noteKey) {
7766
- if (!observedInlineExplicitCaptureKeys.has(noteKey)) {
7767
- observedInlineExplicitCaptureKeys.add(noteKey);
7768
- observedInlineExplicitCaptureKeyOrder.push(noteKey);
7769
- }
7770
- while (observedInlineExplicitCaptureKeyOrder.length > MAX_OBSERVED_INLINE_EXPLICIT_CAPTURE_KEYS) {
7771
- const expired = observedInlineExplicitCaptureKeyOrder.shift();
7772
- if (expired) observedInlineExplicitCaptureKeys.delete(expired);
7773
- }
7774
- }, buildInlineExplicitCaptureDedupeKey2 = function(messageKey, note) {
7775
- if (!messageKey) return null;
7776
- return `${messageKey}:inline-memory-note:${createHash4("sha256").update(JSON.stringify(note)).digest("hex")}`;
7777
7783
  }, resolveStoredCodexThreadId2 = function(sessionKey) {
7778
7784
  const threadId = codexThreadBySession.get(sessionKey);
7779
7785
  return typeof threadId === "string" && threadId.length > 0 ? threadId : null;
@@ -8055,7 +8061,7 @@ Keep the reflection grounded in the evidence below.
8055
8061
  const lowered = prompt.trim().toLowerCase();
8056
8062
  return lowered.startsWith("read heartbeat.md") || lowered.startsWith("run the following periodic tasks");
8057
8063
  };
8058
- 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;
8064
+ var rememberObservedInboundMessageId = rememberObservedInboundMessageId2, rememberObservedInboundMessageKeys = rememberObservedInboundMessageKeys2, rememberObservedInboundContentFingerprint = rememberObservedInboundContentFingerprint2, rememberObservedInboundCaptureContentFingerprint = rememberObservedInboundCaptureContentFingerprint2, rememberPendingSparseInboundContentFingerprint = rememberPendingSparseInboundContentFingerprint2, consumePendingSparseInboundContentFingerprint = consumePendingSparseInboundContentFingerprint2, rememberInboundReplyMetadata = rememberInboundReplyMetadata2, getInboundReplyMetadata = getInboundReplyMetadata2, 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;
8059
8065
  const hooksPolicy = readPluginHooksPolicy(api.config, serviceId);
8060
8066
  const promptInjectionAllowed = coerceRawConfigBoolean(hooksPolicy?.allowPromptInjection) !== false;
8061
8067
  const useMemoryPromptSection = sdkCaps.hasRegisterMemoryPromptSection && typeof api.registerMemoryPromptSection === "function" && promptInjectionAllowed;
@@ -8071,57 +8077,25 @@ Keep the reflection grounded in the evidence below.
8071
8077
  const observedInboundMessageIdOrder = [];
8072
8078
  const observedInboundContentFingerprints = /* @__PURE__ */ new Set();
8073
8079
  const observedInboundContentFingerprintOrder = [];
8080
+ const observedInboundCaptureContentFingerprints = /* @__PURE__ */ new Set();
8081
+ const observedInboundCaptureContentFingerprintOrder = [];
8074
8082
  const pendingSparseInboundContentFingerprints = /* @__PURE__ */ new Set();
8075
8083
  const pendingSparseInboundContentFingerprintOrder = [];
8076
8084
  const inboundReplyMetadataByMessageKey = /* @__PURE__ */ new Map();
8077
8085
  const inboundReplyMetadataKeyOrder = [];
8078
- const observedInlineExplicitCaptureKeys = /* @__PURE__ */ new Set();
8079
- const observedInlineExplicitCaptureKeyOrder = [];
8086
+ const inlineCaptureProcessor = new InlineExplicitCaptureProcessor(orchestrator, {
8087
+ sourceConnector: "openclaw"
8088
+ });
8080
8089
  let codexCompactionModeLogged = false;
8081
- async function processInlineExplicitCaptureNotes(notes, messageKeys) {
8082
- let processed = 0;
8083
- for (const note of notes) {
8084
- const noteKeys = (messageKeys ?? []).map((messageKey) => buildInlineExplicitCaptureDedupeKey2(messageKey, note)).filter((noteKey) => typeof noteKey === "string");
8085
- if (noteKeys.length > 0 && noteKeys.some((noteKey) => observedInlineExplicitCaptureKeys.has(noteKey))) {
8086
- continue;
8087
- }
8088
- try {
8089
- await persistExplicitCapture(
8090
- orchestrator,
8091
- { ...validateExplicitCaptureInput(note), sourceConnector: "openclaw" },
8092
- "inline"
8093
- );
8094
- orchestrator.requestQmdMaintenanceForTool("inline.memory_note");
8095
- for (const noteKey of noteKeys) {
8096
- rememberObservedInlineExplicitCaptureKey2(noteKey);
8097
- }
8098
- processed += 1;
8099
- } catch (error) {
8100
- try {
8101
- const queued = await queueExplicitCaptureForReview(
8102
- orchestrator,
8103
- { ...note, sourceConnector: "openclaw" },
8104
- "inline",
8105
- error
8106
- );
8107
- orchestrator.requestQmdMaintenanceForTool(
8108
- "inline.memory_note.review"
8109
- );
8110
- for (const noteKey of noteKeys) {
8111
- rememberObservedInlineExplicitCaptureKey2(noteKey);
8112
- }
8113
- processed += 1;
8114
- logger_exports.log.warn(
8115
- `explicit inline capture queued for review: ${queued.id}${queued.duplicateOf ? ` (duplicate of ${queued.duplicateOf})` : ""}`
8116
- );
8117
- } catch (queueError) {
8118
- logger_exports.log.warn(
8119
- `explicit inline capture rejected: ${error}; review queue fallback failed: ${queueError}`
8120
- );
8121
- }
8122
- }
8123
- }
8124
- return processed;
8090
+ async function processInlineExplicitCapture(content, messageKeys, fallbackDedupeKeys = [], sessionKey = "default") {
8091
+ const dedupeKeys = mergeInlineCaptureDedupeKeys(messageKeys, fallbackDedupeKeys);
8092
+ const reviewNamespace = typeof orchestrator.resolveSelfNamespace === "function" ? orchestrator.resolveSelfNamespace(sessionKey) : void 0;
8093
+ return inlineCaptureProcessor.process({
8094
+ captureMode: orchestrator.config.captureMode,
8095
+ content,
8096
+ dedupeKeys: [...dedupeKeys],
8097
+ ...reviewNamespace ? { reviewNamespace, reviewNamespacePreResolved: true } : {}
8098
+ });
8125
8099
  }
8126
8100
  async function flushAndForgetCodexThreadOnProviderSwitch(sessionKey, sessionIdentity) {
8127
8101
  if (sessionIdentity.isCodex || !sessionIdentity.previousCodexThreadId) {
@@ -8981,34 +8955,49 @@ Keep the reflection grounded in the evidence below.
8981
8955
  const eventDate = typeof event.timestamp === "number" && Number.isFinite(event.timestamp) ? new Date(event.timestamp) : /* @__PURE__ */ new Date();
8982
8956
  const timestamp = Number.isFinite(eventDate.getTime()) ? eventDate.toISOString() : (/* @__PURE__ */ new Date()).toISOString();
8983
8957
  const cleaned = cleanOpenClawUserMessage(content);
8984
- const inlineCaptureEnabled = shouldProcessInlineExplicitCapture(
8985
- orchestrator.config
8958
+ const inlineCaptureContentFingerprint = buildOpenClawInboundContentFingerprint(
8959
+ cleaned,
8960
+ event,
8961
+ event,
8962
+ ctx,
8963
+ sessionKey
8986
8964
  );
8987
- const explicitNotes = inlineCaptureEnabled ? parseInlineExplicitCaptureNotes(cleaned) : [];
8988
- const transcriptContent = inlineCaptureEnabled && hasInlineExplicitCaptureMarkup(cleaned) ? stripInlineExplicitCaptureNotes(cleaned) : cleaned;
8965
+ const sparseInlineCaptureContentFingerprint = buildOpenClawSparseInboundContentFingerprint(cleaned, sessionKey);
8966
+ const transcriptCandidate = shouldProcessInlineExplicitCapture(orchestrator.config) ? stripInlineExplicitCaptureNotes(cleaned) : cleaned;
8989
8967
  const inboundContentFingerprint = buildOpenClawInboundContentFingerprint(
8990
- transcriptContent,
8968
+ transcriptCandidate,
8991
8969
  event,
8992
8970
  event,
8993
8971
  ctx,
8994
8972
  sessionKey
8995
8973
  );
8996
8974
  const sparseInboundContentFingerprint = buildOpenClawSparseInboundContentFingerprint(
8997
- transcriptContent,
8975
+ transcriptCandidate,
8998
8976
  sessionKey
8999
8977
  );
8978
+ if (inboundMessageKeys.length === 0 && inlineCaptureContentFingerprint && observedInboundCaptureContentFingerprints.has(inlineCaptureContentFingerprint)) {
8979
+ return;
8980
+ }
8981
+ const inlineCapture = await processInlineExplicitCapture(
8982
+ cleaned,
8983
+ inboundMessageKeys,
8984
+ [inlineCaptureContentFingerprint, sparseInlineCaptureContentFingerprint],
8985
+ sessionKey
8986
+ );
8987
+ const transcriptContent = inlineCapture.content;
8988
+ const inlineCaptureWasHandled = inlineCapture.failed === 0 && (inlineCapture.processed > 0 || inlineCapture.content === cleaned);
9000
8989
  if (inboundContentFingerprint && observedInboundContentFingerprints.has(inboundContentFingerprint)) {
8990
+ if (inlineCaptureWasHandled) {
8991
+ rememberObservedInboundCaptureContentFingerprint2(inlineCaptureContentFingerprint);
8992
+ }
9001
8993
  return;
9002
8994
  }
9003
- const inlineCaptureDedupeKeys = inboundMessageKeys.length > 0 ? inboundMessageKeys : inboundContentFingerprint ? [inboundContentFingerprint] : sparseInboundContentFingerprint ? [sparseInboundContentFingerprint] : [];
9004
- const processedExplicitNotes = explicitNotes.length > 0 ? await processInlineExplicitCaptureNotes(
9005
- explicitNotes,
9006
- inlineCaptureDedupeKeys
9007
- ) : 0;
8995
+ const processedExplicitNotes = inlineCapture.processed;
9008
8996
  if (!orchestrator.config.transcriptEnabled || transcriptContent.length === 0) {
9009
8997
  rememberInboundReplyMetadata2(inboundMessageKeys, inboundReplyHintMetadata);
9010
- if (processedExplicitNotes > 0) {
8998
+ if (processedExplicitNotes > 0 && inlineCapture.failed === 0) {
9011
8999
  rememberObservedInboundMessageKeys2(inboundMessageKeys);
9000
+ rememberObservedInboundCaptureContentFingerprint2(inlineCaptureContentFingerprint);
9012
9001
  rememberObservedInboundContentFingerprint2(inboundContentFingerprint);
9013
9002
  if (inboundMessageKeys.length === 0) {
9014
9003
  rememberPendingSparseInboundContentFingerprint2(sparseInboundContentFingerprint);
@@ -9025,12 +9014,15 @@ Keep the reflection grounded in the evidence below.
9025
9014
  turnId: crypto.randomUUID(),
9026
9015
  ...metadata ? { metadata } : {}
9027
9016
  });
9028
- if (inboundMessageKeys.length > 0) {
9017
+ if (inboundMessageKeys.length > 0 && inlineCapture.failed === 0) {
9029
9018
  rememberObservedInboundMessageKeys2(inboundMessageKeys);
9030
9019
  rememberInboundReplyMetadata2(inboundMessageKeys, inboundReplyHintMetadata);
9031
9020
  }
9021
+ if (inlineCaptureWasHandled) {
9022
+ rememberObservedInboundCaptureContentFingerprint2(inlineCaptureContentFingerprint);
9023
+ }
9032
9024
  rememberObservedInboundContentFingerprint2(inboundContentFingerprint);
9033
- if (inboundMessageKeys.length === 0) {
9025
+ if (inlineCapture.failed === 0 && inboundMessageKeys.length === 0) {
9034
9026
  rememberPendingSparseInboundContentFingerprint2(sparseInboundContentFingerprint);
9035
9027
  }
9036
9028
  } catch (err) {
@@ -9122,26 +9114,38 @@ Keep the reflection grounded in the evidence below.
9122
9114
  const content = extractTextContent(msg);
9123
9115
  if (content.length < 10) continue;
9124
9116
  const cleaned = role === "user" ? cleanOpenClawUserMessage(content) : content;
9125
- const inlineCaptureEnabled = shouldProcessInlineExplicitCapture(
9126
- orchestrator.config
9127
- );
9128
- const explicitNotes = inlineCaptureEnabled ? parseInlineExplicitCaptureNotes(cleaned) : [];
9129
- const stripped = inlineCaptureEnabled && hasInlineExplicitCaptureMarkup(cleaned) ? stripInlineExplicitCaptureNotes(cleaned) : cleaned;
9130
- const messageMetadata = buildOpenClawMessageMetadata(
9117
+ const messageDedupeKeys = getOpenClawMessageDedupeKeys(msg, event, ctx, sessionKey);
9118
+ const inlineCaptureContentFingerprint = buildOpenClawInboundContentFingerprint(
9119
+ cleaned,
9131
9120
  msg,
9132
9121
  event,
9133
9122
  ctx,
9134
- cfg
9123
+ sessionKey
9135
9124
  );
9136
- const messageDedupeKeys = getOpenClawMessageDedupeKeys(msg, event, ctx, sessionKey);
9125
+ const sparseInlineCaptureContentFingerprint = buildOpenClawSparseInboundContentFingerprint(cleaned, sessionKey);
9126
+ const transcriptCandidate = shouldProcessInlineExplicitCapture(orchestrator.config) ? stripInlineExplicitCaptureNotes(cleaned) : cleaned;
9137
9127
  const messageContentFingerprint = buildOpenClawInboundContentFingerprint(
9138
- stripped,
9128
+ transcriptCandidate,
9139
9129
  msg,
9140
9130
  event,
9141
9131
  ctx,
9142
9132
  sessionKey
9143
9133
  );
9144
- const sparseMessageContentFingerprint = buildOpenClawSparseInboundContentFingerprint(stripped, sessionKey);
9134
+ const sparseMessageContentFingerprint = buildOpenClawSparseInboundContentFingerprint(transcriptCandidate, sessionKey);
9135
+ const inlineCapture = await processInlineExplicitCapture(
9136
+ cleaned,
9137
+ messageDedupeKeys,
9138
+ [inlineCaptureContentFingerprint, sparseInlineCaptureContentFingerprint],
9139
+ sessionKey
9140
+ );
9141
+ const stripped = inlineCapture.content;
9142
+ const inlineCaptureWasHandled = inlineCapture.failed === 0 && (inlineCapture.processed > 0 || inlineCapture.content === cleaned);
9143
+ const messageMetadata = buildOpenClawMessageMetadata(
9144
+ msg,
9145
+ event,
9146
+ ctx,
9147
+ cfg
9148
+ );
9145
9149
  const cachedReplyHintMetadata = role === "user" && cfg.openclawReplyMetadataExtractionHintsEnabled ? getInboundReplyMetadata2(messageDedupeKeys) : null;
9146
9150
  const replyHintMetadata = cfg.openclawReplyMetadataExtractionHintsEnabled ? cachedReplyHintMetadata ?? buildOpenClawMessageMetadata(msg, event, ctx, {
9147
9151
  openclawReplyMetadataCaptureEnabled: true
@@ -9149,11 +9153,6 @@ Keep the reflection grounded in the evidence below.
9149
9153
  const messageDedupeKey = messageDedupeKeys[0];
9150
9154
  const sparseInboundAlreadyCaptured = role === "user" && messageDedupeKeys.length === 0 && consumePendingSparseInboundContentFingerprint2(sparseMessageContentFingerprint);
9151
9155
  const transcriptAlreadyCaptured = role === "user" && (messageDedupeKeys.length > 0 && messageDedupeKeys.some((key) => observedInboundMessageIds.has(key)) || sparseInboundAlreadyCaptured || messageContentFingerprint !== null && observedInboundContentFingerprints.has(messageContentFingerprint));
9152
- const inlineCaptureDedupeKeys = messageDedupeKeys.length > 0 ? messageDedupeKeys : messageContentFingerprint ? [messageContentFingerprint] : sparseMessageContentFingerprint ? [sparseMessageContentFingerprint] : [];
9153
- await processInlineExplicitCaptureNotes(
9154
- explicitNotes,
9155
- inlineCaptureDedupeKeys
9156
- );
9157
9156
  if (orchestrator.config.transcriptEnabled && stripped.length > 0 && !transcriptAlreadyCaptured) {
9158
9157
  await orchestrator.transcript.append({
9159
9158
  timestamp: eventTimestamp,
@@ -9164,8 +9163,15 @@ Keep the reflection grounded in the evidence below.
9164
9163
  ...messageMetadata ? { metadata: messageMetadata } : {}
9165
9164
  });
9166
9165
  if (role === "user") {
9167
- if (messageDedupeKey) {
9168
- rememberObservedInboundMessageKeys2(messageDedupeKeys);
9166
+ if (inlineCapture.failed === 0) {
9167
+ if (messageDedupeKey) {
9168
+ rememberObservedInboundMessageKeys2(messageDedupeKeys);
9169
+ }
9170
+ if (inlineCaptureWasHandled) {
9171
+ rememberObservedInboundCaptureContentFingerprint2(
9172
+ inlineCaptureContentFingerprint
9173
+ );
9174
+ }
9169
9175
  }
9170
9176
  rememberObservedInboundContentFingerprint2(messageContentFingerprint);
9171
9177
  }