@mnemoai/core 1.1.0 → 1.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/dist/cli.d.ts +2 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +7 -0
- package/dist/cli.js.map +7 -0
- package/dist/index.d.ts +128 -0
- package/dist/index.d.ts.map +1 -0
- package/{index.ts → dist/index.js} +526 -1333
- package/dist/index.js.map +7 -0
- package/dist/src/access-tracker.d.ts +97 -0
- package/dist/src/access-tracker.d.ts.map +1 -0
- package/dist/src/access-tracker.js +184 -0
- package/dist/src/access-tracker.js.map +7 -0
- package/dist/src/adapters/chroma.d.ts +31 -0
- package/dist/src/adapters/chroma.d.ts.map +1 -0
- package/{src/adapters/chroma.ts → dist/src/adapters/chroma.js} +45 -107
- package/dist/src/adapters/chroma.js.map +7 -0
- package/dist/src/adapters/lancedb.d.ts +29 -0
- package/dist/src/adapters/lancedb.d.ts.map +1 -0
- package/{src/adapters/lancedb.ts → dist/src/adapters/lancedb.js} +41 -109
- package/dist/src/adapters/lancedb.js.map +7 -0
- package/dist/src/adapters/pgvector.d.ts +33 -0
- package/dist/src/adapters/pgvector.d.ts.map +1 -0
- package/{src/adapters/pgvector.ts → dist/src/adapters/pgvector.js} +42 -104
- package/dist/src/adapters/pgvector.js.map +7 -0
- package/dist/src/adapters/qdrant.d.ts +34 -0
- package/dist/src/adapters/qdrant.d.ts.map +1 -0
- package/dist/src/adapters/qdrant.js +132 -0
- package/dist/src/adapters/qdrant.js.map +7 -0
- package/dist/src/adaptive-retrieval.d.ts +14 -0
- package/dist/src/adaptive-retrieval.d.ts.map +1 -0
- package/dist/src/adaptive-retrieval.js +52 -0
- package/dist/src/adaptive-retrieval.js.map +7 -0
- package/dist/src/audit-log.d.ts +56 -0
- package/dist/src/audit-log.d.ts.map +1 -0
- package/dist/src/audit-log.js +139 -0
- package/dist/src/audit-log.js.map +7 -0
- package/dist/src/chunker.d.ts +45 -0
- package/dist/src/chunker.d.ts.map +1 -0
- package/dist/src/chunker.js +157 -0
- package/dist/src/chunker.js.map +7 -0
- package/dist/src/config.d.ts +70 -0
- package/dist/src/config.d.ts.map +1 -0
- package/dist/src/config.js +142 -0
- package/dist/src/config.js.map +7 -0
- package/dist/src/decay-engine.d.ts +73 -0
- package/dist/src/decay-engine.d.ts.map +1 -0
- package/dist/src/decay-engine.js +119 -0
- package/dist/src/decay-engine.js.map +7 -0
- package/dist/src/embedder.d.ts +94 -0
- package/dist/src/embedder.d.ts.map +1 -0
- package/{src/embedder.ts → dist/src/embedder.js} +119 -317
- package/dist/src/embedder.js.map +7 -0
- package/dist/src/extraction-prompts.d.ts +12 -0
- package/dist/src/extraction-prompts.d.ts.map +1 -0
- package/dist/src/extraction-prompts.js +311 -0
- package/dist/src/extraction-prompts.js.map +7 -0
- package/dist/src/license.d.ts +29 -0
- package/dist/src/license.d.ts.map +1 -0
- package/{src/license.ts → dist/src/license.js} +42 -113
- package/dist/src/license.js.map +7 -0
- package/dist/src/llm-client.d.ts +23 -0
- package/dist/src/llm-client.d.ts.map +1 -0
- package/{src/llm-client.ts → dist/src/llm-client.js} +22 -55
- package/dist/src/llm-client.js.map +7 -0
- package/dist/src/logger.d.ts +33 -0
- package/dist/src/logger.d.ts.map +1 -0
- package/dist/src/logger.js +35 -0
- package/dist/src/logger.js.map +7 -0
- package/dist/src/mcp-server.d.ts +16 -0
- package/dist/src/mcp-server.d.ts.map +1 -0
- package/{src/mcp-server.ts → dist/src/mcp-server.js} +81 -181
- package/dist/src/mcp-server.js.map +7 -0
- package/dist/src/memory-categories.d.ts +40 -0
- package/dist/src/memory-categories.d.ts.map +1 -0
- package/dist/src/memory-categories.js +33 -0
- package/dist/src/memory-categories.js.map +7 -0
- package/dist/src/memory-upgrader.d.ts +71 -0
- package/dist/src/memory-upgrader.d.ts.map +1 -0
- package/dist/src/memory-upgrader.js +238 -0
- package/dist/src/memory-upgrader.js.map +7 -0
- package/dist/src/migrate.d.ts +47 -0
- package/dist/src/migrate.d.ts.map +1 -0
- package/{src/migrate.ts → dist/src/migrate.js} +57 -165
- package/dist/src/migrate.js.map +7 -0
- package/dist/src/mnemo.d.ts +67 -0
- package/dist/src/mnemo.d.ts.map +1 -0
- package/dist/src/mnemo.js +66 -0
- package/dist/src/mnemo.js.map +7 -0
- package/dist/src/noise-filter.d.ts +23 -0
- package/dist/src/noise-filter.d.ts.map +1 -0
- package/dist/src/noise-filter.js +62 -0
- package/dist/src/noise-filter.js.map +7 -0
- package/dist/src/noise-prototypes.d.ts +40 -0
- package/dist/src/noise-prototypes.d.ts.map +1 -0
- package/dist/src/noise-prototypes.js +116 -0
- package/dist/src/noise-prototypes.js.map +7 -0
- package/dist/src/observability.d.ts +16 -0
- package/dist/src/observability.d.ts.map +1 -0
- package/dist/src/observability.js +53 -0
- package/dist/src/observability.js.map +7 -0
- package/dist/src/query-tracker.d.ts +27 -0
- package/dist/src/query-tracker.d.ts.map +1 -0
- package/dist/src/query-tracker.js +32 -0
- package/dist/src/query-tracker.js.map +7 -0
- package/dist/src/reflection-event-store.d.ts +44 -0
- package/dist/src/reflection-event-store.d.ts.map +1 -0
- package/dist/src/reflection-event-store.js +50 -0
- package/dist/src/reflection-event-store.js.map +7 -0
- package/dist/src/reflection-item-store.d.ts +58 -0
- package/dist/src/reflection-item-store.d.ts.map +1 -0
- package/dist/src/reflection-item-store.js +69 -0
- package/dist/src/reflection-item-store.js.map +7 -0
- package/dist/src/reflection-mapped-metadata.d.ts +47 -0
- package/dist/src/reflection-mapped-metadata.d.ts.map +1 -0
- package/dist/src/reflection-mapped-metadata.js +40 -0
- package/dist/src/reflection-mapped-metadata.js.map +7 -0
- package/dist/src/reflection-metadata.d.ts +11 -0
- package/dist/src/reflection-metadata.d.ts.map +1 -0
- package/dist/src/reflection-metadata.js +24 -0
- package/dist/src/reflection-metadata.js.map +7 -0
- package/dist/src/reflection-ranking.d.ts +13 -0
- package/dist/src/reflection-ranking.d.ts.map +1 -0
- package/{src/reflection-ranking.ts → dist/src/reflection-ranking.js} +12 -21
- package/dist/src/reflection-ranking.js.map +7 -0
- package/dist/src/reflection-retry.d.ts +30 -0
- package/dist/src/reflection-retry.d.ts.map +1 -0
- package/{src/reflection-retry.ts → dist/src/reflection-retry.js} +24 -64
- package/dist/src/reflection-retry.js.map +7 -0
- package/dist/src/reflection-slices.d.ts +42 -0
- package/dist/src/reflection-slices.d.ts.map +1 -0
- package/{src/reflection-slices.ts → dist/src/reflection-slices.js} +60 -136
- package/dist/src/reflection-slices.js.map +7 -0
- package/dist/src/reflection-store.d.ts +85 -0
- package/dist/src/reflection-store.d.ts.map +1 -0
- package/dist/src/reflection-store.js +407 -0
- package/dist/src/reflection-store.js.map +7 -0
- package/dist/src/resonance-state.d.ts +19 -0
- package/dist/src/resonance-state.d.ts.map +1 -0
- package/{src/resonance-state.ts → dist/src/resonance-state.js} +13 -42
- package/dist/src/resonance-state.js.map +7 -0
- package/dist/src/retriever.d.ts +228 -0
- package/dist/src/retriever.d.ts.map +1 -0
- package/dist/src/retriever.js +1006 -0
- package/dist/src/retriever.js.map +7 -0
- package/dist/src/scopes.d.ts +58 -0
- package/dist/src/scopes.d.ts.map +1 -0
- package/dist/src/scopes.js +252 -0
- package/dist/src/scopes.js.map +7 -0
- package/dist/src/self-improvement-files.d.ts +20 -0
- package/dist/src/self-improvement-files.d.ts.map +1 -0
- package/{src/self-improvement-files.ts → dist/src/self-improvement-files.js} +24 -49
- package/dist/src/self-improvement-files.js.map +7 -0
- package/dist/src/semantic-gate.d.ts +24 -0
- package/dist/src/semantic-gate.d.ts.map +1 -0
- package/dist/src/semantic-gate.js +86 -0
- package/dist/src/semantic-gate.js.map +7 -0
- package/dist/src/session-recovery.d.ts +9 -0
- package/dist/src/session-recovery.d.ts.map +1 -0
- package/{src/session-recovery.ts → dist/src/session-recovery.js} +40 -57
- package/dist/src/session-recovery.js.map +7 -0
- package/dist/src/smart-extractor.d.ts +107 -0
- package/dist/src/smart-extractor.d.ts.map +1 -0
- package/{src/smart-extractor.ts → dist/src/smart-extractor.js} +130 -383
- package/dist/src/smart-extractor.js.map +7 -0
- package/dist/src/smart-metadata.d.ts +103 -0
- package/dist/src/smart-metadata.d.ts.map +1 -0
- package/dist/src/smart-metadata.js +361 -0
- package/dist/src/smart-metadata.js.map +7 -0
- package/dist/src/storage-adapter.d.ts +102 -0
- package/dist/src/storage-adapter.d.ts.map +1 -0
- package/dist/src/storage-adapter.js +22 -0
- package/dist/src/storage-adapter.js.map +7 -0
- package/dist/src/store.d.ts +108 -0
- package/dist/src/store.d.ts.map +1 -0
- package/dist/src/store.js +939 -0
- package/dist/src/store.js.map +7 -0
- package/dist/src/tier-manager.d.ts +57 -0
- package/dist/src/tier-manager.d.ts.map +1 -0
- package/dist/src/tier-manager.js +80 -0
- package/dist/src/tier-manager.js.map +7 -0
- package/dist/src/tools.d.ts +43 -0
- package/dist/src/tools.d.ts.map +1 -0
- package/dist/src/tools.js +1075 -0
- package/dist/src/tools.js.map +7 -0
- package/dist/src/wal-recovery.d.ts +30 -0
- package/dist/src/wal-recovery.d.ts.map +1 -0
- package/{src/wal-recovery.ts → dist/src/wal-recovery.js} +26 -79
- package/dist/src/wal-recovery.js.map +7 -0
- package/package.json +21 -2
- package/openclaw.plugin.json +0 -815
- package/src/access-tracker.ts +0 -341
- package/src/adapters/README.md +0 -78
- package/src/adapters/qdrant.ts +0 -191
- package/src/adaptive-retrieval.ts +0 -90
- package/src/audit-log.ts +0 -238
- package/src/chunker.ts +0 -254
- package/src/config.ts +0 -271
- package/src/decay-engine.ts +0 -238
- package/src/extraction-prompts.ts +0 -339
- package/src/memory-categories.ts +0 -71
- package/src/memory-upgrader.ts +0 -388
- package/src/mnemo.ts +0 -142
- package/src/noise-filter.ts +0 -97
- package/src/noise-prototypes.ts +0 -164
- package/src/observability.ts +0 -81
- package/src/query-tracker.ts +0 -57
- package/src/reflection-event-store.ts +0 -98
- package/src/reflection-item-store.ts +0 -112
- package/src/reflection-mapped-metadata.ts +0 -84
- package/src/reflection-metadata.ts +0 -23
- package/src/reflection-store.ts +0 -602
- package/src/retriever.ts +0 -1510
- package/src/scopes.ts +0 -375
- package/src/semantic-gate.ts +0 -121
- package/src/smart-metadata.ts +0 -561
- package/src/storage-adapter.ts +0 -153
- package/src/store.ts +0 -1330
- package/src/tier-manager.ts +0 -189
- package/src/tools.ts +0 -1292
- package/test/core.test.mjs +0 -301
package/src/noise-prototypes.ts
DELETED
|
@@ -1,164 +0,0 @@
|
|
|
1
|
-
// SPDX-License-Identifier: MIT
|
|
2
|
-
/**
|
|
3
|
-
* Embedding-based Noise Prototype Bank
|
|
4
|
-
*
|
|
5
|
-
* Language-agnostic noise detection: maintains a bank of noise prototype
|
|
6
|
-
* embeddings (recall queries, agent denials, greetings). Input texts are
|
|
7
|
-
* compared via cosine similarity — no regex maintenance required.
|
|
8
|
-
*
|
|
9
|
-
* The bank starts with ~15 built-in multilingual prototypes and grows
|
|
10
|
-
* automatically when the LLM extraction returns zero memories (feedback loop).
|
|
11
|
-
*/
|
|
12
|
-
|
|
13
|
-
import type { Embedder } from "./embedder.js";
|
|
14
|
-
|
|
15
|
-
// ============================================================================
|
|
16
|
-
// Built-in noise prototypes (multilingual)
|
|
17
|
-
// ============================================================================
|
|
18
|
-
|
|
19
|
-
const BUILTIN_NOISE_TEXTS: readonly string[] = [
|
|
20
|
-
// Recall queries
|
|
21
|
-
"Do you remember what I told you?",
|
|
22
|
-
"Can you recall my preferences?",
|
|
23
|
-
"What did I say about that?",
|
|
24
|
-
"你还记得我喜欢什么吗",
|
|
25
|
-
"你知道我之前说过什么吗",
|
|
26
|
-
"記得我上次提到的嗎",
|
|
27
|
-
"我之前跟你说过吗",
|
|
28
|
-
// Agent denials
|
|
29
|
-
"I don't have any information about that",
|
|
30
|
-
"I don't recall any previous conversation",
|
|
31
|
-
"我没有相关的记忆",
|
|
32
|
-
// Greetings / boilerplate
|
|
33
|
-
"Hello, how are you doing today?",
|
|
34
|
-
"Hi there, what's up",
|
|
35
|
-
"新的一天开始了",
|
|
36
|
-
];
|
|
37
|
-
|
|
38
|
-
// ============================================================================
|
|
39
|
-
// Constants
|
|
40
|
-
// ============================================================================
|
|
41
|
-
|
|
42
|
-
const DEFAULT_THRESHOLD = 0.82;
|
|
43
|
-
const MAX_LEARNED_PROTOTYPES = 200;
|
|
44
|
-
const DEDUP_THRESHOLD = 0.95;
|
|
45
|
-
|
|
46
|
-
// ============================================================================
|
|
47
|
-
// NoisePrototypeBank
|
|
48
|
-
// ============================================================================
|
|
49
|
-
|
|
50
|
-
export class NoisePrototypeBank {
|
|
51
|
-
private vectors: number[][] = [];
|
|
52
|
-
private builtinCount = 0;
|
|
53
|
-
private _initialized = false;
|
|
54
|
-
private debugLog: (msg: string) => void;
|
|
55
|
-
|
|
56
|
-
constructor(debugLog?: (msg: string) => void) {
|
|
57
|
-
this.debugLog = debugLog ?? (() => { });
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
/** Whether the bank has been initialized with prototype embeddings. */
|
|
61
|
-
get initialized(): boolean {
|
|
62
|
-
return this._initialized;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
/** Total number of prototypes (built-in + learned). */
|
|
66
|
-
get size(): number {
|
|
67
|
-
return this.vectors.length;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
/**
|
|
71
|
-
* Embed all built-in noise prototypes and cache their vectors.
|
|
72
|
-
* Call once at plugin startup. Safe to call multiple times (no-op after first).
|
|
73
|
-
*/
|
|
74
|
-
async init(embedder: Embedder): Promise<void> {
|
|
75
|
-
if (this._initialized) return;
|
|
76
|
-
|
|
77
|
-
for (const text of BUILTIN_NOISE_TEXTS) {
|
|
78
|
-
try {
|
|
79
|
-
const v = await embedder.embed(text);
|
|
80
|
-
if (v && v.length > 0) this.vectors.push(v);
|
|
81
|
-
} catch {
|
|
82
|
-
// Skip failed embeddings — bank will work with whatever succeeds
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
this.builtinCount = this.vectors.length;
|
|
86
|
-
this._initialized = true;
|
|
87
|
-
|
|
88
|
-
// Degeneracy check: if all prototype vectors are nearly identical, the
|
|
89
|
-
// embedding model does not produce discriminative outputs (e.g. a
|
|
90
|
-
// deterministic mock that ignores text). In that case the noise bank
|
|
91
|
-
// would flag every input as noise, so we disable ourselves.
|
|
92
|
-
if (this.vectors.length >= 2) {
|
|
93
|
-
const sim = cosine(this.vectors[0], this.vectors[1]);
|
|
94
|
-
if (sim > 0.98) {
|
|
95
|
-
this.debugLog(
|
|
96
|
-
`noise-prototype-bank: degenerate embeddings detected (pairwise cosine=${sim.toFixed(4)}), disabling noise filter`,
|
|
97
|
-
);
|
|
98
|
-
this._initialized = false;
|
|
99
|
-
this.vectors = [];
|
|
100
|
-
return;
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
this.debugLog(
|
|
105
|
-
`noise-prototype-bank: initialized with ${this.builtinCount} built-in prototypes`,
|
|
106
|
-
);
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
/**
|
|
110
|
-
* Check if a text vector matches any noise prototype.
|
|
111
|
-
* Returns true if cosine similarity >= threshold with any prototype.
|
|
112
|
-
*/
|
|
113
|
-
isNoise(textVector: number[], threshold = DEFAULT_THRESHOLD): boolean {
|
|
114
|
-
if (!this._initialized || this.vectors.length === 0) return false;
|
|
115
|
-
for (const proto of this.vectors) {
|
|
116
|
-
if (cosine(proto, textVector) >= threshold) return true;
|
|
117
|
-
}
|
|
118
|
-
return false;
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
/**
|
|
122
|
-
* LLM feedback: add a text vector to the learned noise bank.
|
|
123
|
-
* Called when LLM extraction returns zero memories (strong noise signal).
|
|
124
|
-
* Deduplicates against existing prototypes (>= 0.95 similarity = skip).
|
|
125
|
-
* Evicts oldest learned prototype when bank exceeds MAX_LEARNED_PROTOTYPES.
|
|
126
|
-
*/
|
|
127
|
-
learn(textVector: number[]): void {
|
|
128
|
-
if (!this._initialized) return;
|
|
129
|
-
|
|
130
|
-
// Deduplicate: too similar to an existing prototype → skip
|
|
131
|
-
for (const proto of this.vectors) {
|
|
132
|
-
if (cosine(proto, textVector) >= DEDUP_THRESHOLD) return;
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
this.vectors.push(textVector);
|
|
136
|
-
|
|
137
|
-
// Evict oldest learned prototype if over limit (preserve built-in prototypes)
|
|
138
|
-
if (this.vectors.length > this.builtinCount + MAX_LEARNED_PROTOTYPES) {
|
|
139
|
-
this.vectors.splice(this.builtinCount, 1);
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
this.debugLog(
|
|
143
|
-
`noise-prototype-bank: learned new noise prototype (total: ${this.vectors.length})`,
|
|
144
|
-
);
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
// ============================================================================
|
|
149
|
-
// Cosine Similarity
|
|
150
|
-
// ============================================================================
|
|
151
|
-
|
|
152
|
-
function cosine(a: number[], b: number[]): number {
|
|
153
|
-
if (a.length !== b.length) return 0;
|
|
154
|
-
let dot = 0;
|
|
155
|
-
let na = 0;
|
|
156
|
-
let nb = 0;
|
|
157
|
-
for (let i = 0; i < a.length; i++) {
|
|
158
|
-
dot += a[i] * b[i];
|
|
159
|
-
na += a[i] * a[i];
|
|
160
|
-
nb += b[i] * b[i];
|
|
161
|
-
}
|
|
162
|
-
const denom = Math.sqrt(na) * Math.sqrt(nb);
|
|
163
|
-
return denom === 0 ? 0 : dot / denom;
|
|
164
|
-
}
|
package/src/observability.ts
DELETED
|
@@ -1,81 +0,0 @@
|
|
|
1
|
-
// SPDX-License-Identifier: LicenseRef-Mnemo-Pro
|
|
2
|
-
/**
|
|
3
|
-
* Observability — aggregated stats from query-tracking.jsonl
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import { getRecentQueries, type QueryRecord } from "./query-tracker.js";
|
|
7
|
-
|
|
8
|
-
export interface QueryStats {
|
|
9
|
-
totalQueries: number;
|
|
10
|
-
avgLatencyMs: number;
|
|
11
|
-
resonancePassRate: number;
|
|
12
|
-
avgHitCount: number;
|
|
13
|
-
queryTypeDistribution: Record<string, number>;
|
|
14
|
-
hourlyTrend: { hour: string; count: number }[];
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
export async function getStats(maxRecords = 1000): Promise<QueryStats> {
|
|
18
|
-
const records = await getRecentQueries(maxRecords);
|
|
19
|
-
|
|
20
|
-
if (records.length === 0) {
|
|
21
|
-
return {
|
|
22
|
-
totalQueries: 0,
|
|
23
|
-
avgLatencyMs: 0,
|
|
24
|
-
resonancePassRate: 0,
|
|
25
|
-
avgHitCount: 0,
|
|
26
|
-
queryTypeDistribution: {},
|
|
27
|
-
hourlyTrend: [],
|
|
28
|
-
};
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
const totalQueries = records.length;
|
|
32
|
-
const avgLatencyMs = Math.round(
|
|
33
|
-
records.reduce((sum, r) => sum + r.latency_ms, 0) / totalQueries
|
|
34
|
-
);
|
|
35
|
-
const resonancePassRate = +(
|
|
36
|
-
records.filter((r) => r.resonancePass).length / totalQueries
|
|
37
|
-
).toFixed(3);
|
|
38
|
-
const avgHitCount = +(
|
|
39
|
-
records.reduce((sum, r) => sum + r.hitCount, 0) / totalQueries
|
|
40
|
-
).toFixed(2);
|
|
41
|
-
|
|
42
|
-
// Query type distribution
|
|
43
|
-
const queryTypeDistribution: Record<string, number> = {};
|
|
44
|
-
for (const r of records) {
|
|
45
|
-
queryTypeDistribution[r.queryType] =
|
|
46
|
-
(queryTypeDistribution[r.queryType] || 0) + 1;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
// Hourly trend — last 24h bucketed by hour
|
|
50
|
-
const now = Date.now();
|
|
51
|
-
const cutoff = now - 24 * 60 * 60 * 1000;
|
|
52
|
-
const hourBuckets = new Map<string, number>();
|
|
53
|
-
|
|
54
|
-
for (let i = 0; i < 24; i++) {
|
|
55
|
-
const d = new Date(now - i * 60 * 60 * 1000);
|
|
56
|
-
const key = d.toISOString().slice(0, 13); // "YYYY-MM-DDTHH"
|
|
57
|
-
hourBuckets.set(key, 0);
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
for (const r of records) {
|
|
61
|
-
const ts = new Date(r.timestamp).getTime();
|
|
62
|
-
if (ts < cutoff) continue;
|
|
63
|
-
const key = r.timestamp.slice(0, 13);
|
|
64
|
-
if (hourBuckets.has(key)) {
|
|
65
|
-
hourBuckets.set(key, hourBuckets.get(key)! + 1);
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
const hourlyTrend = Array.from(hourBuckets.entries())
|
|
70
|
-
.map(([hour, count]) => ({ hour, count }))
|
|
71
|
-
.sort((a, b) => a.hour.localeCompare(b.hour));
|
|
72
|
-
|
|
73
|
-
return {
|
|
74
|
-
totalQueries,
|
|
75
|
-
avgLatencyMs,
|
|
76
|
-
resonancePassRate,
|
|
77
|
-
avgHitCount,
|
|
78
|
-
queryTypeDistribution,
|
|
79
|
-
hourlyTrend,
|
|
80
|
-
};
|
|
81
|
-
}
|
package/src/query-tracker.ts
DELETED
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
// SPDX-License-Identifier: LicenseRef-Mnemo-Pro
|
|
2
|
-
/**
|
|
3
|
-
* Query Tracker
|
|
4
|
-
*
|
|
5
|
-
* Lightweight, append-only JSONL tracker for every recall query.
|
|
6
|
-
* Fire-and-forget writes — never blocks the recall path.
|
|
7
|
-
* Persisted to ~/.openclaw/memory/query-tracking.jsonl.
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
import { appendFile, readFile, mkdir } from "node:fs/promises";
|
|
11
|
-
import { homedir } from "node:os";
|
|
12
|
-
import { join, dirname } from "node:path";
|
|
13
|
-
|
|
14
|
-
const TRACKING_PATH = join(homedir(), ".openclaw", "memory", "query-tracking.jsonl");
|
|
15
|
-
|
|
16
|
-
export interface QueryRecord {
|
|
17
|
-
timestamp: string;
|
|
18
|
-
query: string;
|
|
19
|
-
source: "auto" | "manual" | "cli";
|
|
20
|
-
hitCount: number;
|
|
21
|
-
topScore: number;
|
|
22
|
-
latency_ms: number;
|
|
23
|
-
queryType: "single" | "multi-hop" | "gated-out";
|
|
24
|
-
resonancePass: boolean;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
let dirEnsured = false;
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
* Record a query to the tracking log (fire-and-forget).
|
|
31
|
-
* Errors are silently swallowed to avoid impacting recall latency.
|
|
32
|
-
*/
|
|
33
|
-
export function recordQuery(data: QueryRecord): void {
|
|
34
|
-
const line = JSON.stringify(data) + "\n";
|
|
35
|
-
const doWrite = async () => {
|
|
36
|
-
if (!dirEnsured) {
|
|
37
|
-
await mkdir(dirname(TRACKING_PATH), { recursive: true });
|
|
38
|
-
dirEnsured = true;
|
|
39
|
-
}
|
|
40
|
-
await appendFile(TRACKING_PATH, line, "utf8");
|
|
41
|
-
};
|
|
42
|
-
doWrite().catch(() => {});
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
/**
|
|
46
|
-
* Read the most recent N query records from the tracking log.
|
|
47
|
-
*/
|
|
48
|
-
export async function getRecentQueries(n: number = 100): Promise<QueryRecord[]> {
|
|
49
|
-
try {
|
|
50
|
-
const raw = await readFile(TRACKING_PATH, "utf8");
|
|
51
|
-
const lines = raw.trim().split("\n").filter(Boolean);
|
|
52
|
-
const recent = lines.slice(-n);
|
|
53
|
-
return recent.map((line) => JSON.parse(line) as QueryRecord);
|
|
54
|
-
} catch {
|
|
55
|
-
return [];
|
|
56
|
-
}
|
|
57
|
-
}
|
|
@@ -1,98 +0,0 @@
|
|
|
1
|
-
// SPDX-License-Identifier: LicenseRef-Mnemo-Pro
|
|
2
|
-
import { createHash } from "node:crypto";
|
|
3
|
-
|
|
4
|
-
export const REFLECTION_SCHEMA_VERSION = 4;
|
|
5
|
-
|
|
6
|
-
export type ReflectionErrorSignalLike = {
|
|
7
|
-
signatureHash: string;
|
|
8
|
-
};
|
|
9
|
-
|
|
10
|
-
export interface ReflectionEventMetadata {
|
|
11
|
-
type: "memory-reflection-event";
|
|
12
|
-
reflectionVersion: 4;
|
|
13
|
-
stage: "reflect-store";
|
|
14
|
-
eventId: string;
|
|
15
|
-
sessionKey: string;
|
|
16
|
-
sessionId: string;
|
|
17
|
-
agentId: string;
|
|
18
|
-
command: string;
|
|
19
|
-
storedAt: number;
|
|
20
|
-
usedFallback: boolean;
|
|
21
|
-
errorSignals: string[];
|
|
22
|
-
sourceReflectionPath?: string;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
export interface ReflectionEventPayload {
|
|
26
|
-
kind: "event";
|
|
27
|
-
text: string;
|
|
28
|
-
metadata: ReflectionEventMetadata;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
export interface BuildReflectionEventPayloadParams {
|
|
32
|
-
eventId?: string;
|
|
33
|
-
scope: string;
|
|
34
|
-
sessionKey: string;
|
|
35
|
-
sessionId: string;
|
|
36
|
-
agentId: string;
|
|
37
|
-
command: string;
|
|
38
|
-
toolErrorSignals: ReflectionErrorSignalLike[];
|
|
39
|
-
runAt: number;
|
|
40
|
-
usedFallback: boolean;
|
|
41
|
-
sourceReflectionPath?: string;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
export function createReflectionEventId(params: {
|
|
45
|
-
runAt: number;
|
|
46
|
-
sessionKey: string;
|
|
47
|
-
sessionId: string;
|
|
48
|
-
agentId: string;
|
|
49
|
-
command: string;
|
|
50
|
-
}): string {
|
|
51
|
-
const safeRunAt = Number.isFinite(params.runAt) ? Math.max(0, Math.floor(params.runAt)) : Date.now();
|
|
52
|
-
const datePart = new Date(safeRunAt).toISOString().replace(/[-:.TZ]/g, "").slice(0, 14);
|
|
53
|
-
const digest = createHash("sha1")
|
|
54
|
-
.update(`${safeRunAt}|${params.sessionKey}|${params.sessionId}|${params.agentId}|${params.command}`)
|
|
55
|
-
.digest("hex")
|
|
56
|
-
.slice(0, 8);
|
|
57
|
-
return `refl-${datePart}-${digest}`;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
export function buildReflectionEventPayload(params: BuildReflectionEventPayloadParams): ReflectionEventPayload {
|
|
61
|
-
const eventId = params.eventId || createReflectionEventId({
|
|
62
|
-
runAt: params.runAt,
|
|
63
|
-
sessionKey: params.sessionKey,
|
|
64
|
-
sessionId: params.sessionId,
|
|
65
|
-
agentId: params.agentId,
|
|
66
|
-
command: params.command,
|
|
67
|
-
});
|
|
68
|
-
|
|
69
|
-
const metadata: ReflectionEventMetadata = {
|
|
70
|
-
type: "memory-reflection-event",
|
|
71
|
-
reflectionVersion: REFLECTION_SCHEMA_VERSION,
|
|
72
|
-
stage: "reflect-store",
|
|
73
|
-
eventId,
|
|
74
|
-
sessionKey: params.sessionKey,
|
|
75
|
-
sessionId: params.sessionId,
|
|
76
|
-
agentId: params.agentId,
|
|
77
|
-
command: params.command,
|
|
78
|
-
storedAt: params.runAt,
|
|
79
|
-
usedFallback: params.usedFallback,
|
|
80
|
-
errorSignals: params.toolErrorSignals.map((signal) => signal.signatureHash),
|
|
81
|
-
...(params.sourceReflectionPath ? { sourceReflectionPath: params.sourceReflectionPath } : {}),
|
|
82
|
-
};
|
|
83
|
-
|
|
84
|
-
const text = [
|
|
85
|
-
`reflection-event · ${params.scope}`,
|
|
86
|
-
`eventId=${eventId}`,
|
|
87
|
-
`session=${params.sessionId}`,
|
|
88
|
-
`agent=${params.agentId}`,
|
|
89
|
-
`command=${params.command}`,
|
|
90
|
-
`usedFallback=${params.usedFallback ? "true" : "false"}`,
|
|
91
|
-
].join("\n");
|
|
92
|
-
|
|
93
|
-
return {
|
|
94
|
-
kind: "event",
|
|
95
|
-
text,
|
|
96
|
-
metadata,
|
|
97
|
-
};
|
|
98
|
-
}
|
|
@@ -1,112 +0,0 @@
|
|
|
1
|
-
// SPDX-License-Identifier: LicenseRef-Mnemo-Pro
|
|
2
|
-
import type { ReflectionSliceItem } from "./reflection-slices.js";
|
|
3
|
-
|
|
4
|
-
export type ReflectionItemKind = "invariant" | "derived";
|
|
5
|
-
|
|
6
|
-
export interface ReflectionItemMetadata {
|
|
7
|
-
type: "memory-reflection-item";
|
|
8
|
-
reflectionVersion: 4;
|
|
9
|
-
stage: "reflect-store";
|
|
10
|
-
eventId: string;
|
|
11
|
-
itemKind: ReflectionItemKind;
|
|
12
|
-
section: "Invariants" | "Derived";
|
|
13
|
-
ordinal: number;
|
|
14
|
-
groupSize: number;
|
|
15
|
-
agentId: string;
|
|
16
|
-
sessionKey: string;
|
|
17
|
-
sessionId: string;
|
|
18
|
-
storedAt: number;
|
|
19
|
-
usedFallback: boolean;
|
|
20
|
-
errorSignals: string[];
|
|
21
|
-
decayModel: "logistic";
|
|
22
|
-
decayMidpointDays: number;
|
|
23
|
-
decayK: number;
|
|
24
|
-
baseWeight: number;
|
|
25
|
-
quality: number;
|
|
26
|
-
sourceReflectionPath?: string;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
export interface ReflectionItemPayload {
|
|
30
|
-
kind: "item-invariant" | "item-derived";
|
|
31
|
-
text: string;
|
|
32
|
-
metadata: ReflectionItemMetadata;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
export interface BuildReflectionItemPayloadsParams {
|
|
36
|
-
items: ReflectionSliceItem[];
|
|
37
|
-
eventId: string;
|
|
38
|
-
agentId: string;
|
|
39
|
-
sessionKey: string;
|
|
40
|
-
sessionId: string;
|
|
41
|
-
runAt: number;
|
|
42
|
-
usedFallback: boolean;
|
|
43
|
-
toolErrorSignals: Array<{ signatureHash: string }>;
|
|
44
|
-
sourceReflectionPath?: string;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
export const REFLECTION_INVARIANT_DECAY_MIDPOINT_DAYS = 45;
|
|
48
|
-
export const REFLECTION_INVARIANT_DECAY_K = 0.22;
|
|
49
|
-
export const REFLECTION_INVARIANT_BASE_WEIGHT = 1.1;
|
|
50
|
-
export const REFLECTION_INVARIANT_QUALITY = 1;
|
|
51
|
-
|
|
52
|
-
export const REFLECTION_DERIVED_DECAY_MIDPOINT_DAYS = 7;
|
|
53
|
-
export const REFLECTION_DERIVED_DECAY_K = 0.65;
|
|
54
|
-
export const REFLECTION_DERIVED_BASE_WEIGHT = 1;
|
|
55
|
-
export const REFLECTION_DERIVED_QUALITY = 0.95;
|
|
56
|
-
|
|
57
|
-
export function getReflectionItemDecayDefaults(itemKind: ReflectionItemKind): {
|
|
58
|
-
midpointDays: number;
|
|
59
|
-
k: number;
|
|
60
|
-
baseWeight: number;
|
|
61
|
-
quality: number;
|
|
62
|
-
} {
|
|
63
|
-
if (itemKind === "invariant") {
|
|
64
|
-
return {
|
|
65
|
-
midpointDays: REFLECTION_INVARIANT_DECAY_MIDPOINT_DAYS,
|
|
66
|
-
k: REFLECTION_INVARIANT_DECAY_K,
|
|
67
|
-
baseWeight: REFLECTION_INVARIANT_BASE_WEIGHT,
|
|
68
|
-
quality: REFLECTION_INVARIANT_QUALITY,
|
|
69
|
-
};
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
return {
|
|
73
|
-
midpointDays: REFLECTION_DERIVED_DECAY_MIDPOINT_DAYS,
|
|
74
|
-
k: REFLECTION_DERIVED_DECAY_K,
|
|
75
|
-
baseWeight: REFLECTION_DERIVED_BASE_WEIGHT,
|
|
76
|
-
quality: REFLECTION_DERIVED_QUALITY,
|
|
77
|
-
};
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
export function buildReflectionItemPayloads(params: BuildReflectionItemPayloadsParams): ReflectionItemPayload[] {
|
|
81
|
-
return params.items.map((item) => {
|
|
82
|
-
const defaults = getReflectionItemDecayDefaults(item.itemKind);
|
|
83
|
-
const metadata: ReflectionItemMetadata = {
|
|
84
|
-
type: "memory-reflection-item",
|
|
85
|
-
reflectionVersion: 4,
|
|
86
|
-
stage: "reflect-store",
|
|
87
|
-
eventId: params.eventId,
|
|
88
|
-
itemKind: item.itemKind,
|
|
89
|
-
section: item.section,
|
|
90
|
-
ordinal: item.ordinal,
|
|
91
|
-
groupSize: item.groupSize,
|
|
92
|
-
agentId: params.agentId,
|
|
93
|
-
sessionKey: params.sessionKey,
|
|
94
|
-
sessionId: params.sessionId,
|
|
95
|
-
storedAt: params.runAt,
|
|
96
|
-
usedFallback: params.usedFallback,
|
|
97
|
-
errorSignals: params.toolErrorSignals.map((signal) => signal.signatureHash),
|
|
98
|
-
decayModel: "logistic",
|
|
99
|
-
decayMidpointDays: defaults.midpointDays,
|
|
100
|
-
decayK: defaults.k,
|
|
101
|
-
baseWeight: defaults.baseWeight,
|
|
102
|
-
quality: defaults.quality,
|
|
103
|
-
...(params.sourceReflectionPath ? { sourceReflectionPath: params.sourceReflectionPath } : {}),
|
|
104
|
-
};
|
|
105
|
-
|
|
106
|
-
return {
|
|
107
|
-
kind: item.itemKind === "invariant" ? "item-invariant" : "item-derived",
|
|
108
|
-
text: item.text,
|
|
109
|
-
metadata,
|
|
110
|
-
};
|
|
111
|
-
});
|
|
112
|
-
}
|
|
@@ -1,84 +0,0 @@
|
|
|
1
|
-
// SPDX-License-Identifier: LicenseRef-Mnemo-Pro
|
|
2
|
-
import type { ReflectionMappedMemoryItem } from "./reflection-slices.js";
|
|
3
|
-
|
|
4
|
-
export type ReflectionMappedKind = "user-model" | "agent-model" | "lesson" | "decision";
|
|
5
|
-
export type ReflectionMappedCategory = "preference" | "fact" | "decision";
|
|
6
|
-
|
|
7
|
-
export interface ReflectionMappedMetadata {
|
|
8
|
-
type: "memory-reflection-mapped";
|
|
9
|
-
reflectionVersion: 4;
|
|
10
|
-
stage: "reflect-store";
|
|
11
|
-
eventId: string;
|
|
12
|
-
mappedKind: ReflectionMappedKind;
|
|
13
|
-
mappedCategory: ReflectionMappedCategory;
|
|
14
|
-
section: string;
|
|
15
|
-
ordinal: number;
|
|
16
|
-
groupSize: number;
|
|
17
|
-
agentId: string;
|
|
18
|
-
sessionKey: string;
|
|
19
|
-
sessionId: string;
|
|
20
|
-
storedAt: number;
|
|
21
|
-
usedFallback: boolean;
|
|
22
|
-
errorSignals: string[];
|
|
23
|
-
decayModel: "logistic";
|
|
24
|
-
decayMidpointDays: number;
|
|
25
|
-
decayK: number;
|
|
26
|
-
baseWeight: number;
|
|
27
|
-
quality: number;
|
|
28
|
-
sourceReflectionPath?: string;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
export interface ReflectionMappedDecayDefaults {
|
|
32
|
-
midpointDays: number;
|
|
33
|
-
k: number;
|
|
34
|
-
baseWeight: number;
|
|
35
|
-
quality: number;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
const REFLECTION_MAPPED_DECAY_DEFAULTS: Record<ReflectionMappedKind, ReflectionMappedDecayDefaults> = {
|
|
39
|
-
decision: { midpointDays: 45, k: 0.25, baseWeight: 1.1, quality: 1 },
|
|
40
|
-
"user-model": { midpointDays: 21, k: 0.3, baseWeight: 1, quality: 0.95 },
|
|
41
|
-
"agent-model": { midpointDays: 10, k: 0.35, baseWeight: 0.95, quality: 0.93 },
|
|
42
|
-
lesson: { midpointDays: 7, k: 0.45, baseWeight: 0.9, quality: 0.9 },
|
|
43
|
-
};
|
|
44
|
-
|
|
45
|
-
export function getReflectionMappedDecayDefaults(kind: ReflectionMappedKind): ReflectionMappedDecayDefaults {
|
|
46
|
-
return REFLECTION_MAPPED_DECAY_DEFAULTS[kind];
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
export function buildReflectionMappedMetadata(params: {
|
|
50
|
-
mappedItem: ReflectionMappedMemoryItem;
|
|
51
|
-
eventId: string;
|
|
52
|
-
agentId: string;
|
|
53
|
-
sessionKey: string;
|
|
54
|
-
sessionId: string;
|
|
55
|
-
runAt: number;
|
|
56
|
-
usedFallback: boolean;
|
|
57
|
-
toolErrorSignals: Array<{ signatureHash: string }>;
|
|
58
|
-
sourceReflectionPath?: string;
|
|
59
|
-
}): ReflectionMappedMetadata {
|
|
60
|
-
const defaults = getReflectionMappedDecayDefaults(params.mappedItem.mappedKind);
|
|
61
|
-
return {
|
|
62
|
-
type: "memory-reflection-mapped",
|
|
63
|
-
reflectionVersion: 4,
|
|
64
|
-
stage: "reflect-store",
|
|
65
|
-
eventId: params.eventId,
|
|
66
|
-
mappedKind: params.mappedItem.mappedKind,
|
|
67
|
-
mappedCategory: params.mappedItem.category,
|
|
68
|
-
section: params.mappedItem.heading,
|
|
69
|
-
ordinal: params.mappedItem.ordinal,
|
|
70
|
-
groupSize: params.mappedItem.groupSize,
|
|
71
|
-
agentId: params.agentId,
|
|
72
|
-
sessionKey: params.sessionKey,
|
|
73
|
-
sessionId: params.sessionId,
|
|
74
|
-
storedAt: params.runAt,
|
|
75
|
-
usedFallback: params.usedFallback,
|
|
76
|
-
errorSignals: params.toolErrorSignals.map((signal) => signal.signatureHash),
|
|
77
|
-
decayModel: "logistic",
|
|
78
|
-
decayMidpointDays: defaults.midpointDays,
|
|
79
|
-
decayK: defaults.k,
|
|
80
|
-
baseWeight: defaults.baseWeight,
|
|
81
|
-
quality: defaults.quality,
|
|
82
|
-
...(params.sourceReflectionPath ? { sourceReflectionPath: params.sourceReflectionPath } : {}),
|
|
83
|
-
};
|
|
84
|
-
}
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
// SPDX-License-Identifier: LicenseRef-Mnemo-Pro
|
|
2
|
-
export function parseReflectionMetadata(metadataRaw: string | undefined): Record<string, unknown> {
|
|
3
|
-
if (!metadataRaw) return {};
|
|
4
|
-
try {
|
|
5
|
-
const parsed = JSON.parse(metadataRaw);
|
|
6
|
-
return parsed && typeof parsed === "object" ? parsed as Record<string, unknown> : {};
|
|
7
|
-
} catch {
|
|
8
|
-
return {};
|
|
9
|
-
}
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
export function isReflectionEntry(entry: { category: string; metadata?: string }): boolean {
|
|
13
|
-
if (entry.category === "reflection") return true;
|
|
14
|
-
const metadata = parseReflectionMetadata(entry.metadata);
|
|
15
|
-
return metadata.type === "memory-reflection" ||
|
|
16
|
-
metadata.type === "memory-reflection-event" ||
|
|
17
|
-
metadata.type === "memory-reflection-item";
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
export function getDisplayCategoryTag(entry: { category: string; scope: string; metadata?: string }): string {
|
|
21
|
-
if (!isReflectionEntry(entry)) return `${entry.category}:${entry.scope}`;
|
|
22
|
-
return `reflection:${entry.scope}`;
|
|
23
|
-
}
|