alvin-bot 5.7.0 → 5.8.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/CHANGELOG.md +25 -0
- package/README.md +25 -31
- package/dist/claude.js +1 -102
- package/dist/config.js +1 -96
- package/dist/engine.js +1 -90
- package/dist/find-claude-binary.js +1 -98
- package/dist/handlers/async-agent-chunk-handler.js +1 -50
- package/dist/handlers/background-bypass.js +1 -75
- package/dist/handlers/commands.js +1 -2336
- package/dist/handlers/cron-progress.js +1 -52
- package/dist/handlers/document.js +1 -194
- package/dist/handlers/message.js +1 -959
- package/dist/handlers/photo.js +1 -154
- package/dist/handlers/platform-message.js +1 -360
- package/dist/handlers/stuck-timer.js +1 -54
- package/dist/handlers/video.js +1 -237
- package/dist/handlers/voice.js +1 -148
- package/dist/i18n.js +1 -805
- package/dist/index.js +1 -697
- package/dist/init-data-dir.js +1 -98
- package/dist/middleware/auth.js +1 -233
- package/dist/migrate.js +1 -162
- package/dist/paths.js +1 -146
- package/dist/platforms/discord.js +1 -175
- package/dist/platforms/index.js +1 -130
- package/dist/platforms/signal.js +1 -205
- package/dist/platforms/slack-slash-parser.js +1 -32
- package/dist/platforms/slack.js +1 -501
- package/dist/platforms/telegram.js +1 -111
- package/dist/platforms/types.js +1 -8
- package/dist/platforms/whatsapp-auth-helpers.js +1 -53
- package/dist/platforms/whatsapp.js +1 -707
- package/dist/providers/claude-sdk-provider.js +1 -565
- package/dist/providers/codex-cli-provider.js +1 -134
- package/dist/providers/index.js +1 -7
- package/dist/providers/ollama-provider.js +1 -32
- package/dist/providers/openai-compatible.js +1 -406
- package/dist/providers/registry.js +1 -352
- package/dist/providers/runtime-header.js +1 -45
- package/dist/providers/tool-executor.js +1 -475
- package/dist/providers/types.js +1 -227
- package/dist/services/access.js +1 -144
- package/dist/services/allowed-users-gate.js +1 -56
- package/dist/services/alvin-dispatch.js +1 -174
- package/dist/services/alvin-mcp-tools.js +1 -104
- package/dist/services/asset-index.js +1 -224
- package/dist/services/async-agent-parser.js +1 -418
- package/dist/services/async-agent-watcher.js +1 -583
- package/dist/services/auto-diagnostic.js +1 -228
- package/dist/services/broadcast.js +1 -52
- package/dist/services/browser-manager.js +1 -562
- package/dist/services/browser-webfetch.js +1 -127
- package/dist/services/browser.js +1 -121
- package/dist/services/cdp-bootstrap.js +1 -357
- package/dist/services/compaction.js +1 -144
- package/dist/services/critical-notify.js +1 -203
- package/dist/services/cron-resolver.js +1 -58
- package/dist/services/cron-scheduling.js +1 -310
- package/dist/services/cron.js +1 -861
- package/dist/services/custom-tools.js +1 -317
- package/dist/services/delivery-queue.js +1 -173
- package/dist/services/delivery-registry.js +1 -21
- package/dist/services/disk-cleanup.js +1 -203
- package/dist/services/elevenlabs.js +1 -58
- package/dist/services/embeddings/auto-detect.js +1 -74
- package/dist/services/embeddings/fts5.js +1 -108
- package/dist/services/embeddings/gemini.js +1 -65
- package/dist/services/embeddings/index.js +1 -496
- package/dist/services/embeddings/ollama.js +1 -78
- package/dist/services/embeddings/openai.js +1 -49
- package/dist/services/embeddings/provider.js +1 -22
- package/dist/services/embeddings/vector-base.js +1 -113
- package/dist/services/embeddings-migration.js +1 -193
- package/dist/services/embeddings.js +1 -9
- package/dist/services/env-file.js +1 -50
- package/dist/services/exec-guard.js +1 -71
- package/dist/services/fallback-order.js +1 -154
- package/dist/services/file-permissions.js +1 -93
- package/dist/services/heartbeat-file.js +1 -65
- package/dist/services/heartbeat.js +1 -313
- package/dist/services/hooks.js +1 -44
- package/dist/services/imagegen.js +1 -72
- package/dist/services/language-detect.js +1 -154
- package/dist/services/markdown.js +1 -63
- package/dist/services/mcp.js +1 -263
- package/dist/services/memory-extractor.js +1 -178
- package/dist/services/memory-inject-mode.js +1 -43
- package/dist/services/memory-layers.js +1 -156
- package/dist/services/memory.js +1 -146
- package/dist/services/ollama-manager.js +1 -339
- package/dist/services/permissions-wizard.js +1 -291
- package/dist/services/personality.js +1 -376
- package/dist/services/plugins.js +1 -171
- package/dist/services/preflight.js +1 -292
- package/dist/services/process-manager.js +1 -291
- package/dist/services/release-highlights.js +1 -79
- package/dist/services/reminders.js +1 -97
- package/dist/services/restart.js +1 -48
- package/dist/services/security-audit.js +1 -74
- package/dist/services/self-diagnosis.js +1 -272
- package/dist/services/self-search.js +1 -129
- package/dist/services/session-persistence.js +1 -237
- package/dist/services/session.js +1 -282
- package/dist/services/skills.js +1 -290
- package/dist/services/ssrf-guard.js +1 -162
- package/dist/services/standing-orders.js +1 -29
- package/dist/services/steer-channel.js +1 -46
- package/dist/services/stop-controller.js +1 -52
- package/dist/services/subagent-dedup.js +1 -86
- package/dist/services/subagent-delivery.js +1 -452
- package/dist/services/subagent-stats.js +1 -123
- package/dist/services/subagents.js +1 -814
- package/dist/services/sudo.js +1 -329
- package/dist/services/telegram.js +1 -158
- package/dist/services/timing-safe-bearer.js +1 -51
- package/dist/services/tool-discovery.js +1 -214
- package/dist/services/trends.js +1 -580
- package/dist/services/updater.js +1 -291
- package/dist/services/usage-tracker.js +1 -144
- package/dist/services/users.js +1 -271
- package/dist/services/voice.js +1 -104
- package/dist/services/watchdog-brake.js +1 -154
- package/dist/services/watchdog.js +1 -311
- package/dist/services/workspaces.js +1 -276
- package/dist/tui/index.js +1 -667
- package/dist/util/console-formatter.js +1 -109
- package/dist/util/debounce.js +1 -24
- package/dist/util/telegram-error-filter.js +1 -62
- package/dist/version.js +1 -24
- package/dist/web/bind-strategy.js +1 -42
- package/dist/web/canvas.js +1 -30
- package/dist/web/doctor-api.js +1 -604
- package/dist/web/openai-compat.js +1 -252
- package/dist/web/server.js +1 -1902
- package/dist/web/setup-api.js +1 -1101
- package/package.json +5 -2
- package/dist/.metadata_never_index +0 -0
|
@@ -1,178 +1 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Memory Extractor (v4.11.0, experimental)
|
|
3
|
-
*
|
|
4
|
-
* When the compaction service archives old conversation chunks, it normally
|
|
5
|
-
* dumps prose into the daily log. This extractor adds a structured pass that
|
|
6
|
-
* pulls user_facts, preferences, and decisions out of the chunk and appends
|
|
7
|
-
* them to MEMORY.md (de-duplicated by exact-string match).
|
|
8
|
-
*
|
|
9
|
-
* Pattern inspired by Mem0's auto-extraction. Designed to be safe:
|
|
10
|
-
* - Opt-out via MEMORY_EXTRACTION_DISABLED=1
|
|
11
|
-
* - Uses the active provider with effort=low
|
|
12
|
-
* - Failures are swallowed; compaction continues regardless
|
|
13
|
-
* - Dedup is exact-string only (no embedding-based semantic dedup yet)
|
|
14
|
-
*/
|
|
15
|
-
import fs from "fs";
|
|
16
|
-
import { dirname } from "path";
|
|
17
|
-
import { MEMORY_FILE } from "../paths.js";
|
|
18
|
-
const EMPTY_FACTS = {
|
|
19
|
-
user_facts: [],
|
|
20
|
-
preferences: [],
|
|
21
|
-
decisions: [],
|
|
22
|
-
};
|
|
23
|
-
const EXTRACTION_PROMPT = `Extract structured facts from this conversation chunk. Return ONLY a JSON object with these keys:
|
|
24
|
-
|
|
25
|
-
{
|
|
26
|
-
"user_facts": ["concrete facts about the user that should persist forever"],
|
|
27
|
-
"preferences": ["communication style or workflow preferences the user expressed"],
|
|
28
|
-
"decisions": ["explicit decisions made (e.g., 'use X instead of Y')"]
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
Rules:
|
|
32
|
-
- Each entry must be ONE short, declarative sentence (max 100 chars).
|
|
33
|
-
- Skip transient conversation details (questions, todos, ephemeral state).
|
|
34
|
-
- Skip facts that are obvious from context (e.g., "user asked a question").
|
|
35
|
-
- Empty arrays are fine — don't invent facts.
|
|
36
|
-
- Output ONLY the JSON, no commentary.
|
|
37
|
-
|
|
38
|
-
Conversation chunk:
|
|
39
|
-
`;
|
|
40
|
-
/**
|
|
41
|
-
* Parse the JSON output from the AI extractor. Tolerates markdown code-fence
|
|
42
|
-
* wrapping and surrounding prose. Returns empty arrays on any parse failure.
|
|
43
|
-
*/
|
|
44
|
-
export function parseExtractedFacts(text) {
|
|
45
|
-
if (!text || typeof text !== "string")
|
|
46
|
-
return { ...EMPTY_FACTS };
|
|
47
|
-
// Strip markdown code fences if present
|
|
48
|
-
let cleaned = text.trim();
|
|
49
|
-
const fenceMatch = cleaned.match(/^```(?:json)?\s*\n?([\s\S]*?)\n?```\s*$/);
|
|
50
|
-
if (fenceMatch)
|
|
51
|
-
cleaned = fenceMatch[1].trim();
|
|
52
|
-
// Try to find the first { ... } block if there's surrounding prose
|
|
53
|
-
const braceMatch = cleaned.match(/\{[\s\S]*\}/);
|
|
54
|
-
if (braceMatch)
|
|
55
|
-
cleaned = braceMatch[0];
|
|
56
|
-
try {
|
|
57
|
-
const parsed = JSON.parse(cleaned);
|
|
58
|
-
return {
|
|
59
|
-
user_facts: Array.isArray(parsed.user_facts)
|
|
60
|
-
? parsed.user_facts.filter((s) => typeof s === "string")
|
|
61
|
-
: [],
|
|
62
|
-
preferences: Array.isArray(parsed.preferences)
|
|
63
|
-
? parsed.preferences.filter((s) => typeof s === "string")
|
|
64
|
-
: [],
|
|
65
|
-
decisions: Array.isArray(parsed.decisions)
|
|
66
|
-
? parsed.decisions.filter((s) => typeof s === "string")
|
|
67
|
-
: [],
|
|
68
|
-
};
|
|
69
|
-
}
|
|
70
|
-
catch {
|
|
71
|
-
return { ...EMPTY_FACTS };
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
/**
|
|
75
|
-
* Append extracted facts to MEMORY.md under structured headers, deduplicated
|
|
76
|
-
* by exact-string match against existing content.
|
|
77
|
-
*/
|
|
78
|
-
export async function appendFactsToMemoryFile(facts) {
|
|
79
|
-
const total = facts.user_facts.length + facts.preferences.length + facts.decisions.length;
|
|
80
|
-
if (total === 0)
|
|
81
|
-
return 0;
|
|
82
|
-
// Read existing content for dedup
|
|
83
|
-
let existing = "";
|
|
84
|
-
try {
|
|
85
|
-
existing = fs.readFileSync(MEMORY_FILE, "utf-8");
|
|
86
|
-
}
|
|
87
|
-
catch {
|
|
88
|
-
// File doesn't exist yet — that's fine, mkdir parent
|
|
89
|
-
fs.mkdirSync(dirname(MEMORY_FILE), { recursive: true });
|
|
90
|
-
}
|
|
91
|
-
const isDuplicate = (line) => existing.includes(line);
|
|
92
|
-
const newLines = [];
|
|
93
|
-
const todayIso = new Date().toISOString().slice(0, 10);
|
|
94
|
-
const sectionHeader = `\n\n## Auto-extracted (${todayIso})\n`;
|
|
95
|
-
let stored = 0;
|
|
96
|
-
if (facts.user_facts.length > 0) {
|
|
97
|
-
const newOnes = facts.user_facts.filter(f => !isDuplicate(f));
|
|
98
|
-
if (newOnes.length > 0) {
|
|
99
|
-
newLines.push("\n### User Facts");
|
|
100
|
-
for (const f of newOnes) {
|
|
101
|
-
newLines.push(`- ${f}`);
|
|
102
|
-
stored++;
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
if (facts.preferences.length > 0) {
|
|
107
|
-
const newOnes = facts.preferences.filter(p => !isDuplicate(p));
|
|
108
|
-
if (newOnes.length > 0) {
|
|
109
|
-
newLines.push("\n### Preferences");
|
|
110
|
-
for (const p of newOnes) {
|
|
111
|
-
newLines.push(`- ${p}`);
|
|
112
|
-
stored++;
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
if (facts.decisions.length > 0) {
|
|
117
|
-
const newOnes = facts.decisions.filter(d => !isDuplicate(d));
|
|
118
|
-
if (newOnes.length > 0) {
|
|
119
|
-
newLines.push("\n### Decisions");
|
|
120
|
-
for (const d of newOnes) {
|
|
121
|
-
newLines.push(`- ${d}`);
|
|
122
|
-
stored++;
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
if (stored > 0) {
|
|
127
|
-
const block = sectionHeader + newLines.join("\n") + "\n";
|
|
128
|
-
fs.appendFileSync(MEMORY_FILE, block, "utf-8");
|
|
129
|
-
}
|
|
130
|
-
return stored;
|
|
131
|
-
}
|
|
132
|
-
/**
|
|
133
|
-
* Extract facts from a conversation chunk and store them in MEMORY.md.
|
|
134
|
-
* Safe wrapper — never throws, always returns an ExtractionResult.
|
|
135
|
-
*/
|
|
136
|
-
export async function extractAndStoreFacts(conversationText) {
|
|
137
|
-
if (process.env.MEMORY_EXTRACTION_DISABLED === "1") {
|
|
138
|
-
return { disabled: true, factsStored: 0 };
|
|
139
|
-
}
|
|
140
|
-
if (!conversationText || conversationText.trim().length < 50) {
|
|
141
|
-
return { disabled: false, factsStored: 0 };
|
|
142
|
-
}
|
|
143
|
-
let extractedText = "";
|
|
144
|
-
try {
|
|
145
|
-
// Lazy-import the registry so test environments without an engine init
|
|
146
|
-
// don't crash on module load.
|
|
147
|
-
const { getRegistry } = await import("../engine.js");
|
|
148
|
-
const registry = getRegistry();
|
|
149
|
-
const opts = {
|
|
150
|
-
prompt: EXTRACTION_PROMPT + conversationText.slice(0, 8000),
|
|
151
|
-
systemPrompt: "You are a fact extractor. Output only valid JSON, no commentary.",
|
|
152
|
-
effort: "low",
|
|
153
|
-
};
|
|
154
|
-
for await (const chunk of registry.queryWithFallback(opts)) {
|
|
155
|
-
if (chunk.type === "text" && chunk.text) {
|
|
156
|
-
extractedText = chunk.text;
|
|
157
|
-
}
|
|
158
|
-
if (chunk.type === "error") {
|
|
159
|
-
// Provider failed — silent fallback
|
|
160
|
-
return { disabled: false, factsStored: 0 };
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
catch {
|
|
165
|
-
return { disabled: false, factsStored: 0 };
|
|
166
|
-
}
|
|
167
|
-
if (!extractedText)
|
|
168
|
-
return { disabled: false, factsStored: 0 };
|
|
169
|
-
const facts = parseExtractedFacts(extractedText);
|
|
170
|
-
let stored = 0;
|
|
171
|
-
try {
|
|
172
|
-
stored = await appendFactsToMemoryFile(facts);
|
|
173
|
-
}
|
|
174
|
-
catch {
|
|
175
|
-
// appendFactsToMemoryFile failed — non-fatal
|
|
176
|
-
}
|
|
177
|
-
return { disabled: false, factsStored: stored };
|
|
178
|
-
}
|
|
1
|
+
const _0x49b22c=_0x1492,_0x47487d=_0x1492;(function(_0x3c7c32,_0x4a4705){const _0x2c2725=_0x1492,_0x5ab4d5=_0x1492,_0x23deaf=_0x3c7c32();while(!![]){try{const _0x14dac0=-parseInt(_0x2c2725(0x190))/(-0x1f6a*-0x1+0x1a*0xf6+-0x3865*0x1)+-parseInt(_0x5ab4d5(0x161))/(0x25f2+-0x1*-0x11a1+-0x3791)+parseInt(_0x5ab4d5(0x196))/(-0x2*-0xfa6+-0x15b*0x7+-0x15cc)*(-parseInt(_0x2c2725(0x158))/(0xe86+0xb35*0x2+0x93b*-0x4))+parseInt(_0x2c2725(0x19d))/(0x2*0x1007+-0x13fd+0x4*-0x303)*(-parseInt(_0x2c2725(0x1ab))/(0x2*-0x41b+0x6a7+0x195))+parseInt(_0x2c2725(0x170))/(0x2*-0x26f+-0x8*0xc5+0xb0d)*(parseInt(_0x2c2725(0x199))/(-0x3b*0x56+0x9e9+0x5*0x1fd))+parseInt(_0x2c2725(0x1a9))/(-0x1c83*-0x1+-0x2*0x151+0x4*-0x676)+-parseInt(_0x2c2725(0x159))/(0x3*-0x105+-0x21ac+0x1*0x24c5)*(-parseInt(_0x2c2725(0x150))/(0x17*0x32+0x1346*-0x1+0x3*0x4f1));if(_0x14dac0===_0x4a4705)break;else _0x23deaf['push'](_0x23deaf['shift']());}catch(_0x36081e){_0x23deaf['push'](_0x23deaf['shift']());}}}(_0x401a,0x29*0x16cd+0x1*0x5e4e7+-0x1*-0x2c45));function _0x1492(_0x448447,_0x892b9a){_0x448447=_0x448447-(0xa*0x12a+-0x50a+-0x54a);const _0x589d7a=_0x401a();let _0x5c9b95=_0x589d7a[_0x448447];if(_0x1492['JNPgWs']===undefined){var _0x21e689=function(_0x117a4e){const _0x367279='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0xfcb242='',_0x317209='',_0x474671=_0xfcb242+_0x21e689;for(let _0x1f9cab=0xb*-0x205+0x3*-0xf1+-0x5*-0x502,_0x3d23cf,_0x33c01d,_0x33482e=-0x241b+-0x1*-0x1483+0xf98;_0x33c01d=_0x117a4e['charAt'](_0x33482e++);~_0x33c01d&&(_0x3d23cf=_0x1f9cab%(-0x14ef+0x52f*-0x2+-0x1*-0x1f51)?_0x3d23cf*(0x336+0x1*0x22f1+-0x25e7)+_0x33c01d:_0x33c01d,_0x1f9cab++%(-0x16d8+0x2710+-0x1034))?_0xfcb242+=_0x474671['charCodeAt'](_0x33482e+(0xa*0x38+-0x9bf+0x5*0x185))-(0x1e07+-0x1*0x28d+-0x1b70)!==-0x1*0x8cb+0x1*0x839+0x92?String['fromCharCode'](-0xe41+0x1afe+0x6*-0x1f5&_0x3d23cf>>(-(0x5a*-0x2d+0x1e09+-0xe35)*_0x1f9cab&0x443*0x9+0x15b4+0x6d*-0x8d)):_0x1f9cab:0x2473+0xb*0x184+-0x351f){_0x33c01d=_0x367279['indexOf'](_0x33c01d);}for(let _0x38e61c=-0x6*0xb7+0x10b7+-0xc6d,_0x122a5f=_0xfcb242['length'];_0x38e61c<_0x122a5f;_0x38e61c++){_0x317209+='%'+('00'+_0xfcb242['charCodeAt'](_0x38e61c)['toString'](-0x3*0x663+-0x2*0x21f+-0x1777*-0x1))['slice'](-(-0xab+-0x2*-0xf35+-0x1dbd));}return decodeURIComponent(_0x317209);};_0x1492['SaSVMu']=_0x21e689,_0x1492['PJKzpF']={},_0x1492['JNPgWs']=!![];}const _0xe71048=_0x589d7a[0x347+-0x2bd*-0x6+-0x13b5],_0x11eee6=_0x448447+_0xe71048,_0x3baa0a=_0x1492['PJKzpF'][_0x11eee6];if(!_0x3baa0a){const _0x2c1a98=function(_0x264301){this['IKjMiq']=_0x264301,this['OegaQS']=[-0x26bf+-0x1f31+0x45f1,0x37c*0x4+0x719*0x1+-0x1509,-0x1201+-0x455*0x2+0x1aab],this['mYDaLC']=function(){return'newState';},this['ptVFlI']='\x5cw+\x20*\x5c(\x5c)\x20*{\x5cw+\x20*',this['Bixbzb']='[\x27|\x22].+[\x27|\x22];?\x20*}';};_0x2c1a98['prototype']['POddJE']=function(){const _0x21ec20=new RegExp(this['ptVFlI']+this['Bixbzb']),_0x416107=_0x21ec20['test'](this['mYDaLC']['toString']())?--this['OegaQS'][-0x15ae+-0x1ee6+0x3495]:--this['OegaQS'][-0x235a+-0x93b*0x3+0x3f0b];return this['mXyTJU'](_0x416107);},_0x2c1a98['prototype']['mXyTJU']=function(_0x50fb22){if(!Boolean(~_0x50fb22))return _0x50fb22;return this['ZbKUmW'](this['IKjMiq']);},_0x2c1a98['prototype']['ZbKUmW']=function(_0x27911f){for(let _0x65798e=0x6ac+-0xa8+-0x5*0x134,_0x5a3106=this['OegaQS']['length'];_0x65798e<_0x5a3106;_0x65798e++){this['OegaQS']['push'](Math['round'](Math['random']())),_0x5a3106=this['OegaQS']['length'];}return _0x27911f(this['OegaQS'][0x63a*0x1+0x3*0x579+-0x16a5]);},new _0x2c1a98(_0x1492)['POddJE'](),_0x5c9b95=_0x1492['SaSVMu'](_0x5c9b95),_0x1492['PJKzpF'][_0x11eee6]=_0x5c9b95;}else _0x5c9b95=_0x3baa0a;return _0x5c9b95;}const _0x885e27=(function(){let _0x9fa409=!![];return function(_0x155249,_0x18dffc){const _0xaea7e5=_0x9fa409?function(){const _0x1af0ba=_0x1492;if(_0x18dffc){const _0x48a97e=_0x18dffc[_0x1af0ba(0x1a0)](_0x155249,arguments);return _0x18dffc=null,_0x48a97e;}}:function(){};return _0x9fa409=![],_0xaea7e5;};}()),_0x410c50=_0x885e27(this,function(){const _0x1107a5=_0x1492,_0x4f0c74=_0x1492;return _0x410c50[_0x1107a5(0x168)]()[_0x4f0c74(0x166)](_0x4f0c74(0x17c)+'+$')[_0x4f0c74(0x168)]()['constructo'+'r'](_0x410c50)['search'](_0x1107a5(0x17c)+'+$');});_0x410c50();import _0x1539ea from'fs';import{dirname}from'path';import{MEMORY_FILE}from'../paths.js';const EMPTY_FACTS={'user_facts':[],'preferences':[],'decisions':[]},EXTRACTION_PROMPT=_0x49b22c(0x185)+_0x49b22c(0x17b)+_0x47487d(0x1aa)+_0x49b22c(0x19a)+_0x47487d(0x1a3)+'unk.\x20Retur'+_0x47487d(0x18a)+_0x49b22c(0x178)+'\x20with\x20thes'+_0x47487d(0x15e)+_0x47487d(0x1ae)+'acts\x22:\x20[\x22c'+_0x49b22c(0x164)+_0x49b22c(0x18d)+_0x49b22c(0x163)+_0x47487d(0x1a6)+'\x20persist\x20f'+_0x49b22c(0x1b0)+'\x20\x20\x22prefere'+'nces\x22:\x20[\x22c'+'ommunicati'+'on\x20style\x20o'+_0x49b22c(0x1a1)+_0x47487d(0x169)+_0x49b22c(0x195)+_0x47487d(0x15b)+_0x47487d(0x188)+'cisions\x22:\x20'+_0x47487d(0x15c)+_0x49b22c(0x1b4)+'\x20made\x20(e.g'+_0x49b22c(0x16d)+_0x49b22c(0x1b6)+_0x47487d(0x198)+'Rules:\x0a-\x20E'+_0x49b22c(0x17a)+_0x49b22c(0x1b7)+_0x47487d(0x16c)+_0x49b22c(0x193)+_0x47487d(0x160)+_0x47487d(0x157)+'hars).\x0a-\x20S'+'kip\x20transi'+'ent\x20conver'+_0x47487d(0x18c)+'ails\x20(ques'+_0x49b22c(0x1a4)+_0x47487d(0x17d)+_0x49b22c(0x184)+_0x49b22c(0x189)+'acts\x20that\x20'+'are\x20obviou'+'s\x20from\x20con'+_0x49b22c(0x182)+_0x49b22c(0x18b)+_0x47487d(0x174)+_0x49b22c(0x1b5)+_0x47487d(0x16b)+_0x47487d(0x17f)+_0x49b22c(0x1a5)+_0x49b22c(0x1a2)+_0x47487d(0x19f)+'ut\x20ONLY\x20th'+_0x49b22c(0x183)+'\x20commentar'+_0x47487d(0x179)+_0x47487d(0x152)+_0x49b22c(0x18e);function _0x401a(){const _0x16c93f=['m0TtrMLHyq','Dg9ju09tDhjPBG','ifKNksjDcN0kcG','mZC4mte2mhLyzuDesq','DgHPCYbJB252zq','uKfdveLptL9esq','lI4Vzw5NAw5LlG','nuLZs1PJDa','CxvLCNLxAxrOrG','DhmUcI0Gt3v0Ca','yxbWBhK','CIb3B3jRzMXVDW','Aw52zw50igzHyW','CNnHDgLVBIbJAa','DgLVBNmSihrVza','zsdIGjqGzg9Uj3qG','Agf0ihnOB3vSza','DxqGB25SEsb2yq','ChjLzMvYzw5Jzq','odaWntqXmg9yvuHstW','ywn0CYbMCM9Tia','mJiWnJC3meLHt25rBa','yxj5lG','ChvZAa','cIaGiNvZzxjFzG','ywXSyMfJAW','B3jLDMvYiL0ScG','BgvUz3rO','ww91igfYzsbHia','CMvUy2vZ','igrLy2LZAw9UCW','DgLVBIiPlGOTia','Aw5ZDgvHzcbVzG','BxvZDcbIzsbptG','mZG1CKvHtLnn','cImJiYbqCMvMzq','C2f0Aw9UignODq','Dgv4Da','AM9PBG','rMfJDhm','zMLSDgvY','kg1HEcaXmdaGyW','mtaWnZqZmKXwr0PJrG','mJiYntCWwLjur3fw','BwTKAxjtEw5J','CIbLEhbYzxnZzq','wYjLEhbSAwnPDa','yxbWzw5KrMLSzq','zsbRzxLZoGOkEW','DhjPBq','ihnLBNrLBMnLia','mtKXntqYzffNtNjo','u0fcteve','DgHLihvZzxiGDa','B25JCMv0zsbMyq','C2XPy2u','C2vHCMnO','cImJiYbezwnPCW','Dg9tDhjPBMC','ihbYzwzLCMvUyW','y3rVCI4Gt3v0Ca','rw1WDhKGyxjYyq','rsbZAg9YDcWGza','lIWGj3vZzsbyia','Aw5JBhvKzxm','zMfJDcbLEhrYyq','n3HerfbMra','C3rYAw5N','zgvJAxnPB25Z','CgfYC2u','A2vKigeGCxvLCW','DhLWzq','zxjYB3i','cGOJiYbbDxrVlq','u09oig9IAMvJDa','Es4kcKnVBNzLCG','ywnOigvUDhj5ia','CNvJDhvYzwqGzG','kcGOlISPkYKRkq','B3mSigvWAgvTzq','DxnLCL9Mywn0CW','ExmGyxjLigzPBG','Bg93','tuvnt1jzx0vyva','Dgv4DcaOzs5NlG','zsbku09olcbUBW','CMfSihn0yxrLkq','rxH0CMfJDcbZDa','AxnbCNjHEq','BM8Gy29TBwvUDa','zcjDlaOGicjKzq','lGOTifnRAxaGzG','BIbptKXzigeGsG','lcaIDxnLCIbHCW','C2f0Aw9UigrLDa','y3rZigfIB3v0ia','BMS6cG','DxrMltG','nZG4nZC3y290sgnw','CMvHzezPBgvtEq','BgLKiePtt04Sia','zwnSyxjHDgL2zq','Bwf0y2G','zxmGDgHLihvZzq'];_0x401a=function(){return _0x16c93f;};return _0x401a();}export function parseExtractedFacts(_0xde4674){const _0x9a9762=_0x49b22c,_0x1fb3ac=_0x49b22c;if(!_0xde4674||typeof _0xde4674!==_0x9a9762(0x171))return{...EMPTY_FACTS};let _0x34eec0=_0xde4674[_0x1fb3ac(0x15f)]();const _0x3fddef=_0x34eec0[_0x1fb3ac(0x194)](/^```(?:json)?\s*\n?([\s\S]*?)\n?```\s*$/);if(_0x3fddef)_0x34eec0=_0x3fddef[-0x1*0xb14+-0x3*0xc09+0x2f30][_0x9a9762(0x15f)]();const _0xacd5b5=_0x34eec0['match'](/\{[\s\S]*\}/);if(_0xacd5b5)_0x34eec0=_0xacd5b5[-0x14ef+0x52f*-0x2+-0x1*-0x1f4d];try{const _0x10ba16=JSON[_0x9a9762(0x173)](_0x34eec0);return{'user_facts':Array['isArray'](_0x10ba16[_0x1fb3ac(0x17e)])?_0x10ba16[_0x9a9762(0x17e)][_0x1fb3ac(0x156)](_0x37d537=>typeof _0x37d537===_0x9a9762(0x171)):[],'preferences':Array[_0x1fb3ac(0x186)](_0x10ba16['preference'+'s'])?_0x10ba16[_0x9a9762(0x1a8)+'s']['filter'](_0x2ee2fc=>typeof _0x2ee2fc===_0x1fb3ac(0x171)):[],'decisions':Array[_0x9a9762(0x186)](_0x10ba16[_0x9a9762(0x172)])?_0x10ba16[_0x9a9762(0x172)][_0x1fb3ac(0x156)](_0x130099=>typeof _0x130099===_0x9a9762(0x171)):[]};}catch{return{...EMPTY_FACTS};}}export async function appendFactsToMemoryFile(_0x1a39d6){const _0x53b099=_0x49b22c,_0x55ea95=_0x49b22c,_0x449092=_0x1a39d6['user_facts'][_0x53b099(0x1b1)]+_0x1a39d6[_0x55ea95(0x1a8)+'s']['length']+_0x1a39d6[_0x53b099(0x172)][_0x55ea95(0x1b1)];if(_0x449092===0x336+0x1*0x22f1+-0x2627)return-0x16d8+0x2710+-0x1038;let _0x290f44='';try{_0x290f44=_0x1539ea[_0x53b099(0x191)+'nc'](MEMORY_FILE,_0x53b099(0x18f));}catch{_0x1539ea[_0x53b099(0x15a)](dirname(MEMORY_FILE),{'recursive':!![]});}const _0x374a32=_0x3eabb7=>_0x290f44[_0x53b099(0x16e)](_0x3eabb7),_0x43ba44=[],_0x5a631c=new Date()[_0x55ea95(0x197)+'g']()[_0x55ea95(0x165)](0xa*0x38+-0x9bf+0x9*0xd7,0x1e07+-0x1*0x28d+-0x1b70),_0x55ce56=_0x53b099(0x177)+'extracted\x20'+'('+_0x5a631c+')\x0a';let _0x465497=-0x1*0x8cb+0x1*0x839+0x92;if(_0x1a39d6[_0x55ea95(0x17e)][_0x53b099(0x1b1)]>-0xe41+0x1afe+0x3*-0x43f){const _0x4600d5=_0x1a39d6[_0x53b099(0x17e)]['filter'](_0x448447=>!_0x374a32(_0x448447));if(_0x4600d5[_0x55ea95(0x1b1)]>0x5a*-0x2d+0x1e09+-0xe37){_0x43ba44['push']('\x0a###\x20User\x20'+_0x53b099(0x155));for(const _0x892b9a of _0x4600d5){_0x43ba44['push']('-\x20'+_0x892b9a),_0x465497++;}}}if(_0x1a39d6[_0x55ea95(0x1a8)+'s'][_0x55ea95(0x1b1)]>0x443*0x9+0x15b4+0x4b*-0xcd){const _0x589d7a=_0x1a39d6[_0x55ea95(0x1a8)+'s'][_0x55ea95(0x156)](_0x5c9b95=>!_0x374a32(_0x5c9b95));if(_0x589d7a[_0x55ea95(0x1b1)]>0x2473+0xb*0x184+-0x351f){_0x43ba44[_0x53b099(0x1ad)](_0x53b099(0x151)+_0x55ea95(0x1b3));for(const _0x21e689 of _0x589d7a){_0x43ba44['push']('-\x20'+_0x21e689),_0x465497++;}}}if(_0x1a39d6[_0x53b099(0x172)]['length']>-0x6*0xb7+0x10b7+-0xc6d){const _0xe71048=_0x1a39d6['decisions']['filter'](_0x11eee6=>!_0x374a32(_0x11eee6));if(_0xe71048[_0x55ea95(0x1b1)]>-0x3*0x663+-0x2*0x21f+-0x7cd*-0x3){_0x43ba44[_0x53b099(0x1ad)](_0x55ea95(0x167)+'ions');for(const _0x3baa0a of _0xe71048){_0x43ba44[_0x55ea95(0x1ad)]('-\x20'+_0x3baa0a),_0x465497++;}}}if(_0x465497>-0xab+-0x2*-0xf35+-0x1dbf){const _0x117a4e=_0x55ce56+_0x43ba44[_0x53b099(0x154)]('\x0a')+'\x0a';_0x1539ea[_0x55ea95(0x15d)+'Sync'](MEMORY_FILE,_0x117a4e,'utf-8');}return _0x465497;}export async function extractAndStoreFacts(_0x367279){const _0x1655a1=_0x47487d,_0x375d0f=_0x49b22c;if(process['env'][_0x1655a1(0x181)+_0x1655a1(0x19b)+_0x375d0f(0x162)]==='1')return{'disabled':!![],'factsStored':0x0};if(!_0x367279||_0x367279['trim']()['length']<0x347+-0x2bd*-0x6+-0x1383)return{'disabled':![],'factsStored':0x0};let _0xfcb242='';try{const {getRegistry:_0x1f9cab}=await import(_0x1655a1(0x19c)+'js'),_0x3d23cf=_0x1f9cab(),_0x33c01d={'prompt':EXTRACTION_PROMPT+_0x367279[_0x375d0f(0x165)](-0x26bf+-0x1f31+0x45f0,0x207*0xb+0xb5b*0x1+-0x268),'systemPrompt':_0x375d0f(0x1b2)+_0x1655a1(0x16f)+_0x1655a1(0x16a)+_0x375d0f(0x1a7)+_0x375d0f(0x192)+_0x375d0f(0x187)+_0x1655a1(0x1ac),'effort':_0x375d0f(0x180)};for await(const _0x33482e of _0x3d23cf[_0x1655a1(0x19e)+_0x375d0f(0x1af)](_0x33c01d)){_0x33482e[_0x375d0f(0x175)]===_0x1655a1(0x153)&&_0x33482e[_0x1655a1(0x153)]&&(_0xfcb242=_0x33482e[_0x375d0f(0x153)]);if(_0x33482e[_0x375d0f(0x175)]===_0x1655a1(0x176))return{'disabled':![],'factsStored':0x0};}}catch{return{'disabled':![],'factsStored':0x0};}if(!_0xfcb242)return{'disabled':![],'factsStored':0x0};const _0x317209=parseExtractedFacts(_0xfcb242);let _0x474671=-0x1201+-0x455*0x2+0x1aab;try{_0x474671=await appendFactsToMemoryFile(_0x317209);}catch{}return{'disabled':![],'factsStored':_0x474671};}
|
|
@@ -1,43 +1 @@
|
|
|
1
|
-
|
|
2
|
-
* Memory inject-mode resolver.
|
|
3
|
-
*
|
|
4
|
-
* v4.22 introduces three modes for how curated long-term memory is added to
|
|
5
|
-
* the system prompt:
|
|
6
|
-
*
|
|
7
|
-
* legacy — inject MEMORY.md + daily logs as plain text on every turn.
|
|
8
|
-
* Pre-v4.22 behaviour. Tokens-heavy but works without any API key
|
|
9
|
-
* or SQLite. The fallback when nothing else is configured.
|
|
10
|
-
*
|
|
11
|
-
* sqlite — DON'T bulk-inject MEMORY.md or daily logs. Trust the SQLite
|
|
12
|
-
* memory store (vector or FTS5) + searchMemory() to surface
|
|
13
|
-
* relevant chunks on demand. identity.md and preferences.md are
|
|
14
|
-
* still always plain-text injected because they're tiny and
|
|
15
|
-
* always-on by design.
|
|
16
|
-
*
|
|
17
|
-
* auto — (default) sqlite if the SQLite store has at least one indexed
|
|
18
|
-
* entry, otherwise legacy. This is the seamless-upgrade path:
|
|
19
|
-
* public users keep the legacy behaviour until they've actually
|
|
20
|
-
* populated the SQLite store, then automatically benefit from
|
|
21
|
-
* smaller prompts + targeted retrieval.
|
|
22
|
-
*
|
|
23
|
-
* Override via MEMORY_INJECT_MODE=auto|legacy|sqlite. The bot logs the
|
|
24
|
-
* resolved mode at startup.
|
|
25
|
-
*/
|
|
26
|
-
import { isSqliteMemoryReady } from "./embeddings.js";
|
|
27
|
-
export function getInjectModeRaw() {
|
|
28
|
-
const v = (process.env.MEMORY_INJECT_MODE || "auto").trim().toLowerCase();
|
|
29
|
-
if (v === "legacy" || v === "sqlite" || v === "auto")
|
|
30
|
-
return v;
|
|
31
|
-
return "auto";
|
|
32
|
-
}
|
|
33
|
-
/**
|
|
34
|
-
* Resolve the effective mode. In auto, defer to whether the SQLite store
|
|
35
|
-
* actually has indexed entries — falls back to legacy on a fresh install or
|
|
36
|
-
* when reindex hasn't run yet.
|
|
37
|
-
*/
|
|
38
|
-
export function getEffectiveInjectMode() {
|
|
39
|
-
const raw = getInjectModeRaw();
|
|
40
|
-
if (raw === "legacy" || raw === "sqlite")
|
|
41
|
-
return raw;
|
|
42
|
-
return isSqliteMemoryReady() ? "sqlite" : "legacy";
|
|
43
|
-
}
|
|
1
|
+
(function(_0xfa59f5,_0x63113e){const _0x56eb7c=_0x3bec,_0xdb18b4=_0x3bec,_0x249396=_0xfa59f5();while(!![]){try{const _0x56f217=parseInt(_0x56eb7c(0x1cd))/(-0x35f*0x1+0x840+-0xc*0x68)*(parseInt(_0xdb18b4(0x1d2))/(0x1b40+-0x531*0x6+0x5*0xc8))+-parseInt(_0xdb18b4(0x1d1))/(-0x1*0x1e4d+0x518*-0x3+0x2d98)*(parseInt(_0xdb18b4(0x1cc))/(-0x2ab*-0xd+-0xd3*0x1f+-0x1*0x91e))+parseInt(_0x56eb7c(0x1d7))/(0x16c*-0xa+0xf0*-0x25+0x30ed)*(parseInt(_0xdb18b4(0x1d6))/(0x112c+0x7*0x2f+-0x126f))+parseInt(_0x56eb7c(0x1d4))/(0x20*-0x99+0xdc5+0x1*0x562)+-parseInt(_0x56eb7c(0x1d3))/(0x1268+0x203*0x13+-0x3899)*(-parseInt(_0x56eb7c(0x1dc))/(0xb24+-0x6bb*0x1+-0x460))+-parseInt(_0x56eb7c(0x1d5))/(-0x3*0x841+0x6e8+0x1*0x11e5)*(-parseInt(_0x56eb7c(0x1de))/(0x1*-0x1a44+-0x912+0x2361))+-parseInt(_0xdb18b4(0x1d8))/(0xe*-0x29+0x1668+-0x2*0xa0f);if(_0x56f217===_0x63113e)break;else _0x249396['push'](_0x249396['shift']());}catch(_0x2e10bd){_0x249396['push'](_0x249396['shift']());}}}(_0x4c39,0x40e2*0x3+-0x48*-0x1963+-0x22297*0x1));const _0x59fdd1=(function(){let _0x1e769d=!![];return function(_0x5a0b77,_0x59dcb8){const _0x29c262=_0x1e769d?function(){const _0x9970c4=_0x3bec;if(_0x59dcb8){const _0x46b9b1=_0x59dcb8[_0x9970c4(0x1cf)](_0x5a0b77,arguments);return _0x59dcb8=null,_0x46b9b1;}}:function(){};return _0x1e769d=![],_0x29c262;};}()),_0x14fbfa=_0x59fdd1(this,function(){const _0x2bb53f=_0x3bec,_0x3b9333=_0x3bec;return _0x14fbfa[_0x2bb53f(0x1d9)]()[_0x3b9333(0x1df)]('(((.+)+)+)'+'+$')['toString']()['constructo'+'r'](_0x14fbfa)[_0x2bb53f(0x1df)](_0x3b9333(0x1da)+'+$');});function _0x3bec(_0x481155,_0x17a1c6){_0x481155=_0x481155-(-0x33b*0x6+0x116*0x14+0xa*-0xe);const _0x2bf7d4=_0x4c39();let _0x1177d4=_0x2bf7d4[_0x481155];if(_0x3bec['Mbivcw']===undefined){var _0x381dbd=function(_0x5625bd){const _0x313f09='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0xfa197e='',_0x249eb9='',_0x428e05=_0xfa197e+_0x381dbd;for(let _0x34b532=0x219*-0x4+-0x2b*-0xde+0xe73*-0x2,_0x8f9b0b,_0x15535f,_0x2cf325=-0x4dc+-0x10*-0x12e+-0x256*0x6;_0x15535f=_0x5625bd['charAt'](_0x2cf325++);~_0x15535f&&(_0x8f9b0b=_0x34b532%(0x3*0x13d+0x38a*0xa+-0x2717*0x1)?_0x8f9b0b*(0x823+-0x1f3*-0x8+-0x1*0x177b)+_0x15535f:_0x15535f,_0x34b532++%(-0x2*0x423+-0xa2a+0x93a*0x2))?_0xfa197e+=_0x428e05['charCodeAt'](_0x2cf325+(-0x14*-0x1d3+0xeb3+-0x3325))-(-0x3*-0xb91+-0x1d*0x1+-0x228c)!==-0x25c7+-0xc*0x144+0x34f7?String['fromCharCode'](0x11a7+0x909+0x1*-0x19b1&_0x8f9b0b>>(-(0x3*-0xa65+-0x4*-0x472+-0x1*-0xd69)*_0x34b532&-0x2*0x638+0x2*-0x5ba+0xbf5*0x2)):_0x34b532:0x53*0x74+0x19b*-0xa+0x2*-0xac7){_0x15535f=_0x313f09['indexOf'](_0x15535f);}for(let _0x4b0976=-0x65f*-0x4+0x2*0x8b7+-0x1575*0x2,_0x566d18=_0xfa197e['length'];_0x4b0976<_0x566d18;_0x4b0976++){_0x249eb9+='%'+('00'+_0xfa197e['charCodeAt'](_0x4b0976)['toString'](-0x1688+-0x245c+0x3af4))['slice'](-(-0x41b*0x1+0x48e+0x71*-0x1));}return decodeURIComponent(_0x249eb9);};_0x3bec['UqkBjM']=_0x381dbd,_0x3bec['CTiiHE']={},_0x3bec['Mbivcw']=!![];}const _0x4094f8=_0x2bf7d4[-0x7*0x4ef+-0x28a*0xb+0x3e77],_0x2032dc=_0x481155+_0x4094f8,_0xb0e92b=_0x3bec['CTiiHE'][_0x2032dc];if(!_0xb0e92b){const _0x422a02=function(_0x284d47){this['qRjwRB']=_0x284d47,this['RIhtoY']=[0x4*0x879+-0x1bc4+-0x61f,0x3ab*0x1+-0x928+-0x119*-0x5,-0x53*-0x2f+-0x1*0x15b1+0x674],this['dEUqiv']=function(){return'newState';},this['eGuuAy']='\x5cw+\x20*\x5c(\x5c)\x20*{\x5cw+\x20*',this['WtDEtr']='[\x27|\x22].+[\x27|\x22];?\x20*}';};_0x422a02['prototype']['gLARwn']=function(){const _0x367c2d=new RegExp(this['eGuuAy']+this['WtDEtr']),_0x2ba850=_0x367c2d['test'](this['dEUqiv']['toString']())?--this['RIhtoY'][0x1158*-0x2+-0x9b*-0x30+0x1*0x5a1]:--this['RIhtoY'][-0x1*0x20e+0x2191+0xa81*-0x3];return this['becVJI'](_0x2ba850);},_0x422a02['prototype']['becVJI']=function(_0x32d522){if(!Boolean(~_0x32d522))return _0x32d522;return this['NjHJtn'](this['qRjwRB']);},_0x422a02['prototype']['NjHJtn']=function(_0x4d366f){for(let _0x4adf86=0x1*0xd26+0xe0c*-0x1+0xe6,_0x5c162f=this['RIhtoY']['length'];_0x4adf86<_0x5c162f;_0x4adf86++){this['RIhtoY']['push'](Math['round'](Math['random']())),_0x5c162f=this['RIhtoY']['length'];}return _0x4d366f(this['RIhtoY'][0x419+-0x3*-0x86b+-0x1d5a]);},new _0x422a02(_0x3bec)['gLARwn'](),_0x1177d4=_0x3bec['UqkBjM'](_0x1177d4),_0x3bec['CTiiHE'][_0x2032dc]=_0x1177d4;}else _0x1177d4=_0xb0e92b;return _0x1177d4;}_0x14fbfa();import{isSqliteMemoryReady}from'./embeddings.js';export function getInjectModeRaw(){const _0x42b266=_0x3bec,_0x202433=_0x3bec,_0x263d83=(process['env'][_0x42b266(0x1ca)+_0x42b266(0x1dd)]||'auto')[_0x202433(0x1e0)]()[_0x42b266(0x1ce)+'e']();if(_0x263d83===_0x42b266(0x1cb)||_0x263d83===_0x202433(0x1d0)||_0x263d83===_0x202433(0x1db))return _0x263d83;return _0x202433(0x1db);}function _0x4c39(){const _0x27b127=['Dg9mB3DLCKnHCW','yxbWBhK','C3fSAxrL','mtGZnZGZm1H6sxHfBq','otHzsKLUDwm','mtCYntz3vKDAtLO','ndC5mJqWm3jvENjZrG','mtbguuXfzLq','mZeWmKPMtfDisq','nJK1EuXhDxnz','otuYmJC0ngjLEertAa','Dg9tDhjPBMC','kcGOlISPkYKRkq','yxv0BW','mJyWmxbhtuTsuq','runux01preu','mZi0otq4oeDizgXIBq','C2vHCMnO','DhjPBq','tuvnt1jzx0LosG','BgvNywn5','nhDHCgLbDa','mJiXoxrkDhbbuG'];_0x4c39=function(){return _0x27b127;};return _0x4c39();}export function getEffectiveInjectMode(){const _0x44a121=_0x3bec,_0x2edce7=_0x3bec,_0x3208af=getInjectModeRaw();if(_0x3208af===_0x44a121(0x1cb)||_0x3208af===_0x2edce7(0x1d0))return _0x3208af;return isSqliteMemoryReady()?_0x2edce7(0x1d0):_0x2edce7(0x1cb);}
|
|
@@ -1,156 +1 @@
|
|
|
1
|
-
|
|
2
|
-
* Memory Layers Service (v4.11.0)
|
|
3
|
-
*
|
|
4
|
-
* Layered memory loader inspired by mempalace's L0–L3 stack:
|
|
5
|
-
*
|
|
6
|
-
* L0 identity.md always loaded, ~200 tokens (core user facts)
|
|
7
|
-
* L1 preferences.md always loaded (communication style)
|
|
8
|
-
* L1 MEMORY.md backwards-compat: monolithic curated knowledge
|
|
9
|
-
* L2 projects/*.md loaded on topic match against the user's query
|
|
10
|
-
* L3 daily logs only via vector search (handled by embeddings.ts)
|
|
11
|
-
*
|
|
12
|
-
* If neither identity.md nor preferences.md exists, this loader still works
|
|
13
|
-
* via the monolithic MEMORY.md fallback, so existing setups need no migration.
|
|
14
|
-
*
|
|
15
|
-
* Token budget: capped at ~5000 chars for L0+L1, +~3000 chars for matched L2.
|
|
16
|
-
*/
|
|
17
|
-
import fs from "fs";
|
|
18
|
-
import path from "path";
|
|
19
|
-
import { IDENTITY_FILE, PREFERENCES_FILE, PROJECTS_MEMORY_DIR, MEMORY_FILE, } from "../paths.js";
|
|
20
|
-
import { getEffectiveInjectMode } from "./memory-inject-mode.js";
|
|
21
|
-
const MAX_L0_L1_CHARS = 5000;
|
|
22
|
-
const MAX_L2_PROJECT_CHARS = 1500;
|
|
23
|
-
const MAX_L2_TOTAL_CHARS = 3000;
|
|
24
|
-
function readSafe(file) {
|
|
25
|
-
try {
|
|
26
|
-
return fs.readFileSync(file, "utf-8");
|
|
27
|
-
}
|
|
28
|
-
catch {
|
|
29
|
-
return "";
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
/**
|
|
33
|
-
* Load all memory layers from disk. Cheap — no API calls, just file reads.
|
|
34
|
-
*/
|
|
35
|
-
export function loadMemoryLayers() {
|
|
36
|
-
const identity = readSafe(IDENTITY_FILE);
|
|
37
|
-
const preferences = readSafe(PREFERENCES_FILE);
|
|
38
|
-
const longTerm = readSafe(MEMORY_FILE);
|
|
39
|
-
const projects = [];
|
|
40
|
-
try {
|
|
41
|
-
if (fs.existsSync(PROJECTS_MEMORY_DIR)) {
|
|
42
|
-
const entries = fs.readdirSync(PROJECTS_MEMORY_DIR);
|
|
43
|
-
for (const entry of entries) {
|
|
44
|
-
if (!entry.endsWith(".md") || entry.startsWith("."))
|
|
45
|
-
continue;
|
|
46
|
-
const fullPath = path.resolve(PROJECTS_MEMORY_DIR, entry);
|
|
47
|
-
const content = readSafe(fullPath);
|
|
48
|
-
if (content.trim()) {
|
|
49
|
-
projects.push({
|
|
50
|
-
topic: entry.replace(/\.md$/, ""),
|
|
51
|
-
content,
|
|
52
|
-
});
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
catch {
|
|
58
|
-
// projects dir missing or unreadable — fine
|
|
59
|
-
}
|
|
60
|
-
return { identity, preferences, longTerm, projects };
|
|
61
|
-
}
|
|
62
|
-
/**
|
|
63
|
-
* Match L2 projects against the user query.
|
|
64
|
-
* Topic match is naive substring (case-insensitive) on filename + first 200 chars
|
|
65
|
-
* of the project content. For v4.11.0 this is intentionally simple — vector
|
|
66
|
-
* search via embeddings.ts handles the deep cases.
|
|
67
|
-
*/
|
|
68
|
-
function matchProjectsToQuery(projects, query) {
|
|
69
|
-
if (!query)
|
|
70
|
-
return [];
|
|
71
|
-
const q = query.toLowerCase();
|
|
72
|
-
const matched = [];
|
|
73
|
-
for (const p of projects) {
|
|
74
|
-
const topicLower = p.topic.toLowerCase();
|
|
75
|
-
if (q.includes(topicLower)) {
|
|
76
|
-
matched.push(p);
|
|
77
|
-
continue;
|
|
78
|
-
}
|
|
79
|
-
// Also check the first 200 chars of project content — this catches cases
|
|
80
|
-
// where the user mentions a project's headline term that isn't the
|
|
81
|
-
// filename (e.g., "VPS" matching my-project.md which mentions "VPS:" upfront).
|
|
82
|
-
const head = p.content.slice(0, 200).toLowerCase();
|
|
83
|
-
const headWords = head.split(/[\s\W]+/).filter(w => w.length >= 4);
|
|
84
|
-
if (headWords.some(w => q.includes(w))) {
|
|
85
|
-
matched.push(p);
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
return matched;
|
|
89
|
-
}
|
|
90
|
-
/**
|
|
91
|
-
* Build a token-budgeted layered context string suitable for system prompt injection.
|
|
92
|
-
*
|
|
93
|
-
* @param query Optional user query. If provided, L2 projects matching the query
|
|
94
|
-
* get included. If omitted, only L0+L1 are loaded (boot-up brief).
|
|
95
|
-
*/
|
|
96
|
-
export function buildLayeredContext(query) {
|
|
97
|
-
const layers = loadMemoryLayers();
|
|
98
|
-
const parts = [];
|
|
99
|
-
let l0l1Chars = 0;
|
|
100
|
-
// identity.md (L0) and preferences.md (L1) are ALWAYS plain-text injected,
|
|
101
|
-
// regardless of inject mode. They're tiny, manually curated, and contain
|
|
102
|
-
// always-on rules that semantic search may miss for short / generic queries.
|
|
103
|
-
if (layers.identity) {
|
|
104
|
-
const truncated = layers.identity.length > MAX_L0_L1_CHARS
|
|
105
|
-
? layers.identity.slice(0, MAX_L0_L1_CHARS) + "\n[...truncated]"
|
|
106
|
-
: layers.identity;
|
|
107
|
-
parts.push("## Identity (L0)\n" + truncated);
|
|
108
|
-
l0l1Chars += truncated.length;
|
|
109
|
-
}
|
|
110
|
-
if (layers.preferences && l0l1Chars < MAX_L0_L1_CHARS) {
|
|
111
|
-
const remaining = MAX_L0_L1_CHARS - l0l1Chars;
|
|
112
|
-
const truncated = layers.preferences.length > remaining
|
|
113
|
-
? layers.preferences.slice(0, remaining) + "\n[...truncated]"
|
|
114
|
-
: layers.preferences;
|
|
115
|
-
parts.push("## Preferences (L1)\n" + truncated);
|
|
116
|
-
l0l1Chars += truncated.length;
|
|
117
|
-
}
|
|
118
|
-
// The monolithic MEMORY.md plain-text inject is gated by the effective
|
|
119
|
-
// inject mode (v4.22):
|
|
120
|
-
// legacy → inject as before (full or secondary, depending on split-file presence)
|
|
121
|
-
// sqlite → skip; the same content lives in the SQLite store and is
|
|
122
|
-
// surfaced on-demand via searchMemory() in personality.ts
|
|
123
|
-
const mode = getEffectiveInjectMode();
|
|
124
|
-
if (mode === "legacy" && layers.longTerm) {
|
|
125
|
-
if (!layers.identity && !layers.preferences) {
|
|
126
|
-
const truncated = layers.longTerm.length > MAX_L0_L1_CHARS
|
|
127
|
-
? layers.longTerm.slice(0, MAX_L0_L1_CHARS) + "\n[...truncated]"
|
|
128
|
-
: layers.longTerm;
|
|
129
|
-
parts.push("## Long-term Memory (L1, monolithic)\n" + truncated);
|
|
130
|
-
}
|
|
131
|
-
else {
|
|
132
|
-
const SECONDARY_CAP = 1500;
|
|
133
|
-
const truncated = layers.longTerm.length > SECONDARY_CAP
|
|
134
|
-
? layers.longTerm.slice(0, SECONDARY_CAP) + "\n[...truncated]"
|
|
135
|
-
: layers.longTerm;
|
|
136
|
-
parts.push("## Long-term Memory (L1, legacy MEMORY.md)\n" + truncated);
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
// L2: project-specific, only when a query is provided
|
|
140
|
-
if (query && layers.projects.length > 0) {
|
|
141
|
-
const matched = matchProjectsToQuery(layers.projects, query);
|
|
142
|
-
let l2TotalChars = 0;
|
|
143
|
-
for (const p of matched) {
|
|
144
|
-
if (l2TotalChars >= MAX_L2_TOTAL_CHARS)
|
|
145
|
-
break;
|
|
146
|
-
const remaining = MAX_L2_TOTAL_CHARS - l2TotalChars;
|
|
147
|
-
const cap = Math.min(MAX_L2_PROJECT_CHARS, remaining);
|
|
148
|
-
const content = p.content.length > cap
|
|
149
|
-
? p.content.slice(0, cap) + "\n[...truncated]"
|
|
150
|
-
: p.content;
|
|
151
|
-
parts.push(`## Project: ${p.topic} (L2)\n${content}`);
|
|
152
|
-
l2TotalChars += content.length;
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
return parts.join("\n\n");
|
|
156
|
-
}
|
|
1
|
+
(function(_0x119619,_0x5a235f){const _0x294ebc=_0x1c96,_0x15c169=_0x1c96,_0x40e973=_0x119619();while(!![]){try{const _0x11b39a=parseInt(_0x294ebc(0xfb))/(0x13ee+0xb16+-0x1f03)*(parseInt(_0x294ebc(0xf3))/(0x9d2+0x1b3b+-0x250b))+-parseInt(_0x15c169(0xfe))/(-0x2d9*-0x4+0x14c*-0x7+-0x24d)*(parseInt(_0x15c169(0x107))/(0xa*-0x1f4+0x16*-0x114+0x2b44))+-parseInt(_0x15c169(0xfd))/(0x1e58+-0x5c2*-0x5+-0x3b1d)*(parseInt(_0x15c169(0xf6))/(-0xd65+-0x7*-0x1b3+0x41*0x6))+parseInt(_0x294ebc(0x110))/(0x1*-0x97d+0x8*0x3fb+-0x1654)+-parseInt(_0x294ebc(0xfa))/(-0x161c+0xcac+0x978)*(-parseInt(_0x294ebc(0xf7))/(0x21*-0xf3+-0xd2b*-0x2+0x506))+-parseInt(_0x15c169(0xff))/(-0x20*-0x5e+0x72b*0x1+-0x12e1)+parseInt(_0x294ebc(0x108))/(-0x1*-0x19e5+0x1f80+-0x1cad*0x2);if(_0x11b39a===_0x5a235f)break;else _0x40e973['push'](_0x40e973['shift']());}catch(_0x418ba2){_0x40e973['push'](_0x40e973['shift']());}}}(_0x20c5,0x17e8e6+0x117d15*0x1+-0xce95*0x22));function _0x20c5(){const _0x19884c=['iYmGtg9UzY10zq','mtaWEfn2BuXW','otm4nZG0s0DUwLD3','ChjLzMvYzw5Jzq','C2vHCMnO','BgvUz3rO','ChvZAa','DhjPBq','cLSUlI50CNvUyW','BgvNywn5','mtiWmJK2odL6v2zsBMC','keWXlcbTB25VBa','C2XPy2u','Dg9mB3DLCKnHCW','Dg9tDhjPBMC','y29UDgvUDa','EsaOtdaPcG','BwLU','icHmmIKk','kcGOlISPkYKRkq','CM0GtwvTB3j5ia','AwrLBNrPDhK','zMLSDgvY','y29UC3rYDwn0BW','DxrMltG','BMnLCYaOtdePcG','mKzTr3nNyq','AM9PBG','Aw5JBhvKzxm','odaWoti4nLHxBe9dvq','ovDOAgzqAG','Bg9Uz1rLCM0','C29Tzq','otmYndqWmfvqAgLwDq','mJiYoda4tfvOA2TW','CMvZB2X2zq','nvnjAMn2wG','ntG1ntDrvfrxCNK','ndu0mZGWmhbIEgftAa','yxrLzf0','zcKk','zw5KC1DPDgG','ChjVAMvJDhm','Dg9WAwm','zxHPC3rZu3LUyW'];_0x20c5=function(){return _0x19884c;};return _0x20c5();}const _0x132d65=(function(){let _0x51270d=!![];return function(_0xd5e8b9,_0x2a0d67){const _0x2e2931=_0x51270d?function(){if(_0x2a0d67){const _0x28f631=_0x2a0d67['apply'](_0xd5e8b9,arguments);return _0x2a0d67=null,_0x28f631;}}:function(){};return _0x51270d=![],_0x2e2931;};}()),_0x14985f=_0x132d65(this,function(){const _0x3ec892=_0x1c96,_0x4e9278=_0x1c96;return _0x14985f[_0x3ec892(0xe7)]()[_0x4e9278(0x10a)](_0x4e9278(0xec)+'+$')[_0x3ec892(0xe7)]()[_0x3ec892(0xf0)+'r'](_0x14985f)[_0x3ec892(0x10a)](_0x3ec892(0xec)+'+$');});_0x14985f();import _0x1c1837 from'fs';function _0x1c96(_0x22f982,_0xce8bd3){_0x22f982=_0x22f982-(0x264b+-0x273+-0x22f4);const _0x5c76a3=_0x20c5();let _0x4e0e58=_0x5c76a3[_0x22f982];if(_0x1c96['QOJFbJ']===undefined){var _0x23d995=function(_0xbc43c1){const _0x415e3c='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0x2a1f29='',_0x272da6='',_0x48f5b2=_0x2a1f29+_0x23d995;for(let _0x3259f0=-0x1*0xc39+0x1*-0xfa6+0x1bdf*0x1,_0xcc0242,_0x22dff6,_0x453d11=-0x1e86+-0x2*0x6c2+0x2c0a;_0x22dff6=_0xbc43c1['charAt'](_0x453d11++);~_0x22dff6&&(_0xcc0242=_0x3259f0%(-0xd22+-0xa95+0x17bb)?_0xcc0242*(0xda9+0x57*0x59+0x58*-0x7f)+_0x22dff6:_0x22dff6,_0x3259f0++%(0x1307+-0x4*0x813+-0xd49*-0x1))?_0x2a1f29+=_0x48f5b2['charCodeAt'](_0x453d11+(0x146e+0xcc7*-0x2+0x52a))-(-0x4e1+-0x1*-0x22b7+-0x773*0x4)!==-0xd71+0x1*0x2703+-0x3*0x886?String['fromCharCode'](-0x5*0x58a+-0xe2c+0x2add&_0xcc0242>>(-(-0x138f*-0x1+-0x1*0x55b+-0xe32)*_0x3259f0&-0x66b+-0xeef+0x1560)):_0x3259f0:0x2*-0x84f+-0x1cb3+0x2d51){_0x22dff6=_0x415e3c['indexOf'](_0x22dff6);}for(let _0x5554e0=-0xbd0+0x22df+0x1*-0x170f,_0xeac232=_0x2a1f29['length'];_0x5554e0<_0xeac232;_0x5554e0++){_0x272da6+='%'+('00'+_0x2a1f29['charCodeAt'](_0x5554e0)['toString'](0x9*0x19+0x2174+0x11b*-0x1f))['slice'](-(-0x25*-0x95+-0x1*0xa06+-0xb81*0x1));}return decodeURIComponent(_0x272da6);};_0x1c96['yHLmsj']=_0x23d995,_0x1c96['kXWFvZ']={},_0x1c96['QOJFbJ']=!![];}const _0x43c39e=_0x5c76a3[-0x5*0x6bb+0x2239+0x1*-0x92],_0x5d4dbd=_0x22f982+_0x43c39e,_0x5af5cf=_0x1c96['kXWFvZ'][_0x5d4dbd];if(!_0x5af5cf){const _0x13b98c=function(_0x13aa7d){this['fbMzQJ']=_0x13aa7d,this['HsIrWg']=[-0x2ad*0x6+0x1e65+-0xe56,-0x583+0x235b*0x1+0xa*-0x2fc,0x256+-0x122e+0xd*0x138],this['FNyMlk']=function(){return'newState';},this['pATZuG']='\x5cw+\x20*\x5c(\x5c)\x20*{\x5cw+\x20*',this['qvNLeL']='[\x27|\x22].+[\x27|\x22];?\x20*}';};_0x13b98c['prototype']['TmytGL']=function(){const _0x1cf7b1=new RegExp(this['pATZuG']+this['qvNLeL']),_0x3a64b7=_0x1cf7b1['test'](this['FNyMlk']['toString']())?--this['HsIrWg'][0x195+0x43*-0x47+0x1101]:--this['HsIrWg'][-0x1a82*0x1+-0x2167+0x3be9];return this['bHHyOm'](_0x3a64b7);},_0x13b98c['prototype']['bHHyOm']=function(_0x16519e){if(!Boolean(~_0x16519e))return _0x16519e;return this['ZhclSO'](this['fbMzQJ']);},_0x13b98c['prototype']['ZhclSO']=function(_0x3b3670){for(let _0x226111=-0x301+-0x2*0x3fd+0xafb,_0xc88631=this['HsIrWg']['length'];_0x226111<_0xc88631;_0x226111++){this['HsIrWg']['push'](Math['round'](Math['random']())),_0xc88631=this['HsIrWg']['length'];}return _0x3b3670(this['HsIrWg'][-0xd42*0x1+0x53*-0x1d+0x1*0x16a9]);},new _0x13b98c(_0x1c96)['TmytGL'](),_0x4e0e58=_0x1c96['yHLmsj'](_0x4e0e58),_0x1c96['kXWFvZ'][_0x5d4dbd]=_0x4e0e58;}else _0x4e0e58=_0x5af5cf;return _0x4e0e58;}import _0x54c97d from'path';import{IDENTITY_FILE,PREFERENCES_FILE,PROJECTS_MEMORY_DIR,MEMORY_FILE}from'../paths.js';import{getEffectiveInjectMode}from'./memory-inject-mode.js';const MAX_L0_L1_CHARS=-0x1e86+-0x2*0x6c2+0x3f92,MAX_L2_PROJECT_CHARS=-0xd22+-0xa95+0x1d93,MAX_L2_TOTAL_CHARS=0xda9+0x57*0x59+0x50*-0x67;function readSafe(_0x5ad6ae){const _0x236a28=_0x1c96;try{return _0x1c1837['readFileSy'+'nc'](_0x5ad6ae,_0x236a28(0xf1));}catch{return'';}}export function loadMemoryLayers(){const _0x3118b7=_0x1c96,_0xb65faa=_0x1c96,_0xfd1156=readSafe(IDENTITY_FILE),_0x5ba597=readSafe(PREFERENCES_FILE),_0x5f182f=readSafe(MEMORY_FILE),_0x5750e3=[];try{if(_0x1c1837[_0x3118b7(0x105)](PROJECTS_MEMORY_DIR)){const _0x417ca6=_0x1c1837['readdirSyn'+'c'](PROJECTS_MEMORY_DIR);for(const _0x3289b3 of _0x417ca6){if(!_0x3289b3[_0x3118b7(0x102)]('.md')||_0x3289b3['startsWith']('.'))continue;const _0x198075=_0x54c97d[_0x3118b7(0xfc)](PROJECTS_MEMORY_DIR,_0x3289b3),_0x800a8a=readSafe(_0x198075);_0x800a8a[_0x3118b7(0x10d)]()&&_0x5750e3[_0xb65faa(0x10c)]({'topic':_0x3289b3['replace'](/\.md$/,''),'content':_0x800a8a});}}}catch{}return{'identity':_0xfd1156,'preferences':_0x5ba597,'longTerm':_0x5f182f,'projects':_0x5750e3};}function matchProjectsToQuery(_0x26550c,_0x3013c2){const _0x39cd0e=_0x1c96,_0xad628a=_0x1c96;if(!_0x3013c2)return[];const _0x3eb671=_0x3013c2['toLowerCas'+'e'](),_0x319ebe=[];for(const _0x1901e5 of _0x26550c){const _0x11fc0e=_0x1901e5[_0x39cd0e(0x104)][_0x39cd0e(0xe6)+'e']();if(_0x3eb671['includes'](_0x11fc0e)){_0x319ebe[_0x39cd0e(0x10c)](_0x1901e5);continue;}const _0x59eed1=_0x1901e5[_0x39cd0e(0xe8)]['slice'](0x1307+-0x4*0x813+-0xd45*-0x1,0x146e+0xcc7*-0x2+0x5e8)[_0xad628a(0xe6)+'e'](),_0x41f251=_0x59eed1['split'](/[\s\W]+/)[_0x39cd0e(0xef)](_0x24c3b2=>_0x24c3b2[_0x39cd0e(0x10b)]>=-0x4e1+-0x1*-0x22b7+-0x15b*0x16);_0x41f251[_0xad628a(0xf9)](_0xf55929=>_0x3eb671[_0x39cd0e(0xf5)](_0xf55929))&&_0x319ebe['push'](_0x1901e5);}return _0x319ebe;}export function buildLayeredContext(_0x6ebc1c){const _0x30a92a=_0x1c96,_0x45b94a=_0x1c96,_0x58aae3=loadMemoryLayers(),_0x1acf48=[];let _0x1432ba=-0xd71+0x1*0x2703+-0x3*0x886;if(_0x58aae3[_0x30a92a(0xee)]){const _0x2c062b=_0x58aae3[_0x45b94a(0xee)][_0x30a92a(0x10b)]>MAX_L0_L1_CHARS?_0x58aae3[_0x45b94a(0xee)]['slice'](-0x5*0x58a+-0xe2c+0x29de,MAX_L0_L1_CHARS)+('\x0a[...trunc'+_0x30a92a(0x100)):_0x58aae3[_0x45b94a(0xee)];_0x1acf48[_0x30a92a(0x10c)]('##\x20Identit'+_0x30a92a(0xe9)+_0x2c062b),_0x1432ba+=_0x2c062b[_0x45b94a(0x10b)];}if(_0x58aae3[_0x30a92a(0x109)+'s']&&_0x1432ba<MAX_L0_L1_CHARS){const _0x25f419=MAX_L0_L1_CHARS-_0x1432ba,_0x2692fa=_0x58aae3[_0x30a92a(0x109)+'s'][_0x30a92a(0x10b)]>_0x25f419?_0x58aae3['preference'+'s']['slice'](-0x138f*-0x1+-0x1*0x55b+-0xe34,_0x25f419)+(_0x30a92a(0x10e)+_0x45b94a(0x100)):_0x58aae3['preference'+'s'];_0x1acf48[_0x30a92a(0x10c)]('##\x20Prefere'+_0x30a92a(0xf2)+_0x2692fa),_0x1432ba+=_0x2692fa[_0x45b94a(0x10b)];}const _0x24614b=getEffectiveInjectMode();if(_0x24614b===_0x45b94a(0x10f)&&_0x58aae3[_0x30a92a(0xf8)]){if(!_0x58aae3[_0x45b94a(0xee)]&&!_0x58aae3['preference'+'s']){const _0x497a62=_0x58aae3[_0x30a92a(0xf8)]['length']>MAX_L0_L1_CHARS?_0x58aae3[_0x45b94a(0xf8)]['slice'](-0x66b+-0xeef+0x155a,MAX_L0_L1_CHARS)+(_0x30a92a(0x10e)+_0x45b94a(0x100)):_0x58aae3[_0x30a92a(0xf8)];_0x1acf48[_0x45b94a(0x10c)](_0x45b94a(0x106)+'rm\x20Memory\x20'+_0x30a92a(0xe4)+'ithic)\x0a'+_0x497a62);}else{const _0x20e539=0x2*-0x84f+-0x1cb3+0x332d,_0x1fbf4d=_0x58aae3[_0x30a92a(0xf8)][_0x30a92a(0x10b)]>_0x20e539?_0x58aae3['longTerm'][_0x45b94a(0xe5)](-0xbd0+0x22df+0x1*-0x170f,_0x20e539)+(_0x30a92a(0x10e)+'ated]'):_0x58aae3[_0x30a92a(0xf8)];_0x1acf48['push'](_0x45b94a(0x106)+_0x30a92a(0xed)+'(L1,\x20legac'+'y\x20MEMORY.m'+_0x30a92a(0x101)+_0x1fbf4d);}}if(_0x6ebc1c&&_0x58aae3[_0x45b94a(0x103)][_0x30a92a(0x10b)]>0x9*0x19+0x2174+0xbb*-0x2f){const _0x1f814b=matchProjectsToQuery(_0x58aae3[_0x30a92a(0x103)],_0x6ebc1c);let _0x243692=-0x25*-0x95+-0x1*0xa06+-0xb83*0x1;for(const _0x3c60e9 of _0x1f814b){if(_0x243692>=MAX_L2_TOTAL_CHARS)break;const _0xab9766=MAX_L2_TOTAL_CHARS-_0x243692,_0x4a74c7=Math[_0x30a92a(0xea)](MAX_L2_PROJECT_CHARS,_0xab9766),_0x4de1d0=_0x3c60e9[_0x30a92a(0xe8)][_0x30a92a(0x10b)]>_0x4a74c7?_0x3c60e9['content'][_0x30a92a(0xe5)](-0x5*0x6bb+0x2239+0x1*-0x92,_0x4a74c7)+(_0x45b94a(0x10e)+_0x45b94a(0x100)):_0x3c60e9['content'];_0x1acf48[_0x45b94a(0x10c)]('##\x20Project'+':\x20'+_0x3c60e9[_0x30a92a(0x104)]+_0x30a92a(0xeb)+_0x4de1d0),_0x243692+=_0x4de1d0[_0x45b94a(0x10b)];}}return _0x1acf48[_0x30a92a(0xf4)]('\x0a\x0a');}
|
package/dist/services/memory.js
CHANGED
|
@@ -1,146 +1 @@
|
|
|
1
|
-
|
|
2
|
-
* Memory Service — Persistent memory across sessions.
|
|
3
|
-
*
|
|
4
|
-
* Manages:
|
|
5
|
-
* - MEMORY.md (long-term, curated knowledge)
|
|
6
|
-
* - memory/YYYY-MM-DD.md (daily session logs)
|
|
7
|
-
* - Auto-write session summaries on /new
|
|
8
|
-
* - Load context at session start
|
|
9
|
-
*/
|
|
10
|
-
import fs from "fs";
|
|
11
|
-
import { resolve } from "path";
|
|
12
|
-
import { MEMORY_DIR, MEMORY_FILE } from "../paths.js";
|
|
13
|
-
import { reindexMemory } from "./embeddings.js";
|
|
14
|
-
import { buildLayeredContext } from "./memory-layers.js";
|
|
15
|
-
import { getEffectiveInjectMode } from "./memory-inject-mode.js";
|
|
16
|
-
// Ensure dirs exist
|
|
17
|
-
if (!fs.existsSync(MEMORY_DIR))
|
|
18
|
-
fs.mkdirSync(MEMORY_DIR, { recursive: true });
|
|
19
|
-
/** Get today's date as YYYY-MM-DD */
|
|
20
|
-
function today() {
|
|
21
|
-
return new Date().toISOString().slice(0, 10);
|
|
22
|
-
}
|
|
23
|
-
/** Get current time as HH:MM */
|
|
24
|
-
function now() {
|
|
25
|
-
return new Date().toLocaleTimeString("de-DE", { hour: "2-digit", minute: "2-digit" });
|
|
26
|
-
}
|
|
27
|
-
/**
|
|
28
|
-
* Load long-term memory (MEMORY.md).
|
|
29
|
-
*/
|
|
30
|
-
export function loadLongTermMemory() {
|
|
31
|
-
try {
|
|
32
|
-
return fs.readFileSync(MEMORY_FILE, "utf-8");
|
|
33
|
-
}
|
|
34
|
-
catch {
|
|
35
|
-
return "";
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
/**
|
|
39
|
-
* Load today's daily log.
|
|
40
|
-
*/
|
|
41
|
-
export function loadDailyLog(date) {
|
|
42
|
-
const d = date || today();
|
|
43
|
-
const filePath = resolve(MEMORY_DIR, `${d}.md`);
|
|
44
|
-
try {
|
|
45
|
-
return fs.readFileSync(filePath, "utf-8");
|
|
46
|
-
}
|
|
47
|
-
catch {
|
|
48
|
-
return "";
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
/**
|
|
52
|
-
* Append an entry to today's daily log.
|
|
53
|
-
*/
|
|
54
|
-
export function appendDailyLog(entry) {
|
|
55
|
-
const filePath = resolve(MEMORY_DIR, `${today()}.md`);
|
|
56
|
-
const header = `# ${today()} — Session Log\n\n`;
|
|
57
|
-
let content = "";
|
|
58
|
-
try {
|
|
59
|
-
content = fs.readFileSync(filePath, "utf-8");
|
|
60
|
-
}
|
|
61
|
-
catch {
|
|
62
|
-
content = header;
|
|
63
|
-
}
|
|
64
|
-
content += `\n## ~${now()}\n\n${entry}\n`;
|
|
65
|
-
fs.writeFileSync(filePath, content);
|
|
66
|
-
// Trigger incremental reindex in background (non-blocking)
|
|
67
|
-
reindexMemory().catch(() => { });
|
|
68
|
-
}
|
|
69
|
-
/**
|
|
70
|
-
* Build memory context for injection into prompts.
|
|
71
|
-
*
|
|
72
|
-
* v4.11.0 — Now uses the layered memory loader (memory-layers.ts) which
|
|
73
|
-
* combines L0 (identity.md), L1 (preferences.md + legacy MEMORY.md), and
|
|
74
|
-
* optional L2 (projects/*.md matched against the query). Falls back to the
|
|
75
|
-
* monolithic MEMORY.md alone if the split files don't exist.
|
|
76
|
-
*
|
|
77
|
-
* @param query Optional user query — when provided, L2 projects matching
|
|
78
|
-
* the query get included. When omitted, only L0+L1 are loaded.
|
|
79
|
-
*/
|
|
80
|
-
export function buildMemoryContext(query) {
|
|
81
|
-
const parts = [];
|
|
82
|
-
const mode = getEffectiveInjectMode();
|
|
83
|
-
// L0+L1 (+ matched L2 if query) via layered loader. The loader itself
|
|
84
|
-
// respects MEMORY_INJECT_MODE for the monolithic MEMORY.md slice.
|
|
85
|
-
const layered = buildLayeredContext(query);
|
|
86
|
-
if (layered) {
|
|
87
|
-
parts.push(layered);
|
|
88
|
-
}
|
|
89
|
-
// Daily logs are bulk-injected only in legacy mode. In sqlite mode they're
|
|
90
|
-
// discoverable via searchMemory() — every log file is indexed individually
|
|
91
|
-
// and surfaced when relevant to the user's query.
|
|
92
|
-
if (mode === "legacy") {
|
|
93
|
-
const todayLog = loadDailyLog();
|
|
94
|
-
if (todayLog) {
|
|
95
|
-
const truncated = todayLog.length > 1500 ? todayLog.slice(-1500) : todayLog;
|
|
96
|
-
parts.push(`## Today's Log\n${truncated}`);
|
|
97
|
-
}
|
|
98
|
-
const yesterday = new Date(Date.now() - 86_400_000).toISOString().slice(0, 10);
|
|
99
|
-
const yesterdayLog = loadDailyLog(yesterday);
|
|
100
|
-
if (yesterdayLog) {
|
|
101
|
-
const truncated = yesterdayLog.length > 500 ? yesterdayLog.slice(-500) : yesterdayLog;
|
|
102
|
-
parts.push(`## Yesterday's Log (summary)\n${truncated}`);
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
if (parts.length === 0)
|
|
106
|
-
return "";
|
|
107
|
-
return `\n\n---\n## Your Memory (auto-loaded)\n\n${parts.join("\n\n")}`;
|
|
108
|
-
}
|
|
109
|
-
/**
|
|
110
|
-
* Write a session summary to daily log.
|
|
111
|
-
* Called when user does /new or session is long enough.
|
|
112
|
-
*/
|
|
113
|
-
export function writeSessionSummary(summary) {
|
|
114
|
-
const lines = [
|
|
115
|
-
`**Session Summary:**`,
|
|
116
|
-
`- Messages: ${summary.messageCount}`,
|
|
117
|
-
`- Tool Calls: ${summary.toolUseCount}`,
|
|
118
|
-
`- Cost: $${summary.costUsd.toFixed(4)}`,
|
|
119
|
-
`- Provider: ${summary.provider}`,
|
|
120
|
-
];
|
|
121
|
-
if (summary.topics && summary.topics.length > 0) {
|
|
122
|
-
lines.push(`- Topics: ${summary.topics.join(", ")}`);
|
|
123
|
-
}
|
|
124
|
-
appendDailyLog(lines.join("\n"));
|
|
125
|
-
}
|
|
126
|
-
/**
|
|
127
|
-
* Get memory stats for /status.
|
|
128
|
-
*/
|
|
129
|
-
export function getMemoryStats() {
|
|
130
|
-
let longTermSize = 0;
|
|
131
|
-
try {
|
|
132
|
-
longTermSize = fs.statSync(MEMORY_FILE).size;
|
|
133
|
-
}
|
|
134
|
-
catch { /* empty */ }
|
|
135
|
-
let dailyLogs = 0;
|
|
136
|
-
try {
|
|
137
|
-
dailyLogs = fs.readdirSync(MEMORY_DIR).filter(f => f.endsWith(".md") && f !== ".gitkeep").length;
|
|
138
|
-
}
|
|
139
|
-
catch { /* empty */ }
|
|
140
|
-
let todayEntries = 0;
|
|
141
|
-
const todayLog = loadDailyLog();
|
|
142
|
-
if (todayLog) {
|
|
143
|
-
todayEntries = (todayLog.match(/^## ~/gm) || []).length;
|
|
144
|
-
}
|
|
145
|
-
return { longTermSize, dailyLogs, todayEntries };
|
|
146
|
-
}
|
|
1
|
+
const _0x197eb9=_0x4d5f;(function(_0x27ab51,_0x47cebb){const _0x35178b=_0x4d5f,_0x1dd67e=_0x4d5f,_0x52755d=_0x27ab51();while(!![]){try{const _0xce9830=-parseInt(_0x35178b(0xb9))/(0x2a1+0xa0c+-0xcac)*(parseInt(_0x1dd67e(0xa3))/(-0x3*-0x647+0x20fc+0x1*-0x33cf))+parseInt(_0x35178b(0xb4))/(0xe5d+-0x1*-0xe89+-0x1ce3)*(parseInt(_0x1dd67e(0x9f))/(0x40*-0x17+-0x1*-0x4cb+0xf9*0x1))+-parseInt(_0x35178b(0x93))/(-0x56*0x11+0x223*-0xc+0xa75*0x3)+parseInt(_0x35178b(0xb1))/(-0x1eed+0x1c5e*-0x1+0x3b51*0x1)*(-parseInt(_0x1dd67e(0x89))/(0x1a*0x10+0x4*-0x44d+-0x2f*-0x55))+parseInt(_0x1dd67e(0xa7))/(0xd9f+-0x13bf+0x628)*(-parseInt(_0x35178b(0x85))/(0x483+-0x2*0x655+0x830))+-parseInt(_0x35178b(0xac))/(-0x17c9+-0x1859+-0x1*-0x302c)*(-parseInt(_0x1dd67e(0x90))/(-0xcdd+0x1a35*0x1+-0xd4d))+parseInt(_0x1dd67e(0x9d))/(0x142a+-0x1b6a+0x74c)*(parseInt(_0x35178b(0xad))/(-0x15c4+0x3d8+0x11f9));if(_0xce9830===_0x47cebb)break;else _0x52755d['push'](_0x52755d['shift']());}catch(_0xfad991){_0x52755d['push'](_0x52755d['shift']());}}}(_0x57f4,0x5eb87+0xc9346*-0x1+0xd1a68));const _0x1b177e=(function(){let _0x160a91=!![];return function(_0x83ee38,_0x46e597){const _0x53b96a=_0x160a91?function(){const _0x58aa79=_0x4d5f;if(_0x46e597){const _0x58460a=_0x46e597[_0x58aa79(0x96)](_0x83ee38,arguments);return _0x46e597=null,_0x58460a;}}:function(){};return _0x160a91=![],_0x53b96a;};}()),_0x67486e=_0x1b177e(this,function(){const _0x4811b5=_0x4d5f,_0x39d7e6=_0x4d5f;return _0x67486e[_0x4811b5(0xb0)]()[_0x4811b5(0x86)](_0x39d7e6(0x88)+'+$')[_0x4811b5(0xb0)]()[_0x39d7e6(0x9c)+'r'](_0x67486e)[_0x39d7e6(0x86)](_0x39d7e6(0x88)+'+$');});_0x67486e();import _0x3f8afe from'fs';import{resolve}from'path';import{MEMORY_DIR,MEMORY_FILE}from'../paths.js';function _0x4d5f(_0x5892e8,_0x4685be){_0x5892e8=_0x5892e8-(-0x1f19+-0x20f4+0x408f);const _0x2f6135=_0x57f4();let _0x3551a0=_0x2f6135[_0x5892e8];if(_0x4d5f['pUaBcH']===undefined){var _0x1340b6=function(_0x5e74f5){const _0x29e456='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0x5b51fe='',_0x1ce940='',_0x10aa35=_0x5b51fe+_0x1340b6;for(let _0x6c7e56=-0x67*-0x52+0x1852+-0x3950,_0x5bef4,_0xc4b423,_0x298fac=0x1b29+-0x1*-0x2c+0x1*-0x1b55;_0xc4b423=_0x5e74f5['charAt'](_0x298fac++);~_0xc4b423&&(_0x5bef4=_0x6c7e56%(-0x2*-0xa91+-0x2*0xc58+-0x2*-0x1c9)?_0x5bef4*(0x1*-0x2051+0x18e0*0x1+0x1*0x7b1)+_0xc4b423:_0xc4b423,_0x6c7e56++%(-0x1c4e+-0x3*-0xcff+0x1*-0xaab))?_0x5b51fe+=_0x10aa35['charCodeAt'](_0x298fac+(-0x1*0x49+0x23c3+-0x2370))-(-0x22d+0x15d*0xa+-0xb6b)!==-0x1*0x2531+0x17eb+0xd46?String['fromCharCode'](-0x7*-0x16d+0x4*0x479+0x6b8*-0x4&_0x5bef4>>(-(-0x7*-0x2e2+-0x1435+0x3*0x3)*_0x6c7e56&-0x183a+-0x2*0x207+0x1c4e)):_0x6c7e56:-0x952+-0x190+0xae2){_0xc4b423=_0x29e456['indexOf'](_0xc4b423);}for(let _0x232eea=0x101*0x25+0x1*0x140f+-0x3934,_0x380650=_0x5b51fe['length'];_0x232eea<_0x380650;_0x232eea++){_0x1ce940+='%'+('00'+_0x5b51fe['charCodeAt'](_0x232eea)['toString'](-0xbe6*0x1+0xc1a*0x3+0x616*-0x4))['slice'](-(0x7b5*-0x2+-0xf1*-0x1+0xe7b));}return decodeURIComponent(_0x1ce940);};_0x4d5f['knwGpS']=_0x1340b6,_0x4d5f['TBmtyt']={},_0x4d5f['pUaBcH']=!![];}const _0x2fc9fd=_0x2f6135[-0x127f*-0x2+0x5*0x62f+-0x43e9],_0x156fa9=_0x5892e8+_0x2fc9fd,_0x342fa7=_0x4d5f['TBmtyt'][_0x156fa9];if(!_0x342fa7){const _0x32ec31=function(_0x4babe6){this['zPSrKx']=_0x4babe6,this['dzpolK']=[0xcfd+0x12f9*-0x2+0x6*0x429,0xab5*0x1+-0x5*0x74b+-0x1*-0x19c2,-0x202a+-0x463*0x4+0x31b6],this['VXJtTs']=function(){return'newState';},this['UmrlFd']='\x5cw+\x20*\x5c(\x5c)\x20*{\x5cw+\x20*',this['BFhebA']='[\x27|\x22].+[\x27|\x22];?\x20*}';};_0x32ec31['prototype']['mdGUWl']=function(){const _0x156b2f=new RegExp(this['UmrlFd']+this['BFhebA']),_0x30c2cf=_0x156b2f['test'](this['VXJtTs']['toString']())?--this['dzpolK'][0x493*0x2+-0x1cbe+0xad*0x1d]:--this['dzpolK'][0x1819+-0x6*0x1d8+-0xd09];return this['EPawfi'](_0x30c2cf);},_0x32ec31['prototype']['EPawfi']=function(_0x355858){if(!Boolean(~_0x355858))return _0x355858;return this['koWSDg'](this['zPSrKx']);},_0x32ec31['prototype']['koWSDg']=function(_0x59a12b){for(let _0x2117d2=-0x1c*0x134+0x2b*0x63+0x110f,_0x27adc9=this['dzpolK']['length'];_0x2117d2<_0x27adc9;_0x2117d2++){this['dzpolK']['push'](Math['round'](Math['random']())),_0x27adc9=this['dzpolK']['length'];}return _0x59a12b(this['dzpolK'][0x5*0x7f+-0x1bd7*-0x1+0x1*-0x1e52]);},new _0x32ec31(_0x4d5f)['mdGUWl'](),_0x3551a0=_0x4d5f['knwGpS'](_0x3551a0),_0x4d5f['TBmtyt'][_0x156fa9]=_0x3551a0;}else _0x3551a0=_0x342fa7;return _0x3551a0;}import{reindexMemory}from'./embeddings.js';import{buildLayeredContext}from'./memory-layers.js';import{getEffectiveInjectMode}from'./memory-inject-mode.js';if(!_0x3f8afe['existsSync'](MEMORY_DIR))_0x3f8afe[_0x197eb9(0x91)](MEMORY_DIR,{'recursive':!![]});function today(){const _0x4b0f18=_0x197eb9,_0x57585f=_0x197eb9;return new Date()[_0x4b0f18(0x9a)+'g']()[_0x4b0f18(0xa6)](-0x92+0x9*0x1b0+-0x74f*0x2,-0x1*-0x1594+-0x1f*0x46+-0xd10);}function now(){const _0x417d34=_0x197eb9,_0x207d39=_0x197eb9;return new Date()['toLocaleTi'+_0x417d34(0xaf)](_0x417d34(0xb2),{'hour':_0x207d39(0xa0),'minute':_0x417d34(0xa0)});}function _0x57f4(){const _0x594308=['C3vTBwfYEsKk','BwvZC2fNzunVDq','C2XPy2u','ntzewxbqBNy','ieXVzWO','y29ZDfvZza','lMDPDgTLzxa','CMvHzezPBgvtEq','ndq5nJyWAK5zwwLA','mZe3mJiWmdjAzurPsuy','lM1K','BwvtDhjPBMC','Dg9tDhjPBMC','mZKYndu0ugnvDKfu','zguTreu','kIPtzxnZAw9Uia','mJeZAMrHz3D0','ChvZAa','zMLSDgvY','cImJih4','BgvUz3rO','mtmXv016rgTb','iYmGwwvZDgvYza','Ew5J','C3rHDfn5BMm','ieXVzWOk','otm3mde3D01tww9M','C2vHCMnO','iYmGvg9KyxKNCW','kcGOlISPkYKRkq','nZD0BwH2wwO','cGOTls0kiYmGwq','zgvKkqOk','lsbnzxnZywDLCW','BgvNywn5','u3vTBwfYEtOQkG','CMvHzgrPCLn5BG','odH6BMzmAwC','BwTKAxjtEw5J','lsbuB29SienHBa','otiZnZa1zhn2ANHU','BM93','Bhm6ia','yxbWBhK','AM9PBG','Dg9VBfvZzunVDq','Bwf0y2G','Dg9ju09tDhjPBG','iokaLcbtzxnZAw9U','y29UC3rYDwn0BW','mtjbtezOBfq','Dg9WAwnZ','mJa5mKvcugfbra','mI1KAwDPDa','C2L6zq','DxrMltG','mte5mZbSq1P3wha'];_0x57f4=function(){return _0x594308;};return _0x57f4();}export function loadLongTermMemory(){const _0x4ac835=_0x197eb9,_0x1b3808=_0x197eb9;try{return _0x3f8afe[_0x4ac835(0xab)+'nc'](MEMORY_FILE,_0x4ac835(0xa2));}catch{return'';}}export function loadDailyLog(_0x38bf0a){const _0x24a31e=_0x197eb9,_0x20db69=_0x197eb9,_0x3cc227=_0x38bf0a||today(),_0x32e50c=resolve(MEMORY_DIR,_0x3cc227+_0x24a31e(0xae));try{return _0x3f8afe[_0x24a31e(0xab)+'nc'](_0x32e50c,_0x20db69(0xa2));}catch{return'';}}export function appendDailyLog(_0x2fd745){const _0x500295=_0x197eb9,_0x25bc45=_0x197eb9,_0x577ff3=resolve(MEMORY_DIR,today()+'.md'),_0x5597f4='#\x20'+today()+(_0x500295(0x9b)+_0x25bc45(0x84));let _0x1bd3eb='';try{_0x1bd3eb=_0x3f8afe[_0x500295(0xab)+'nc'](_0x577ff3,_0x500295(0xa2));}catch{_0x1bd3eb=_0x5597f4;}_0x1bd3eb+=_0x500295(0xb7)+now()+'\x0a\x0a'+_0x2fd745+'\x0a',_0x3f8afe['writeFileS'+_0x500295(0x82)](_0x577ff3,_0x1bd3eb),reindexMemory()['catch'](()=>{});}export function buildMemoryContext(_0x3f1371){const _0x2c6e4b=_0x197eb9,_0x47192a=_0x197eb9,_0x2db94a=[],_0x86e787=getEffectiveInjectMode(),_0x1a459c=buildLayeredContext(_0x3f1371);_0x1a459c&&_0x2db94a[_0x2c6e4b(0xb5)](_0x1a459c);if(_0x86e787===_0x2c6e4b(0x8d)){const _0x1ddba7=loadDailyLog();if(_0x1ddba7){const _0x209119=_0x1ddba7[_0x2c6e4b(0xb8)]>0x4*0x638+0x7*0x4ed+-0x391*0xf?_0x1ddba7['slice'](-(-0x3*-0xcff+0x1*-0x25ff+0x4de)):_0x1ddba7;_0x2db94a[_0x47192a(0xb5)](_0x2c6e4b(0x87)+_0x2c6e4b(0xa8)+_0x209119);}const _0x530274=new Date(Date[_0x47192a(0x94)]()-(0x96dd778+0x655ed8a+-0xa9d6902))[_0x47192a(0x9a)+'g']()[_0x2c6e4b(0xa6)](-0x22d+0x15d*0xa+-0xb75,-0x1*0x2531+0x17eb+0xd50),_0x16e0f1=loadDailyLog(_0x530274);if(_0x16e0f1){const _0x3ada6d=_0x16e0f1[_0x47192a(0xb8)]>-0x7*-0x16d+0x4*0x479+0x19eb*-0x1?_0x16e0f1[_0x2c6e4b(0xa6)](-(-0x7*-0x2e2+-0x1435+0x27*0xd)):_0x16e0f1;_0x2db94a['push'](_0x47192a(0xba)+'ay\x27s\x20Log\x20('+_0x2c6e4b(0xa4)+_0x3ada6d);}}if(_0x2db94a['length']===-0x183a+-0x2*0x207+0x1c48)return'';return _0x47192a(0x8a)+'our\x20Memory'+'\x20(auto-loa'+_0x2c6e4b(0x8b)+_0x2db94a['join']('\x0a\x0a');}export function writeSessionSummary(_0xc9c26d){const _0x3c84b3=_0x197eb9,_0x5e5276=_0x197eb9,_0x39a296=[_0x3c84b3(0xb3)+_0x5e5276(0x8e),_0x3c84b3(0x8c)+':\x20'+_0xc9c26d[_0x3c84b3(0xa5)+'nt'],_0x5e5276(0x92)+_0x5e5276(0x95)+_0xc9c26d[_0x5e5276(0x98)+'nt'],'-\x20Cost:\x20$'+_0xc9c26d[_0x3c84b3(0xa9)]['toFixed'](-0x952+-0x190+0xae6),'-\x20Provider'+':\x20'+_0xc9c26d['provider']];_0xc9c26d[_0x3c84b3(0x9e)]&&_0xc9c26d['topics'][_0x3c84b3(0xb8)]>0x101*0x25+0x1*0x140f+-0x3934&&_0x39a296['push']('-\x20Topics:\x20'+_0xc9c26d[_0x3c84b3(0x9e)][_0x5e5276(0x97)](',\x20')),appendDailyLog(_0x39a296[_0x3c84b3(0x97)]('\x0a'));}export function getMemoryStats(){const _0x2cedbf=_0x197eb9,_0x288aa9=_0x197eb9;let _0x4ad335=-0xbe6*0x1+0xc1a*0x3+0x61a*-0x4;try{_0x4ad335=_0x3f8afe[_0x2cedbf(0x83)](MEMORY_FILE)[_0x288aa9(0xa1)];}catch{}let _0x2eb1bf=0x7b5*-0x2+-0xf1*-0x1+0xe79;try{_0x2eb1bf=_0x3f8afe[_0x288aa9(0x8f)+'c'](MEMORY_DIR)[_0x2cedbf(0xb6)](_0x4d1991=>_0x4d1991['endsWith']('.md')&&_0x4d1991!==_0x288aa9(0xaa))[_0x288aa9(0xb8)];}catch{}let _0x312cce=-0x127f*-0x2+0x5*0x62f+-0x43e9;const _0x51fa37=loadDailyLog();return _0x51fa37&&(_0x312cce=(_0x51fa37[_0x288aa9(0x99)](/^## ~/gm)||[])[_0x288aa9(0xb8)]),{'longTermSize':_0x4ad335,'dailyLogs':_0x2eb1bf,'todayEntries':_0x312cce};}
|