zora-agent 0.9.4 → 0.9.6
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 +1 -1
- package/README.md +103 -92
- package/dist/cli/audit-commands.d.ts.map +1 -1
- package/dist/cli/audit-commands.js +3 -1
- package/dist/cli/audit-commands.js.map +1 -1
- package/dist/cli/daemon.js +86 -28
- package/dist/cli/daemon.js.map +1 -1
- package/dist/cli/edit-commands.d.ts.map +1 -1
- package/dist/cli/edit-commands.js +3 -1
- package/dist/cli/edit-commands.js.map +1 -1
- package/dist/cli/hook-commands.d.ts +9 -0
- package/dist/cli/hook-commands.d.ts.map +1 -0
- package/dist/cli/hook-commands.js +106 -0
- package/dist/cli/hook-commands.js.map +1 -0
- package/dist/cli/index.js +87 -35
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/init-command.d.ts.map +1 -1
- package/dist/cli/init-command.js +108 -9
- package/dist/cli/init-command.js.map +1 -1
- package/dist/cli/memory-commands.d.ts +1 -1
- package/dist/cli/memory-commands.d.ts.map +1 -1
- package/dist/cli/memory-commands.js +213 -1
- package/dist/cli/memory-commands.js.map +1 -1
- package/dist/cli/presets.d.ts.map +1 -1
- package/dist/cli/presets.js +2 -1
- package/dist/cli/presets.js.map +1 -1
- package/dist/cli/skill-commands.d.ts.map +1 -1
- package/dist/cli/skill-commands.js +4 -2
- package/dist/cli/skill-commands.js.map +1 -1
- package/dist/cli/steer-commands.d.ts.map +1 -1
- package/dist/cli/steer-commands.js +6 -4
- package/dist/cli/steer-commands.js.map +1 -1
- package/dist/cli/team-commands.d.ts.map +1 -1
- package/dist/cli/team-commands.js +3 -1
- package/dist/cli/team-commands.js.map +1 -1
- package/dist/config/defaults.d.ts.map +1 -1
- package/dist/config/defaults.js +12 -2
- package/dist/config/defaults.js.map +1 -1
- package/dist/config/loader.d.ts +23 -0
- package/dist/config/loader.d.ts.map +1 -1
- package/dist/config/loader.js +64 -3
- package/dist/config/loader.js.map +1 -1
- package/dist/config/policy-loader.d.ts +14 -0
- package/dist/config/policy-loader.d.ts.map +1 -1
- package/dist/config/policy-loader.js +33 -0
- package/dist/config/policy-loader.js.map +1 -1
- package/dist/dashboard/frontend/dist/assets/index-BcOGj1EF.css +1 -0
- package/dist/dashboard/frontend/dist/assets/index-BtiFO9YN.js +261 -0
- package/dist/dashboard/frontend/dist/assets/index-Cfjy5acU.css +1 -0
- package/dist/dashboard/frontend/dist/assets/index-D41hcjgc.js +253 -0
- package/dist/dashboard/frontend/dist/assets/index-D83BawFd.css +1 -0
- package/dist/dashboard/frontend/dist/assets/index-DAODjoxu.css +1 -0
- package/dist/dashboard/frontend/dist/assets/index-DB-Eu5oV.js +253 -0
- package/dist/dashboard/frontend/dist/assets/index-W0VVEDu6.js +253 -0
- package/dist/dashboard/frontend/dist/index.html +17 -0
- package/dist/dashboard/server.d.ts +19 -2
- package/dist/dashboard/server.d.ts.map +1 -1
- package/dist/dashboard/server.js +121 -20
- package/dist/dashboard/server.js.map +1 -1
- package/dist/hooks/hook-runner.d.ts +55 -0
- package/dist/hooks/hook-runner.d.ts.map +1 -0
- package/dist/hooks/hook-runner.js +120 -0
- package/dist/hooks/hook-runner.js.map +1 -0
- package/dist/hooks/hook-types.d.ts +82 -0
- package/dist/hooks/hook-types.d.ts.map +1 -0
- package/dist/hooks/hook-types.js +20 -0
- package/dist/hooks/hook-types.js.map +1 -0
- package/dist/hooks/index.d.ts +6 -0
- package/dist/hooks/index.d.ts.map +1 -0
- package/dist/hooks/index.js +6 -0
- package/dist/hooks/index.js.map +1 -0
- package/dist/memory/context-compressor.d.ts +108 -0
- package/dist/memory/context-compressor.d.ts.map +1 -0
- package/dist/memory/context-compressor.js +307 -0
- package/dist/memory/context-compressor.js.map +1 -0
- package/dist/memory/index.d.ts +1 -0
- package/dist/memory/index.d.ts.map +1 -1
- package/dist/memory/index.js +1 -0
- package/dist/memory/index.js.map +1 -1
- package/dist/memory/memory-manager.d.ts +88 -4
- package/dist/memory/memory-manager.d.ts.map +1 -1
- package/dist/memory/memory-manager.js +299 -7
- package/dist/memory/memory-manager.js.map +1 -1
- package/dist/memory/observation-store.d.ts +75 -0
- package/dist/memory/observation-store.d.ts.map +1 -0
- package/dist/memory/observation-store.js +162 -0
- package/dist/memory/observation-store.js.map +1 -0
- package/dist/memory/observer-worker.d.ts +34 -0
- package/dist/memory/observer-worker.d.ts.map +1 -0
- package/dist/memory/observer-worker.js +161 -0
- package/dist/memory/observer-worker.js.map +1 -0
- package/dist/memory/reflector-worker.d.ts +40 -0
- package/dist/memory/reflector-worker.d.ts.map +1 -0
- package/dist/memory/reflector-worker.js +185 -0
- package/dist/memory/reflector-worker.js.map +1 -0
- package/dist/memory/salience-scorer.d.ts +16 -6
- package/dist/memory/salience-scorer.d.ts.map +1 -1
- package/dist/memory/salience-scorer.js +42 -22
- package/dist/memory/salience-scorer.js.map +1 -1
- package/dist/memory/structured-memory.d.ts +36 -1
- package/dist/memory/structured-memory.d.ts.map +1 -1
- package/dist/memory/structured-memory.js +207 -8
- package/dist/memory/structured-memory.js.map +1 -1
- package/dist/memory/token-estimator.d.ts +31 -0
- package/dist/memory/token-estimator.d.ts.map +1 -0
- package/dist/memory/token-estimator.js +77 -0
- package/dist/memory/token-estimator.js.map +1 -0
- package/dist/memory/validation-pipeline.d.ts +37 -0
- package/dist/memory/validation-pipeline.d.ts.map +1 -0
- package/dist/memory/validation-pipeline.js +106 -0
- package/dist/memory/validation-pipeline.js.map +1 -0
- package/dist/orchestrator/auth-monitor.d.ts.map +1 -1
- package/dist/orchestrator/auth-monitor.js +3 -1
- package/dist/orchestrator/auth-monitor.js.map +1 -1
- package/dist/orchestrator/execution-loop.d.ts +23 -0
- package/dist/orchestrator/execution-loop.d.ts.map +1 -1
- package/dist/orchestrator/execution-loop.js +60 -19
- package/dist/orchestrator/execution-loop.js.map +1 -1
- package/dist/orchestrator/failover-controller.d.ts +26 -2
- package/dist/orchestrator/failover-controller.d.ts.map +1 -1
- package/dist/orchestrator/failover-controller.js +143 -23
- package/dist/orchestrator/failover-controller.js.map +1 -1
- package/dist/orchestrator/orchestrator.d.ts +70 -7
- package/dist/orchestrator/orchestrator.d.ts.map +1 -1
- package/dist/orchestrator/orchestrator.js +416 -92
- package/dist/orchestrator/orchestrator.js.map +1 -1
- package/dist/orchestrator/retry-queue.d.ts.map +1 -1
- package/dist/orchestrator/retry-queue.js +24 -9
- package/dist/orchestrator/retry-queue.js.map +1 -1
- package/dist/orchestrator/router.d.ts +16 -1
- package/dist/orchestrator/router.d.ts.map +1 -1
- package/dist/orchestrator/router.js +79 -20
- package/dist/orchestrator/router.js.map +1 -1
- package/dist/orchestrator/session-manager.d.ts +26 -1
- package/dist/orchestrator/session-manager.d.ts.map +1 -1
- package/dist/orchestrator/session-manager.js +88 -4
- package/dist/orchestrator/session-manager.js.map +1 -1
- package/dist/providers/circuit-breaker.d.ts +78 -0
- package/dist/providers/circuit-breaker.d.ts.map +1 -0
- package/dist/providers/circuit-breaker.js +129 -0
- package/dist/providers/circuit-breaker.js.map +1 -0
- package/dist/providers/claude-provider.d.ts +27 -11
- package/dist/providers/claude-provider.d.ts.map +1 -1
- package/dist/providers/claude-provider.js +161 -46
- package/dist/providers/claude-provider.js.map +1 -1
- package/dist/providers/gemini-provider.d.ts +9 -1
- package/dist/providers/gemini-provider.d.ts.map +1 -1
- package/dist/providers/gemini-provider.js +97 -48
- package/dist/providers/gemini-provider.js.map +1 -1
- package/dist/providers/index.d.ts +1 -0
- package/dist/providers/index.d.ts.map +1 -1
- package/dist/providers/index.js +1 -0
- package/dist/providers/index.js.map +1 -1
- package/dist/providers/ollama-provider.d.ts +7 -0
- package/dist/providers/ollama-provider.d.ts.map +1 -1
- package/dist/providers/ollama-provider.js +89 -18
- package/dist/providers/ollama-provider.js.map +1 -1
- package/dist/routines/heartbeat.d.ts +10 -2
- package/dist/routines/heartbeat.d.ts.map +1 -1
- package/dist/routines/heartbeat.js +42 -5
- package/dist/routines/heartbeat.js.map +1 -1
- package/dist/routines/routine-manager.d.ts.map +1 -1
- package/dist/routines/routine-manager.js +22 -15
- package/dist/routines/routine-manager.js.map +1 -1
- package/dist/security/audit-logger.d.ts.map +1 -1
- package/dist/security/audit-logger.js +5 -7
- package/dist/security/audit-logger.js.map +1 -1
- package/dist/security/policy-engine.d.ts +28 -17
- package/dist/security/policy-engine.d.ts.map +1 -1
- package/dist/security/policy-engine.js +42 -185
- package/dist/security/policy-engine.js.map +1 -1
- package/dist/security/policy-serializer.d.ts +19 -0
- package/dist/security/policy-serializer.d.ts.map +1 -0
- package/dist/security/policy-serializer.js +100 -0
- package/dist/security/policy-serializer.js.map +1 -0
- package/dist/security/shell-validator.d.ts +42 -0
- package/dist/security/shell-validator.d.ts.map +1 -0
- package/dist/security/shell-validator.js +231 -0
- package/dist/security/shell-validator.js.map +1 -0
- package/dist/skills/index.d.ts +1 -0
- package/dist/skills/index.d.ts.map +1 -1
- package/dist/skills/index.js +1 -0
- package/dist/skills/index.js.map +1 -1
- package/dist/skills/skill-loader.d.ts +38 -2
- package/dist/skills/skill-loader.d.ts.map +1 -1
- package/dist/skills/skill-loader.js +83 -2
- package/dist/skills/skill-loader.js.map +1 -1
- package/dist/skills/subagent-loader.d.ts +66 -0
- package/dist/skills/subagent-loader.d.ts.map +1 -0
- package/dist/skills/subagent-loader.js +143 -0
- package/dist/skills/subagent-loader.js.map +1 -0
- package/dist/steering/flag-manager.d.ts +20 -0
- package/dist/steering/flag-manager.d.ts.map +1 -1
- package/dist/steering/flag-manager.js +94 -11
- package/dist/steering/flag-manager.js.map +1 -1
- package/dist/steering/steering-manager.d.ts +11 -0
- package/dist/steering/steering-manager.d.ts.map +1 -1
- package/dist/steering/steering-manager.js +23 -0
- package/dist/steering/steering-manager.js.map +1 -1
- package/dist/steering/telegram-gateway.d.ts +4 -1
- package/dist/steering/telegram-gateway.d.ts.map +1 -1
- package/dist/steering/telegram-gateway.js +49 -10
- package/dist/steering/telegram-gateway.js.map +1 -1
- package/dist/teams/bridge-watchdog.d.ts.map +1 -1
- package/dist/teams/bridge-watchdog.js +5 -3
- package/dist/teams/bridge-watchdog.js.map +1 -1
- package/dist/teams/gemini-bridge.d.ts.map +1 -1
- package/dist/teams/gemini-bridge.js +9 -4
- package/dist/teams/gemini-bridge.js.map +1 -1
- package/dist/tools/index.d.ts +2 -0
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +2 -0
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/memory-tools.d.ts +16 -0
- package/dist/tools/memory-tools.d.ts.map +1 -0
- package/dist/tools/memory-tools.js +207 -0
- package/dist/tools/memory-tools.js.map +1 -0
- package/dist/tools/notifications.d.ts.map +1 -1
- package/dist/tools/notifications.js +3 -1
- package/dist/tools/notifications.js.map +1 -1
- package/dist/tools/tool-factory.d.ts +36 -0
- package/dist/tools/tool-factory.d.ts.map +1 -0
- package/dist/tools/tool-factory.js +55 -0
- package/dist/tools/tool-factory.js.map +1 -0
- package/dist/types.d.ts +205 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +47 -1
- package/dist/types.js.map +1 -1
- package/dist/utils/errors.d.ts +21 -0
- package/dist/utils/errors.d.ts.map +1 -0
- package/dist/utils/errors.js +29 -0
- package/dist/utils/errors.js.map +1 -0
- package/dist/utils/event-filter.d.ts +25 -0
- package/dist/utils/event-filter.d.ts.map +1 -0
- package/dist/utils/event-filter.js +61 -0
- package/dist/utils/event-filter.js.map +1 -0
- package/dist/utils/logger.d.ts +33 -36
- package/dist/utils/logger.d.ts.map +1 -1
- package/dist/utils/logger.js +60 -130
- package/dist/utils/logger.js.map +1 -1
- package/dist/utils/validate-job-id.d.ts +6 -0
- package/dist/utils/validate-job-id.d.ts.map +1 -0
- package/dist/utils/validate-job-id.js +10 -0
- package/dist/utils/validate-job-id.js.map +1 -0
- package/package.json +12 -3
|
@@ -6,13 +6,22 @@
|
|
|
6
6
|
* - Tier 2: Rolling context (Daily Notes)
|
|
7
7
|
* - Tier 3: Structured items, salience, categories
|
|
8
8
|
* - Aggregates fragments into TaskContext.memoryContext
|
|
9
|
+
*
|
|
10
|
+
* Integrity (MEM-18):
|
|
11
|
+
* - SHA-256 baselines on MEMORY.md to detect tampering
|
|
12
|
+
* - Baselines stored in .memory-integrity.json alongside the memory dir
|
|
13
|
+
* - Mismatch logs a warning (non-fatal — user may legitimately edit)
|
|
9
14
|
*/
|
|
15
|
+
import crypto from 'node:crypto';
|
|
10
16
|
import fs from 'node:fs/promises';
|
|
11
17
|
import path from 'node:path';
|
|
12
18
|
import os from 'node:os';
|
|
13
19
|
import { StructuredMemory } from './structured-memory.js';
|
|
14
20
|
import { SalienceScorer } from './salience-scorer.js';
|
|
15
21
|
import { CategoryOrganizer } from './category-organizer.js';
|
|
22
|
+
import { createLogger } from '../utils/logger.js';
|
|
23
|
+
const log = createLogger('memory-manager');
|
|
24
|
+
const INTEGRITY_FILENAME = '.memory-integrity.json';
|
|
16
25
|
export class MemoryManager {
|
|
17
26
|
_config;
|
|
18
27
|
_baseDir;
|
|
@@ -35,24 +44,104 @@ export class MemoryManager {
|
|
|
35
44
|
const longTermFile = this._getLongTermPath();
|
|
36
45
|
const longTermDir = path.dirname(longTermFile);
|
|
37
46
|
await fs.mkdir(longTermDir, { recursive: true, mode: 0o700 });
|
|
47
|
+
let fileCreated = false;
|
|
38
48
|
try {
|
|
39
49
|
const defaultContent = '# Zora Long-term Memory\n\n- No persistent memories yet.\n';
|
|
40
50
|
// Use 'wx' to atomically fail if the file already exists (preventing race conditions)
|
|
41
51
|
await fs.writeFile(longTermFile, defaultContent, { mode: 0o600, flag: 'wx' });
|
|
52
|
+
fileCreated = true;
|
|
42
53
|
}
|
|
43
54
|
catch (err) {
|
|
44
55
|
if (err.code !== 'EEXIST') {
|
|
45
56
|
throw err;
|
|
46
57
|
}
|
|
47
58
|
}
|
|
59
|
+
// Generate integrity baseline for newly created MEMORY.md
|
|
60
|
+
if (fileCreated) {
|
|
61
|
+
await this._saveIntegrityHash();
|
|
62
|
+
}
|
|
48
63
|
// Tier 3: Structured memory + categories
|
|
49
64
|
await this._structuredMemory.init();
|
|
50
65
|
await this._categoryOrganizer.init();
|
|
51
66
|
}
|
|
67
|
+
/** Cached memory index — invalidated on writes. */
|
|
68
|
+
_indexCache = null;
|
|
69
|
+
/**
|
|
70
|
+
* Returns a lightweight index of memory contents — no item reads.
|
|
71
|
+
* Tells the LLM what's available without dumping everything into context.
|
|
72
|
+
* Cached after first build; invalidated by write operations.
|
|
73
|
+
*/
|
|
74
|
+
async getMemoryIndex() {
|
|
75
|
+
if (this._indexCache)
|
|
76
|
+
return this._indexCache;
|
|
77
|
+
// Count items via directory listing (no file reads)
|
|
78
|
+
let itemCount = 0;
|
|
79
|
+
try {
|
|
80
|
+
const files = await fs.readdir(this._getItemsPath());
|
|
81
|
+
itemCount = files.filter(f => f.endsWith('.json')).length;
|
|
82
|
+
}
|
|
83
|
+
catch (err) {
|
|
84
|
+
if (err.code !== 'ENOENT')
|
|
85
|
+
throw err;
|
|
86
|
+
}
|
|
87
|
+
// List category names from category files
|
|
88
|
+
const categories = await this._categoryOrganizer.listCategories();
|
|
89
|
+
const categoryNames = categories.map(c => c.category);
|
|
90
|
+
// Find most recent daily note
|
|
91
|
+
let mostRecentDailyNote = null;
|
|
92
|
+
let dailyNoteCount = 0;
|
|
93
|
+
try {
|
|
94
|
+
const files = await fs.readdir(this._getDailyNotesPath());
|
|
95
|
+
const dateFiles = files
|
|
96
|
+
.filter(f => /^\d{4}-\d{2}-\d{2}\.md$/.test(f))
|
|
97
|
+
.sort()
|
|
98
|
+
.reverse();
|
|
99
|
+
dailyNoteCount = dateFiles.length;
|
|
100
|
+
if (dateFiles.length > 0) {
|
|
101
|
+
mostRecentDailyNote = dateFiles[0].replace('.md', '');
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
catch (err) {
|
|
105
|
+
if (err.code !== 'ENOENT')
|
|
106
|
+
throw err;
|
|
107
|
+
}
|
|
108
|
+
this._indexCache = { itemCount, categoryNames, mostRecentDailyNote, dailyNoteCount };
|
|
109
|
+
return this._indexCache;
|
|
110
|
+
}
|
|
52
111
|
/**
|
|
53
|
-
* Loads
|
|
112
|
+
* Loads a lightweight context string for the system prompt.
|
|
113
|
+
* Instead of dumping all memory, provides a summary index that tells the LLM
|
|
114
|
+
* to use tools for on-demand retrieval.
|
|
54
115
|
*/
|
|
55
|
-
async loadContext(
|
|
116
|
+
async loadContext(_days) {
|
|
117
|
+
const index = await this.getMemoryIndex();
|
|
118
|
+
const parts = [];
|
|
119
|
+
// Compact summary instead of full dump
|
|
120
|
+
const catList = index.categoryNames.length > 0
|
|
121
|
+
? index.categoryNames.join(', ')
|
|
122
|
+
: 'none yet';
|
|
123
|
+
let summary = `[MEMORY] You have access to persistent memory:\n`;
|
|
124
|
+
summary += `- ${index.itemCount} items across ${index.categoryNames.length} categories (${catList})\n`;
|
|
125
|
+
if (index.mostRecentDailyNote) {
|
|
126
|
+
summary += `- Daily notes available (most recent: ${index.mostRecentDailyNote}, total: ${index.dailyNoteCount})\n`;
|
|
127
|
+
}
|
|
128
|
+
summary += `- Use memory_search to find relevant context\n`;
|
|
129
|
+
summary += `- Use recall_context to read recent daily notes\n`;
|
|
130
|
+
summary += `- Use memory_save to store new facts\n`;
|
|
131
|
+
summary += `Only retrieve what you need for this task.`;
|
|
132
|
+
parts.push(summary);
|
|
133
|
+
// Still include long-term memory (MEMORY.md) — it's typically small and curated
|
|
134
|
+
const longTerm = await this._readLongTerm();
|
|
135
|
+
if (longTerm) {
|
|
136
|
+
parts.push(`[LONG-TERM MEMORY]:\n${longTerm}`);
|
|
137
|
+
}
|
|
138
|
+
return parts;
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Full context load (backward compat). Reads ALL items, daily notes, categories.
|
|
142
|
+
* Use only when progressive loading is not suitable (e.g., export, migration).
|
|
143
|
+
*/
|
|
144
|
+
async loadFullContext(days = this._config.context_days) {
|
|
56
145
|
const context = [];
|
|
57
146
|
// Tier 1: Long-term salience
|
|
58
147
|
const tier1 = await this._readLongTerm();
|
|
@@ -86,6 +175,114 @@ export class MemoryManager {
|
|
|
86
175
|
}
|
|
87
176
|
return context;
|
|
88
177
|
}
|
|
178
|
+
/**
|
|
179
|
+
* Targeted memory recall — searches items by query using BM25 + salience.
|
|
180
|
+
* This is what the LLM calls via the memory_search tool, but exposed as
|
|
181
|
+
* a method for direct use by the Orchestrator.
|
|
182
|
+
*/
|
|
183
|
+
async recallMemory(query, limit = 5) {
|
|
184
|
+
const scores = await this.searchMemory(query, limit);
|
|
185
|
+
const items = [];
|
|
186
|
+
for (const s of scores) {
|
|
187
|
+
// Use peekItem for read-only access — avoids inflating access stats during search
|
|
188
|
+
const item = await this._structuredMemory.peekItem(s.itemId);
|
|
189
|
+
if (item)
|
|
190
|
+
items.push(item);
|
|
191
|
+
}
|
|
192
|
+
return { items, scores };
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* Reads only the requested number of recent daily notes.
|
|
196
|
+
* Exposed for the recall_context tool.
|
|
197
|
+
*/
|
|
198
|
+
async recallDailyNotes(days = 3) {
|
|
199
|
+
return this._readDailyNotes(days);
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* Archives daily notes older than threshold to memory/daily/archive/.
|
|
203
|
+
* Appends a summary header to MEMORY.md noting the archived date range.
|
|
204
|
+
* Archived notes remain on disk in the archive/ subdirectory for manual
|
|
205
|
+
* review but are excluded from the active daily notes directory.
|
|
206
|
+
*
|
|
207
|
+
* If a reflectFn is provided, it will be called with the combined content
|
|
208
|
+
* of notes being archived. This enables extracting structured memory items
|
|
209
|
+
* from daily notes before they are moved to the archive.
|
|
210
|
+
*
|
|
211
|
+
* @param thresholdDays Notes older than this are archived (default: 7)
|
|
212
|
+
* @param reflectFn Optional function to extract memory from notes before archiving
|
|
213
|
+
* @returns Number of notes archived
|
|
214
|
+
*/
|
|
215
|
+
async consolidateDailyNotes(thresholdDays = 7, reflectFn) {
|
|
216
|
+
const dir = this._getDailyNotesPath();
|
|
217
|
+
let files;
|
|
218
|
+
try {
|
|
219
|
+
files = await fs.readdir(dir);
|
|
220
|
+
}
|
|
221
|
+
catch (err) {
|
|
222
|
+
if (err.code === 'ENOENT')
|
|
223
|
+
return 0;
|
|
224
|
+
throw err;
|
|
225
|
+
}
|
|
226
|
+
const cutoff = new Date();
|
|
227
|
+
cutoff.setDate(cutoff.getDate() - thresholdDays);
|
|
228
|
+
const cutoffStr = cutoff.toISOString().split('T')[0];
|
|
229
|
+
const oldFiles = files
|
|
230
|
+
.filter(f => /^\d{4}-\d{2}-\d{2}\.md$/.test(f))
|
|
231
|
+
.filter(f => f.replace('.md', '') < cutoffStr)
|
|
232
|
+
.sort();
|
|
233
|
+
if (oldFiles.length === 0)
|
|
234
|
+
return 0;
|
|
235
|
+
// Run reflector on note content before archiving (extract structured memory)
|
|
236
|
+
if (reflectFn) {
|
|
237
|
+
try {
|
|
238
|
+
const noteContents = [];
|
|
239
|
+
for (const file of oldFiles) {
|
|
240
|
+
try {
|
|
241
|
+
const content = await fs.readFile(path.join(dir, file), 'utf8');
|
|
242
|
+
noteContents.push(`--- ${file} ---\n${content}`);
|
|
243
|
+
}
|
|
244
|
+
catch {
|
|
245
|
+
// Skip unreadable files
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
if (noteContents.length > 0) {
|
|
249
|
+
await reflectFn(noteContents.join('\n\n'));
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
catch (err) {
|
|
253
|
+
log.warn({ err }, 'Reflector pass on daily notes failed, continuing with archive');
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
// Archive old files (moved, not deleted — still accessible for manual review)
|
|
257
|
+
const archiveDir = path.join(dir, 'archive');
|
|
258
|
+
await fs.mkdir(archiveDir, { recursive: true, mode: 0o700 });
|
|
259
|
+
for (const file of oldFiles) {
|
|
260
|
+
try {
|
|
261
|
+
await fs.rename(path.join(dir, file), path.join(archiveDir, file));
|
|
262
|
+
}
|
|
263
|
+
catch {
|
|
264
|
+
// Best-effort archive
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
// Append a consolidation summary to MEMORY.md
|
|
268
|
+
const consolidationSummary = `\n## Archived ${oldFiles.length} daily notes (${oldFiles[0].replace('.md', '')} to ${oldFiles[oldFiles.length - 1].replace('.md', '')})\n`;
|
|
269
|
+
const ltPath = this._getLongTermPath();
|
|
270
|
+
try {
|
|
271
|
+
await fs.appendFile(ltPath, consolidationSummary, { mode: 0o600 });
|
|
272
|
+
await this._saveIntegrityHash();
|
|
273
|
+
}
|
|
274
|
+
catch {
|
|
275
|
+
// Best-effort
|
|
276
|
+
}
|
|
277
|
+
// Invalidate index cache
|
|
278
|
+
this._indexCache = null;
|
|
279
|
+
log.info({ archived: oldFiles.length, thresholdDays }, 'Daily notes archived');
|
|
280
|
+
return oldFiles.length;
|
|
281
|
+
}
|
|
282
|
+
/** Invalidate the cached memory index (call after writes). */
|
|
283
|
+
invalidateIndex() {
|
|
284
|
+
this._indexCache = null;
|
|
285
|
+
}
|
|
89
286
|
/**
|
|
90
287
|
* Appends an entry to today's daily note.
|
|
91
288
|
*/
|
|
@@ -105,18 +302,41 @@ export class MemoryManager {
|
|
|
105
302
|
throw err;
|
|
106
303
|
}
|
|
107
304
|
}
|
|
305
|
+
this._indexCache = null; // Invalidate index on daily note write
|
|
108
306
|
}
|
|
109
307
|
/**
|
|
110
308
|
* Searches structured memory items by query, ranked by salience.
|
|
309
|
+
* Uses MiniSearch BM25+ scores composed with salience factors.
|
|
111
310
|
*/
|
|
112
311
|
async searchMemory(query, limit) {
|
|
113
|
-
const
|
|
114
|
-
|
|
312
|
+
const results = await this._structuredMemory.searchItemsWithScores(query);
|
|
313
|
+
const scored = results.map(({ item, bm25Score }) => this._scorer.scoreItem(item, query, bm25Score));
|
|
314
|
+
scored.sort((a, b) => b.score - a.score);
|
|
315
|
+
return limit !== undefined ? scored.slice(0, limit) : scored;
|
|
115
316
|
}
|
|
116
317
|
/**
|
|
117
|
-
*
|
|
318
|
+
* Soft-deletes a structured memory item by ID.
|
|
319
|
+
* Moves the item to an archive directory before removing.
|
|
118
320
|
*/
|
|
119
|
-
async forgetItem(id) {
|
|
321
|
+
async forgetItem(id, reason) {
|
|
322
|
+
// Use getItem for direct lookup instead of listItems + find
|
|
323
|
+
const item = await this._structuredMemory.getItem(id);
|
|
324
|
+
if (item) {
|
|
325
|
+
const archiveDir = path.join(this._baseDir, 'memory', 'archive');
|
|
326
|
+
try {
|
|
327
|
+
await fs.mkdir(archiveDir, { recursive: true, mode: 0o700 });
|
|
328
|
+
const archiveData = {
|
|
329
|
+
...item,
|
|
330
|
+
archived_at: new Date().toISOString(),
|
|
331
|
+
archive_reason: reason ?? 'No reason provided',
|
|
332
|
+
};
|
|
333
|
+
await fs.writeFile(path.join(archiveDir, `${id}.json`), JSON.stringify(archiveData, null, 2), { mode: 0o600 });
|
|
334
|
+
}
|
|
335
|
+
catch {
|
|
336
|
+
// Archive is best-effort
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
this._indexCache = null; // Invalidate index on delete
|
|
120
340
|
return this._structuredMemory.deleteItem(id);
|
|
121
341
|
}
|
|
122
342
|
/**
|
|
@@ -131,6 +351,12 @@ export class MemoryManager {
|
|
|
131
351
|
get structuredMemory() {
|
|
132
352
|
return this._structuredMemory;
|
|
133
353
|
}
|
|
354
|
+
/**
|
|
355
|
+
* Returns the resolved path to the long-term memory file (MEMORY.md).
|
|
356
|
+
*/
|
|
357
|
+
getLongTermPath() {
|
|
358
|
+
return this._getLongTermPath();
|
|
359
|
+
}
|
|
134
360
|
_resolvePath(p) {
|
|
135
361
|
if (p.startsWith('~/')) {
|
|
136
362
|
return path.join(os.homedir(), p.slice(2));
|
|
@@ -163,7 +389,10 @@ export class MemoryManager {
|
|
|
163
389
|
}
|
|
164
390
|
async _readLongTerm() {
|
|
165
391
|
try {
|
|
166
|
-
|
|
392
|
+
const content = await fs.readFile(this._getLongTermPath(), 'utf8');
|
|
393
|
+
// Verify integrity hash (non-fatal on mismatch)
|
|
394
|
+
await this._verifyIntegrityHash(content);
|
|
395
|
+
return content;
|
|
167
396
|
}
|
|
168
397
|
catch (err) {
|
|
169
398
|
if (err.code === 'ENOENT') {
|
|
@@ -194,5 +423,68 @@ export class MemoryManager {
|
|
|
194
423
|
}
|
|
195
424
|
return notes;
|
|
196
425
|
}
|
|
426
|
+
// ─── Integrity Hashing (MEM-18) ──────────────────────────────────
|
|
427
|
+
/** Path to the integrity baseline file alongside the memory directory. */
|
|
428
|
+
_getIntegrityPath() {
|
|
429
|
+
return path.join(path.dirname(this._getLongTermPath()), INTEGRITY_FILENAME);
|
|
430
|
+
}
|
|
431
|
+
/** Compute SHA-256 hash of the given content. */
|
|
432
|
+
_computeHash(content) {
|
|
433
|
+
return crypto.createHash('sha256').update(content).digest('hex');
|
|
434
|
+
}
|
|
435
|
+
/**
|
|
436
|
+
* Saves a SHA-256 baseline for the current MEMORY.md content.
|
|
437
|
+
* Called after any write to MEMORY.md.
|
|
438
|
+
*/
|
|
439
|
+
async _saveIntegrityHash() {
|
|
440
|
+
try {
|
|
441
|
+
const content = await fs.readFile(this._getLongTermPath(), 'utf8');
|
|
442
|
+
const data = {
|
|
443
|
+
hash: this._computeHash(content),
|
|
444
|
+
updatedAt: new Date().toISOString(),
|
|
445
|
+
};
|
|
446
|
+
await fs.writeFile(this._getIntegrityPath(), JSON.stringify(data, null, 2), { mode: 0o600 });
|
|
447
|
+
}
|
|
448
|
+
catch (err) {
|
|
449
|
+
log.warn({ err }, 'Failed to save memory integrity hash');
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
/**
|
|
453
|
+
* Verifies the current MEMORY.md content against the stored hash baseline.
|
|
454
|
+
* Logs a warning on mismatch but does not throw (the file may have been
|
|
455
|
+
* legitimately edited by the user).
|
|
456
|
+
*/
|
|
457
|
+
async _verifyIntegrityHash(content) {
|
|
458
|
+
try {
|
|
459
|
+
const raw = await fs.readFile(this._getIntegrityPath(), 'utf8');
|
|
460
|
+
const data = JSON.parse(raw);
|
|
461
|
+
const currentHash = this._computeHash(content);
|
|
462
|
+
if (data.hash !== currentHash) {
|
|
463
|
+
log.warn({
|
|
464
|
+
expected: data.hash,
|
|
465
|
+
actual: currentHash,
|
|
466
|
+
baselineDate: data.updatedAt,
|
|
467
|
+
}, 'MEMORY.md integrity mismatch: file may have been modified externally');
|
|
468
|
+
return false;
|
|
469
|
+
}
|
|
470
|
+
return true;
|
|
471
|
+
}
|
|
472
|
+
catch (err) {
|
|
473
|
+
if (err.code === 'ENOENT') {
|
|
474
|
+
// No baseline yet — first run or baseline was deleted
|
|
475
|
+
log.info('No memory integrity baseline found; skipping verification');
|
|
476
|
+
return true;
|
|
477
|
+
}
|
|
478
|
+
log.warn({ err }, 'Failed to verify memory integrity hash');
|
|
479
|
+
return true; // Don't block on verification errors
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
/**
|
|
483
|
+
* Refreshes the integrity baseline for MEMORY.md.
|
|
484
|
+
* Call this after legitimate external edits to acknowledge the new content.
|
|
485
|
+
*/
|
|
486
|
+
async refreshIntegrityBaseline() {
|
|
487
|
+
await this._saveIntegrityHash();
|
|
488
|
+
}
|
|
197
489
|
}
|
|
198
490
|
//# sourceMappingURL=memory-manager.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"memory-manager.js","sourceRoot":"","sources":["../../src/memory/memory-manager.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAClC,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,MAAM,SAAS,CAAC;AAEzB,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAG5D,MAAM,OAAO,aAAa;IACP,OAAO,CAAe;IACtB,QAAQ,CAAS;IAC1B,iBAAiB,CAAmB;IACpC,OAAO,CAAiB;IACxB,kBAAkB,CAAoB;IAE9C,YACE,MAAoB,EACpB,UAAkB,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,OAAO,CAAC,EAClD,WAAsD;QAEtD,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC;QACtB,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC;QACxB,IAAI,CAAC,iBAAiB,GAAG,IAAI,gBAAgB,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC,CAAC;QACpE,IAAI,CAAC,OAAO,GAAG,IAAI,cAAc,EAAE,CAAC;QACpC,IAAI,CAAC,kBAAkB,GAAG,IAAI,iBAAiB,CAC7C,IAAI,CAAC,kBAAkB,EAAE,EACzB,WAAW,IAAI,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,oBAAoB,CAAC,CACtE,CAAC;IACJ,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,IAAI;QACR,MAAM,aAAa,GAAG,IAAI,CAAC,kBAAkB,EAAE,CAAC;QAChD,MAAM,EAAE,CAAC,KAAK,CAAC,aAAa,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;QAEhE,MAAM,YAAY,GAAG,IAAI,CAAC,gBAAgB,EAAE,CAAC;QAC7C,MAAM,WAAW,GAAG,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;QAC/C,MAAM,EAAE,CAAC,KAAK,CAAC,WAAW,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;QAE9D,IAAI,CAAC;YACH,MAAM,cAAc,GAAG,4DAA4D,CAAC;YACpF,sFAAsF;YACtF,MAAM,EAAE,CAAC,SAAS,CAAC,YAAY,EAAE,cAAc,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;QAChF,CAAC;QAAC,OAAO,GAAY,EAAE,CAAC;YACtB,IAAK,GAA6B,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;gBACrD,MAAM,GAAG,CAAC;YACZ,CAAC;QACH,CAAC;QAED,yCAAyC;QACzC,MAAM,IAAI,CAAC,iBAAiB,CAAC,IAAI,EAAE,CAAC;QACpC,MAAM,IAAI,CAAC,kBAAkB,CAAC,IAAI,EAAE,CAAC;IACvC,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,WAAW,CAAC,OAAe,IAAI,CAAC,OAAO,CAAC,YAAY;QACxD,MAAM,OAAO,GAAa,EAAE,CAAC;QAE7B,6BAA6B;QAC7B,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,aAAa,EAAE,CAAC;QACzC,IAAI,KAAK;YAAE,OAAO,CAAC,IAAI,CAAC,wBAAwB,KAAK,EAAE,CAAC,CAAC;QAEzD,iDAAiD;QACjD,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC;QAC/C,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACrB,OAAO,CAAC,IAAI,CAAC,sBAAsB,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QAC3D,CAAC;QAED,2DAA2D;QAC3D,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,GAAG,MAAM,IAAI,CAAC,kBAAkB,CAAC,kBAAkB,CAC9E,EAAE,EAAE,0CAA0C;QAC9C,IAAI,CAAC,iBAAiB,EACtB,IAAI,CAAC,OAAO,EACZ,IAAI,CAAC,OAAO,CAAC,sBAAsB,EACnC,IAAI,CAAC,OAAO,CAAC,iBAAiB,CAC/B,CAAC;QAEF,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACzB,MAAM,QAAQ,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,QAAQ,MAAM,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAClF,OAAO,CAAC,IAAI,CAAC,0BAA0B,QAAQ,EAAE,CAAC,CAAC;QACrD,CAAC;QAED,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACxB,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,iBAAiB,CAAC,SAAS,EAAE,CAAC;YAC1D,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;YACtD,MAAM,SAAS,GAAG,QAAQ;iBACvB,GAAG,CAAC,CAAC,CAAC,EAAE;gBACP,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;gBACnC,OAAO,IAAI,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC,IAAI,KAAK,IAAI,CAAC,OAAO,eAAe,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC;YAC5F,CAAC,CAAC;iBACD,MAAM,CAAC,OAAO,CAAC;iBACf,IAAI,CAAC,IAAI,CAAC,CAAC;YACd,IAAI,SAAS,EAAE,CAAC;gBACd,OAAO,CAAC,IAAI,CAAC,oBAAoB,SAAS,EAAE,CAAC,CAAC;YAChD,CAAC;QACH,CAAC;QAED,OAAO,OAAO,CAAC;IACjB,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,eAAe,CAAC,IAAY;QAChC,MAAM,KAAK,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QACrD,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,kBAAkB,EAAE,EAAE,GAAG,KAAK,KAAK,CAAC,CAAC;QACrE,MAAM,KAAK,GAAG,SAAS,IAAI,IAAI,EAAE,CAAC,kBAAkB,EAAE,KAAK,IAAI,IAAI,CAAC;QAEpE,IAAI,CAAC;YACH,MAAM,EAAE,CAAC,UAAU,CAAC,QAAQ,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;QACxD,CAAC;QAAC,OAAO,GAAY,EAAE,CAAC;YACtB,IAAK,GAA6B,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;gBACrD,8CAA8C;gBAC9C,MAAM,EAAE,CAAC,SAAS,CAAC,QAAQ,EAAE,kBAAkB,KAAK,KAAK,KAAK,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;YACrF,CAAC;iBAAM,CAAC;gBACN,MAAM,GAAG,CAAC;YACZ,CAAC;QACH,CAAC;IACH,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,YAAY,CAAC,KAAa,EAAE,KAAc;QAC9C,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,iBAAiB,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;QAC9D,OAAO,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;IACrD,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,UAAU,CAAC,EAAU;QACzB,OAAO,IAAI,CAAC,iBAAiB,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;IAC/C,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,aAAa;QACjB,OAAO,IAAI,CAAC,kBAAkB,CAAC,cAAc,EAAE,CAAC;IAClD,CAAC;IAED;;OAEG;IACH,IAAI,gBAAgB;QAClB,OAAO,IAAI,CAAC,iBAAiB,CAAC;IAChC,CAAC;IAEO,YAAY,CAAC,CAAS;QAC5B,IAAI,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;YACvB,OAAO,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;QAC7C,CAAC;QACD,OAAO,CAAC,CAAC;IACX,CAAC;IAEO,gBAAgB;QACtB,MAAM,QAAQ,GAAG,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;QAChE,OAAO,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC;YAC9B,CAAC,CAAC,QAAQ;YACV,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;IACzC,CAAC;IAEO,kBAAkB;QACxB,MAAM,QAAQ,GAAG,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC;QACjE,OAAO,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC;YAC9B,CAAC,CAAC,QAAQ;YACV,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;IACzC,CAAC;IAEO,aAAa;QACnB,MAAM,QAAQ,GAAG,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;QAC3D,OAAO,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC;YAC9B,CAAC,CAAC,QAAQ;YACV,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;IACzC,CAAC;IAEO,kBAAkB;QACxB,MAAM,QAAQ,GAAG,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;QAChE,OAAO,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC;YAC9B,CAAC,CAAC,QAAQ;YACV,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;IACzC,CAAC;IAEO,KAAK,CAAC,aAAa;QACzB,IAAI,CAAC;YACH,OAAO,MAAM,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,gBAAgB,EAAE,EAAE,MAAM,CAAC,CAAC;QAC5D,CAAC;QAAC,OAAO,GAAY,EAAE,CAAC;YACtB,IAAK,GAA6B,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;gBACrD,OAAO,IAAI,CAAC;YACd,CAAC;YACD,MAAM,GAAG,CAAC;QACZ,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,eAAe,CAAC,IAAY;QACxC,MAAM,KAAK,GAAa,EAAE,CAAC;QAC3B,MAAM,GAAG,GAAG,IAAI,CAAC,kBAAkB,EAAE,CAAC;QAEtC,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;YACpC,MAAM,SAAS,GAAG,KAAK;iBACpB,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,yBAAyB,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;iBAC9C,IAAI,EAAE;iBACN,OAAO,EAAE;iBACT,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;YAElB,KAAK,MAAM,IAAI,IAAI,SAAS,EAAE,CAAC;gBAC7B,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,CAAC;gBAChE,KAAK,CAAC,IAAI,CAAC,OAAO,IAAI,SAAS,OAAO,EAAE,CAAC,CAAC;YAC5C,CAAC;QACH,CAAC;QAAC,OAAO,GAAY,EAAE,CAAC;YACtB,IAAK,GAA6B,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;gBACrD,MAAM,GAAG,CAAC;YACZ,CAAC;QACH,CAAC;QAED,OAAO,KAAK,CAAC;IACf,CAAC;CACF"}
|
|
1
|
+
{"version":3,"file":"memory-manager.js","sourceRoot":"","sources":["../../src/memory/memory-manager.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,MAAM,MAAM,aAAa,CAAC;AACjC,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAClC,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,MAAM,SAAS,CAAC;AAEzB,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAE5D,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAElD,MAAM,GAAG,GAAG,YAAY,CAAC,gBAAgB,CAAC,CAAC;AAgB3C,MAAM,kBAAkB,GAAG,wBAAwB,CAAC;AAEpD,MAAM,OAAO,aAAa;IACP,OAAO,CAAe;IACtB,QAAQ,CAAS;IAC1B,iBAAiB,CAAmB;IACpC,OAAO,CAAiB;IACxB,kBAAkB,CAAoB;IAE9C,YACE,MAAoB,EACpB,UAAkB,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,OAAO,CAAC,EAClD,WAAsD;QAEtD,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC;QACtB,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC;QACxB,IAAI,CAAC,iBAAiB,GAAG,IAAI,gBAAgB,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC,CAAC;QACpE,IAAI,CAAC,OAAO,GAAG,IAAI,cAAc,EAAE,CAAC;QACpC,IAAI,CAAC,kBAAkB,GAAG,IAAI,iBAAiB,CAC7C,IAAI,CAAC,kBAAkB,EAAE,EACzB,WAAW,IAAI,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,oBAAoB,CAAC,CACtE,CAAC;IACJ,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,IAAI;QACR,MAAM,aAAa,GAAG,IAAI,CAAC,kBAAkB,EAAE,CAAC;QAChD,MAAM,EAAE,CAAC,KAAK,CAAC,aAAa,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;QAEhE,MAAM,YAAY,GAAG,IAAI,CAAC,gBAAgB,EAAE,CAAC;QAC7C,MAAM,WAAW,GAAG,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;QAC/C,MAAM,EAAE,CAAC,KAAK,CAAC,WAAW,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;QAE9D,IAAI,WAAW,GAAG,KAAK,CAAC;QACxB,IAAI,CAAC;YACH,MAAM,cAAc,GAAG,4DAA4D,CAAC;YACpF,sFAAsF;YACtF,MAAM,EAAE,CAAC,SAAS,CAAC,YAAY,EAAE,cAAc,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;YAC9E,WAAW,GAAG,IAAI,CAAC;QACrB,CAAC;QAAC,OAAO,GAAY,EAAE,CAAC;YACtB,IAAK,GAA6B,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;gBACrD,MAAM,GAAG,CAAC;YACZ,CAAC;QACH,CAAC;QAED,0DAA0D;QAC1D,IAAI,WAAW,EAAE,CAAC;YAChB,MAAM,IAAI,CAAC,kBAAkB,EAAE,CAAC;QAClC,CAAC;QAED,yCAAyC;QACzC,MAAM,IAAI,CAAC,iBAAiB,CAAC,IAAI,EAAE,CAAC;QACpC,MAAM,IAAI,CAAC,kBAAkB,CAAC,IAAI,EAAE,CAAC;IACvC,CAAC;IAED,mDAAmD;IAC3C,WAAW,GAAuB,IAAI,CAAC;IAE/C;;;;OAIG;IACH,KAAK,CAAC,cAAc;QAClB,IAAI,IAAI,CAAC,WAAW;YAAE,OAAO,IAAI,CAAC,WAAW,CAAC;QAE9C,oDAAoD;QACpD,IAAI,SAAS,GAAG,CAAC,CAAC;QAClB,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC,CAAC;YACrD,SAAS,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC;QAC5D,CAAC;QAAC,OAAO,GAAY,EAAE,CAAC;YACtB,IAAK,GAA6B,CAAC,IAAI,KAAK,QAAQ;gBAAE,MAAM,GAAG,CAAC;QAClE,CAAC;QAED,0CAA0C;QAC1C,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,kBAAkB,CAAC,cAAc,EAAE,CAAC;QAClE,MAAM,aAAa,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;QAEtD,8BAA8B;QAC9B,IAAI,mBAAmB,GAAkB,IAAI,CAAC;QAC9C,IAAI,cAAc,GAAG,CAAC,CAAC;QACvB,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,kBAAkB,EAAE,CAAC,CAAC;YAC1D,MAAM,SAAS,GAAG,KAAK;iBACpB,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,yBAAyB,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;iBAC9C,IAAI,EAAE;iBACN,OAAO,EAAE,CAAC;YACb,cAAc,GAAG,SAAS,CAAC,MAAM,CAAC;YAClC,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACzB,mBAAmB,GAAG,SAAS,CAAC,CAAC,CAAE,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;YACzD,CAAC;QACH,CAAC;QAAC,OAAO,GAAY,EAAE,CAAC;YACtB,IAAK,GAA6B,CAAC,IAAI,KAAK,QAAQ;gBAAE,MAAM,GAAG,CAAC;QAClE,CAAC;QAED,IAAI,CAAC,WAAW,GAAG,EAAE,SAAS,EAAE,aAAa,EAAE,mBAAmB,EAAE,cAAc,EAAE,CAAC;QACrF,OAAO,IAAI,CAAC,WAAW,CAAC;IAC1B,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,WAAW,CAAC,KAAc;QAC9B,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,cAAc,EAAE,CAAC;QAE1C,MAAM,KAAK,GAAa,EAAE,CAAC;QAE3B,uCAAuC;QACvC,MAAM,OAAO,GAAG,KAAK,CAAC,aAAa,CAAC,MAAM,GAAG,CAAC;YAC5C,CAAC,CAAC,KAAK,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC;YAChC,CAAC,CAAC,UAAU,CAAC;QAEf,IAAI,OAAO,GAAG,kDAAkD,CAAC;QACjE,OAAO,IAAI,KAAK,KAAK,CAAC,SAAS,iBAAiB,KAAK,CAAC,aAAa,CAAC,MAAM,gBAAgB,OAAO,KAAK,CAAC;QAEvG,IAAI,KAAK,CAAC,mBAAmB,EAAE,CAAC;YAC9B,OAAO,IAAI,yCAAyC,KAAK,CAAC,mBAAmB,YAAY,KAAK,CAAC,cAAc,KAAK,CAAC;QACrH,CAAC;QAED,OAAO,IAAI,gDAAgD,CAAC;QAC5D,OAAO,IAAI,mDAAmD,CAAC;QAC/D,OAAO,IAAI,wCAAwC,CAAC;QACpD,OAAO,IAAI,4CAA4C,CAAC;QAExD,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAEpB,gFAAgF;QAChF,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,aAAa,EAAE,CAAC;QAC5C,IAAI,QAAQ,EAAE,CAAC;YACb,KAAK,CAAC,IAAI,CAAC,wBAAwB,QAAQ,EAAE,CAAC,CAAC;QACjD,CAAC;QAED,OAAO,KAAK,CAAC;IACf,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,eAAe,CAAC,OAAe,IAAI,CAAC,OAAO,CAAC,YAAY;QAC5D,MAAM,OAAO,GAAa,EAAE,CAAC;QAE7B,6BAA6B;QAC7B,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,aAAa,EAAE,CAAC;QACzC,IAAI,KAAK;YAAE,OAAO,CAAC,IAAI,CAAC,wBAAwB,KAAK,EAAE,CAAC,CAAC;QAEzD,iDAAiD;QACjD,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC;QAC/C,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACrB,OAAO,CAAC,IAAI,CAAC,sBAAsB,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QAC3D,CAAC;QAED,2DAA2D;QAC3D,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,GAAG,MAAM,IAAI,CAAC,kBAAkB,CAAC,kBAAkB,CAC9E,EAAE,EAAE,0CAA0C;QAC9C,IAAI,CAAC,iBAAiB,EACtB,IAAI,CAAC,OAAO,EACZ,IAAI,CAAC,OAAO,CAAC,sBAAsB,EACnC,IAAI,CAAC,OAAO,CAAC,iBAAiB,CAC/B,CAAC;QAEF,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACzB,MAAM,QAAQ,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,QAAQ,MAAM,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAClF,OAAO,CAAC,IAAI,CAAC,0BAA0B,QAAQ,EAAE,CAAC,CAAC;QACrD,CAAC;QAED,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACxB,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,iBAAiB,CAAC,SAAS,EAAE,CAAC;YAC1D,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;YACtD,MAAM,SAAS,GAAG,QAAQ;iBACvB,GAAG,CAAC,CAAC,CAAC,EAAE;gBACP,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;gBACnC,OAAO,IAAI,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC,IAAI,KAAK,IAAI,CAAC,OAAO,eAAe,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC;YAC5F,CAAC,CAAC;iBACD,MAAM,CAAC,OAAO,CAAC;iBACf,IAAI,CAAC,IAAI,CAAC,CAAC;YACd,IAAI,SAAS,EAAE,CAAC;gBACd,OAAO,CAAC,IAAI,CAAC,oBAAoB,SAAS,EAAE,CAAC,CAAC;YAChD,CAAC;QACH,CAAC;QAED,OAAO,OAAO,CAAC;IACjB,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,YAAY,CAAC,KAAa,EAAE,QAAgB,CAAC;QACjD,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,YAAY,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;QACrD,MAAM,KAAK,GAAiB,EAAE,CAAC;QAE/B,KAAK,MAAM,CAAC,IAAI,MAAM,EAAE,CAAC;YACvB,kFAAkF;YAClF,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,iBAAiB,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;YAC7D,IAAI,IAAI;gBAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC7B,CAAC;QAED,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;IAC3B,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,gBAAgB,CAAC,OAAe,CAAC;QACrC,OAAO,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC;IACpC,CAAC;IAED;;;;;;;;;;;;;OAaG;IACH,KAAK,CAAC,qBAAqB,CACzB,gBAAwB,CAAC,EACzB,SAAmD;QAEnD,MAAM,GAAG,GAAG,IAAI,CAAC,kBAAkB,EAAE,CAAC;QACtC,IAAI,KAAe,CAAC;QACpB,IAAI,CAAC;YACH,KAAK,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QAChC,CAAC;QAAC,OAAO,GAAY,EAAE,CAAC;YACtB,IAAK,GAA6B,CAAC,IAAI,KAAK,QAAQ;gBAAE,OAAO,CAAC,CAAC;YAC/D,MAAM,GAAG,CAAC;QACZ,CAAC;QAED,MAAM,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QAC1B,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,EAAE,GAAG,aAAa,CAAC,CAAC;QACjD,MAAM,SAAS,GAAG,MAAM,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAE,CAAC;QAEtD,MAAM,QAAQ,GAAG,KAAK;aACnB,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,yBAAyB,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;aAC9C,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,GAAG,SAAS,CAAC;aAC7C,IAAI,EAAE,CAAC;QAEV,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,CAAC,CAAC;QAEpC,6EAA6E;QAC7E,IAAI,SAAS,EAAE,CAAC;YACd,IAAI,CAAC;gBACH,MAAM,YAAY,GAAa,EAAE,CAAC;gBAClC,KAAK,MAAM,IAAI,IAAI,QAAQ,EAAE,CAAC;oBAC5B,IAAI,CAAC;wBACH,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,CAAC;wBAChE,YAAY,CAAC,IAAI,CAAC,OAAO,IAAI,SAAS,OAAO,EAAE,CAAC,CAAC;oBACnD,CAAC;oBAAC,MAAM,CAAC;wBACP,wBAAwB;oBAC1B,CAAC;gBACH,CAAC;gBACD,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;oBAC5B,MAAM,SAAS,CAAC,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;gBAC7C,CAAC;YACH,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,GAAG,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,EAAE,+DAA+D,CAAC,CAAC;YACrF,CAAC;QACH,CAAC;QAED,8EAA8E;QAC9E,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;QAC7C,MAAM,EAAE,CAAC,KAAK,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;QAC7D,KAAK,MAAM,IAAI,IAAI,QAAQ,EAAE,CAAC;YAC5B,IAAI,CAAC;gBACH,MAAM,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC,CAAC;YACrE,CAAC;YAAC,MAAM,CAAC;gBACP,sBAAsB;YACxB,CAAC;QACH,CAAC;QAED,8CAA8C;QAC9C,MAAM,oBAAoB,GAAG,iBAAiB,QAAQ,CAAC,MAAM,iBAAiB,QAAQ,CAAC,CAAC,CAAE,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,OAAO,QAAQ,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAE,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC;QAC3K,MAAM,MAAM,GAAG,IAAI,CAAC,gBAAgB,EAAE,CAAC;QACvC,IAAI,CAAC;YACH,MAAM,EAAE,CAAC,UAAU,CAAC,MAAM,EAAE,oBAAoB,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;YACnE,MAAM,IAAI,CAAC,kBAAkB,EAAE,CAAC;QAClC,CAAC;QAAC,MAAM,CAAC;YACP,cAAc;QAChB,CAAC;QAED,yBAAyB;QACzB,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;QAExB,GAAG,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,QAAQ,CAAC,MAAM,EAAE,aAAa,EAAE,EAAE,sBAAsB,CAAC,CAAC;QAC/E,OAAO,QAAQ,CAAC,MAAM,CAAC;IACzB,CAAC;IAED,8DAA8D;IAC9D,eAAe;QACb,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;IAC1B,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,eAAe,CAAC,IAAY;QAChC,MAAM,KAAK,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QACrD,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,kBAAkB,EAAE,EAAE,GAAG,KAAK,KAAK,CAAC,CAAC;QACrE,MAAM,KAAK,GAAG,SAAS,IAAI,IAAI,EAAE,CAAC,kBAAkB,EAAE,KAAK,IAAI,IAAI,CAAC;QAEpE,IAAI,CAAC;YACH,MAAM,EAAE,CAAC,UAAU,CAAC,QAAQ,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;QACxD,CAAC;QAAC,OAAO,GAAY,EAAE,CAAC;YACtB,IAAK,GAA6B,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;gBACrD,8CAA8C;gBAC9C,MAAM,EAAE,CAAC,SAAS,CAAC,QAAQ,EAAE,kBAAkB,KAAK,KAAK,KAAK,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;YACrF,CAAC;iBAAM,CAAC;gBACN,MAAM,GAAG,CAAC;YACZ,CAAC;QACH,CAAC;QAED,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC,uCAAuC;IAClE,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,YAAY,CAAC,KAAa,EAAE,KAAc;QAC9C,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,iBAAiB,CAAC,qBAAqB,CAAC,KAAK,CAAC,CAAC;QAC1E,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,EAAE,CACjD,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,IAAI,EAAE,KAAK,EAAE,SAAS,CAAC,CAC/C,CAAC;QACF,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC;QACzC,OAAO,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;IAC/D,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,UAAU,CAAC,EAAU,EAAE,MAAe;QAC1C,4DAA4D;QAC5D,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,iBAAiB,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;QAEtD,IAAI,IAAI,EAAE,CAAC;YACT,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,QAAQ,EAAE,SAAS,CAAC,CAAC;YACjE,IAAI,CAAC;gBACH,MAAM,EAAE,CAAC,KAAK,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;gBAC7D,MAAM,WAAW,GAAG;oBAClB,GAAG,IAAI;oBACP,WAAW,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;oBACrC,cAAc,EAAE,MAAM,IAAI,oBAAoB;iBAC/C,CAAC;gBACF,MAAM,EAAE,CAAC,SAAS,CAChB,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,GAAG,EAAE,OAAO,CAAC,EACnC,IAAI,CAAC,SAAS,CAAC,WAAW,EAAE,IAAI,EAAE,CAAC,CAAC,EACpC,EAAE,IAAI,EAAE,KAAK,EAAE,CAChB,CAAC;YACJ,CAAC;YAAC,MAAM,CAAC;gBACP,yBAAyB;YAC3B,CAAC;QACH,CAAC;QAED,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC,6BAA6B;QACtD,OAAO,IAAI,CAAC,iBAAiB,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;IAC/C,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,aAAa;QACjB,OAAO,IAAI,CAAC,kBAAkB,CAAC,cAAc,EAAE,CAAC;IAClD,CAAC;IAED;;OAEG;IACH,IAAI,gBAAgB;QAClB,OAAO,IAAI,CAAC,iBAAiB,CAAC;IAChC,CAAC;IAED;;OAEG;IACH,eAAe;QACb,OAAO,IAAI,CAAC,gBAAgB,EAAE,CAAC;IACjC,CAAC;IAEO,YAAY,CAAC,CAAS;QAC5B,IAAI,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;YACvB,OAAO,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;QAC7C,CAAC;QACD,OAAO,CAAC,CAAC;IACX,CAAC;IAEO,gBAAgB;QACtB,MAAM,QAAQ,GAAG,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;QAChE,OAAO,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC;YAC9B,CAAC,CAAC,QAAQ;YACV,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;IACzC,CAAC;IAEO,kBAAkB;QACxB,MAAM,QAAQ,GAAG,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC;QACjE,OAAO,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC;YAC9B,CAAC,CAAC,QAAQ;YACV,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;IACzC,CAAC;IAEO,aAAa;QACnB,MAAM,QAAQ,GAAG,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;QAC3D,OAAO,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC;YAC9B,CAAC,CAAC,QAAQ;YACV,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;IACzC,CAAC;IAEO,kBAAkB;QACxB,MAAM,QAAQ,GAAG,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;QAChE,OAAO,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC;YAC9B,CAAC,CAAC,QAAQ;YACV,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;IACzC,CAAC;IAEO,KAAK,CAAC,aAAa;QACzB,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,gBAAgB,EAAE,EAAE,MAAM,CAAC,CAAC;YAEnE,gDAAgD;YAChD,MAAM,IAAI,CAAC,oBAAoB,CAAC,OAAO,CAAC,CAAC;YAEzC,OAAO,OAAO,CAAC;QACjB,CAAC;QAAC,OAAO,GAAY,EAAE,CAAC;YACtB,IAAK,GAA6B,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;gBACrD,OAAO,IAAI,CAAC;YACd,CAAC;YACD,MAAM,GAAG,CAAC;QACZ,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,eAAe,CAAC,IAAY;QACxC,MAAM,KAAK,GAAa,EAAE,CAAC;QAC3B,MAAM,GAAG,GAAG,IAAI,CAAC,kBAAkB,EAAE,CAAC;QAEtC,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;YACpC,MAAM,SAAS,GAAG,KAAK;iBACpB,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,yBAAyB,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;iBAC9C,IAAI,EAAE;iBACN,OAAO,EAAE;iBACT,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;YAElB,KAAK,MAAM,IAAI,IAAI,SAAS,EAAE,CAAC;gBAC7B,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,CAAC;gBAChE,KAAK,CAAC,IAAI,CAAC,OAAO,IAAI,SAAS,OAAO,EAAE,CAAC,CAAC;YAC5C,CAAC;QACH,CAAC;QAAC,OAAO,GAAY,EAAE,CAAC;YACtB,IAAK,GAA6B,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;gBACrD,MAAM,GAAG,CAAC;YACZ,CAAC;QACH,CAAC;QAED,OAAO,KAAK,CAAC;IACf,CAAC;IAED,oEAAoE;IAEpE,0EAA0E;IAClE,iBAAiB;QACvB,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,gBAAgB,EAAE,CAAC,EAAE,kBAAkB,CAAC,CAAC;IAC9E,CAAC;IAED,iDAAiD;IACzC,YAAY,CAAC,OAAe;QAClC,OAAO,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACnE,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,kBAAkB;QACtB,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,gBAAgB,EAAE,EAAE,MAAM,CAAC,CAAC;YACnE,MAAM,IAAI,GAAwB;gBAChC,IAAI,EAAE,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC;gBAChC,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;aACpC,CAAC;YACF,MAAM,EAAE,CAAC,SAAS,CAChB,IAAI,CAAC,iBAAiB,EAAE,EACxB,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,EAC7B,EAAE,IAAI,EAAE,KAAK,EAAE,CAChB,CAAC;QACJ,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,GAAG,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,EAAE,sCAAsC,CAAC,CAAC;QAC5D,CAAC;IACH,CAAC;IAED;;;;OAIG;IACK,KAAK,CAAC,oBAAoB,CAAC,OAAe;QAChD,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,iBAAiB,EAAE,EAAE,MAAM,CAAC,CAAC;YAChE,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAwB,CAAC;YACpD,MAAM,WAAW,GAAG,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;YAE/C,IAAI,IAAI,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;gBAC9B,GAAG,CAAC,IAAI,CACN;oBACE,QAAQ,EAAE,IAAI,CAAC,IAAI;oBACnB,MAAM,EAAE,WAAW;oBACnB,YAAY,EAAE,IAAI,CAAC,SAAS;iBAC7B,EACD,sEAAsE,CACvE,CAAC;gBACF,OAAO,KAAK,CAAC;YACf,CAAC;YAED,OAAO,IAAI,CAAC;QACd,CAAC;QAAC,OAAO,GAAY,EAAE,CAAC;YACtB,IAAK,GAA6B,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;gBACrD,sDAAsD;gBACtD,GAAG,CAAC,IAAI,CAAC,2DAA2D,CAAC,CAAC;gBACtE,OAAO,IAAI,CAAC;YACd,CAAC;YACD,GAAG,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,EAAE,wCAAwC,CAAC,CAAC;YAC5D,OAAO,IAAI,CAAC,CAAC,qCAAqC;QACpD,CAAC;IACH,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,wBAAwB;QAC5B,MAAM,IAAI,CAAC,kBAAkB,EAAE,CAAC;IAClC,CAAC;CACF"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ObservationStore — Persistence for compressed observation blocks.
|
|
3
|
+
*
|
|
4
|
+
* Stores session-tier and cross-session observations as append-only JSONL files.
|
|
5
|
+
* Same pattern as SessionManager — one file per session, crash-resilient reads.
|
|
6
|
+
*
|
|
7
|
+
* Storage layout:
|
|
8
|
+
* ~/.zora/memory/observations/{sessionId}.jsonl (per-session observations)
|
|
9
|
+
* ~/.zora/memory/observations/cross-session.jsonl (cross-session rollups)
|
|
10
|
+
*/
|
|
11
|
+
export interface ObservationBlock {
|
|
12
|
+
/** Unique ID: obs_{timestamp}_{random} */
|
|
13
|
+
id: string;
|
|
14
|
+
/** Session this observation belongs to */
|
|
15
|
+
sessionId: string;
|
|
16
|
+
/** When the observation was created */
|
|
17
|
+
createdAt: string;
|
|
18
|
+
/** Which tier this observation belongs to */
|
|
19
|
+
tier: 'session' | 'cross-session';
|
|
20
|
+
/** The compressed observation text */
|
|
21
|
+
observations: string;
|
|
22
|
+
/** Which message indices were compressed [start, end) */
|
|
23
|
+
sourceMessageRange: [number, number];
|
|
24
|
+
/** Estimated token count of the observation text */
|
|
25
|
+
estimatedTokens: number;
|
|
26
|
+
}
|
|
27
|
+
export declare class ObservationStore {
|
|
28
|
+
private readonly _baseDir;
|
|
29
|
+
constructor(baseDir: string);
|
|
30
|
+
init(): Promise<void>;
|
|
31
|
+
/**
|
|
32
|
+
* Append an observation block to the appropriate file.
|
|
33
|
+
* Append-only — never overwrites existing observations.
|
|
34
|
+
*/
|
|
35
|
+
append(block: ObservationBlock): Promise<void>;
|
|
36
|
+
/**
|
|
37
|
+
* Load all observation blocks for a session, ordered by creation time.
|
|
38
|
+
* Skips malformed lines (crash-resilient).
|
|
39
|
+
*/
|
|
40
|
+
loadSession(sessionId: string): Promise<ObservationBlock[]>;
|
|
41
|
+
/**
|
|
42
|
+
* Load cross-session observations.
|
|
43
|
+
* @param limit Max number of most recent blocks to return.
|
|
44
|
+
*/
|
|
45
|
+
loadCrossSession(limit?: number): Promise<ObservationBlock[]>;
|
|
46
|
+
/**
|
|
47
|
+
* Build the combined observation text for a session.
|
|
48
|
+
* Returns all session-tier observations concatenated in order.
|
|
49
|
+
*/
|
|
50
|
+
buildSessionContext(sessionId: string): Promise<string>;
|
|
51
|
+
/**
|
|
52
|
+
* Build cross-session context string.
|
|
53
|
+
*/
|
|
54
|
+
buildCrossSessionContext(limit?: number): Promise<string>;
|
|
55
|
+
/**
|
|
56
|
+
* Get total estimated tokens for a session's observations.
|
|
57
|
+
*/
|
|
58
|
+
getSessionTokenCount(sessionId: string): Promise<number>;
|
|
59
|
+
/**
|
|
60
|
+
* Prune old session observation files.
|
|
61
|
+
* Keeps only the most recent N session files.
|
|
62
|
+
*/
|
|
63
|
+
pruneOldSessions(keepLast?: number): Promise<number>;
|
|
64
|
+
/**
|
|
65
|
+
* Generate a unique observation block ID.
|
|
66
|
+
*/
|
|
67
|
+
static generateId(): string;
|
|
68
|
+
private _readJsonlFile;
|
|
69
|
+
/**
|
|
70
|
+
* Sanitize a session ID for use as a filename.
|
|
71
|
+
* Prevents path traversal by removing slashes and dots.
|
|
72
|
+
*/
|
|
73
|
+
private _sanitizeId;
|
|
74
|
+
}
|
|
75
|
+
//# sourceMappingURL=observation-store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"observation-store.d.ts","sourceRoot":"","sources":["../../src/memory/observation-store.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAUH,MAAM,WAAW,gBAAgB;IAC/B,0CAA0C;IAC1C,EAAE,EAAE,MAAM,CAAC;IACX,0CAA0C;IAC1C,SAAS,EAAE,MAAM,CAAC;IAClB,uCAAuC;IACvC,SAAS,EAAE,MAAM,CAAC;IAClB,6CAA6C;IAC7C,IAAI,EAAE,SAAS,GAAG,eAAe,CAAC;IAClC,sCAAsC;IACtC,YAAY,EAAE,MAAM,CAAC;IACrB,yDAAyD;IACzD,kBAAkB,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACrC,oDAAoD;IACpD,eAAe,EAAE,MAAM,CAAC;CACzB;AAED,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;gBAEtB,OAAO,EAAE,MAAM;IAIrB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAI3B;;;OAGG;IACG,MAAM,CAAC,KAAK,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC;IASpD;;;OAGG;IACG,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC;IAKjE;;;OAGG;IACG,gBAAgB,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC;IASnE;;;OAGG;IACG,mBAAmB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAM7D;;OAEG;IACG,wBAAwB,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAM/D;;OAEG;IACG,oBAAoB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAK9D;;;OAGG;IACG,gBAAgB,CAAC,QAAQ,GAAE,MAAW,GAAG,OAAO,CAAC,MAAM,CAAC;IAwC9D;;OAEG;IACH,MAAM,CAAC,UAAU,IAAI,MAAM;YAQb,cAAc;IAuB5B;;;OAGG;IACH,OAAO,CAAC,WAAW;CAGpB"}
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ObservationStore — Persistence for compressed observation blocks.
|
|
3
|
+
*
|
|
4
|
+
* Stores session-tier and cross-session observations as append-only JSONL files.
|
|
5
|
+
* Same pattern as SessionManager — one file per session, crash-resilient reads.
|
|
6
|
+
*
|
|
7
|
+
* Storage layout:
|
|
8
|
+
* ~/.zora/memory/observations/{sessionId}.jsonl (per-session observations)
|
|
9
|
+
* ~/.zora/memory/observations/cross-session.jsonl (cross-session rollups)
|
|
10
|
+
*/
|
|
11
|
+
import fs from 'node:fs/promises';
|
|
12
|
+
import path from 'node:path';
|
|
13
|
+
import { createLogger } from '../utils/logger.js';
|
|
14
|
+
const log = createLogger('observation-store');
|
|
15
|
+
const CROSS_SESSION_FILE = 'cross-session.jsonl';
|
|
16
|
+
export class ObservationStore {
|
|
17
|
+
_baseDir;
|
|
18
|
+
constructor(baseDir) {
|
|
19
|
+
this._baseDir = baseDir;
|
|
20
|
+
}
|
|
21
|
+
async init() {
|
|
22
|
+
await fs.mkdir(this._baseDir, { recursive: true, mode: 0o700 });
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Append an observation block to the appropriate file.
|
|
26
|
+
* Append-only — never overwrites existing observations.
|
|
27
|
+
*/
|
|
28
|
+
async append(block) {
|
|
29
|
+
const filePath = block.tier === 'cross-session'
|
|
30
|
+
? path.join(this._baseDir, CROSS_SESSION_FILE)
|
|
31
|
+
: path.join(this._baseDir, `${this._sanitizeId(block.sessionId)}.jsonl`);
|
|
32
|
+
const line = JSON.stringify(block) + '\n';
|
|
33
|
+
await fs.appendFile(filePath, line, { mode: 0o600 });
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Load all observation blocks for a session, ordered by creation time.
|
|
37
|
+
* Skips malformed lines (crash-resilient).
|
|
38
|
+
*/
|
|
39
|
+
async loadSession(sessionId) {
|
|
40
|
+
const filePath = path.join(this._baseDir, `${this._sanitizeId(sessionId)}.jsonl`);
|
|
41
|
+
return this._readJsonlFile(filePath);
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Load cross-session observations.
|
|
45
|
+
* @param limit Max number of most recent blocks to return.
|
|
46
|
+
*/
|
|
47
|
+
async loadCrossSession(limit) {
|
|
48
|
+
const filePath = path.join(this._baseDir, CROSS_SESSION_FILE);
|
|
49
|
+
const blocks = await this._readJsonlFile(filePath);
|
|
50
|
+
if (limit !== undefined && blocks.length > limit) {
|
|
51
|
+
return blocks.slice(-limit);
|
|
52
|
+
}
|
|
53
|
+
return blocks;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Build the combined observation text for a session.
|
|
57
|
+
* Returns all session-tier observations concatenated in order.
|
|
58
|
+
*/
|
|
59
|
+
async buildSessionContext(sessionId) {
|
|
60
|
+
const blocks = await this.loadSession(sessionId);
|
|
61
|
+
if (blocks.length === 0)
|
|
62
|
+
return '';
|
|
63
|
+
return blocks.map(b => b.observations).join('\n\n');
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Build cross-session context string.
|
|
67
|
+
*/
|
|
68
|
+
async buildCrossSessionContext(limit) {
|
|
69
|
+
const blocks = await this.loadCrossSession(limit);
|
|
70
|
+
if (blocks.length === 0)
|
|
71
|
+
return '';
|
|
72
|
+
return blocks.map(b => b.observations).join('\n\n');
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Get total estimated tokens for a session's observations.
|
|
76
|
+
*/
|
|
77
|
+
async getSessionTokenCount(sessionId) {
|
|
78
|
+
const blocks = await this.loadSession(sessionId);
|
|
79
|
+
return blocks.reduce((sum, b) => sum + b.estimatedTokens, 0);
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Prune old session observation files.
|
|
83
|
+
* Keeps only the most recent N session files.
|
|
84
|
+
*/
|
|
85
|
+
async pruneOldSessions(keepLast = 50) {
|
|
86
|
+
let files;
|
|
87
|
+
try {
|
|
88
|
+
files = await fs.readdir(this._baseDir);
|
|
89
|
+
}
|
|
90
|
+
catch (err) {
|
|
91
|
+
if (err.code === 'ENOENT')
|
|
92
|
+
return 0;
|
|
93
|
+
throw err;
|
|
94
|
+
}
|
|
95
|
+
const sessionFiles = files
|
|
96
|
+
.filter(f => f.endsWith('.jsonl') && f !== CROSS_SESSION_FILE);
|
|
97
|
+
// Sort by file modification time (newest last) to avoid lexicographic ordering issues
|
|
98
|
+
const fileStats = await Promise.all(sessionFiles.map(async (f) => ({
|
|
99
|
+
name: f,
|
|
100
|
+
mtime: (await fs.stat(path.join(this._baseDir, f))).mtime
|
|
101
|
+
})));
|
|
102
|
+
const sortedFiles = fileStats
|
|
103
|
+
.sort((a, b) => a.mtime.getTime() - b.mtime.getTime())
|
|
104
|
+
.map(f => f.name);
|
|
105
|
+
if (sortedFiles.length <= keepLast)
|
|
106
|
+
return 0;
|
|
107
|
+
const toRemove = sortedFiles.slice(0, sortedFiles.length - keepLast);
|
|
108
|
+
let removed = 0;
|
|
109
|
+
for (const file of toRemove) {
|
|
110
|
+
try {
|
|
111
|
+
await fs.unlink(path.join(this._baseDir, file));
|
|
112
|
+
removed++;
|
|
113
|
+
}
|
|
114
|
+
catch {
|
|
115
|
+
// Best-effort cleanup
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
log.info({ removed, kept: keepLast }, 'Pruned old session observation files');
|
|
119
|
+
return removed;
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Generate a unique observation block ID.
|
|
123
|
+
*/
|
|
124
|
+
static generateId() {
|
|
125
|
+
const ts = Date.now();
|
|
126
|
+
const rand = Math.random().toString(36).substring(2, 8).padEnd(6, '0');
|
|
127
|
+
return `obs_${ts}_${rand}`;
|
|
128
|
+
}
|
|
129
|
+
// ── Private helpers ──────────────────────────────────────────────
|
|
130
|
+
async _readJsonlFile(filePath) {
|
|
131
|
+
let raw;
|
|
132
|
+
try {
|
|
133
|
+
raw = await fs.readFile(filePath, 'utf8');
|
|
134
|
+
}
|
|
135
|
+
catch (err) {
|
|
136
|
+
if (err.code === 'ENOENT')
|
|
137
|
+
return [];
|
|
138
|
+
throw err;
|
|
139
|
+
}
|
|
140
|
+
const blocks = [];
|
|
141
|
+
for (const line of raw.split('\n')) {
|
|
142
|
+
const trimmed = line.trim();
|
|
143
|
+
if (!trimmed)
|
|
144
|
+
continue;
|
|
145
|
+
try {
|
|
146
|
+
blocks.push(JSON.parse(trimmed));
|
|
147
|
+
}
|
|
148
|
+
catch {
|
|
149
|
+
log.warn({ line: trimmed.substring(0, 100) }, 'Skipping malformed observation line');
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
return blocks;
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Sanitize a session ID for use as a filename.
|
|
156
|
+
* Prevents path traversal by removing slashes and dots.
|
|
157
|
+
*/
|
|
158
|
+
_sanitizeId(id) {
|
|
159
|
+
return id.replace(/[^a-zA-Z0-9_-]/g, '_');
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
//# sourceMappingURL=observation-store.js.map
|