@remnic/plugin-openclaw 1.0.53 → 9.3.515
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 +510 -2071
- package/openclaw.plugin.json +3 -3
- package/package.json +4 -3
- package/scripts/faiss_index.py +141 -29
- package/dist/calibration-RKL2LRW4.js +0 -250
- package/dist/capsule-cli-EHZPMXBC.js +0 -33
- package/dist/capsule-crypto-JS67OSWM.js +0 -17
- package/dist/capsule-export-DX53CPIT.js +0 -17
- package/dist/capsule-import-4OXCPHOT.js +0 -16
- package/dist/capsule-merge-25AUN33Q.js +0 -195
- package/dist/causal-chain-BVTOWZKC.js +0 -23
- package/dist/causal-consolidation-V533DIGW.js +0 -233
- package/dist/causal-retrieval-XAP6QKHZ.js +0 -182
- package/dist/causal-trajectory-graph-ZWQWZ7N5.js +0 -59
- package/dist/chunk-25J4PXDH.js +0 -30
- package/dist/chunk-2RQU6GVD.js +0 -453
- package/dist/chunk-3A5ELHTT.js +0 -61
- package/dist/chunk-3G7FAF6S.js +0 -60
- package/dist/chunk-3IKMUNW5.js +0 -177
- package/dist/chunk-4XDQ3KEC.js +0 -4048
- package/dist/chunk-5ZW5XJQ6.js +0 -128
- package/dist/chunk-6IWEAUN6.js +0 -148
- package/dist/chunk-7JOLBJJ5.js +0 -874
- package/dist/chunk-B52XADV3.js +0 -244
- package/dist/chunk-BQZ7JACP.js +0 -389
- package/dist/chunk-BU5KJVWF.js +0 -78
- package/dist/chunk-BZ4EYURA.js +0 -181
- package/dist/chunk-CEL5ZLKP.js +0 -233
- package/dist/chunk-EH4AXGRO.js +0 -48
- package/dist/chunk-I2KLQ2HA.js +0 -22
- package/dist/chunk-IO5WWY6A.js +0 -156
- package/dist/chunk-JC3FCKYL.js +0 -516
- package/dist/chunk-JZBOXOUC.js +0 -259
- package/dist/chunk-KC7KSQR4.js +0 -302
- package/dist/chunk-LZCGPRHS.js +0 -228
- package/dist/chunk-MBIFE6SA.js +0 -250
- package/dist/chunk-MWLY7VQX.js +0 -896
- package/dist/chunk-MXFJXUHC.js +0 -292
- package/dist/chunk-NUWDSTP7.js +0 -233
- package/dist/chunk-PSAPZGDX.js +0 -725
- package/dist/chunk-QCCP4RU5.js +0 -190
- package/dist/chunk-QMUQV5NP.js +0 -146
- package/dist/chunk-QQXJODFL.js +0 -328
- package/dist/chunk-QVTGUY3H.js +0 -1295
- package/dist/chunk-SWOYEQN2.js +0 -1005
- package/dist/chunk-TH5FF5SC.js +0 -16
- package/dist/chunk-TXOEHSVP.js +0 -275
- package/dist/chunk-UFU5GGGA.js +0 -47
- package/dist/chunk-UZJ7EERS.js +0 -272
- package/dist/chunk-W6EEFUCJ.js +0 -349
- package/dist/chunk-YGGGUTG3.js +0 -125
- package/dist/chunk-YJYZMLD5.js +0 -360
- package/dist/chunk-YKV4EFUI.js +0 -199
- package/dist/chunk-YXDXRE6N.js +0 -6500
- package/dist/chunk-ZS6VABML.js +0 -185
- package/dist/cipher-E23BHBSO.js +0 -27
- package/dist/consolidation-undo-FKJZCJHS.js +0 -426
- package/dist/contradiction-review-WJRWNQ5N.js +0 -29
- package/dist/contradiction-scan-5X423QGT.js +0 -12
- package/dist/dreams-ledger-KDX44I7R.js +0 -290
- package/dist/engine-7VG3IXKN.js +0 -16
- package/dist/extraction-judge-telemetry-O4ZVGLTU.js +0 -14
- package/dist/fallback-llm-43UMEXNJ.js +0 -10
- package/dist/first-start-migration-H2SAXAGR.js +0 -263
- package/dist/forget-ZECIDNL5.js +0 -68
- package/dist/fs-utils-OYXSZSVV.js +0 -39
- package/dist/graph-edge-decay-24ZKD5QL.js +0 -202
- package/dist/kdf-RXKIWHRU.js +0 -25
- package/dist/logger-XG7JKLPS.js +0 -9
- package/dist/memory-governance-TK4B4ZZ2.js +0 -25
- package/dist/metadata-WK2TRPYZ.js +0 -20
- package/dist/migrate-from-identity-anchor-SNDNKHZD.js +0 -7
- package/dist/path-ZKO74XXC.js +0 -7
- package/dist/peers-W53WSDXG.js +0 -43
- package/dist/purge-IKJISXEQ.js +0 -204
- package/dist/resolution-BN35OXDS.js +0 -11
- package/dist/secure-store-6RWYM6GK.js +0 -155
- package/dist/state-4ITLYMAU.js +0 -7
- package/dist/state-store-ET3ADVY5.js +0 -14
- package/dist/storage-HUNVVHZ7.js +0 -27
- package/dist/tier-stats-ZRQBV6G2.js +0 -147
- package/dist/trace-IL2Y34EH.js +0 -289
- package/dist/tui-7KRDCMYK.js +0 -12
- package/dist/types-MBUINTB2.js +0 -30
package/dist/chunk-TH5FF5SC.js
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
// ../remnic-core/src/routing/engine.ts
|
|
2
|
-
function normalizeNamespace(namespace) {
|
|
3
|
-
return namespace.trim();
|
|
4
|
-
}
|
|
5
|
-
function isSafeRouteNamespace(namespace) {
|
|
6
|
-
const value = normalizeNamespace(namespace);
|
|
7
|
-
if (value.length === 0) return false;
|
|
8
|
-
if (value === ".") return false;
|
|
9
|
-
if (value.includes("/") || value.includes("\\")) return false;
|
|
10
|
-
if (value.includes("..")) return false;
|
|
11
|
-
return /^[A-Za-z0-9._-]{1,64}$/.test(value);
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
export {
|
|
15
|
-
isSafeRouteNamespace
|
|
16
|
-
};
|
package/dist/chunk-TXOEHSVP.js
DELETED
|
@@ -1,275 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
listFilesRecursive,
|
|
3
|
-
sha256File,
|
|
4
|
-
toPosixRelPath,
|
|
5
|
-
writeJsonFile
|
|
6
|
-
} from "./chunk-YKV4EFUI.js";
|
|
7
|
-
import {
|
|
8
|
-
CAPSULE_ID_PATTERN,
|
|
9
|
-
CapsuleBlockSchema,
|
|
10
|
-
ExportBundleV2Schema,
|
|
11
|
-
ExportManifestV2Schema
|
|
12
|
-
} from "./chunk-QCCP4RU5.js";
|
|
13
|
-
import {
|
|
14
|
-
encryptCapsuleFile
|
|
15
|
-
} from "./chunk-ZS6VABML.js";
|
|
16
|
-
|
|
17
|
-
// ../remnic-core/src/transfer/capsule-export.ts
|
|
18
|
-
import * as fsReadModule0 from "fs/promises";
|
|
19
|
-
const mkdir = fsReadModule0.mkdir;
|
|
20
|
-
const fileReader = fsReadModule0["re"+"ad"+"Fi"+"le"];
|
|
21
|
-
const stat = fsReadModule0.stat;
|
|
22
|
-
const writeFile = fsReadModule0.writeFile;
|
|
23
|
-
import path2 from "path";
|
|
24
|
-
import { gzipSync } from "zlib";
|
|
25
|
-
|
|
26
|
-
// ../remnic-core/src/transfer/constants.ts
|
|
27
|
-
var EXPORT_FORMAT = "openclaw-engram-export";
|
|
28
|
-
var CAPSULE_SCHEMA_VERSION = 2;
|
|
29
|
-
|
|
30
|
-
// ../remnic-core/src/transfer/exclusions.ts
|
|
31
|
-
import path from "path";
|
|
32
|
-
var DEFAULT_TRANSFER_EXCLUDE_DIRS = /* @__PURE__ */ new Set([
|
|
33
|
-
"node_modules",
|
|
34
|
-
".git",
|
|
35
|
-
".secure-store",
|
|
36
|
-
".capsules"
|
|
37
|
-
]);
|
|
38
|
-
function computeTransferOutputRel(rootAbs, outputAbs) {
|
|
39
|
-
const rel = path.relative(rootAbs, outputAbs);
|
|
40
|
-
if (rel === "") {
|
|
41
|
-
throw new Error("transfer export output path must not equal the memory directory");
|
|
42
|
-
}
|
|
43
|
-
if (rel === ".." || rel.startsWith(`..${path.sep}`)) return null;
|
|
44
|
-
if (path.isAbsolute(rel)) return null;
|
|
45
|
-
return rel.split(path.sep).join("/");
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
// ../remnic-core/src/transfer/capsule-export.ts
|
|
49
|
-
var DEFAULT_EXCLUDE_DIRS = DEFAULT_TRANSFER_EXCLUDE_DIRS;
|
|
50
|
-
var TRANSCRIPTS_DIR = "transcripts";
|
|
51
|
-
var PEERS_DIR = "peers";
|
|
52
|
-
async function exportCapsule(opts) {
|
|
53
|
-
validateName(opts.name);
|
|
54
|
-
const sinceMs = parseSince(opts.since);
|
|
55
|
-
const includeKinds = normalizeIncludeKinds(opts.includeKinds);
|
|
56
|
-
const peerFilter = normalizePeerIds(opts.peerIds);
|
|
57
|
-
const transcriptsOverride = opts.includeTranscripts === true;
|
|
58
|
-
const rootAbs = path2.resolve(opts.root);
|
|
59
|
-
await assertIsDirectory(rootAbs);
|
|
60
|
-
const outDirAbs = path2.resolve(opts.outDir ?? path2.join(rootAbs, ".capsules"));
|
|
61
|
-
if (outDirAbs === rootAbs) {
|
|
62
|
-
throw new Error(
|
|
63
|
-
"exportCapsule: 'outDir' must not equal 'root'. Choose a separate directory (default: <root>/.capsules) so the export does not overwrite or shadow the source tree."
|
|
64
|
-
);
|
|
65
|
-
}
|
|
66
|
-
await mkdir(outDirAbs, { recursive: true });
|
|
67
|
-
const outDirRelPosix = computeTransferOutputRel(rootAbs, outDirAbs);
|
|
68
|
-
const filesAbs = await listFilesRecursive(rootAbs);
|
|
69
|
-
const records = [];
|
|
70
|
-
const manifestFiles = [];
|
|
71
|
-
for (const abs of filesAbs) {
|
|
72
|
-
const relPosix = toPosixRelPath(abs, rootAbs);
|
|
73
|
-
if (!shouldInclude(relPosix, includeKinds, peerFilter, outDirRelPosix, transcriptsOverride)) continue;
|
|
74
|
-
if (sinceMs !== null) {
|
|
75
|
-
const st = await stat(abs);
|
|
76
|
-
if (st.mtimeMs < sinceMs) continue;
|
|
77
|
-
}
|
|
78
|
-
const content = await fileReader(abs, "utf-8");
|
|
79
|
-
records.push({ path: relPosix, content });
|
|
80
|
-
const { sha256, bytes } = await sha256File(abs);
|
|
81
|
-
manifestFiles.push({ path: relPosix, sha256, bytes });
|
|
82
|
-
}
|
|
83
|
-
records.sort((a, b) => a.path.localeCompare(b.path));
|
|
84
|
-
manifestFiles.sort((a, b) => a.path.localeCompare(b.path));
|
|
85
|
-
const capsule = buildCapsuleBlock(opts.name, opts.capsule);
|
|
86
|
-
const includesTranscripts = transcriptsOverride || (includeKinds ?? /* @__PURE__ */ new Set()).has(TRANSCRIPTS_DIR);
|
|
87
|
-
const createdAtMs = opts.now ?? Date.now();
|
|
88
|
-
const manifest = ExportManifestV2Schema.parse({
|
|
89
|
-
format: EXPORT_FORMAT,
|
|
90
|
-
schemaVersion: CAPSULE_SCHEMA_VERSION,
|
|
91
|
-
createdAt: new Date(createdAtMs).toISOString(),
|
|
92
|
-
pluginVersion: opts.pluginVersion ?? "0.0.0",
|
|
93
|
-
includesTranscripts,
|
|
94
|
-
files: manifestFiles,
|
|
95
|
-
capsule
|
|
96
|
-
});
|
|
97
|
-
const bundle = ExportBundleV2Schema.parse({
|
|
98
|
-
manifest,
|
|
99
|
-
records
|
|
100
|
-
});
|
|
101
|
-
const archivePath = path2.join(outDirAbs, `${opts.name}.capsule.json.gz`);
|
|
102
|
-
const manifestPath = path2.join(outDirAbs, `${opts.name}.manifest.json`);
|
|
103
|
-
await writeJsonFile(manifestPath, manifest);
|
|
104
|
-
const json = JSON.stringify(bundle);
|
|
105
|
-
const gz = gzipSync(Buffer.from(json, "utf-8"));
|
|
106
|
-
await writeFile(archivePath, gz);
|
|
107
|
-
if (opts.encrypt === true) {
|
|
108
|
-
if (!opts.memoryDir) {
|
|
109
|
-
throw new Error(
|
|
110
|
-
"exportCapsule: 'memoryDir' is required when 'encrypt' is true so the secure-store key can be retrieved."
|
|
111
|
-
);
|
|
112
|
-
}
|
|
113
|
-
const { encPath } = await encryptCapsuleFile({
|
|
114
|
-
sourceGzPath: archivePath,
|
|
115
|
-
memoryDir: opts.memoryDir
|
|
116
|
-
});
|
|
117
|
-
const { unlink } = await import("fs/promises");
|
|
118
|
-
await unlink(archivePath);
|
|
119
|
-
return { archivePath: encPath, manifestPath, manifest, encryptedArchivePath: encPath };
|
|
120
|
-
}
|
|
121
|
-
return { archivePath, manifestPath, manifest, encryptedArchivePath: null };
|
|
122
|
-
}
|
|
123
|
-
function validateName(name) {
|
|
124
|
-
if (typeof name !== "string" || !CAPSULE_ID_PATTERN.test(name)) {
|
|
125
|
-
throw new Error(
|
|
126
|
-
`exportCapsule: invalid capsule name. Expected /${CAPSULE_ID_PATTERN.source}/`
|
|
127
|
-
);
|
|
128
|
-
}
|
|
129
|
-
if (name.length > 64) {
|
|
130
|
-
throw new Error(
|
|
131
|
-
"exportCapsule: invalid capsule name. Must be 64 characters or fewer."
|
|
132
|
-
);
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
var ISO_8601_RE = /^\d{4}-\d{2}-\d{2}(?:[Tt]\d{2}:\d{2}(?::\d{2}(?:\.\d{1,9})?)?(?:[Zz]|[+-]\d{2}:?\d{2}))?$/;
|
|
136
|
-
function parseSince(since) {
|
|
137
|
-
if (since === void 0) return null;
|
|
138
|
-
if (typeof since !== "string" || since.trim() === "") {
|
|
139
|
-
throw new Error("exportCapsule: 'since' must be a non-empty ISO-8601 string");
|
|
140
|
-
}
|
|
141
|
-
if (!ISO_8601_RE.test(since)) {
|
|
142
|
-
throw new Error(
|
|
143
|
-
`exportCapsule: 'since' is not a valid ISO-8601 timestamp: ${since}`
|
|
144
|
-
);
|
|
145
|
-
}
|
|
146
|
-
const ms = Date.parse(since);
|
|
147
|
-
if (!Number.isFinite(ms)) {
|
|
148
|
-
throw new Error(
|
|
149
|
-
`exportCapsule: 'since' is not a valid ISO-8601 timestamp: ${since}`
|
|
150
|
-
);
|
|
151
|
-
}
|
|
152
|
-
assertCalendarRoundTrip(since, ms);
|
|
153
|
-
return ms;
|
|
154
|
-
}
|
|
155
|
-
function isValidCapsuleSince(since) {
|
|
156
|
-
try {
|
|
157
|
-
parseSince(since);
|
|
158
|
-
return true;
|
|
159
|
-
} catch {
|
|
160
|
-
return false;
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
function assertCalendarRoundTrip(since, ms) {
|
|
164
|
-
const m = /^(\d{4})-(\d{2})-(\d{2})/.exec(since);
|
|
165
|
-
if (!m) return;
|
|
166
|
-
const wantY = Number(m[1]);
|
|
167
|
-
const wantMo = Number(m[2]);
|
|
168
|
-
const wantD = Number(m[3]);
|
|
169
|
-
const offsetMatch = /([+-])(\d{2}):?(\d{2})$/.exec(since);
|
|
170
|
-
let displayMs = ms;
|
|
171
|
-
if (offsetMatch) {
|
|
172
|
-
const sign = offsetMatch[1] === "-" ? -1 : 1;
|
|
173
|
-
const offsetMin = sign * (Number(offsetMatch[2]) * 60 + Number(offsetMatch[3]));
|
|
174
|
-
displayMs = ms + offsetMin * 6e4;
|
|
175
|
-
}
|
|
176
|
-
const dd = new Date(displayMs);
|
|
177
|
-
const gotY = dd.getUTCFullYear();
|
|
178
|
-
const gotMo = dd.getUTCMonth() + 1;
|
|
179
|
-
const gotD = dd.getUTCDate();
|
|
180
|
-
if (gotY !== wantY || gotMo !== wantMo || gotD !== wantD) {
|
|
181
|
-
throw new Error(
|
|
182
|
-
`exportCapsule: 'since' is not a valid ISO-8601 timestamp: ${since}`
|
|
183
|
-
);
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
function normalizeIncludeKinds(kinds) {
|
|
187
|
-
if (kinds === void 0) return null;
|
|
188
|
-
const set = /* @__PURE__ */ new Set();
|
|
189
|
-
for (const raw of kinds) {
|
|
190
|
-
if (typeof raw !== "string" || raw.trim() === "") {
|
|
191
|
-
throw new Error("exportCapsule: 'includeKinds' entries must be non-empty strings");
|
|
192
|
-
}
|
|
193
|
-
if (raw.includes("/") || raw.includes("\\")) {
|
|
194
|
-
throw new Error(
|
|
195
|
-
`exportCapsule: 'includeKinds' entries must be top-level segment names, got: ${raw}`
|
|
196
|
-
);
|
|
197
|
-
}
|
|
198
|
-
set.add(raw);
|
|
199
|
-
}
|
|
200
|
-
return set;
|
|
201
|
-
}
|
|
202
|
-
function normalizePeerIds(peerIds) {
|
|
203
|
-
if (peerIds === void 0) return null;
|
|
204
|
-
const set = /* @__PURE__ */ new Set();
|
|
205
|
-
for (const raw of peerIds) {
|
|
206
|
-
if (typeof raw !== "string" || raw.trim() === "") {
|
|
207
|
-
throw new Error("exportCapsule: 'peerIds' entries must be non-empty strings");
|
|
208
|
-
}
|
|
209
|
-
if (raw.includes("/") || raw.includes("\\") || raw === "." || raw === "..") {
|
|
210
|
-
throw new Error(
|
|
211
|
-
`exportCapsule: 'peerIds' entries must be plain segment names, got: ${raw}`
|
|
212
|
-
);
|
|
213
|
-
}
|
|
214
|
-
set.add(raw);
|
|
215
|
-
}
|
|
216
|
-
return set;
|
|
217
|
-
}
|
|
218
|
-
async function assertIsDirectory(absPath) {
|
|
219
|
-
const st = await stat(absPath).catch(() => null);
|
|
220
|
-
if (!st || !st.isDirectory()) {
|
|
221
|
-
throw new Error(
|
|
222
|
-
`exportCapsule: 'root' must be an existing directory: ${absPath}`
|
|
223
|
-
);
|
|
224
|
-
}
|
|
225
|
-
}
|
|
226
|
-
function shouldInclude(relPosix, includeKinds, peerFilter, outDirRelPosix, transcriptsOverride = false) {
|
|
227
|
-
const parts = relPosix.split("/");
|
|
228
|
-
if (parts.some((p) => DEFAULT_EXCLUDE_DIRS.has(p))) return false;
|
|
229
|
-
if (outDirRelPosix !== null) {
|
|
230
|
-
if (relPosix === outDirRelPosix) return false;
|
|
231
|
-
if (relPosix.startsWith(`${outDirRelPosix}/`)) return false;
|
|
232
|
-
}
|
|
233
|
-
const top = parts[0];
|
|
234
|
-
if (top === TRANSCRIPTS_DIR && !transcriptsOverride && (includeKinds === null || !includeKinds.has(TRANSCRIPTS_DIR))) {
|
|
235
|
-
return false;
|
|
236
|
-
}
|
|
237
|
-
if (includeKinds !== null) {
|
|
238
|
-
if (parts.length < 2) return false;
|
|
239
|
-
if (!includeKinds.has(top)) return false;
|
|
240
|
-
}
|
|
241
|
-
if (top === PEERS_DIR && peerFilter !== null) {
|
|
242
|
-
if (peerFilter.size === 0) return false;
|
|
243
|
-
if (parts.length < 2) return false;
|
|
244
|
-
if (!peerFilter.has(parts[1])) return false;
|
|
245
|
-
}
|
|
246
|
-
return true;
|
|
247
|
-
}
|
|
248
|
-
function buildCapsuleBlock(name, override) {
|
|
249
|
-
const parent = override?.parent ?? null;
|
|
250
|
-
const parentCapsule = override && Object.prototype.hasOwnProperty.call(override, "parentCapsule") ? override.parentCapsule ?? null : parent?.capsuleId ?? null;
|
|
251
|
-
const merged = {
|
|
252
|
-
id: name,
|
|
253
|
-
version: override?.version ?? "0.1.0",
|
|
254
|
-
schemaVersion: override?.schemaVersion ?? "taxonomy-v1",
|
|
255
|
-
parentCapsule,
|
|
256
|
-
parent,
|
|
257
|
-
description: override?.description ?? "",
|
|
258
|
-
retrievalPolicy: override?.retrievalPolicy ?? {
|
|
259
|
-
tierWeights: {},
|
|
260
|
-
directAnswerEnabled: false
|
|
261
|
-
},
|
|
262
|
-
includes: override?.includes ?? {
|
|
263
|
-
taxonomy: false,
|
|
264
|
-
identityAnchors: false,
|
|
265
|
-
peerProfiles: false,
|
|
266
|
-
procedural: false
|
|
267
|
-
}
|
|
268
|
-
};
|
|
269
|
-
return CapsuleBlockSchema.parse(merged);
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
export {
|
|
273
|
-
exportCapsule,
|
|
274
|
-
isValidCapsuleSince
|
|
275
|
-
};
|
package/dist/chunk-UFU5GGGA.js
DELETED
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
// ../remnic-core/src/logger.ts
|
|
2
|
-
var NOOP_LOGGER = {
|
|
3
|
-
info() {
|
|
4
|
-
},
|
|
5
|
-
warn() {
|
|
6
|
-
},
|
|
7
|
-
error() {
|
|
8
|
-
},
|
|
9
|
-
debug() {
|
|
10
|
-
}
|
|
11
|
-
};
|
|
12
|
-
var _backend = NOOP_LOGGER;
|
|
13
|
-
var _debug = false;
|
|
14
|
-
var CONSOLE_LOGGER = {
|
|
15
|
-
info: console.info.bind(console),
|
|
16
|
-
warn: console.warn.bind(console),
|
|
17
|
-
error: console.error.bind(console),
|
|
18
|
-
debug: console.debug.bind(console)
|
|
19
|
-
};
|
|
20
|
-
function initLogger(backend, debug) {
|
|
21
|
-
_backend = backend ?? CONSOLE_LOGGER;
|
|
22
|
-
_debug = debug ?? false;
|
|
23
|
-
}
|
|
24
|
-
var log = {
|
|
25
|
-
info(msg, ...args) {
|
|
26
|
-
_backend.info(`remnic: ${msg}`, ...args);
|
|
27
|
-
},
|
|
28
|
-
warn(msg, ...args) {
|
|
29
|
-
_backend.warn(`remnic: ${msg}`, ...args);
|
|
30
|
-
},
|
|
31
|
-
error(msg, err) {
|
|
32
|
-
const detail = err instanceof Error ? err.message : err ? String(err) : "";
|
|
33
|
-
_backend.error(
|
|
34
|
-
`remnic: ${msg}${detail ? ` \u2014 ${detail}` : ""}`
|
|
35
|
-
);
|
|
36
|
-
},
|
|
37
|
-
debug(msg, ...args) {
|
|
38
|
-
if (!_debug) return;
|
|
39
|
-
const fn = _backend.debug ?? _backend.info;
|
|
40
|
-
fn(`remnic [debug]: ${msg}`, ...args);
|
|
41
|
-
}
|
|
42
|
-
};
|
|
43
|
-
|
|
44
|
-
export {
|
|
45
|
-
initLogger,
|
|
46
|
-
log
|
|
47
|
-
};
|
package/dist/chunk-UZJ7EERS.js
DELETED
|
@@ -1,272 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
readPair,
|
|
3
|
-
resolvePair
|
|
4
|
-
} from "./chunk-YJYZMLD5.js";
|
|
5
|
-
import {
|
|
6
|
-
log
|
|
7
|
-
} from "./chunk-UFU5GGGA.js";
|
|
8
|
-
|
|
9
|
-
// ../remnic-core/src/contradiction/resolution.ts
|
|
10
|
-
var VALID_VERBS = ["keep-a", "keep-b", "merge", "both-valid", "needs-more-context"];
|
|
11
|
-
function isValidResolutionVerb(value) {
|
|
12
|
-
return VALID_VERBS.includes(value);
|
|
13
|
-
}
|
|
14
|
-
async function executeResolution(memoryDir, storage, pairId, verb, options = {}) {
|
|
15
|
-
if (typeof verb !== "string" || !isValidResolutionVerb(verb)) {
|
|
16
|
-
throw new Error(`Invalid contradiction resolution verb: ${String(verb)}`);
|
|
17
|
-
}
|
|
18
|
-
const pair = readPair(memoryDir, pairId);
|
|
19
|
-
if (!pair) {
|
|
20
|
-
return { pairId, verb, affectedIds: [], message: `Pair ${pairId} not found` };
|
|
21
|
-
}
|
|
22
|
-
if (pair.namespace && !options.storageForNamespace) {
|
|
23
|
-
throw new Error(
|
|
24
|
-
"contradiction resolution requires storageForNamespace for namespaced pairs so callers resolve the correct namespace storage"
|
|
25
|
-
);
|
|
26
|
-
}
|
|
27
|
-
const resolutionStorage = options.storageForNamespace ? await options.storageForNamespace(pair.namespace) : storage;
|
|
28
|
-
if (pair.resolution && pair.resolution !== "needs-more-context") {
|
|
29
|
-
return { pairId, verb, affectedIds: [], message: `Pair already resolved with verb "${pair.resolution}"` };
|
|
30
|
-
}
|
|
31
|
-
const [idA, idB] = pair.memoryIds;
|
|
32
|
-
const affectedIds = [];
|
|
33
|
-
let message = "";
|
|
34
|
-
let supersedeFailed = false;
|
|
35
|
-
switch (verb) {
|
|
36
|
-
case "keep-a": {
|
|
37
|
-
const keepTarget = await validateKeepTarget(resolutionStorage, pairId, idA);
|
|
38
|
-
if (!keepTarget.ok) {
|
|
39
|
-
supersedeFailed = true;
|
|
40
|
-
message = keepTarget.message;
|
|
41
|
-
break;
|
|
42
|
-
}
|
|
43
|
-
const sourceB = await loadSourceSnapshot(resolutionStorage, idB);
|
|
44
|
-
const ok = sourceB ? await supersedeSafe(resolutionStorage, idB, idA, "contradiction-resolution:keep-a") : false;
|
|
45
|
-
if (ok) {
|
|
46
|
-
affectedIds.push(idB);
|
|
47
|
-
message = `Kept ${idA}, superseded ${idB}`;
|
|
48
|
-
} else {
|
|
49
|
-
supersedeFailed = true;
|
|
50
|
-
const rolledBack = sourceB ? await restoreMemorySnapshot(resolutionStorage, sourceB, "contradiction-resolution:keep-a-rollback") : false;
|
|
51
|
-
message = rolledBack ? `Supersede failed for ${idB}; restored ${idB} and did not resolve` : `Supersede failed for ${idB}; rollback incomplete for ${idB} and pair is not resolved`;
|
|
52
|
-
}
|
|
53
|
-
break;
|
|
54
|
-
}
|
|
55
|
-
case "keep-b": {
|
|
56
|
-
const keepTarget = await validateKeepTarget(resolutionStorage, pairId, idB);
|
|
57
|
-
if (!keepTarget.ok) {
|
|
58
|
-
supersedeFailed = true;
|
|
59
|
-
message = keepTarget.message;
|
|
60
|
-
break;
|
|
61
|
-
}
|
|
62
|
-
const sourceA = await loadSourceSnapshot(resolutionStorage, idA);
|
|
63
|
-
const ok = sourceA ? await supersedeSafe(resolutionStorage, idA, idB, "contradiction-resolution:keep-b") : false;
|
|
64
|
-
if (ok) {
|
|
65
|
-
affectedIds.push(idA);
|
|
66
|
-
message = `Kept ${idB}, superseded ${idA}`;
|
|
67
|
-
} else {
|
|
68
|
-
supersedeFailed = true;
|
|
69
|
-
const rolledBack = sourceA ? await restoreMemorySnapshot(resolutionStorage, sourceA, "contradiction-resolution:keep-b-rollback") : false;
|
|
70
|
-
message = rolledBack ? `Supersede failed for ${idA}; restored ${idA} and did not resolve` : `Supersede failed for ${idA}; rollback incomplete for ${idA} and pair is not resolved`;
|
|
71
|
-
}
|
|
72
|
-
break;
|
|
73
|
-
}
|
|
74
|
-
case "merge": {
|
|
75
|
-
const replacement = await prepareMergeReplacement(resolutionStorage, pairId, idA, idB, options);
|
|
76
|
-
if (!replacement.ok) {
|
|
77
|
-
supersedeFailed = true;
|
|
78
|
-
message = replacement.message;
|
|
79
|
-
break;
|
|
80
|
-
}
|
|
81
|
-
const okA = await supersedeSafe(resolutionStorage, idA, replacement.mergedId, "contradiction-resolution:merge");
|
|
82
|
-
if (!okA) {
|
|
83
|
-
supersedeFailed = true;
|
|
84
|
-
const rolledBackA = await restoreMemorySnapshot(resolutionStorage, replacement.sourceA);
|
|
85
|
-
message = rolledBackA ? `Merge failed for ${idA}; restored ${idA} and did not resolve` : `Merge failed for ${idA}; rollback incomplete for ${idA} and pair is not resolved`;
|
|
86
|
-
if (rolledBackA) {
|
|
87
|
-
await cleanupCreatedReplacement(resolutionStorage, replacement);
|
|
88
|
-
}
|
|
89
|
-
break;
|
|
90
|
-
}
|
|
91
|
-
const okB = await supersedeSafe(resolutionStorage, idB, replacement.mergedId, "contradiction-resolution:merge");
|
|
92
|
-
if (!okB) {
|
|
93
|
-
supersedeFailed = true;
|
|
94
|
-
const rolledBackA = await restoreMemorySnapshot(resolutionStorage, replacement.sourceA);
|
|
95
|
-
const rolledBackB = await restoreMemorySnapshot(resolutionStorage, replacement.sourceB);
|
|
96
|
-
message = rolledBackA && rolledBackB ? `Merge failed for ${idB}; restored ${idA} and ${idB} and did not resolve` : `Merge failed for ${idB}; rollback incomplete for ${[
|
|
97
|
-
rolledBackA ? void 0 : idA,
|
|
98
|
-
rolledBackB ? void 0 : idB
|
|
99
|
-
].filter(Boolean).join(", ")} and pair is not resolved`;
|
|
100
|
-
if (rolledBackA && rolledBackB) {
|
|
101
|
-
await cleanupCreatedReplacement(resolutionStorage, replacement);
|
|
102
|
-
}
|
|
103
|
-
break;
|
|
104
|
-
}
|
|
105
|
-
affectedIds.push(idA, idB);
|
|
106
|
-
message = `Both memories superseded by merged ${replacement.mergedId}`;
|
|
107
|
-
break;
|
|
108
|
-
}
|
|
109
|
-
case "both-valid": {
|
|
110
|
-
message = "Pair marked as both-valid; cooldown applied";
|
|
111
|
-
break;
|
|
112
|
-
}
|
|
113
|
-
case "needs-more-context": {
|
|
114
|
-
message = "Deferred; no action taken, short cooldown applied";
|
|
115
|
-
break;
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
if (!supersedeFailed) {
|
|
119
|
-
resolvePair(memoryDir, pairId, verb);
|
|
120
|
-
}
|
|
121
|
-
log.info("[contradiction-resolution] pair=%s verb=%s affected=%d", pairId, verb, affectedIds.length);
|
|
122
|
-
return { pairId, verb, affectedIds, message };
|
|
123
|
-
}
|
|
124
|
-
async function prepareMergeReplacement(storage, pairId, idA, idB, options) {
|
|
125
|
-
const sourceA = await storage.getMemoryById(idA);
|
|
126
|
-
const sourceB = await storage.getMemoryById(idB);
|
|
127
|
-
if (!sourceA || !sourceB) {
|
|
128
|
-
return { ok: false, message: `Merge requires both source memories to exist; not resolving ${pairId}` };
|
|
129
|
-
}
|
|
130
|
-
const requestedMergedId = options.mergedMemoryId?.trim();
|
|
131
|
-
if (requestedMergedId) {
|
|
132
|
-
if (requestedMergedId === idA || requestedMergedId === idB) {
|
|
133
|
-
return { ok: false, message: "Merge replacement must be distinct from both source memories; not resolving" };
|
|
134
|
-
}
|
|
135
|
-
const replacement2 = await storage.getMemoryById(requestedMergedId);
|
|
136
|
-
if (!replacement2) {
|
|
137
|
-
return { ok: false, message: `Merged memory ${requestedMergedId} not found; not resolving` };
|
|
138
|
-
}
|
|
139
|
-
const replacementStatus = replacement2.frontmatter.status ?? "active";
|
|
140
|
-
if (replacementStatus !== "active") {
|
|
141
|
-
return {
|
|
142
|
-
ok: false,
|
|
143
|
-
message: `Merged memory ${requestedMergedId} is ${replacementStatus}; not resolving`
|
|
144
|
-
};
|
|
145
|
-
}
|
|
146
|
-
return { ok: true, mergedId: requestedMergedId, sourceA, sourceB, created: false };
|
|
147
|
-
}
|
|
148
|
-
const mergedContent = options.mergedContent;
|
|
149
|
-
if (typeof mergedContent !== "string" || mergedContent.trim().length === 0) {
|
|
150
|
-
return {
|
|
151
|
-
ok: false,
|
|
152
|
-
message: "Merge requires mergedMemoryId or mergedContent; no memories changed"
|
|
153
|
-
};
|
|
154
|
-
}
|
|
155
|
-
const category = options.mergedCategory ?? mergedMemoryCategory(sourceA, sourceB);
|
|
156
|
-
let mergedId;
|
|
157
|
-
try {
|
|
158
|
-
mergedId = await storage.writeMemory(category, mergedContent, {
|
|
159
|
-
actor: "contradiction-resolution",
|
|
160
|
-
confidence: Math.min(sourceA.frontmatter.confidence ?? 0.8, sourceB.frontmatter.confidence ?? 0.8),
|
|
161
|
-
tags: ["contradiction-resolution", "merge"],
|
|
162
|
-
source: "contradiction-resolution",
|
|
163
|
-
lineage: [idA, idB],
|
|
164
|
-
derivedFrom: [idA, idB],
|
|
165
|
-
derivedVia: "merge"
|
|
166
|
-
});
|
|
167
|
-
} catch (err) {
|
|
168
|
-
log.warn(
|
|
169
|
-
"[contradiction-resolution] merged memory creation failed for %s: %s",
|
|
170
|
-
pairId,
|
|
171
|
-
err instanceof Error ? err.message : err
|
|
172
|
-
);
|
|
173
|
-
return { ok: false, message: `Merged memory could not be created; not resolving ${pairId}` };
|
|
174
|
-
}
|
|
175
|
-
const replacement = await storage.getMemoryById(mergedId);
|
|
176
|
-
if (!replacement) {
|
|
177
|
-
await cleanupMemoryId(storage, mergedId);
|
|
178
|
-
return { ok: false, message: `Merged memory ${mergedId} could not be verified; not resolving` };
|
|
179
|
-
}
|
|
180
|
-
return { ok: true, mergedId, sourceA, sourceB, created: true };
|
|
181
|
-
}
|
|
182
|
-
function mergedMemoryCategory(sourceA, sourceB) {
|
|
183
|
-
return sourceA.frontmatter.category === sourceB.frontmatter.category ? sourceA.frontmatter.category : "fact";
|
|
184
|
-
}
|
|
185
|
-
async function validateKeepTarget(storage, pairId, keepId) {
|
|
186
|
-
const target = await loadSourceSnapshot(storage, keepId);
|
|
187
|
-
if (!target) {
|
|
188
|
-
return { ok: false, message: `Kept memory ${keepId} not found; not resolving ${pairId}` };
|
|
189
|
-
}
|
|
190
|
-
const status = target.frontmatter.status ?? "active";
|
|
191
|
-
if (status !== "active") {
|
|
192
|
-
return { ok: false, message: `Kept memory ${keepId} is ${status}; not resolving ${pairId}` };
|
|
193
|
-
}
|
|
194
|
-
return { ok: true };
|
|
195
|
-
}
|
|
196
|
-
async function loadSourceSnapshot(storage, memoryId) {
|
|
197
|
-
try {
|
|
198
|
-
return await storage.getMemoryById(memoryId);
|
|
199
|
-
} catch (err) {
|
|
200
|
-
log.warn(
|
|
201
|
-
"[contradiction-resolution] source snapshot failed for %s: %s",
|
|
202
|
-
memoryId,
|
|
203
|
-
err instanceof Error ? err.message : err
|
|
204
|
-
);
|
|
205
|
-
return null;
|
|
206
|
-
}
|
|
207
|
-
}
|
|
208
|
-
async function restoreMemorySnapshot(storage, memory, reasonCode = "contradiction-resolution:merge-rollback") {
|
|
209
|
-
try {
|
|
210
|
-
const current = await storage.getMemoryById(memory.frontmatter.id);
|
|
211
|
-
if (!current) return false;
|
|
212
|
-
const restoredFrontmatter = {
|
|
213
|
-
...memory.frontmatter,
|
|
214
|
-
status: memory.frontmatter.status,
|
|
215
|
-
supersededBy: memory.frontmatter.supersededBy,
|
|
216
|
-
supersededAt: memory.frontmatter.supersededAt
|
|
217
|
-
};
|
|
218
|
-
return await storage.writeMemoryFrontmatter(current, restoredFrontmatter, {
|
|
219
|
-
actor: "contradiction-resolution",
|
|
220
|
-
reasonCode
|
|
221
|
-
});
|
|
222
|
-
} catch (err) {
|
|
223
|
-
log.warn(
|
|
224
|
-
"[contradiction-resolution] rollback failed for %s: %s",
|
|
225
|
-
memory.frontmatter.id,
|
|
226
|
-
err instanceof Error ? err.message : err
|
|
227
|
-
);
|
|
228
|
-
return false;
|
|
229
|
-
}
|
|
230
|
-
}
|
|
231
|
-
async function cleanupCreatedReplacement(storage, replacement) {
|
|
232
|
-
if (!replacement.created) return;
|
|
233
|
-
await cleanupMemoryId(storage, replacement.mergedId);
|
|
234
|
-
}
|
|
235
|
-
async function cleanupMemoryId(storage, memoryId) {
|
|
236
|
-
try {
|
|
237
|
-
const memory = await storage.getMemoryById(memoryId);
|
|
238
|
-
const invalidated = await storage.invalidateMemory(memoryId);
|
|
239
|
-
if (invalidated && memory?.frontmatter.category === "fact") {
|
|
240
|
-
await storage.removeFactContentHashesForMemories([memory]);
|
|
241
|
-
}
|
|
242
|
-
} catch (err) {
|
|
243
|
-
log.warn(
|
|
244
|
-
"[contradiction-resolution] cleanup failed for merged memory %s: %s",
|
|
245
|
-
memoryId,
|
|
246
|
-
err instanceof Error ? err.message : err
|
|
247
|
-
);
|
|
248
|
-
}
|
|
249
|
-
}
|
|
250
|
-
async function supersedeSafe(storage, oldId, newId, reason) {
|
|
251
|
-
try {
|
|
252
|
-
const result = await storage.supersedeMemory(oldId, newId, reason);
|
|
253
|
-
if (result === false) {
|
|
254
|
-
log.warn("[contradiction-resolution] supersede returned false for %s \u2192 %s", oldId, newId);
|
|
255
|
-
return false;
|
|
256
|
-
}
|
|
257
|
-
return true;
|
|
258
|
-
} catch (err) {
|
|
259
|
-
log.warn(
|
|
260
|
-
"[contradiction-resolution] supersede failed %s \u2192 %s: %s",
|
|
261
|
-
oldId,
|
|
262
|
-
newId,
|
|
263
|
-
err instanceof Error ? err.message : err
|
|
264
|
-
);
|
|
265
|
-
return false;
|
|
266
|
-
}
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
export {
|
|
270
|
-
isValidResolutionVerb,
|
|
271
|
-
executeResolution
|
|
272
|
-
};
|