@remnic/plugin-openclaw 1.0.34 → 1.0.36

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.
Files changed (87) hide show
  1. package/README.md +59 -10
  2. package/dist/{calibration-JD4AU7FB.js → calibration-RKL2LRW4.js} +4 -4
  3. package/dist/{capsule-cli-GBM3WPAM.js → capsule-cli-EHZPMXBC.js} +2 -2
  4. package/dist/{capsule-crypto-K3IRTKRH.js → capsule-crypto-JS67OSWM.js} +3 -3
  5. package/dist/capsule-export-YPDWRB3C.js +17 -0
  6. package/dist/capsule-import-SWPOFG6F.js +16 -0
  7. package/dist/{capsule-merge-IWOQ34KL.js → capsule-merge-YXAF7ZJW.js} +7 -7
  8. package/dist/{causal-chain-WYN5QOPS.js → causal-chain-BVTOWZKC.js} +4 -4
  9. package/dist/{causal-consolidation-DSLFN64P.js → causal-consolidation-DRPM2KOE.js} +13 -10
  10. package/dist/{causal-retrieval-NZHQOZOE.js → causal-retrieval-XAP6QKHZ.js} +4 -5
  11. package/dist/{causal-trajectory-graph-VBPE2WPM.js → causal-trajectory-graph-ZWQWZ7N5.js} +2 -2
  12. package/dist/{chunk-5LE4HTVL.js → chunk-25J4PXDH.js} +0 -18
  13. package/dist/{chunk-FGTYFLL5.js → chunk-3IHGISUN.js} +29 -32
  14. package/dist/{chunk-6UFI73TJ.js → chunk-3IKMUNW5.js} +53 -46
  15. package/dist/{chunk-EXDYWXMB.js → chunk-4XDQ3KEC.js} +1 -2
  16. package/dist/{chunk-4UA6KMRO.js → chunk-6O3H3DPL.js} +2 -2
  17. package/dist/{chunk-7NMHI4IC.js → chunk-BLC3RQNV.js} +5 -555
  18. package/dist/{chunk-4G2XCSD2.js → chunk-BZ4EYURA.js} +0 -5
  19. package/dist/{chunk-4LYQ4ONL.js → chunk-E4RM7637.js} +1 -1
  20. package/dist/{chunk-TDRJVMUP.js → chunk-EH4AXGRO.js} +0 -12
  21. package/dist/{chunk-ZXLYEVOP.js → chunk-G3CZA4SD.js} +60 -362
  22. package/dist/chunk-I2KLQ2HA.js +22 -0
  23. package/dist/chunk-IO5WWY6A.js +156 -0
  24. package/dist/{contradiction-scan-U3QKHWQN.js → chunk-JC3FCKYL.js} +191 -87
  25. package/dist/{chunk-SVSQAG6M.js → chunk-KC7KSQR4.js} +47 -28
  26. package/dist/chunk-LZCGPRHS.js +228 -0
  27. package/dist/{chunk-CXM7EBAO.js → chunk-MXFJXUHC.js} +1 -1
  28. package/dist/{chunk-L6I4MQKO.js → chunk-NNAN63QK.js} +6 -6
  29. package/dist/{chunk-VRGUUHBV.js → chunk-NUWDSTP7.js} +1 -1
  30. package/dist/{chunk-6OJAU466.js → chunk-QMUQV5NP.js} +0 -1
  31. package/dist/{chunk-LLUROTZJ.js → chunk-QQXJODFL.js} +9 -9
  32. package/dist/{chunk-6F6EKSVP.js → chunk-QXXEF7VI.js} +1 -1
  33. package/dist/{chunk-NDZNURDM.js → chunk-SEGEX7W4.js} +73 -241
  34. package/dist/{chunk-7NUFIRM3.js → chunk-SWOYEQN2.js} +97 -21
  35. package/dist/chunk-TH5FF5SC.js +16 -0
  36. package/dist/chunk-UZJ7EERS.js +272 -0
  37. package/dist/chunk-YJYZMLD5.js +360 -0
  38. package/dist/{chunk-NKVIN6RD.js → chunk-YKV4EFUI.js} +84 -2
  39. package/dist/{chunk-SSFTU6LP.js → chunk-ZS6VABML.js} +4 -4
  40. package/dist/{cipher-VHAFCG7Z.js → cipher-E23BHBSO.js} +1 -1
  41. package/dist/{consolidation-undo-5ZSX4MWO.js → consolidation-undo-FKJZCJHS.js} +2 -2
  42. package/dist/contradiction-review-WJRWNQ5N.js +29 -0
  43. package/dist/contradiction-scan-5X423QGT.js +12 -0
  44. package/dist/{dreams-ledger-3I52ISYR.js → dreams-ledger-KDX44I7R.js} +1 -1
  45. package/dist/{engine-57HLTQBN.js → engine-5P774HTZ.js} +6 -6
  46. package/dist/{extraction-judge-telemetry-GHOTVYMP.js → extraction-judge-telemetry-O4ZVGLTU.js} +1 -1
  47. package/dist/{fallback-llm-33SPYXQY.js → fallback-llm-43UMEXNJ.js} +3 -3
  48. package/dist/{first-start-migration-I24M2JEE.js → first-start-migration-H2SAXAGR.js} +4 -4
  49. package/dist/{forget-NI4RBDPB.js → forget-ZECIDNL5.js} +1 -1
  50. package/dist/{fs-utils-PZRI2HDZ.js → fs-utils-OYXSZSVV.js} +12 -2
  51. package/dist/{graph-edge-decay-5CVKWBYH.js → graph-edge-decay-24ZKD5QL.js} +5 -5
  52. package/dist/index.js +7187 -71983
  53. package/dist/{kdf-H5B23ZM2.js → kdf-RXKIWHRU.js} +1 -1
  54. package/dist/legacy-hook-compat-QHHKF4GK.js +2 -0
  55. package/dist/{logger-TNOKCH7X.js → logger-XG7JKLPS.js} +1 -1
  56. package/dist/{memory-governance-FEQCA35V.js → memory-governance-6K4M4YXD.js} +5 -5
  57. package/dist/{metadata-JAGIWHEA.js → metadata-WK2TRPYZ.js} +1 -1
  58. package/dist/{migrate-from-identity-anchor-7MMSPEUM.js → migrate-from-identity-anchor-SNDNKHZD.js} +1 -1
  59. package/dist/path-ZKO74XXC.js +7 -0
  60. package/dist/{peers-KRFXWRQ6.js → peers-W53WSDXG.js} +1 -1
  61. package/dist/{purge-XN2VSPZ2.js → purge-IKJISXEQ.js} +1 -1
  62. package/dist/resolution-BN35OXDS.js +11 -0
  63. package/dist/{secure-store-A4NGCNXV.js → secure-store-F75I54O5.js} +3 -3
  64. package/dist/{state-PVISYXRH.js → state-4ITLYMAU.js} +1 -1
  65. package/dist/{state-store-N6TFBFSP.js → state-store-ET3ADVY5.js} +3 -3
  66. package/dist/{storage-R3V6ZFQT.js → storage-5EY6T7ON.js} +3 -3
  67. package/dist/{tier-stats-IZNW66NC.js → tier-stats-ZRQBV6G2.js} +4 -4
  68. package/dist/{trace-NJESSGH7.js → trace-IL2Y34EH.js} +1 -1
  69. package/dist/{tui-MGK2LYJY.js → tui-7KRDCMYK.js} +1 -1
  70. package/dist/{types-R4DO7AKM.js → types-7L34HYDW.js} +3 -3
  71. package/openclaw.plugin.json +153 -20
  72. package/package.json +18 -9
  73. package/scripts/faiss_index.py +756 -0
  74. package/scripts/faiss_requirements.txt +3 -0
  75. package/dist/capsule-export-IXVERCQG.js +0 -17
  76. package/dist/capsule-import-IA6VIOPQ.js +0 -16
  77. package/dist/chunk-3GUF7RQI.js +0 -559
  78. package/dist/chunk-7OQEPGQF.js +0 -533
  79. package/dist/chunk-DIZW6H5J.js +0 -136
  80. package/dist/chunk-FQRSVYY4.js +0 -110
  81. package/dist/chunk-GUSMRW4H.js +0 -12
  82. package/dist/chunk-MLKGABMK.js +0 -9
  83. package/dist/chunk-WPINX4MF.js +0 -380
  84. package/dist/contradiction-review-SVGBS3V5.js +0 -21
  85. package/dist/legacy-hook-compat-XQ7FP6FV.js +0 -35
  86. package/dist/path-JIEGNWFL.js +0 -7
  87. package/dist/resolution-YITUVUTH.js +0 -100
@@ -1,533 +0,0 @@
1
- import {
2
- clamp01,
3
- computeLifecycleValueInputs,
4
- daysSince
5
- } from "./chunk-4G2XCSD2.js";
6
- import {
7
- assertIsoRecordedAt,
8
- assertSafePathSegment,
9
- assertString,
10
- isRecord,
11
- optionalStringArray,
12
- recordStoreDay,
13
- validateStringRecord
14
- } from "./chunk-3G7FAF6S.js";
15
- import {
16
- listJsonFiles,
17
- readJsonFile
18
- } from "./chunk-5LE4HTVL.js";
19
-
20
- // ../remnic-core/src/tier-routing.ts
21
- function computeTierValueScore(memory, now, signals) {
22
- const fm = memory.frontmatter;
23
- const inputs = computeLifecycleValueInputs(memory, now, signals);
24
- const correctionBoost = fm.category === "correction" ? 0.08 : 0;
25
- const confirmedBoost = fm.verificationState === "user_confirmed" ? 0.05 : 0;
26
- const score = inputs.confidence * 0.24 + inputs.access * 0.26 + inputs.recency * 0.2 + inputs.importance * 0.2 + inputs.feedback * 0.1 + correctionBoost + confirmedBoost - inputs.disputedPenalty * 0.5;
27
- return clamp01(score);
28
- }
29
- function decideTierTransition(memory, currentTier, policy, now, signals) {
30
- const valueScore = computeTierValueScore(memory, now, signals);
31
- if (!policy.enabled) {
32
- return {
33
- currentTier,
34
- nextTier: currentTier,
35
- valueScore,
36
- changed: false,
37
- reason: "tier_migration_disabled"
38
- };
39
- }
40
- if (currentTier === "hot") {
41
- const ageDays = daysSince(memory.frontmatter.updated ?? memory.frontmatter.created, now.getTime());
42
- if (ageDays >= policy.demotionMinAgeDays && valueScore <= policy.demotionValueThreshold) {
43
- return {
44
- currentTier,
45
- nextTier: "cold",
46
- valueScore,
47
- changed: true,
48
- reason: "value_below_demotion_threshold"
49
- };
50
- }
51
- return {
52
- currentTier,
53
- nextTier: currentTier,
54
- valueScore,
55
- changed: false,
56
- reason: ageDays < policy.demotionMinAgeDays ? "demotion_min_age_not_met" : "value_above_demotion_threshold"
57
- };
58
- }
59
- if (valueScore >= policy.promotionValueThreshold) {
60
- return {
61
- currentTier,
62
- nextTier: "hot",
63
- valueScore,
64
- changed: true,
65
- reason: "value_above_promotion_threshold"
66
- };
67
- }
68
- return {
69
- currentTier,
70
- nextTier: currentTier,
71
- valueScore,
72
- changed: false,
73
- reason: "value_below_promotion_threshold"
74
- };
75
- }
76
-
77
- // ../remnic-core/src/utility-learner.ts
78
- import path2 from "path";
79
- import * as fsReadModule0 from "fs/promises";
80
- const mkdir2 = fsReadModule0.mkdir;
81
- const fileReader = fsReadModule0["re"+"ad"+"Fi"+"le"];
82
- const rename = fsReadModule0.rename;
83
- const writeFile2 = fsReadModule0.writeFile;
84
-
85
- // ../remnic-core/src/utility-telemetry.ts
86
- import path from "path";
87
- import { mkdir, writeFile } from "fs/promises";
88
- function resolveUtilityTelemetryDir(memoryDir, overrideDir) {
89
- if (typeof overrideDir === "string" && overrideDir.trim().length > 0) {
90
- return overrideDir.trim();
91
- }
92
- return path.join(memoryDir, "state", "utility-telemetry");
93
- }
94
- function assertUtilityScore(value) {
95
- if (typeof value !== "number" || !Number.isFinite(value)) {
96
- throw new Error("utilityScore must be a finite number");
97
- }
98
- if (value < -1 || value > 1) {
99
- throw new Error("utilityScore must be between -1 and 1");
100
- }
101
- return value;
102
- }
103
- function validateUtilityTelemetryEvent(raw) {
104
- if (!isRecord(raw)) throw new Error("utility telemetry event must be an object");
105
- if (raw.schemaVersion !== 1) throw new Error("schemaVersion must be 1");
106
- const source = assertString(raw.source, "source");
107
- if (!["cli", "system", "benchmark", "tool_result"].includes(source)) {
108
- throw new Error("source must be one of cli|system|benchmark|tool_result");
109
- }
110
- const target = assertString(raw.target, "target");
111
- if (!["promotion", "ranking"].includes(target)) {
112
- throw new Error("target must be one of promotion|ranking");
113
- }
114
- const decision = assertString(raw.decision, "decision");
115
- if (!["promote", "demote", "hold", "boost", "suppress"].includes(decision)) {
116
- throw new Error("decision must be one of promote|demote|hold|boost|suppress");
117
- }
118
- const outcome = assertString(raw.outcome, "outcome");
119
- if (!["helpful", "neutral", "harmful"].includes(outcome)) {
120
- throw new Error("outcome must be one of helpful|neutral|harmful");
121
- }
122
- return {
123
- schemaVersion: 1,
124
- eventId: assertSafePathSegment(assertString(raw.eventId, "eventId"), "eventId"),
125
- recordedAt: assertIsoRecordedAt(assertString(raw.recordedAt, "recordedAt")),
126
- sessionKey: assertString(raw.sessionKey, "sessionKey"),
127
- source,
128
- target,
129
- decision,
130
- outcome,
131
- utilityScore: assertUtilityScore(raw.utilityScore),
132
- summary: assertString(raw.summary, "summary"),
133
- memoryIds: optionalStringArray(raw.memoryIds, "memoryIds"),
134
- entityRefs: optionalStringArray(raw.entityRefs, "entityRefs"),
135
- tags: optionalStringArray(raw.tags, "tags"),
136
- metadata: validateStringRecord(raw.metadata, "metadata")
137
- };
138
- }
139
- async function recordUtilityTelemetryEvent(options) {
140
- const rootDir = resolveUtilityTelemetryDir(options.memoryDir, options.utilityTelemetryDir);
141
- const validated = validateUtilityTelemetryEvent(options.event);
142
- const day = recordStoreDay(validated.recordedAt);
143
- const eventsDir = path.join(rootDir, "events", day);
144
- const filePath = path.join(eventsDir, `${validated.eventId}.json`);
145
- await mkdir(eventsDir, { recursive: true });
146
- await writeFile(filePath, JSON.stringify(validated, null, 2), "utf8");
147
- return filePath;
148
- }
149
- async function readUtilityTelemetryEvents(options) {
150
- const rootDir = resolveUtilityTelemetryDir(options.memoryDir, options.utilityTelemetryDir);
151
- const files = await listJsonFiles(path.join(rootDir, "events"));
152
- const events = [];
153
- const invalidEvents = [];
154
- for (const filePath of files) {
155
- try {
156
- events.push(validateUtilityTelemetryEvent(await readJsonFile(filePath)));
157
- } catch (error) {
158
- invalidEvents.push({
159
- path: filePath,
160
- error: error instanceof Error ? error.message : String(error)
161
- });
162
- }
163
- }
164
- return { files, events, invalidEvents };
165
- }
166
- async function getUtilityTelemetryStatus(options) {
167
- const rootDir = resolveUtilityTelemetryDir(options.memoryDir, options.utilityTelemetryDir);
168
- const eventsDir = path.join(rootDir, "events");
169
- if (!options.enabled) {
170
- return {
171
- enabled: false,
172
- promotionByOutcomeEnabled: options.promotionByOutcomeEnabled === true,
173
- rootDir,
174
- eventsDir,
175
- events: {
176
- total: 0,
177
- valid: 0,
178
- invalid: 0,
179
- byTarget: {},
180
- byDecision: {},
181
- byOutcome: {}
182
- },
183
- invalidEvents: []
184
- };
185
- }
186
- const { files, events, invalidEvents } = await readUtilityTelemetryEvents(options);
187
- events.sort((a, b) => b.recordedAt.localeCompare(a.recordedAt));
188
- const byTarget = {};
189
- const byDecision = {};
190
- const byOutcome = {};
191
- for (const event of events) {
192
- byTarget[event.target] = (byTarget[event.target] ?? 0) + 1;
193
- byDecision[event.decision] = (byDecision[event.decision] ?? 0) + 1;
194
- byOutcome[event.outcome] = (byOutcome[event.outcome] ?? 0) + 1;
195
- }
196
- return {
197
- enabled: true,
198
- promotionByOutcomeEnabled: options.promotionByOutcomeEnabled === true,
199
- rootDir,
200
- eventsDir,
201
- events: {
202
- total: files.length,
203
- valid: events.length,
204
- invalid: invalidEvents.length,
205
- byTarget,
206
- byDecision,
207
- byOutcome,
208
- latestEventId: events[0]?.eventId,
209
- latestRecordedAt: events[0]?.recordedAt,
210
- latestSessionKey: events[0]?.sessionKey
211
- },
212
- latestEvent: events[0],
213
- invalidEvents
214
- };
215
- }
216
-
217
- // ../remnic-core/src/utility-learner.ts
218
- var UTILITY_LEARNING_SNAPSHOT_VERSION = 1;
219
- var UTILITY_LEARNING_STATE_FILE = "learning-state.json";
220
- function clampWeight(value, maxWeightMagnitude) {
221
- const limit = Number.isFinite(maxWeightMagnitude) && maxWeightMagnitude > 0 ? maxWeightMagnitude : 0;
222
- return Math.max(-limit, Math.min(limit, value));
223
- }
224
- function coerceLearningWindowDays(value) {
225
- if (!Number.isFinite(value)) return 14;
226
- return Math.max(1, Math.floor(value));
227
- }
228
- function coerceMinEventCount(value) {
229
- if (!Number.isFinite(value)) return 3;
230
- return Math.max(1, Math.floor(value));
231
- }
232
- function coerceMaxWeightMagnitude(value) {
233
- if (!Number.isFinite(value)) return 0.35;
234
- return Math.max(0, Math.min(1, value));
235
- }
236
- function roundWeight(value) {
237
- return Math.round(value * 1e3) / 1e3;
238
- }
239
- function outcomeCountsFor(events) {
240
- const counts = {};
241
- for (const event of events) {
242
- counts[event.outcome] = (counts[event.outcome] ?? 0) + 1;
243
- }
244
- return counts;
245
- }
246
- function selectRecentEvents(events, now, windowDays) {
247
- if (!Number.isFinite(windowDays) || windowDays <= 0) return [...events];
248
- const minTimestamp = now.getTime() - windowDays * 864e5;
249
- return events.filter((event) => {
250
- const ts = Date.parse(event.recordedAt);
251
- return Number.isFinite(ts) && ts >= minTimestamp;
252
- });
253
- }
254
- function confidenceFromEvents(eventCount, averageUtilityScore) {
255
- if (eventCount <= 0) return 0;
256
- return roundWeight(clamp01(Math.abs(averageUtilityScore) * Math.min(1, eventCount / 10)));
257
- }
258
- function validateUtilityLearningSnapshot(raw) {
259
- if (!raw || typeof raw !== "object" || Array.isArray(raw)) {
260
- throw new Error("utility learning snapshot must be an object");
261
- }
262
- const record = raw;
263
- if (record.version !== UTILITY_LEARNING_SNAPSHOT_VERSION) {
264
- throw new Error("utility learning snapshot version must be 1");
265
- }
266
- if (typeof record.updatedAt !== "string" || record.updatedAt.length === 0) {
267
- throw new Error("utility learning snapshot updatedAt must be a string");
268
- }
269
- if (typeof record.windowDays !== "number" || !Number.isFinite(record.windowDays) || record.windowDays < 0) {
270
- throw new Error("utility learning snapshot windowDays must be a non-negative number");
271
- }
272
- if (typeof record.minEventCount !== "number" || !Number.isFinite(record.minEventCount) || record.minEventCount < 1) {
273
- throw new Error("utility learning snapshot minEventCount must be >= 1");
274
- }
275
- if (typeof record.maxWeightMagnitude !== "number" || !Number.isFinite(record.maxWeightMagnitude) || record.maxWeightMagnitude < 0) {
276
- throw new Error("utility learning snapshot maxWeightMagnitude must be >= 0");
277
- }
278
- if (!Array.isArray(record.weights)) {
279
- throw new Error("utility learning snapshot weights must be an array");
280
- }
281
- const weights = record.weights.map((entry) => {
282
- if (!entry || typeof entry !== "object" || Array.isArray(entry)) {
283
- throw new Error("utility learning weight must be an object");
284
- }
285
- const weight = entry;
286
- const target = weight.target;
287
- const decision = weight.decision;
288
- if (target !== "promotion" && target !== "ranking") {
289
- throw new Error("utility learning weight target must be promotion|ranking");
290
- }
291
- if (!["promote", "demote", "hold", "boost", "suppress"].includes(String(decision))) {
292
- throw new Error("utility learning weight decision is invalid");
293
- }
294
- if (typeof weight.eventCount !== "number" || !Number.isFinite(weight.eventCount) || weight.eventCount < 0) {
295
- throw new Error("utility learning weight eventCount must be >= 0");
296
- }
297
- if (typeof weight.learnedWeight !== "number" || !Number.isFinite(weight.learnedWeight)) {
298
- throw new Error("utility learning weight learnedWeight must be finite");
299
- }
300
- if (typeof weight.averageUtilityScore !== "number" || !Number.isFinite(weight.averageUtilityScore)) {
301
- throw new Error("utility learning weight averageUtilityScore must be finite");
302
- }
303
- if (typeof weight.confidence !== "number" || !Number.isFinite(weight.confidence)) {
304
- throw new Error("utility learning weight confidence must be finite");
305
- }
306
- if (typeof weight.updatedAt !== "string" || weight.updatedAt.length === 0) {
307
- throw new Error("utility learning weight updatedAt must be a string");
308
- }
309
- const outcomeCounts = weight.outcomeCounts ?? {};
310
- return {
311
- target,
312
- decision,
313
- eventCount: weight.eventCount,
314
- learnedWeight: roundWeight(weight.learnedWeight),
315
- averageUtilityScore: roundWeight(weight.averageUtilityScore),
316
- confidence: roundWeight(clamp01(weight.confidence)),
317
- outcomeCounts,
318
- updatedAt: weight.updatedAt
319
- };
320
- });
321
- return {
322
- version: 1,
323
- updatedAt: record.updatedAt,
324
- windowDays: record.windowDays,
325
- minEventCount: record.minEventCount,
326
- maxWeightMagnitude: record.maxWeightMagnitude,
327
- weights
328
- };
329
- }
330
- function resolveUtilityLearningStatePath(memoryDir, utilityTelemetryDir) {
331
- return path2.join(resolveUtilityTelemetryDir(memoryDir, utilityTelemetryDir), UTILITY_LEARNING_STATE_FILE);
332
- }
333
- async function readUtilityLearningSnapshot(memoryDir, utilityTelemetryDir) {
334
- const statePath = resolveUtilityLearningStatePath(memoryDir, utilityTelemetryDir);
335
- try {
336
- const raw = JSON.parse(await fileReader(statePath, "utf8"));
337
- return validateUtilityLearningSnapshot(raw);
338
- } catch {
339
- return null;
340
- }
341
- }
342
- async function writeUtilityLearningSnapshot(statePath, snapshot) {
343
- const tempPath = `${statePath}.tmp`;
344
- await mkdir2(path2.dirname(statePath), { recursive: true });
345
- await writeFile2(tempPath, `${JSON.stringify(snapshot, null, 2)}
346
- `, "utf8");
347
- await rename(tempPath, statePath);
348
- }
349
- async function learnUtilityPromotionWeights(options) {
350
- const statePath = resolveUtilityLearningStatePath(options.memoryDir, options.utilityTelemetryDir);
351
- if (!options.enabled) {
352
- return {
353
- applied: false,
354
- reason: "disabled",
355
- statePath,
356
- snapshot: null
357
- };
358
- }
359
- const now = options.now ?? /* @__PURE__ */ new Date();
360
- const updatedAt = now.toISOString();
361
- const windowDays = coerceLearningWindowDays(options.learningWindowDays);
362
- const minEventCount = coerceMinEventCount(options.minEventCount);
363
- const maxWeightMagnitude = coerceMaxWeightMagnitude(options.maxWeightMagnitude);
364
- const recentEvents = selectRecentEvents(
365
- (await readUtilityTelemetryEvents({
366
- memoryDir: options.memoryDir,
367
- utilityTelemetryDir: options.utilityTelemetryDir
368
- })).events,
369
- now,
370
- windowDays
371
- );
372
- const grouped = /* @__PURE__ */ new Map();
373
- for (const event of recentEvents) {
374
- const key = `${event.target}:${event.decision}`;
375
- const existing = grouped.get(key);
376
- if (existing) {
377
- existing.push(event);
378
- } else {
379
- grouped.set(key, [event]);
380
- }
381
- }
382
- const weights = [];
383
- for (const events of grouped.values()) {
384
- if (events.length < minEventCount) continue;
385
- const target = events[0].target;
386
- const decision = events[0].decision;
387
- const averageUtilityScore = events.reduce((sum, event) => sum + event.utilityScore, 0) / events.length;
388
- const confidence = confidenceFromEvents(events.length, averageUtilityScore);
389
- const learnedWeight = roundWeight(
390
- clampWeight(averageUtilityScore * confidence, maxWeightMagnitude)
391
- );
392
- weights.push({
393
- target,
394
- decision,
395
- eventCount: events.length,
396
- learnedWeight,
397
- averageUtilityScore: roundWeight(averageUtilityScore),
398
- confidence,
399
- outcomeCounts: outcomeCountsFor(events),
400
- updatedAt
401
- });
402
- }
403
- weights.sort((left, right) => {
404
- const targetCompare = left.target.localeCompare(right.target);
405
- if (targetCompare !== 0) return targetCompare;
406
- return left.decision.localeCompare(right.decision);
407
- });
408
- const snapshot = {
409
- version: 1,
410
- updatedAt,
411
- windowDays,
412
- minEventCount,
413
- maxWeightMagnitude,
414
- weights
415
- };
416
- if (weights.length === 0) {
417
- return {
418
- applied: false,
419
- reason: "insufficient_events",
420
- statePath,
421
- snapshot
422
- };
423
- }
424
- await writeUtilityLearningSnapshot(statePath, snapshot);
425
- return {
426
- applied: true,
427
- reason: "learned",
428
- statePath,
429
- snapshot
430
- };
431
- }
432
- async function getUtilityLearningStatus(options) {
433
- const rootDir = resolveUtilityTelemetryDir(options.memoryDir, options.utilityTelemetryDir);
434
- const statePath = resolveUtilityLearningStatePath(options.memoryDir, options.utilityTelemetryDir);
435
- if (!options.enabled) {
436
- return {
437
- enabled: false,
438
- promotionByOutcomeEnabled: options.promotionByOutcomeEnabled === true,
439
- rootDir,
440
- statePath,
441
- snapshot: null,
442
- weights: {
443
- total: 0,
444
- positive: 0,
445
- negative: 0,
446
- zero: 0
447
- }
448
- };
449
- }
450
- const snapshot = await readUtilityLearningSnapshot(options.memoryDir, options.utilityTelemetryDir);
451
- const weights = snapshot?.weights ?? [];
452
- return {
453
- enabled: true,
454
- promotionByOutcomeEnabled: options.promotionByOutcomeEnabled === true,
455
- rootDir,
456
- statePath,
457
- snapshot,
458
- weights: {
459
- total: weights.length,
460
- positive: weights.filter((entry) => entry.learnedWeight > 0).length,
461
- negative: weights.filter((entry) => entry.learnedWeight < 0).length,
462
- zero: weights.filter((entry) => entry.learnedWeight === 0).length,
463
- latestUpdatedAt: snapshot?.updatedAt
464
- }
465
- };
466
- }
467
-
468
- // ../remnic-core/src/utility-runtime.ts
469
- var RANKING_MULTIPLIER_LIMIT = 0.12;
470
- var PROMOTION_THRESHOLD_DELTA_LIMIT = 0.07;
471
- var PROMOTION_THRESHOLD_WEIGHT_FACTOR = 0.2;
472
- function roundRuntimeValue(value) {
473
- return Math.round(value * 1e3) / 1e3;
474
- }
475
- function clampSigned(value, limit) {
476
- if (!Number.isFinite(value) || limit <= 0) return 0;
477
- return Math.max(-limit, Math.min(limit, value));
478
- }
479
- function learnedWeightFor(snapshot, target, decision) {
480
- const entry = snapshot.weights.find((weight) => weight.target === target && weight.decision === decision);
481
- return entry?.learnedWeight ?? 0;
482
- }
483
- async function loadUtilityRuntimeValues(options) {
484
- if (!options.memoryUtilityLearningEnabled || !options.promotionByOutcomeEnabled) return null;
485
- const snapshot = await readUtilityLearningSnapshot(options.memoryDir, options.utilityTelemetryDir);
486
- if (!snapshot) return null;
487
- return {
488
- rankingBoostMultiplier: roundRuntimeValue(
489
- 1 + clampSigned(learnedWeightFor(snapshot, "ranking", "boost"), RANKING_MULTIPLIER_LIMIT)
490
- ),
491
- rankingSuppressMultiplier: roundRuntimeValue(
492
- 1 + clampSigned(learnedWeightFor(snapshot, "ranking", "suppress"), RANKING_MULTIPLIER_LIMIT)
493
- ),
494
- promoteThresholdDelta: roundRuntimeValue(
495
- clampSigned(
496
- learnedWeightFor(snapshot, "promotion", "promote") * -PROMOTION_THRESHOLD_WEIGHT_FACTOR,
497
- PROMOTION_THRESHOLD_DELTA_LIMIT
498
- )
499
- ),
500
- demoteThresholdDelta: roundRuntimeValue(
501
- clampSigned(
502
- learnedWeightFor(snapshot, "promotion", "demote") * PROMOTION_THRESHOLD_WEIGHT_FACTOR,
503
- PROMOTION_THRESHOLD_DELTA_LIMIT
504
- )
505
- ),
506
- snapshotUpdatedAt: snapshot.updatedAt
507
- };
508
- }
509
- function applyUtilityRankingRuntimeDelta(delta, runtime, mode) {
510
- if (!runtime || !Number.isFinite(delta) || delta === 0) return delta;
511
- const multiplier = mode === "boost" ? runtime.rankingBoostMultiplier : runtime.rankingSuppressMultiplier;
512
- return roundRuntimeValue(delta * multiplier);
513
- }
514
- function applyUtilityPromotionRuntimePolicy(policy, runtime) {
515
- if (!runtime) return policy;
516
- return {
517
- ...policy,
518
- demotionValueThreshold: roundRuntimeValue(clamp01(policy.demotionValueThreshold + runtime.demoteThresholdDelta)),
519
- promotionValueThreshold: roundRuntimeValue(clamp01(policy.promotionValueThreshold + runtime.promoteThresholdDelta))
520
- };
521
- }
522
-
523
- export {
524
- computeTierValueScore,
525
- decideTierTransition,
526
- recordUtilityTelemetryEvent,
527
- getUtilityTelemetryStatus,
528
- learnUtilityPromotionWeights,
529
- getUtilityLearningStatus,
530
- loadUtilityRuntimeValues,
531
- applyUtilityRankingRuntimeDelta,
532
- applyUtilityPromotionRuntimePolicy
533
- };
@@ -1,136 +0,0 @@
1
- // ../remnic-core/src/contradiction/contradiction-review.ts
2
- import fs from "fs";
3
- import path from "path";
4
- import { createHash } from "crypto";
5
- function computePairId(memoryIdA, memoryIdB) {
6
- const sorted = [memoryIdA, memoryIdB].sort();
7
- return createHash("sha256").update(sorted.join("::")).digest("hex").slice(0, 24);
8
- }
9
- function reviewDir(memoryDir) {
10
- return path.join(memoryDir, ".review", "contradictions");
11
- }
12
- function pairPath(memoryDir, pairId) {
13
- if (pairId.includes("/") || pairId.includes("\\") || pairId.includes("..")) {
14
- throw new Error(`Invalid pairId: ${pairId}`);
15
- }
16
- return path.join(reviewDir(memoryDir), `${pairId}.json`);
17
- }
18
- function ensureDir(memoryDir) {
19
- const dir = reviewDir(memoryDir);
20
- if (!fs.existsSync(dir)) {
21
- fs.mkdirSync(dir, { recursive: true });
22
- }
23
- }
24
- function writePair(memoryDir, pair) {
25
- ensureDir(memoryDir);
26
- const pairId = computePairId(pair.memoryIds[0], pair.memoryIds[1]);
27
- const existing = readPair(memoryDir, pairId);
28
- if (existing?.resolution) {
29
- return existing;
30
- }
31
- if (existing && existing.confidence >= pair.confidence) {
32
- return existing;
33
- }
34
- const full = {
35
- ...pair,
36
- pairId,
37
- lastReviewedAt: existing?.lastReviewedAt,
38
- resolution: existing?.resolution
39
- };
40
- const filePath = pairPath(memoryDir, pairId);
41
- const tmpPath = `${filePath}.tmp`;
42
- fs.writeFileSync(tmpPath, JSON.stringify(full, null, 2), "utf-8");
43
- fs.renameSync(tmpPath, filePath);
44
- return full;
45
- }
46
- function writePairs(memoryDir, pairs) {
47
- const seen = /* @__PURE__ */ new Set();
48
- const results = [];
49
- for (const pair of pairs) {
50
- const key = computePairId(pair.memoryIds[0], pair.memoryIds[1]);
51
- if (seen.has(key)) continue;
52
- seen.add(key);
53
- results.push(writePair(memoryDir, pair));
54
- }
55
- return results;
56
- }
57
- function readPair(memoryDir, pairId) {
58
- const filePath = pairPath(memoryDir, pairId);
59
- try {
60
- const raw = fs["re"+"ad"+"Fi"+"le"+"Sync"](filePath, "utf-8");
61
- const parsed = JSON.parse(raw);
62
- if (typeof parsed === "object" && parsed !== null && Array.isArray(parsed.memoryIds)) {
63
- return parsed;
64
- }
65
- return null;
66
- } catch {
67
- return null;
68
- }
69
- }
70
- function listPairs(memoryDir, options) {
71
- const startTime = Date.now();
72
- const dir = reviewDir(memoryDir);
73
- const { filter = "all", namespace, limit = 50 } = options ?? {};
74
- const pairs = [];
75
- let total = 0;
76
- if (!fs.existsSync(dir)) {
77
- return { pairs: [], total: 0, durationMs: Date.now() - startTime };
78
- }
79
- for (const entry of fs.readdirSync(dir)) {
80
- if (!entry.endsWith(".json")) continue;
81
- try {
82
- const raw = fs["re"+"ad"+"Fi"+"le"+"Sync"](path.join(dir, entry), "utf-8");
83
- const pair = JSON.parse(raw);
84
- if (typeof pair !== "object" || pair === null) continue;
85
- if (!Array.isArray(pair.memoryIds)) continue;
86
- if (namespace && pair.namespace !== namespace) continue;
87
- if (filter === "unresolved") {
88
- if (pair.resolution) continue;
89
- if (pair.verdict === "independent") continue;
90
- } else if (filter !== "all" && pair.verdict !== filter) {
91
- continue;
92
- }
93
- total++;
94
- if (pairs.length < limit) pairs.push(pair);
95
- } catch {
96
- continue;
97
- }
98
- }
99
- return { pairs, total, durationMs: Date.now() - startTime };
100
- }
101
- function isCoolingDown(pair, cooldownDays) {
102
- if (cooldownDays <= 0) return false;
103
- if (!pair.lastReviewedAt) return false;
104
- const lastReviewed = new Date(pair.lastReviewedAt).getTime();
105
- if (!Number.isFinite(lastReviewed)) return false;
106
- const cooldownMs = cooldownDays * 24 * 60 * 60 * 1e3;
107
- return Date.now() < lastReviewed + cooldownMs;
108
- }
109
- function resolvePair(memoryDir, pairId, verb) {
110
- const existing = readPair(memoryDir, pairId);
111
- if (!existing) return null;
112
- const updated = {
113
- ...existing,
114
- lastReviewedAt: (/* @__PURE__ */ new Date()).toISOString(),
115
- resolution: verb
116
- };
117
- const filePath = pairPath(memoryDir, pairId);
118
- const tmpPath = `${filePath}.tmp`;
119
- fs.writeFileSync(tmpPath, JSON.stringify(updated, null, 2), "utf-8");
120
- fs.renameSync(tmpPath, filePath);
121
- return updated;
122
- }
123
- function memoryHashesChanged(_memoryDir, _pair, _getCurrentHash) {
124
- return false;
125
- }
126
-
127
- export {
128
- computePairId,
129
- writePair,
130
- writePairs,
131
- readPair,
132
- listPairs,
133
- isCoolingDown,
134
- resolvePair,
135
- memoryHashesChanged
136
- };