mark-improving-agent 2.2.7 → 2.2.8

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/VERSION CHANGED
@@ -1 +1 @@
1
- 2.2.7
1
+ 2.2.8
@@ -0,0 +1,225 @@
1
+ /**
2
+ * Cognitive Budget Manager
3
+ *
4
+ * Intelligently manages token usage and context window to prevent overflow.
5
+ * Tracks token consumption, predicts when context will exceed limits,
6
+ * and proactively compresses or archives low-priority content.
7
+ *
8
+ * @module cognition/cognitive-budget
9
+ * @fileoverview Cognitive budget management for context window optimization
10
+ */
11
+ import { atomicWriteJSON, readJSON } from '../../storage/archive.js';
12
+ import { createLogger } from '../../utils/logger.js';
13
+ const logger = createLogger('[CognitiveBudget]');
14
+ const DEFAULT_CONFIG = {
15
+ maxTokens: 100000,
16
+ warningThreshold: 0.7,
17
+ criticalThreshold: 0.9,
18
+ autoCompress: true,
19
+ compressionRatio: 0.5,
20
+ };
21
+ const STATE_FILE = 'cognitive-budget.json';
22
+ /**
23
+ * Estimate tokens from text (rough approximation)
24
+ * 1 token ≈ 4 characters for English, 2 for Chinese
25
+ */
26
+ function estimateTokens(text) {
27
+ if (!text)
28
+ return 0;
29
+ let count = 0;
30
+ for (const char of text) {
31
+ if (char.charCodeAt(0) > 127) {
32
+ count += 2; // Chinese/Unicode
33
+ }
34
+ else {
35
+ count += 1;
36
+ }
37
+ }
38
+ return Math.ceil(count / 4);
39
+ }
40
+ /**
41
+ * Categorize content by priority
42
+ */
43
+ function getContentPriority(category) {
44
+ const priorityMap = {
45
+ 'system': 1.0, // Highest - system prompts
46
+ 'identity': 0.95, // Identity core
47
+ 'memory': 0.8, // Long-term memory
48
+ 'goals': 0.75, // Active goals
49
+ 'context': 0.6, // Recent context
50
+ 'reflection': 0.5, // Reflection data
51
+ 'history': 0.3, // Chat history
52
+ 'archive': 0.1, // Archived content - lowest
53
+ };
54
+ return priorityMap[category] ?? 0.5;
55
+ }
56
+ export function createCognitiveBudgetManager(dataDir, config = {}) {
57
+ const cfg = { ...DEFAULT_CONFIG, ...config };
58
+ const usage = new Map();
59
+ const alerts = [];
60
+ let totalTokens = 0;
61
+ let sessionStart = Date.now();
62
+ const statePath = `${dataDir}/cognition/${STATE_FILE}`;
63
+ function track(category, tokens) {
64
+ if (tokens <= 0)
65
+ return;
66
+ const current = usage.get(category) || 0;
67
+ usage.set(category, current + tokens);
68
+ totalTokens += tokens;
69
+ logger.debug(`Tracked ${tokens} tokens for '${category}'`, {
70
+ categoryTotal: usage.get(category),
71
+ overallTotal: totalTokens,
72
+ });
73
+ }
74
+ function getUsage() {
75
+ const byCategory = {};
76
+ let sum = 0;
77
+ for (const [cat, tokens] of usage) {
78
+ byCategory[cat] = tokens;
79
+ sum += tokens;
80
+ }
81
+ return {
82
+ current: sum,
83
+ max: cfg.maxTokens,
84
+ ratio: sum / cfg.maxTokens,
85
+ byCategory,
86
+ };
87
+ }
88
+ function getLoadLevel() {
89
+ const ratio = getUsage().ratio;
90
+ if (ratio >= cfg.criticalThreshold)
91
+ return 'critical';
92
+ if (ratio >= cfg.warningThreshold)
93
+ return 'warning';
94
+ if (ratio >= 0.5)
95
+ return 'moderate';
96
+ return 'healthy';
97
+ }
98
+ function checkThresholds() {
99
+ const level = getLoadLevel();
100
+ if (level === 'healthy')
101
+ return null;
102
+ const usage = getUsage();
103
+ const recommendations = [];
104
+ switch (level) {
105
+ case 'moderate':
106
+ recommendations.push('Consider summarizing old context soon');
107
+ break;
108
+ case 'warning':
109
+ recommendations.push('Archive low-priority content');
110
+ recommendations.push('Enable compression if not already');
111
+ break;
112
+ case 'critical':
113
+ recommendations.push('Immediately archive or compress content');
114
+ recommendations.push('Consider fragmenting long context');
115
+ recommendations.push('Prune oldest history entries');
116
+ break;
117
+ }
118
+ const messages = {
119
+ healthy: 'Context budget healthy',
120
+ moderate: 'Context usage increasing',
121
+ warning: 'Context approaching limit - action recommended',
122
+ critical: 'Context critical - immediate action required',
123
+ };
124
+ return {
125
+ level,
126
+ message: messages[level],
127
+ timestamp: Date.now(),
128
+ recommendations,
129
+ };
130
+ }
131
+ function getCompressionRecommendations(limit = 5) {
132
+ const recommendations = [];
133
+ const usage = getUsage();
134
+ if (usage.current < cfg.maxTokens * 0.5) {
135
+ return recommendations;
136
+ }
137
+ // Analyze each category for compression potential
138
+ for (const [category, tokens] of Object.entries(usage.byCategory)) {
139
+ const priority = getContentPriority(category);
140
+ const capacity = cfg.maxTokens * (1 - priority);
141
+ if (tokens > capacity * 0.3) {
142
+ const excess = tokens - capacity * 0.3;
143
+ const priorityScore = 1 - priority;
144
+ recommendations.push({
145
+ priority: priorityScore,
146
+ reason: `Category '${category}' has ${tokens} tokens at priority ${priority.toFixed(2)}`,
147
+ estimatedSavings: Math.floor(excess * 0.5),
148
+ target: category,
149
+ strategy: priority < 0.3 ? 'prune' : priority < 0.6 ? 'archive' : 'summarize',
150
+ });
151
+ }
152
+ }
153
+ // Sort by priority (highest first)
154
+ recommendations.sort((a, b) => b.priority - a.priority);
155
+ return recommendations.slice(0, limit);
156
+ }
157
+ async function compress(recommendation) {
158
+ logger.info(`Compressing category: ${recommendation.target}`, recommendation);
159
+ const current = usage.get(recommendation.target) || 0;
160
+ const savings = Math.floor(current * (1 - cfg.compressionRatio));
161
+ // Apply compression
162
+ usage.set(recommendation.target, current - savings);
163
+ totalTokens -= savings;
164
+ // Record alert
165
+ alerts.push({
166
+ level: getLoadLevel(),
167
+ message: `Compressed ${recommendation.target}: freed ~${savings} tokens`,
168
+ timestamp: Date.now(),
169
+ recommendations: [recommendation.strategy],
170
+ });
171
+ // Keep only last 50 alerts
172
+ if (alerts.length > 50) {
173
+ alerts.shift();
174
+ }
175
+ await persist();
176
+ return true;
177
+ }
178
+ function reset() {
179
+ usage.clear();
180
+ totalTokens = 0;
181
+ sessionStart = Date.now();
182
+ alerts.length = 0;
183
+ }
184
+ async function persist() {
185
+ const state = {
186
+ usage: Object.fromEntries(usage),
187
+ totalTokens,
188
+ sessionStart,
189
+ config: cfg,
190
+ alerts: alerts.slice(-20),
191
+ };
192
+ await atomicWriteJSON(statePath, state);
193
+ }
194
+ async function boot() {
195
+ const loaded = await readJSON(statePath, {});
196
+ if (loaded) {
197
+ if (loaded.usage) {
198
+ for (const [k, v] of Object.entries(loaded.usage)) {
199
+ usage.set(k, v);
200
+ }
201
+ }
202
+ if (typeof loaded.totalTokens === 'number') {
203
+ totalTokens = loaded.totalTokens;
204
+ }
205
+ if (loaded.alerts) {
206
+ alerts.push(...loaded.alerts.slice(-20));
207
+ }
208
+ }
209
+ logger.info('CognitiveBudgetManager initialized', {
210
+ maxTokens: cfg.maxTokens,
211
+ currentTokens: getUsage().current,
212
+ });
213
+ }
214
+ return {
215
+ track,
216
+ getUsage,
217
+ getLoadLevel,
218
+ checkThresholds,
219
+ getCompressionRecommendations,
220
+ compress,
221
+ reset,
222
+ persist,
223
+ boot,
224
+ };
225
+ }
@@ -11,3 +11,4 @@ export * from './self-evolution.js';
11
11
  export * from './cognitive-architecture.js';
12
12
  export * from './meta-agent.js';
13
13
  export * from './active-inference.js';
14
+ export { createCognitiveBudgetManager } from './cognitive-budget.js';
package/dist/version.js CHANGED
@@ -1 +1 @@
1
- export const VERSION = '2.2.7';
1
+ export const VERSION = '2.2.8';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mark-improving-agent",
3
- "version": "2.2.7",
3
+ "version": "2.2.8",
4
4
  "description": "Self-evolving AI agent with permanent memory, identity continuity, and self-evolution — for AI agents that need to remember, learn, and evolve across sessions",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",