@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/scopes.ts
DELETED
|
@@ -1,375 +0,0 @@
|
|
|
1
|
-
// SPDX-License-Identifier: MIT
|
|
2
|
-
/**
|
|
3
|
-
* Multi-Scope Access Control System
|
|
4
|
-
* Manages memory isolation and access permissions
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
// ============================================================================
|
|
8
|
-
// Types & Configuration
|
|
9
|
-
// ============================================================================
|
|
10
|
-
|
|
11
|
-
export interface ScopeDefinition {
|
|
12
|
-
description: string;
|
|
13
|
-
metadata?: Record<string, unknown>;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
export interface ScopeConfig {
|
|
17
|
-
default: string;
|
|
18
|
-
definitions: Record<string, ScopeDefinition>;
|
|
19
|
-
agentAccess: Record<string, string[]>;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
export interface ScopeManager {
|
|
23
|
-
getAccessibleScopes(agentId?: string): string[];
|
|
24
|
-
getDefaultScope(agentId?: string): string;
|
|
25
|
-
isAccessible(scope: string, agentId?: string): boolean;
|
|
26
|
-
validateScope(scope: string): boolean;
|
|
27
|
-
getAllScopes(): string[];
|
|
28
|
-
getScopeDefinition(scope: string): ScopeDefinition | undefined;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
// ============================================================================
|
|
32
|
-
// Default Configuration
|
|
33
|
-
// ============================================================================
|
|
34
|
-
|
|
35
|
-
export const DEFAULT_SCOPE_CONFIG: ScopeConfig = {
|
|
36
|
-
default: "global",
|
|
37
|
-
definitions: {
|
|
38
|
-
global: {
|
|
39
|
-
description: "Shared knowledge across all agents",
|
|
40
|
-
},
|
|
41
|
-
},
|
|
42
|
-
agentAccess: {},
|
|
43
|
-
};
|
|
44
|
-
|
|
45
|
-
// ============================================================================
|
|
46
|
-
// Built-in Scope Patterns
|
|
47
|
-
// ============================================================================
|
|
48
|
-
|
|
49
|
-
const SCOPE_PATTERNS = {
|
|
50
|
-
GLOBAL: "global",
|
|
51
|
-
AGENT: (agentId: string) => `agent:${agentId}`,
|
|
52
|
-
CUSTOM: (name: string) => `custom:${name}`,
|
|
53
|
-
PROJECT: (projectId: string) => `project:${projectId}`,
|
|
54
|
-
USER: (userId: string) => `user:${userId}`,
|
|
55
|
-
};
|
|
56
|
-
|
|
57
|
-
// ============================================================================
|
|
58
|
-
// Scope Manager Implementation
|
|
59
|
-
// ============================================================================
|
|
60
|
-
|
|
61
|
-
export class MemoryScopeManager implements ScopeManager {
|
|
62
|
-
private config: ScopeConfig;
|
|
63
|
-
|
|
64
|
-
constructor(config: Partial<ScopeConfig> = {}) {
|
|
65
|
-
this.config = {
|
|
66
|
-
default: config.default || DEFAULT_SCOPE_CONFIG.default,
|
|
67
|
-
definitions: {
|
|
68
|
-
...DEFAULT_SCOPE_CONFIG.definitions,
|
|
69
|
-
...config.definitions,
|
|
70
|
-
},
|
|
71
|
-
agentAccess: {
|
|
72
|
-
...DEFAULT_SCOPE_CONFIG.agentAccess,
|
|
73
|
-
...config.agentAccess,
|
|
74
|
-
},
|
|
75
|
-
};
|
|
76
|
-
|
|
77
|
-
// Ensure global scope always exists
|
|
78
|
-
if (!this.config.definitions.global) {
|
|
79
|
-
this.config.definitions.global = {
|
|
80
|
-
description: "Shared knowledge across all agents",
|
|
81
|
-
};
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
this.validateConfiguration();
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
private validateConfiguration(): void {
|
|
88
|
-
// Validate default scope exists in definitions
|
|
89
|
-
if (!this.config.definitions[this.config.default]) {
|
|
90
|
-
throw new Error(`Default scope '${this.config.default}' not found in definitions`);
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
// Validate agent access scopes exist in definitions
|
|
94
|
-
for (const [agentId, scopes] of Object.entries(this.config.agentAccess)) {
|
|
95
|
-
for (const scope of scopes) {
|
|
96
|
-
if (!this.config.definitions[scope] && !this.isBuiltInScope(scope)) {
|
|
97
|
-
console.warn(`Agent '${agentId}' has access to undefined scope '${scope}'`);
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
private isBuiltInScope(scope: string): boolean {
|
|
104
|
-
return (
|
|
105
|
-
scope === "global" ||
|
|
106
|
-
scope.startsWith("agent:") ||
|
|
107
|
-
scope.startsWith("custom:") ||
|
|
108
|
-
scope.startsWith("project:") ||
|
|
109
|
-
scope.startsWith("user:")
|
|
110
|
-
);
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
getAccessibleScopes(agentId?: string): string[] {
|
|
114
|
-
if (!agentId) {
|
|
115
|
-
// No agent specified, return all scopes
|
|
116
|
-
return this.getAllScopes();
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
// Check explicit agent access configuration
|
|
120
|
-
const explicitAccess = this.config.agentAccess[agentId];
|
|
121
|
-
if (explicitAccess) {
|
|
122
|
-
return explicitAccess;
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
// Default access: global + agent-specific scope
|
|
126
|
-
const defaultScopes = ["global"];
|
|
127
|
-
const agentScope = SCOPE_PATTERNS.AGENT(agentId);
|
|
128
|
-
|
|
129
|
-
// Only include agent scope if it already exists — don't mutate config as a side effect
|
|
130
|
-
if (this.config.definitions[agentScope] || this.isBuiltInScope(agentScope)) {
|
|
131
|
-
defaultScopes.push(agentScope);
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
return defaultScopes;
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
getDefaultScope(agentId?: string): string {
|
|
138
|
-
if (!agentId) {
|
|
139
|
-
return this.config.default;
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
// For agents, default to their private scope if they have access to it
|
|
143
|
-
const agentScope = SCOPE_PATTERNS.AGENT(agentId);
|
|
144
|
-
const accessibleScopes = this.getAccessibleScopes(agentId);
|
|
145
|
-
|
|
146
|
-
if (accessibleScopes.includes(agentScope)) {
|
|
147
|
-
return agentScope;
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
return this.config.default;
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
isAccessible(scope: string, agentId?: string): boolean {
|
|
154
|
-
if (!agentId) {
|
|
155
|
-
// No agent specified, allow access to all valid scopes
|
|
156
|
-
return this.validateScope(scope);
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
const accessibleScopes = this.getAccessibleScopes(agentId);
|
|
160
|
-
return accessibleScopes.includes(scope);
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
validateScope(scope: string): boolean {
|
|
164
|
-
if (!scope || typeof scope !== "string" || scope.trim().length === 0) {
|
|
165
|
-
return false;
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
const trimmedScope = scope.trim();
|
|
169
|
-
|
|
170
|
-
// Check if scope is defined or is a built-in pattern
|
|
171
|
-
return (
|
|
172
|
-
this.config.definitions[trimmedScope] !== undefined ||
|
|
173
|
-
this.isBuiltInScope(trimmedScope)
|
|
174
|
-
);
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
getAllScopes(): string[] {
|
|
178
|
-
return Object.keys(this.config.definitions);
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
getScopeDefinition(scope: string): ScopeDefinition | undefined {
|
|
182
|
-
return this.config.definitions[scope];
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
// Management methods
|
|
186
|
-
|
|
187
|
-
addScopeDefinition(scope: string, definition: ScopeDefinition): void {
|
|
188
|
-
if (!this.validateScopeFormat(scope)) {
|
|
189
|
-
throw new Error(`Invalid scope format: ${scope}`);
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
this.config.definitions[scope] = definition;
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
removeScopeDefinition(scope: string): boolean {
|
|
196
|
-
if (scope === "global") {
|
|
197
|
-
throw new Error("Cannot remove global scope");
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
if (!this.config.definitions[scope]) {
|
|
201
|
-
return false;
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
delete this.config.definitions[scope];
|
|
205
|
-
|
|
206
|
-
// Clean up agent access references
|
|
207
|
-
for (const [agentId, scopes] of Object.entries(this.config.agentAccess)) {
|
|
208
|
-
const filtered = scopes.filter(s => s !== scope);
|
|
209
|
-
if (filtered.length !== scopes.length) {
|
|
210
|
-
this.config.agentAccess[agentId] = filtered;
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
return true;
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
setAgentAccess(agentId: string, scopes: string[]): void {
|
|
218
|
-
if (!agentId || typeof agentId !== "string") {
|
|
219
|
-
throw new Error("Invalid agent ID");
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
// Validate all scopes
|
|
223
|
-
for (const scope of scopes) {
|
|
224
|
-
if (!this.validateScope(scope)) {
|
|
225
|
-
throw new Error(`Invalid scope: ${scope}`);
|
|
226
|
-
}
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
this.config.agentAccess[agentId] = [...scopes];
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
removeAgentAccess(agentId: string): boolean {
|
|
233
|
-
if (!this.config.agentAccess[agentId]) {
|
|
234
|
-
return false;
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
delete this.config.agentAccess[agentId];
|
|
238
|
-
return true;
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
private validateScopeFormat(scope: string): boolean {
|
|
242
|
-
if (!scope || typeof scope !== "string") {
|
|
243
|
-
return false;
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
const trimmed = scope.trim();
|
|
247
|
-
|
|
248
|
-
// Basic format validation
|
|
249
|
-
if (trimmed.length === 0 || trimmed.length > 100) {
|
|
250
|
-
return false;
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
// Allow alphanumeric, hyphens, underscores, colons, and dots
|
|
254
|
-
const validFormat = /^[a-zA-Z0-9._:-]+$/.test(trimmed);
|
|
255
|
-
return validFormat;
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
// Export/Import configuration
|
|
259
|
-
|
|
260
|
-
exportConfig(): ScopeConfig {
|
|
261
|
-
return JSON.parse(JSON.stringify(this.config));
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
importConfig(config: Partial<ScopeConfig>): void {
|
|
265
|
-
this.config = {
|
|
266
|
-
default: config.default || this.config.default,
|
|
267
|
-
definitions: {
|
|
268
|
-
...this.config.definitions,
|
|
269
|
-
...config.definitions,
|
|
270
|
-
},
|
|
271
|
-
agentAccess: {
|
|
272
|
-
...this.config.agentAccess,
|
|
273
|
-
...config.agentAccess,
|
|
274
|
-
},
|
|
275
|
-
};
|
|
276
|
-
|
|
277
|
-
this.validateConfiguration();
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
// Statistics
|
|
281
|
-
|
|
282
|
-
getStats(): {
|
|
283
|
-
totalScopes: number;
|
|
284
|
-
agentsWithCustomAccess: number;
|
|
285
|
-
scopesByType: Record<string, number>;
|
|
286
|
-
} {
|
|
287
|
-
const scopes = this.getAllScopes();
|
|
288
|
-
const scopesByType: Record<string, number> = {
|
|
289
|
-
global: 0,
|
|
290
|
-
agent: 0,
|
|
291
|
-
custom: 0,
|
|
292
|
-
project: 0,
|
|
293
|
-
user: 0,
|
|
294
|
-
other: 0,
|
|
295
|
-
};
|
|
296
|
-
|
|
297
|
-
for (const scope of scopes) {
|
|
298
|
-
if (scope === "global") {
|
|
299
|
-
scopesByType.global++;
|
|
300
|
-
} else if (scope.startsWith("agent:")) {
|
|
301
|
-
scopesByType.agent++;
|
|
302
|
-
} else if (scope.startsWith("custom:")) {
|
|
303
|
-
scopesByType.custom++;
|
|
304
|
-
} else if (scope.startsWith("project:")) {
|
|
305
|
-
scopesByType.project++;
|
|
306
|
-
} else if (scope.startsWith("user:")) {
|
|
307
|
-
scopesByType.user++;
|
|
308
|
-
} else {
|
|
309
|
-
scopesByType.other++;
|
|
310
|
-
}
|
|
311
|
-
}
|
|
312
|
-
|
|
313
|
-
return {
|
|
314
|
-
totalScopes: scopes.length,
|
|
315
|
-
agentsWithCustomAccess: Object.keys(this.config.agentAccess).length,
|
|
316
|
-
scopesByType,
|
|
317
|
-
};
|
|
318
|
-
}
|
|
319
|
-
}
|
|
320
|
-
|
|
321
|
-
// ============================================================================
|
|
322
|
-
// Factory Functions
|
|
323
|
-
// ============================================================================
|
|
324
|
-
|
|
325
|
-
export function createScopeManager(config?: Partial<ScopeConfig>): MemoryScopeManager {
|
|
326
|
-
return new MemoryScopeManager(config);
|
|
327
|
-
}
|
|
328
|
-
|
|
329
|
-
export function createAgentScope(agentId: string): string {
|
|
330
|
-
return SCOPE_PATTERNS.AGENT(agentId);
|
|
331
|
-
}
|
|
332
|
-
|
|
333
|
-
export function createCustomScope(name: string): string {
|
|
334
|
-
return SCOPE_PATTERNS.CUSTOM(name);
|
|
335
|
-
}
|
|
336
|
-
|
|
337
|
-
export function createProjectScope(projectId: string): string {
|
|
338
|
-
return SCOPE_PATTERNS.PROJECT(projectId);
|
|
339
|
-
}
|
|
340
|
-
|
|
341
|
-
export function createUserScope(userId: string): string {
|
|
342
|
-
return SCOPE_PATTERNS.USER(userId);
|
|
343
|
-
}
|
|
344
|
-
|
|
345
|
-
// ============================================================================
|
|
346
|
-
// Utility Functions
|
|
347
|
-
// ============================================================================
|
|
348
|
-
|
|
349
|
-
export function parseScopeId(scope: string): { type: string; id: string } | null {
|
|
350
|
-
if (scope === "global") {
|
|
351
|
-
return { type: "global", id: "" };
|
|
352
|
-
}
|
|
353
|
-
|
|
354
|
-
const colonIndex = scope.indexOf(":");
|
|
355
|
-
if (colonIndex === -1) {
|
|
356
|
-
return null;
|
|
357
|
-
}
|
|
358
|
-
|
|
359
|
-
return {
|
|
360
|
-
type: scope.substring(0, colonIndex),
|
|
361
|
-
id: scope.substring(colonIndex + 1),
|
|
362
|
-
};
|
|
363
|
-
}
|
|
364
|
-
|
|
365
|
-
export function isScopeAccessible(scope: string, allowedScopes: string[]): boolean {
|
|
366
|
-
return allowedScopes.includes(scope);
|
|
367
|
-
}
|
|
368
|
-
|
|
369
|
-
export function filterScopesForAgent(scopes: string[], agentId?: string, scopeManager?: ScopeManager): string[] {
|
|
370
|
-
if (!scopeManager || !agentId) {
|
|
371
|
-
return scopes;
|
|
372
|
-
}
|
|
373
|
-
|
|
374
|
-
return scopes.filter(scope => scopeManager.isAccessible(scope, agentId));
|
|
375
|
-
}
|
package/src/semantic-gate.ts
DELETED
|
@@ -1,121 +0,0 @@
|
|
|
1
|
-
// SPDX-License-Identifier: MIT
|
|
2
|
-
/**
|
|
3
|
-
* Semantic Noise Gate
|
|
4
|
-
*
|
|
5
|
-
* Pre-filters memory candidates by checking their embedding similarity against
|
|
6
|
-
* domain-relevant anchor texts. Fragments that are too far from any anchor are
|
|
7
|
-
* rejected as noise before reaching the dedup or store pipeline.
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
import type { Embedder } from "./embedder.js";
|
|
11
|
-
import { appendFile, mkdir } from "node:fs/promises";
|
|
12
|
-
import { homedir } from "node:os";
|
|
13
|
-
import { join, dirname } from "node:path";
|
|
14
|
-
|
|
15
|
-
// ============================================================================
|
|
16
|
-
// Anchor Texts
|
|
17
|
-
// ============================================================================
|
|
18
|
-
|
|
19
|
-
const ANCHOR_TEXTS = [
|
|
20
|
-
"投资决策 估值分析 持仓管理 尽职调查",
|
|
21
|
-
"个人偏好 日常习惯 人际关系 生活方式",
|
|
22
|
-
"技术架构 系统设计 代码实现 工程优化",
|
|
23
|
-
] as const;
|
|
24
|
-
|
|
25
|
-
// ============================================================================
|
|
26
|
-
// Cosine Similarity
|
|
27
|
-
// ============================================================================
|
|
28
|
-
|
|
29
|
-
function cosineSimilarity(a: number[], b: number[]): number {
|
|
30
|
-
if (a.length !== b.length || a.length === 0) return 0;
|
|
31
|
-
let dot = 0;
|
|
32
|
-
let normA = 0;
|
|
33
|
-
let normB = 0;
|
|
34
|
-
for (let i = 0; i < a.length; i++) {
|
|
35
|
-
dot += a[i] * b[i];
|
|
36
|
-
normA += a[i] * a[i];
|
|
37
|
-
normB += b[i] * b[i];
|
|
38
|
-
}
|
|
39
|
-
const denom = Math.sqrt(normA) * Math.sqrt(normB);
|
|
40
|
-
return denom === 0 ? 0 : dot / denom;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
// ============================================================================
|
|
44
|
-
// Semantic Gate
|
|
45
|
-
// ============================================================================
|
|
46
|
-
|
|
47
|
-
const FILTER_LOG_PATH = join(homedir(), ".openclaw", "memory", "store-filtered.log");
|
|
48
|
-
|
|
49
|
-
export class SemanticGate {
|
|
50
|
-
private anchorEmbeddings: number[][] | null = null;
|
|
51
|
-
private initPromise: Promise<void> | null = null;
|
|
52
|
-
private readonly threshold: number;
|
|
53
|
-
|
|
54
|
-
constructor(
|
|
55
|
-
private readonly embedder: Embedder,
|
|
56
|
-
threshold = 0.20,
|
|
57
|
-
) {
|
|
58
|
-
this.threshold = threshold;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
private async ensureInitialized(): Promise<void> {
|
|
62
|
-
if (this.anchorEmbeddings) return;
|
|
63
|
-
if (this.initPromise) return this.initPromise;
|
|
64
|
-
|
|
65
|
-
this.initPromise = this.computeAnchors().catch((err) => {
|
|
66
|
-
this.initPromise = null;
|
|
67
|
-
throw err;
|
|
68
|
-
});
|
|
69
|
-
return this.initPromise;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
private async computeAnchors(): Promise<void> {
|
|
73
|
-
const embeddings: number[][] = [];
|
|
74
|
-
for (const text of ANCHOR_TEXTS) {
|
|
75
|
-
const vec = await this.embedder.embed(text);
|
|
76
|
-
embeddings.push(vec);
|
|
77
|
-
}
|
|
78
|
-
this.anchorEmbeddings = embeddings;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
/**
|
|
82
|
-
* Check whether a memory vector passes the semantic gate.
|
|
83
|
-
* Returns true if the memory is relevant enough to persist.
|
|
84
|
-
*/
|
|
85
|
-
async shouldPass(vector: number[], text: string): Promise<boolean> {
|
|
86
|
-
try {
|
|
87
|
-
await this.ensureInitialized();
|
|
88
|
-
} catch {
|
|
89
|
-
// If anchor computation fails, pass everything through
|
|
90
|
-
return true;
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
if (!this.anchorEmbeddings || this.anchorEmbeddings.length === 0) {
|
|
94
|
-
return true;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
let maxSim = 0;
|
|
98
|
-
for (const anchor of this.anchorEmbeddings) {
|
|
99
|
-
const sim = cosineSimilarity(vector, anchor);
|
|
100
|
-
if (sim > maxSim) maxSim = sim;
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
if (maxSim < this.threshold) {
|
|
104
|
-
// Log filtered content
|
|
105
|
-
this.logFiltered(text, maxSim).catch(() => {});
|
|
106
|
-
return false;
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
return true;
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
private async logFiltered(text: string, maxSim: number): Promise<void> {
|
|
113
|
-
try {
|
|
114
|
-
await mkdir(dirname(FILTER_LOG_PATH), { recursive: true });
|
|
115
|
-
const line = `${new Date().toISOString()} maxSim=${maxSim.toFixed(4)} text=${text.slice(0, 200).replace(/\n/g, " ")}\n`;
|
|
116
|
-
await appendFile(FILTER_LOG_PATH, line, "utf8");
|
|
117
|
-
} catch {
|
|
118
|
-
// Non-critical
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
}
|