dsh-companion-memory-core 0.1.0 → 0.1.1
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/README.md +7 -0
- package/lib/core/llm-reviewer.js +25 -4
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -21,6 +21,13 @@ through the host's slot service; note browsing stays on the tool surface. A
|
|
|
21
21
|
custom pane is deferred: host remote namespaces are Typert-generated, so a
|
|
22
22
|
third-party plugin cannot register a new RPC group at runtime.
|
|
23
23
|
|
|
24
|
+
When consolidation runs, the model route is borrowed from the current session
|
|
25
|
+
request header. Set `reviewProvider` / `reviewModel` in the profile config to
|
|
26
|
+
pin a specific one; leaving both empty follows whatever the conversation uses.
|
|
27
|
+
Every written note carries an `evidence` quote that is verified verbatim
|
|
28
|
+
against the input actually shown to the model — fabricated quotes are dropped
|
|
29
|
+
before they reach disk.
|
|
30
|
+
|
|
24
31
|
The host exposes no `learning` / `contentMode` / `toolVerified` admission
|
|
25
32
|
metadata, so unverified `tool/result` output is deliberately never archived.
|
|
26
33
|
User and assistant messages are the only long-term sources in v0.
|
package/lib/core/llm-reviewer.js
CHANGED
|
@@ -11,6 +11,10 @@ const NOTE_TYPES = ['user', 'feedback', 'project', 'reference'];
|
|
|
11
11
|
function operationMarker(body) {
|
|
12
12
|
return /<!-- op: ([a-f0-9]+) -->/.exec(body)?.[1];
|
|
13
13
|
}
|
|
14
|
+
/** Whitespace/case-tolerant containment so verbatim quotes survive line wrapping. */
|
|
15
|
+
function normalizeQuote(text) {
|
|
16
|
+
return text.replace(/\s+/g, ' ').trim().toLowerCase();
|
|
17
|
+
}
|
|
14
18
|
function parseNotes(text) {
|
|
15
19
|
const start = text.indexOf('{');
|
|
16
20
|
const end = text.lastIndexOf('}');
|
|
@@ -67,17 +71,20 @@ export class LlmReviewer {
|
|
|
67
71
|
return empty;
|
|
68
72
|
const budget = this.options.contextTokens ?? 800;
|
|
69
73
|
const lines = [];
|
|
70
|
-
|
|
74
|
+
const usedCandidates = [];
|
|
75
|
+
let spent = 0;
|
|
71
76
|
for (const item of batch) {
|
|
72
77
|
const line = `[${item.role}] ${item.content.slice(0, 800)}`;
|
|
73
78
|
const cost = estimateTokens(line);
|
|
74
|
-
if (
|
|
79
|
+
if (spent + cost > budget)
|
|
75
80
|
break;
|
|
76
81
|
lines.push(line);
|
|
77
|
-
|
|
82
|
+
usedCandidates.push(item);
|
|
83
|
+
spent += cost;
|
|
78
84
|
}
|
|
79
85
|
if (lines.length === 0)
|
|
80
86
|
return empty;
|
|
87
|
+
const haystack = normalizeQuote(lines.join('\n'));
|
|
81
88
|
let answer;
|
|
82
89
|
try {
|
|
83
90
|
answer = (await this.adapter.complete({
|
|
@@ -101,6 +108,20 @@ export class LlmReviewer {
|
|
|
101
108
|
const written = [];
|
|
102
109
|
const today = new Date().toISOString().slice(0, 10);
|
|
103
110
|
for (const note of parsed) {
|
|
111
|
+
// Verbatim gate: an evidence quote the model was never shown (or garbled)
|
|
112
|
+
// must never reach disk.
|
|
113
|
+
const evidenceNorm = normalizeQuote(note.evidence);
|
|
114
|
+
if (!haystack.includes(evidenceNorm))
|
|
115
|
+
continue;
|
|
116
|
+
const sourceRefs = usedCandidates
|
|
117
|
+
.filter((item) => normalizeQuote(`[${item.role}] ${item.content.slice(0, 800)}`)
|
|
118
|
+
.includes(evidenceNorm))
|
|
119
|
+
.map((item) => item.id)
|
|
120
|
+
.slice(0, 4);
|
|
121
|
+
// A quote spanning two adjacent lines still passes the haystack check;
|
|
122
|
+
// attribute it to the batch window instead of inventing a source.
|
|
123
|
+
if (sourceRefs.length === 0)
|
|
124
|
+
sourceRefs.push(usedCandidates[0].id);
|
|
104
125
|
const payloadHash = createHash('sha256').update(JSON.stringify(note)).digest('hex');
|
|
105
126
|
const opId = operationId(companionId, batch[0].id, batch[0].seq, payloadHash);
|
|
106
127
|
if (seen.has(opId))
|
|
@@ -113,7 +134,7 @@ export class LlmReviewer {
|
|
|
113
134
|
created: today,
|
|
114
135
|
updated: today,
|
|
115
136
|
evidence: note.evidence,
|
|
116
|
-
sourceRefs
|
|
137
|
+
sourceRefs,
|
|
117
138
|
supersededBy: null,
|
|
118
139
|
confidence: 0.7,
|
|
119
140
|
strength: 0.6,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-companion-memory-core",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"description": "Local, host-independent long-term memory core for DeepSeek Harness: plain-text notes, a bounded index, and auditable evidence.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|