@remnic/plugin-openclaw 9.54.4 → 9.54.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
@@ -214,6 +214,49 @@ import {
214
214
 
215
215
  // ../../src/tools.ts
216
216
  import { runMemoryGovernance } from "@remnic/core/maintenance/memory-governance";
217
+
218
+ // ../../src/memory-action-target.ts
219
+ import { isSupportPassportPrivateMemory } from "@remnic/core";
220
+ function clampUnitInterval(value, fallback) {
221
+ if (typeof value !== "number" || !Number.isFinite(value)) return fallback;
222
+ if (value < 0) return 0;
223
+ if (value > 1) return 1;
224
+ return value;
225
+ }
226
+ function normalizeEligibilitySource(value) {
227
+ switch (value) {
228
+ case "extraction":
229
+ case "consolidation":
230
+ case "replay":
231
+ case "manual":
232
+ return value;
233
+ default:
234
+ return "unknown";
235
+ }
236
+ }
237
+ function deriveMemoryActionPolicyEligibility(memory) {
238
+ if (!memory) return void 0;
239
+ const frontmatter = memory.frontmatter;
240
+ return {
241
+ confidence: clampUnitInterval(frontmatter.confidence, 0),
242
+ lifecycleState: frontmatter.status === "archived" ? "archived" : frontmatter.lifecycleState ?? "candidate",
243
+ importance: clampUnitInterval(frontmatter.importance?.score, 0),
244
+ source: normalizeEligibilitySource(frontmatter.source)
245
+ };
246
+ }
247
+ async function readReferencedMemoryForPolicyEligibility(storage, memoryId) {
248
+ if (!memoryId) return void 0;
249
+ const direct = await storage.getMemoryById?.(memoryId);
250
+ if (direct) return direct;
251
+ const active = (await storage.readAllMemories?.())?.find((memory) => memory.frontmatter.id === memoryId);
252
+ if (active) return active;
253
+ return (await storage.readArchivedMemories?.())?.find((memory) => memory.frontmatter.id === memoryId);
254
+ }
255
+ function blocksSupportPassportMutation(action, memory) {
256
+ return (action === "update_note" || action === "discard" || action === "link_graph") && Boolean(memory && isSupportPassportPrivateMemory(memory));
257
+ }
258
+
259
+ // ../../src/tools.ts
217
260
  function toolResult(text) {
218
261
  return { content: [{ type: "text", text }], details: void 0 };
219
262
  }
@@ -232,12 +275,6 @@ function asNonEmptyString(value) {
232
275
  function normalizeToolNamespace(value) {
233
276
  return asNonEmptyString(value);
234
277
  }
235
- function clampUnitInterval(value, fallback) {
236
- if (typeof value !== "number" || !Number.isFinite(value)) return fallback;
237
- if (value < 0) return 0;
238
- if (value > 1) return 1;
239
- return value;
240
- }
241
278
  function normalizeProfilingReportLimit(value) {
242
279
  if (value === void 0) return 5;
243
280
  if (typeof value !== "number" || !Number.isFinite(value) || !Number.isInteger(value)) {
@@ -252,43 +289,7 @@ function normalizeMemorySearchResultLimit(value) {
252
289
  }
253
290
  return Math.min(Math.max(value, 1), 50);
254
291
  }
255
- function normalizeMemoryActionEligibilitySource(value) {
256
- switch (value) {
257
- case "extraction":
258
- case "consolidation":
259
- case "replay":
260
- case "manual":
261
- return value;
262
- default:
263
- return "unknown";
264
- }
265
- }
266
- function deriveMemoryActionPolicyEligibility(memory) {
267
- if (!memory) return void 0;
268
- const frontmatter = memory.frontmatter;
269
- return {
270
- confidence: clampUnitInterval(frontmatter.confidence, 0),
271
- lifecycleState: frontmatter.status === "archived" ? "archived" : frontmatter.lifecycleState ?? "candidate",
272
- importance: clampUnitInterval(frontmatter.importance?.score, 0),
273
- source: normalizeMemoryActionEligibilitySource(frontmatter.source)
274
- };
275
- }
276
- async function readReferencedMemoryForPolicyEligibility(storage, memoryId) {
277
- if (!memoryId) return void 0;
278
- if (typeof storage.getMemoryById === "function") {
279
- const direct = await storage.getMemoryById(memoryId);
280
- if (direct) return direct;
281
- }
282
- if (typeof storage.readAllMemories === "function") {
283
- const active = (await storage.readAllMemories()).find((memory) => memory.frontmatter.id === memoryId);
284
- if (active) return active;
285
- }
286
- if (typeof storage.readArchivedMemories === "function") {
287
- const archived = (await storage.readArchivedMemories()).find((memory) => memory.frontmatter.id === memoryId);
288
- if (archived) return archived;
289
- }
290
- return void 0;
291
- }
292
+ var MEMORY_SEARCH_CANDIDATE_CAP = 25e3;
292
293
  var WORK_TASK_STATUSES = /* @__PURE__ */ new Set(["todo", "in_progress", "blocked", "done", "cancelled"]);
293
294
  var WORK_TASK_PRIORITIES = /* @__PURE__ */ new Set(["low", "medium", "high"]);
294
295
  var WORK_PROJECT_STATUSES = /* @__PURE__ */ new Set(["active", "on_hold", "completed", "archived"]);
@@ -568,12 +569,39 @@ Best for:
568
569
  const { query, maxResults, collection, namespace } = params;
569
570
  const namespaceFilter = namespace && namespace.length > 0 ? namespace : void 0;
570
571
  const resultLimit = normalizeMemorySearchResultLimit(maxResults);
571
- const filtered = collection === "global" && !namespaceFilter ? (await orchestrator.qmd.searchGlobal(query, resultLimit)).slice(0, resultLimit) : await orchestrator.searchAcrossNamespaces({
572
+ const searchCandidates = async (limit) => collection === "global" && !namespaceFilter ? await orchestrator.qmd.searchGlobal(query, limit) : await orchestrator.searchAcrossNamespaces({
572
573
  query,
573
574
  namespaces: namespaceFilter ? [namespaceFilter] : void 0,
574
- maxResults: resultLimit,
575
+ maxResults: limit,
575
576
  mode: "search"
576
577
  });
578
+ let candidateLimit = resultLimit;
579
+ const privateVisibilityCache = /* @__PURE__ */ new Map();
580
+ let candidates = await searchCandidates(candidateLimit);
581
+ let filtered = await orchestrator.filterPrivateSearchResults(
582
+ candidates,
583
+ namespaceFilter ? [namespaceFilter] : [],
584
+ false,
585
+ privateVisibilityCache
586
+ );
587
+ while (filtered.length < resultLimit && candidates.length >= candidateLimit && candidateLimit < MEMORY_SEARCH_CANDIDATE_CAP) {
588
+ const nextCandidateLimit = Math.min(
589
+ MEMORY_SEARCH_CANDIDATE_CAP,
590
+ Math.max(candidateLimit + 16, candidateLimit * 2)
591
+ );
592
+ if (nextCandidateLimit === candidateLimit) break;
593
+ const nextCandidates = await searchCandidates(nextCandidateLimit);
594
+ if (nextCandidates.length <= candidates.length) break;
595
+ candidateLimit = nextCandidateLimit;
596
+ candidates = nextCandidates;
597
+ filtered = await orchestrator.filterPrivateSearchResults(
598
+ candidates,
599
+ namespaceFilter ? [namespaceFilter] : [],
600
+ false,
601
+ privateVisibilityCache
602
+ );
603
+ }
604
+ filtered = filtered.slice(0, resultLimit);
577
605
  if (filtered.length === 0) {
578
606
  return toolResult(`No memories found matching: "${query}"`);
579
607
  }
@@ -1600,6 +1628,19 @@ NOTE: You did not provide sessionKey; under concurrency this may not match your
1600
1628
  }
1601
1629
  const storage = typeof orchestrator.getStorage === "function" ? await orchestrator.getStorage(ns) : orchestrator.storage;
1602
1630
  const referencedMemory = await readReferencedMemoryForPolicyEligibility(storage, memoryIdValue);
1631
+ if (blocksSupportPassportMutation(action, referencedMemory)) {
1632
+ await orchestrator.appendMemoryActionEvent({
1633
+ ...baseEvent,
1634
+ outcome: "failed",
1635
+ status: "rejected",
1636
+ dryRun: dryRun === true,
1637
+ outputMemoryIds: [],
1638
+ reason: "validation: support passport records require the owner surface"
1639
+ });
1640
+ return toolResult(
1641
+ "Validation failed: support passport records can only be changed through the support passport owner surface."
1642
+ );
1643
+ }
1603
1644
  const structuredEvent = {
1604
1645
  ...baseEvent,
1605
1646
  outcome: outcome ?? "applied",
@@ -8403,9 +8444,11 @@ function buildTurnFingerprint(input) {
8403
8444
  import { planRecallMode } from "@remnic/core/intent";
8404
8445
  import {
8405
8446
  expandTildePath as expandTildePath4,
8447
+ isSupportPassportPrivateMemory as isSupportPassportPrivateMemory2,
8406
8448
  renderMemoryContextPrompt as renderSharedMemoryContextPrompt,
8407
8449
  resolveAgentAccessAuthToken,
8408
- resolvePrincipal
8450
+ resolvePrincipal,
8451
+ searchWithGenericExclusion
8409
8452
  } from "@remnic/core";
8410
8453
  import {
8411
8454
  normalizeHostEmbeddingVector,
@@ -10671,17 +10714,27 @@ Keep the reflection grounded in the evidence below.
10671
10714
  async search(query, opts) {
10672
10715
  const namespace = typeof orchestrator.resolveSelfNamespace === "function" ? orchestrator.resolveSelfNamespace(opts?.sessionKey) : void 0;
10673
10716
  const resolvedMode = opts?.qmdSearchModeOverride === "vsearch" ? "vector" : opts?.qmdSearchModeOverride === "query" ? "search" : opts?.qmdSearchModeOverride ?? "search";
10674
- const rawResults = await orchestrator.searchAcrossNamespaces({
10675
- query,
10676
- maxResults: opts?.maxResults,
10677
- namespaces: namespace ? [namespace] : void 0,
10678
- mode: resolvedMode
10717
+ const requestedMaxResults = typeof opts?.maxResults === "number" && Number.isFinite(opts.maxResults) ? Math.max(0, Math.floor(opts.maxResults)) : void 0;
10718
+ const minScore = typeof opts?.minScore === "number" && Number.isFinite(opts.minScore) ? opts.minScore : void 0;
10719
+ const visibleResults = await searchWithGenericExclusion({
10720
+ budget: requestedMaxResults ?? Number.MAX_SAFE_INTEGER,
10721
+ sendInitialLimit: requestedMaxResults !== void 0,
10722
+ search: (limit) => orchestrator.searchAcrossNamespaces({
10723
+ query,
10724
+ ...limit !== void 0 ? { maxResults: limit } : {},
10725
+ namespaces: namespace ? [namespace] : void 0,
10726
+ mode: resolvedMode
10727
+ }),
10728
+ filterPrivate: async (results) => {
10729
+ const visible = await orchestrator.filterPrivateSearchResults(
10730
+ results,
10731
+ namespace ? [namespace] : []
10732
+ );
10733
+ return minScore === void 0 ? visible : visible.filter((result) => result.score >= minScore);
10734
+ },
10735
+ isExcluded: (resultPath) => isMemoryArtifactPath(resultPath)
10679
10736
  });
10680
- return rawResults.filter((result) => {
10681
- const candidate = result;
10682
- const p = typeof candidate.path === "string" ? candidate.path : typeof candidate.id === "string" ? candidate.id : "";
10683
- return !isMemoryArtifactPath(p);
10684
- }).map((result, index) => {
10737
+ return visibleResults.map((result, index) => {
10685
10738
  const candidate = result;
10686
10739
  const rawPath = typeof candidate.path === "string" ? candidate.path : typeof candidate.id === "string" ? candidate.id : `memory-${index + 1}`;
10687
10740
  const absolutePath = readScope.absolutize(rawPath);
@@ -10697,13 +10750,20 @@ Keep the reflection grounded in the evidence below.
10697
10750
  source: isSessionsMemoryPath(normalizedPath) ? "sessions" : "memory",
10698
10751
  citation: normalizedPath
10699
10752
  };
10700
- }).filter(
10701
- (result) => typeof opts?.minScore === "number" && Number.isFinite(opts.minScore) ? result.score >= opts.minScore : true
10702
- );
10753
+ });
10703
10754
  },
10704
10755
  async readFile(params) {
10705
10756
  const requestedPath = readScope.normalizeWorkspacePath(params.relPath);
10706
10757
  const absolutePath = await readScope.resolveReadablePath(params.relPath);
10758
+ const visible = await orchestrator.filterPrivateSearchResults([{
10759
+ docid: absolutePath,
10760
+ path: absolutePath,
10761
+ snippet: "",
10762
+ score: 0
10763
+ }], [], true);
10764
+ if (visible.length === 0) {
10765
+ throw new Error(`memory read excluded (private record): ${params.relPath}`);
10766
+ }
10707
10767
  const text = await readTextFileLater(absolutePath);
10708
10768
  const allLines = text.split(/\r?\n/);
10709
10769
  const from = typeof params.from === "number" ? Math.max(1, Math.floor(params.from)) : 1;
@@ -11594,17 +11654,22 @@ Keep the reflection grounded in the evidence below.
11594
11654
  const agentSessionKey = typeof params === "object" ? params.agentSessionKey : void 0;
11595
11655
  const namespace = typeof orchestrator.resolveSelfNamespace === "function" ? orchestrator.resolveSelfNamespace(agentSessionKey) : void 0;
11596
11656
  try {
11597
- const rawResults = await orchestrator.searchAcrossNamespaces({
11598
- query,
11599
- maxResults,
11600
- namespaces: namespace ? [namespace] : void 0,
11601
- mode: "search"
11657
+ const visibleResults = await searchWithGenericExclusion({
11658
+ budget: maxResults,
11659
+ sendInitialLimit: true,
11660
+ search: (limit) => orchestrator.searchAcrossNamespaces({
11661
+ query,
11662
+ ...limit !== void 0 ? { maxResults: limit } : {},
11663
+ namespaces: namespace ? [namespace] : void 0,
11664
+ mode: "search"
11665
+ }),
11666
+ filterPrivate: (results) => orchestrator.filterPrivateSearchResults(
11667
+ results,
11668
+ namespace ? [namespace] : []
11669
+ ),
11670
+ isExcluded: (resultPath) => isMemoryArtifactPath(resultPath)
11602
11671
  });
11603
- return rawResults.filter((result) => {
11604
- const candidate = result;
11605
- const p = typeof candidate.path === "string" ? candidate.path : typeof candidate.id === "string" ? candidate.id : "";
11606
- return !isMemoryArtifactPath(p);
11607
- }).map((result, index) => {
11672
+ return visibleResults.map((result, index) => {
11608
11673
  const candidate = result;
11609
11674
  const lookupPath = typeof candidate.path === "string" ? candidate.path : typeof candidate.id === "string" ? candidate.id : `remnic-memory-${index + 1}`;
11610
11675
  const startLine = typeof candidate.startLine === "number" && Number.isFinite(candidate.startLine) ? Math.max(1, Math.floor(candidate.startLine)) : 1;
@@ -11642,7 +11707,7 @@ Keep the reflection grounded in the evidence below.
11642
11707
  const resolved = await readMemoryByLookup(lookup, agentSessionKey);
11643
11708
  if (!resolved) return null;
11644
11709
  const { memory, displayPath } = resolved;
11645
- if (isMemoryArtifactPath(displayPath) || isMemoryArtifactPath(memory.path)) {
11710
+ if (isMemoryArtifactPath(displayPath) || isMemoryArtifactPath(memory.path) || isSupportPassportPrivateMemory2(memory)) {
11646
11711
  return null;
11647
11712
  }
11648
11713
  const allLines = memory.content.split(/\r?\n/);