@hmharness/evolution 0.8.1 → 0.8.2
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/memory.js +25 -3
- package/package.json +1 -1
package/dist/memory.js
CHANGED
|
@@ -19,6 +19,7 @@
|
|
|
19
19
|
import { appendFile, mkdir, readFile, writeFile } from 'node:fs/promises';
|
|
20
20
|
import { createHash } from 'node:crypto';
|
|
21
21
|
import { join } from 'node:path';
|
|
22
|
+
import { rankContext } from "./ranker.js";
|
|
22
23
|
export async function readNotes(home) {
|
|
23
24
|
let raw;
|
|
24
25
|
try {
|
|
@@ -171,11 +172,32 @@ export async function retrieveMemory(home, task, opts = {}) {
|
|
|
171
172
|
else {
|
|
172
173
|
ranked = scoreNotes(notes, task, opts.workspace);
|
|
173
174
|
}
|
|
175
|
+
// V2 M5: the blueprint-weighted ContextRanker governs the final pick.
|
|
176
|
+
// Existing scores become `relevance`; recency derives from the note time
|
|
177
|
+
// (distillations are curated -> more important); dependency/similarity stay
|
|
178
|
+
// neutral until richer signals exist. Cost = chars/4.
|
|
179
|
+
const maxScore = Math.max(1, ...ranked.map((r) => r.score));
|
|
180
|
+
const newestTime = Date.parse(notes[notes.length - 1]?.time ?? '') || Date.now();
|
|
181
|
+
const oldestTime = Date.parse(notes[0]?.time ?? '') || newestTime;
|
|
182
|
+
const span = Math.max(1, newestTime - oldestTime);
|
|
183
|
+
const reRanked = rankContext(ranked.map(({ note, score }) => ({
|
|
184
|
+
source: 'memory',
|
|
185
|
+
contentRef: note.text,
|
|
186
|
+
relevance: score / maxScore,
|
|
187
|
+
recency: span > 1 ? (Date.parse(note.time) - oldestTime) / span : 1,
|
|
188
|
+
importance: /^\(distilled\)/.test(note.text) ? 0.8 : 0.5,
|
|
189
|
+
dependency: 0.5,
|
|
190
|
+
similarity: 0.5,
|
|
191
|
+
tokenCost: Math.ceil(note.text.length / 4),
|
|
192
|
+
})));
|
|
174
193
|
const picked = [];
|
|
175
194
|
const seen = new Set();
|
|
176
|
-
for (const
|
|
177
|
-
|
|
178
|
-
seen.
|
|
195
|
+
for (const c of reRanked.slice(0, topK)) {
|
|
196
|
+
const hit = ranked.find((r) => r.note.text === c.contentRef);
|
|
197
|
+
if (!hit || seen.has(hit.note.text))
|
|
198
|
+
continue;
|
|
199
|
+
picked.push(hit.note);
|
|
200
|
+
seen.add(hit.note.text);
|
|
179
201
|
}
|
|
180
202
|
for (const note of (newest > 0 ? notes.slice(-newest) : [])) {
|
|
181
203
|
if (!seen.has(note.text))
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hmharness/evolution",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.2",
|
|
4
4
|
"description": "hmharness evolution subsystem: persistent memory, insight capture, skill library, and the bench that gives evolution its fitness signal. First-class kernel citizen, not a plugin.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|