@remnic/core 9.3.642 → 9.3.643
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/access-http.js +3 -3
- package/dist/access-mcp.js +2 -2
- package/dist/{chunk-ACNU2UBF.js → chunk-2GCNTHRA.js} +3 -3
- package/dist/{chunk-5IDVOWBE.js → chunk-GJSNDJHR.js} +14 -2
- package/dist/chunk-GJSNDJHR.js.map +1 -0
- package/dist/{chunk-6DDBW2V4.js → chunk-S2SEPLLA.js} +2 -2
- package/dist/{chunk-6L46YAEZ.js → chunk-T4WDJPEZ.js} +45 -14
- package/dist/chunk-T4WDJPEZ.js.map +1 -0
- package/dist/cli.js +4 -4
- package/dist/index.js +4 -4
- package/dist/mcp-memory-inspector-app.d.ts +1 -0
- package/dist/mcp-memory-inspector-app.js +1 -1
- package/dist/schemas.d.ts +22 -22
- package/dist/transfer/types.d.ts +12 -12
- package/package.json +1 -1
- package/src/access-mcp.ts +16 -0
- package/src/mcp-memory-inspector-app.ts +79 -17
- package/dist/chunk-5IDVOWBE.js.map +0 -1
- package/dist/chunk-6L46YAEZ.js.map +0 -1
- /package/dist/{chunk-ACNU2UBF.js.map → chunk-2GCNTHRA.js.map} +0 -0
- /package/dist/{chunk-6DDBW2V4.js.map → chunk-S2SEPLLA.js.map} +0 -0
package/src/access-mcp.ts
CHANGED
|
@@ -715,6 +715,11 @@ export class EngramMcpServer {
|
|
|
715
715
|
description:
|
|
716
716
|
"Optional current user-context scopes, such as repo, work, personal, client, or private.",
|
|
717
717
|
},
|
|
718
|
+
allowUnverifiedPreview: {
|
|
719
|
+
type: "boolean",
|
|
720
|
+
description:
|
|
721
|
+
"If true, the inspector may show recalled preview text when X-ray provenance is missing or unavailable. Explicitly blocked memories remain redacted.",
|
|
722
|
+
},
|
|
718
723
|
},
|
|
719
724
|
required: ["query"],
|
|
720
725
|
additionalProperties: false,
|
|
@@ -2608,6 +2613,17 @@ export class EngramMcpServer {
|
|
|
2608
2613
|
if (currentContextScopes !== undefined) {
|
|
2609
2614
|
input.currentContextScopes = currentContextScopes;
|
|
2610
2615
|
}
|
|
2616
|
+
if (
|
|
2617
|
+
args.allowUnverifiedPreview !== undefined &&
|
|
2618
|
+
args.allowUnverifiedPreview !== null
|
|
2619
|
+
) {
|
|
2620
|
+
if (typeof args.allowUnverifiedPreview !== "boolean") {
|
|
2621
|
+
throw new EngramAccessInputError(
|
|
2622
|
+
"allowUnverifiedPreview must be a boolean",
|
|
2623
|
+
);
|
|
2624
|
+
}
|
|
2625
|
+
input.allowUnverifiedPreview = args.allowUnverifiedPreview;
|
|
2626
|
+
}
|
|
2611
2627
|
const recallSessionKey = resolveChatGptInspectorRecallSessionKey(
|
|
2612
2628
|
input.sessionKey,
|
|
2613
2629
|
effectivePrincipal,
|
|
@@ -18,6 +18,7 @@ export interface RemnicChatGptMemoryInspectorInput {
|
|
|
18
18
|
sessionKey?: string;
|
|
19
19
|
namespace?: string;
|
|
20
20
|
currentContextScopes?: string[];
|
|
21
|
+
allowUnverifiedPreview?: boolean;
|
|
21
22
|
}
|
|
22
23
|
|
|
23
24
|
export interface RemnicChatGptMemoryCard {
|
|
@@ -115,21 +116,42 @@ export function buildChatGptMemoryInspectorResult(
|
|
|
115
116
|
actionConfidence: ActionConfidenceResult,
|
|
116
117
|
): RemnicChatGptMemoryInspectorResult {
|
|
117
118
|
const xrayUnavailable = xray === null;
|
|
118
|
-
const
|
|
119
|
+
const allowUnverifiedPreview = input.allowUnverifiedPreview === true;
|
|
120
|
+
const matchXrayResult = buildXrayResultMatcher(xray, recall.results);
|
|
119
121
|
const matchedXrayResults = recall.results.map(matchXrayResult);
|
|
122
|
+
const hasBlockedSameId = buildBlockedSameIdMatcher(xray);
|
|
120
123
|
|
|
121
124
|
const memories = recall.results.slice(0, 8).map((summary) => {
|
|
122
125
|
const xrayResult = matchXrayResult(summary);
|
|
123
126
|
const provenance = xrayResult?.provenance;
|
|
124
|
-
const
|
|
125
|
-
|
|
127
|
+
const blockedByAmbiguousSameId = !xrayUnavailable
|
|
128
|
+
&& xrayResult === undefined
|
|
129
|
+
&& hasBlockedSameId(summary.id);
|
|
130
|
+
const blocked = provenance?.safety === "blocked" || blockedByAmbiguousSameId;
|
|
131
|
+
const unverified = !xrayUnavailable && provenance === undefined && !blockedByAmbiguousSameId;
|
|
126
132
|
const preview = xrayUnavailable
|
|
127
|
-
?
|
|
128
|
-
|
|
129
|
-
|
|
133
|
+
? allowUnverifiedPreview
|
|
134
|
+
? summary.preview
|
|
135
|
+
: "Preview withheld: X-ray provenance was unavailable for this recall."
|
|
130
136
|
: blocked
|
|
131
137
|
? "Preview withheld: this memory is blocked in the current context."
|
|
132
|
-
:
|
|
138
|
+
: unverified
|
|
139
|
+
? allowUnverifiedPreview
|
|
140
|
+
? summary.preview
|
|
141
|
+
: "Preview withheld: X-ray provenance was missing for this memory."
|
|
142
|
+
: summary.preview;
|
|
143
|
+
const fallbackSafety = blockedByAmbiguousSameId
|
|
144
|
+
? "blocked"
|
|
145
|
+
: xrayUnavailable || unverified
|
|
146
|
+
? allowUnverifiedPreview
|
|
147
|
+
? "requires-review"
|
|
148
|
+
: "blocked"
|
|
149
|
+
: undefined;
|
|
150
|
+
const fallbackSafetyReason = xrayUnavailable
|
|
151
|
+
? "X-ray provenance was unavailable for this recall."
|
|
152
|
+
: blockedByAmbiguousSameId
|
|
153
|
+
? "An unmatched X-ray row with this memory id was blocked."
|
|
154
|
+
: "X-ray provenance was missing for this memory.";
|
|
133
155
|
return {
|
|
134
156
|
id: summary.id,
|
|
135
157
|
path: summary.path,
|
|
@@ -144,25 +166,43 @@ export function buildChatGptMemoryInspectorResult(
|
|
|
144
166
|
confidence: provenance?.confidence,
|
|
145
167
|
stale: provenance?.stale,
|
|
146
168
|
corrected: provenance?.corrected,
|
|
147
|
-
safeToUse: provenance?.safeToUse
|
|
148
|
-
|
|
169
|
+
safeToUse: provenance?.safeToUse
|
|
170
|
+
?? (xrayUnavailable || unverified || blockedByAmbiguousSameId ? false : undefined),
|
|
171
|
+
safety: provenance?.safety ?? fallbackSafety,
|
|
149
172
|
safetyReasons: provenance?.safetyReasons
|
|
150
|
-
?? (
|
|
173
|
+
?? (
|
|
174
|
+
xrayUnavailable || unverified || blockedByAmbiguousSameId
|
|
175
|
+
? [fallbackSafetyReason]
|
|
176
|
+
: []
|
|
177
|
+
),
|
|
151
178
|
userContextScopes: provenance?.userContextScopes ?? [],
|
|
152
179
|
};
|
|
153
180
|
});
|
|
154
181
|
const blockedCount = matchedXrayResults
|
|
155
182
|
.filter((result) => result?.provenance?.safety === "blocked")
|
|
156
183
|
.length;
|
|
184
|
+
const ambiguousBlockedCount = recall.results
|
|
185
|
+
.filter((summary, index) =>
|
|
186
|
+
matchedXrayResults[index] === undefined && hasBlockedSameId(summary.id)
|
|
187
|
+
)
|
|
188
|
+
.length;
|
|
157
189
|
const missingProvenanceCount = xrayUnavailable
|
|
158
190
|
? 0
|
|
159
191
|
: matchedXrayResults
|
|
160
|
-
.filter((result) =>
|
|
192
|
+
.filter((result, index) =>
|
|
193
|
+
result?.provenance === undefined
|
|
194
|
+
&& !(result === undefined && hasBlockedSameId(recall.results[index]?.id ?? ""))
|
|
195
|
+
)
|
|
161
196
|
.length;
|
|
197
|
+
const totalBlockedCount = blockedCount + ambiguousBlockedCount;
|
|
162
198
|
const safeRecallPreview = xrayUnavailable
|
|
163
|
-
?
|
|
164
|
-
|
|
165
|
-
|
|
199
|
+
? allowUnverifiedPreview
|
|
200
|
+
? `Unverified recall preview: X-ray provenance was unavailable, so memory safety could not be verified.\n\n${truncate(recall.context, 1_500)}`
|
|
201
|
+
: "Recall preview withheld: X-ray provenance was unavailable, so memory safety could not be verified."
|
|
202
|
+
: totalBlockedCount > 0 || missingProvenanceCount > 0
|
|
203
|
+
? totalBlockedCount > 0 || !allowUnverifiedPreview
|
|
204
|
+
? formatUnsafeRecallPreview(totalBlockedCount, missingProvenanceCount)
|
|
205
|
+
: `Unverified recall preview: ${missingProvenanceCount} retrieved ${memoryNoun(missingProvenanceCount)} ${isAre(missingProvenanceCount)} missing X-ray provenance.\n\n${truncate(recall.context, 1_500)}`
|
|
166
206
|
: truncate(recall.context, 1_500);
|
|
167
207
|
|
|
168
208
|
const primaryMemoryId = memories[0]?.id ?? "<memory-id>";
|
|
@@ -372,7 +412,7 @@ function buildRecallProvenances(
|
|
|
372
412
|
if (xray === null) {
|
|
373
413
|
return recall.results.map(missingRecallProvenance);
|
|
374
414
|
}
|
|
375
|
-
const matchXrayResult = buildXrayResultMatcher(xray);
|
|
415
|
+
const matchXrayResult = buildXrayResultMatcher(xray, recall.results);
|
|
376
416
|
return recall.results.map((summary) => {
|
|
377
417
|
const result = matchXrayResult(summary);
|
|
378
418
|
if (result === undefined) {
|
|
@@ -384,21 +424,43 @@ function buildRecallProvenances(
|
|
|
384
424
|
|
|
385
425
|
function buildXrayResultMatcher(
|
|
386
426
|
xray: RecallXraySnapshot | null,
|
|
427
|
+
recallResults: EngramAccessRecallResponse["results"],
|
|
387
428
|
): (summary: EngramAccessRecallResponse["results"][number]) => RecallXrayResult | undefined {
|
|
388
429
|
const xrayById = new Map<string, RecallXrayResult>();
|
|
430
|
+
const xrayIdCounts = new Map<string, number>();
|
|
431
|
+
const recallIdCounts = new Map<string, number>();
|
|
389
432
|
const xrayByPath = new Map<string, RecallXrayResult>();
|
|
433
|
+
for (const summary of recallResults) {
|
|
434
|
+
recallIdCounts.set(summary.id, (recallIdCounts.get(summary.id) ?? 0) + 1);
|
|
435
|
+
}
|
|
390
436
|
for (const result of xray?.results ?? []) {
|
|
391
437
|
xrayById.set(result.memoryId, result);
|
|
438
|
+
xrayIdCounts.set(result.memoryId, (xrayIdCounts.get(result.memoryId) ?? 0) + 1);
|
|
392
439
|
xrayByPath.set(result.path, result);
|
|
393
440
|
}
|
|
394
441
|
return (summary) => {
|
|
395
442
|
if (summary.path) {
|
|
396
|
-
|
|
443
|
+
const pathMatch = xrayByPath.get(summary.path);
|
|
444
|
+
if (pathMatch) return pathMatch;
|
|
397
445
|
}
|
|
398
|
-
return
|
|
446
|
+
return xrayIdCounts.get(summary.id) === 1 && recallIdCounts.get(summary.id) === 1
|
|
447
|
+
? xrayById.get(summary.id)
|
|
448
|
+
: undefined;
|
|
399
449
|
};
|
|
400
450
|
}
|
|
401
451
|
|
|
452
|
+
function buildBlockedSameIdMatcher(
|
|
453
|
+
xray: RecallXraySnapshot | null,
|
|
454
|
+
): (memoryId: string) => boolean {
|
|
455
|
+
const blockedIds = new Set<string>();
|
|
456
|
+
for (const result of xray?.results ?? []) {
|
|
457
|
+
if (result.provenance?.safety === "blocked") {
|
|
458
|
+
blockedIds.add(result.memoryId);
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
return (memoryId) => blockedIds.has(memoryId);
|
|
462
|
+
}
|
|
463
|
+
|
|
402
464
|
function missingProvenance(result: RecallXrayResult): RetrievedMemoryProvenance {
|
|
403
465
|
return {
|
|
404
466
|
source: "unknown",
|