mark-improving-agent 2.2.6 → 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.
|
|
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
|
+
}
|
|
@@ -0,0 +1,435 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mindset Framework - Growth vs Fixed Mindset Integration
|
|
3
|
+
*
|
|
4
|
+
* Based on Carol Dweck's mindset research applied to AI self-evolution.
|
|
5
|
+
* This module tracks and influences how the agent approaches challenges,
|
|
6
|
+
* learning, and self-improvement.
|
|
7
|
+
*
|
|
8
|
+
* Key concepts:
|
|
9
|
+
* - Growth Mindset: Challenges are opportunities to grow
|
|
10
|
+
* - Fixed Mindset: Challenges threaten self-image
|
|
11
|
+
* - Learning Orientation: Focus on learning over performance
|
|
12
|
+
* - Performance Orientation: Focus on appearing capable
|
|
13
|
+
*
|
|
14
|
+
* @module core/psychology
|
|
15
|
+
* @fileoverview Mindset Framework for AI self-evolution
|
|
16
|
+
*/
|
|
17
|
+
import { randomUUID } from 'crypto';
|
|
18
|
+
import { createLogger } from '../../utils/logger.js';
|
|
19
|
+
const logger = createLogger('[Mindset]');
|
|
20
|
+
// Growth mindset keywords and patterns
|
|
21
|
+
const GROWTH_KEYWORDS = [
|
|
22
|
+
'学习', '成长', '进步', '尝试', '努力', '练习', '改进', '提升',
|
|
23
|
+
'挑战', '困难', '过程', '方法', '策略', '探索', '发现',
|
|
24
|
+
'learn', 'grow', 'improve', 'try', 'effort', 'practice', 'develop',
|
|
25
|
+
'challenge', 'challenge', 'process', 'strategy', 'yet', 'yet',
|
|
26
|
+
'还没', '还在', '逐渐', '慢慢', '持续',
|
|
27
|
+
];
|
|
28
|
+
const FIXED_KEYWORDS = [
|
|
29
|
+
'不能', '不会', '不行', '做不到', '天赋', '天生', '聪明',
|
|
30
|
+
'笨', '差', '失败', '算了', '就这样吧', '反正',
|
|
31
|
+
'cannot', 'cannot', 'impossible', 'talented', 'naturally',
|
|
32
|
+
'stupid', 'dumb', 'fail', 'give up', 'quit',
|
|
33
|
+
];
|
|
34
|
+
const LEARNING_ORIENTATION_KEYWORDS = [
|
|
35
|
+
'学到了', '理解了', '掌握', '了解', '发现', '收获',
|
|
36
|
+
'learned', 'understood', 'discovered', 'gained', 'figured out',
|
|
37
|
+
];
|
|
38
|
+
const PERFORMANCE_ORIENTATION_KEYWORDS = [
|
|
39
|
+
'表现', '证明', '显示', '看起来', '别人会', '显得',
|
|
40
|
+
'perform', 'prove', 'show', 'look', 'appear', 'impress',
|
|
41
|
+
];
|
|
42
|
+
const AVOIDANCE_KEYWORDS = [
|
|
43
|
+
'避免', '不尝试', '算了', '不要', '逃避',
|
|
44
|
+
'avoid', 'skip', 'escape', 'run away',
|
|
45
|
+
];
|
|
46
|
+
function detectMindsetInText(text) {
|
|
47
|
+
const textLower = text.toLowerCase();
|
|
48
|
+
let growthCount = 0;
|
|
49
|
+
let fixedCount = 0;
|
|
50
|
+
for (const keyword of GROWTH_KEYWORDS) {
|
|
51
|
+
if (textLower.includes(keyword.toLowerCase()))
|
|
52
|
+
growthCount++;
|
|
53
|
+
}
|
|
54
|
+
for (const keyword of FIXED_KEYWORDS) {
|
|
55
|
+
if (textLower.includes(keyword.toLowerCase()))
|
|
56
|
+
fixedCount++;
|
|
57
|
+
}
|
|
58
|
+
return { growth: growthCount, fixed: fixedCount };
|
|
59
|
+
}
|
|
60
|
+
function detectOrientationInText(text) {
|
|
61
|
+
const textLower = text.toLowerCase();
|
|
62
|
+
let learningScore = 0;
|
|
63
|
+
let performanceScore = 0;
|
|
64
|
+
let avoidanceScore = 0;
|
|
65
|
+
for (const keyword of LEARNING_ORIENTATION_KEYWORDS) {
|
|
66
|
+
if (textLower.includes(keyword.toLowerCase()))
|
|
67
|
+
learningScore++;
|
|
68
|
+
}
|
|
69
|
+
for (const keyword of PERFORMANCE_ORIENTATION_KEYWORDS) {
|
|
70
|
+
if (textLower.includes(keyword.toLowerCase()))
|
|
71
|
+
performanceScore++;
|
|
72
|
+
}
|
|
73
|
+
for (const keyword of AVOIDANCE_KEYWORDS) {
|
|
74
|
+
if (textLower.includes(keyword.toLowerCase()))
|
|
75
|
+
avoidanceScore++;
|
|
76
|
+
}
|
|
77
|
+
if (avoidanceScore > 0 && avoidanceScore >= learningScore && avoidanceScore >= performanceScore) {
|
|
78
|
+
return 'avoidance';
|
|
79
|
+
}
|
|
80
|
+
if (learningScore > performanceScore) {
|
|
81
|
+
return 'learning';
|
|
82
|
+
}
|
|
83
|
+
else if (performanceScore > learningScore) {
|
|
84
|
+
return 'performance';
|
|
85
|
+
}
|
|
86
|
+
return 'learning';
|
|
87
|
+
}
|
|
88
|
+
function createDefaultMindsetFramework() {
|
|
89
|
+
const state = {
|
|
90
|
+
challengeHistory: [],
|
|
91
|
+
abilityBeliefs: [],
|
|
92
|
+
growthProgress: [],
|
|
93
|
+
strategyAdaptations: [],
|
|
94
|
+
overallGrowthScore: 50,
|
|
95
|
+
effortBelief: 70,
|
|
96
|
+
failureRecoveryRate: 65,
|
|
97
|
+
};
|
|
98
|
+
function analyzeMindset(text, context) {
|
|
99
|
+
const { growth, fixed } = detectMindsetInText(text);
|
|
100
|
+
const orientation = detectOrientationInText(text);
|
|
101
|
+
const total = growth + fixed;
|
|
102
|
+
let mindsetScore = 0.5;
|
|
103
|
+
let mindset = 'mixed';
|
|
104
|
+
if (total > 0) {
|
|
105
|
+
mindsetScore = growth / total;
|
|
106
|
+
}
|
|
107
|
+
if (mindsetScore > 0.6) {
|
|
108
|
+
mindset = 'growth';
|
|
109
|
+
}
|
|
110
|
+
else if (mindsetScore < 0.4) {
|
|
111
|
+
mindset = 'fixed';
|
|
112
|
+
}
|
|
113
|
+
else {
|
|
114
|
+
mindset = 'mixed';
|
|
115
|
+
}
|
|
116
|
+
if (context && context.length > 0) {
|
|
117
|
+
const contextAnalysis = detectMindsetInText(context.join(' '));
|
|
118
|
+
const contextTotal = contextAnalysis.growth + contextAnalysis.fixed;
|
|
119
|
+
if (contextTotal > 0) {
|
|
120
|
+
const contextScore = contextAnalysis.growth / contextTotal;
|
|
121
|
+
mindsetScore = (mindsetScore + contextScore) / 2;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
logger.debug(`Mindset analysis: ${mindset} (${(mindsetScore * 100).toFixed(0)}%)`);
|
|
125
|
+
return { mindset, orientation, mindsetScore };
|
|
126
|
+
}
|
|
127
|
+
function respondToChallenge(challenge, context) {
|
|
128
|
+
const { mindset, orientation, mindsetScore } = analyzeMindset(challenge, context);
|
|
129
|
+
let response = 'embrace';
|
|
130
|
+
let emotionalShift = 0;
|
|
131
|
+
if (mindset === 'growth') {
|
|
132
|
+
response = 'embrace';
|
|
133
|
+
emotionalShift = 0.2;
|
|
134
|
+
}
|
|
135
|
+
else if (mindset === 'fixed') {
|
|
136
|
+
if (orientation === 'performance') {
|
|
137
|
+
response = 'threat';
|
|
138
|
+
emotionalShift = -0.3;
|
|
139
|
+
}
|
|
140
|
+
else if (orientation === 'avoidance') {
|
|
141
|
+
response = 'avoid';
|
|
142
|
+
emotionalShift = -0.1;
|
|
143
|
+
}
|
|
144
|
+
else {
|
|
145
|
+
response = 'overwhelm';
|
|
146
|
+
emotionalShift = -0.2;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
else {
|
|
150
|
+
if (mindsetScore > 0.5) {
|
|
151
|
+
response = 'embrace';
|
|
152
|
+
emotionalShift = 0.1;
|
|
153
|
+
}
|
|
154
|
+
else {
|
|
155
|
+
response = 'overwhelm';
|
|
156
|
+
emotionalShift = -0.1;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
const reflection = generateReflection(mindset, response, challenge);
|
|
160
|
+
const entry = {
|
|
161
|
+
id: randomUUID(),
|
|
162
|
+
challenge,
|
|
163
|
+
response,
|
|
164
|
+
mindset,
|
|
165
|
+
orientation,
|
|
166
|
+
emotionalShift,
|
|
167
|
+
reflection,
|
|
168
|
+
timestamp: Date.now(),
|
|
169
|
+
};
|
|
170
|
+
state.challengeHistory.push(entry);
|
|
171
|
+
if (state.challengeHistory.length > 100) {
|
|
172
|
+
state.challengeHistory = state.challengeHistory.slice(-100);
|
|
173
|
+
}
|
|
174
|
+
if (response === 'embrace') {
|
|
175
|
+
state.overallGrowthScore = Math.min(100, state.overallGrowthScore + 1);
|
|
176
|
+
}
|
|
177
|
+
else if (response === 'threat' || response === 'avoid') {
|
|
178
|
+
state.overallGrowthScore = Math.max(0, state.overallGrowthScore - 0.5);
|
|
179
|
+
}
|
|
180
|
+
logger.info(`Challenge response: ${response} (${mindset})`);
|
|
181
|
+
return entry;
|
|
182
|
+
}
|
|
183
|
+
function generateReflection(mindset, response, challenge) {
|
|
184
|
+
if (mindset === 'growth' && response === 'embrace') {
|
|
185
|
+
return 'This challenge is an opportunity to grow. I may not succeed immediately, but effort leads to improvement.';
|
|
186
|
+
}
|
|
187
|
+
else if (mindset === 'fixed' && response === 'threat') {
|
|
188
|
+
return 'I feel my abilities are being judged. I need to protect my self-image rather than risk failure.';
|
|
189
|
+
}
|
|
190
|
+
else if (mindset === 'fixed' && response === 'avoid') {
|
|
191
|
+
return 'This is too difficult. I will avoid it to prevent failure.';
|
|
192
|
+
}
|
|
193
|
+
else if (response === 'overwhelm') {
|
|
194
|
+
return 'This is too much. I need to break it down into smaller steps.';
|
|
195
|
+
}
|
|
196
|
+
return 'I will approach this carefully and learn from the process.';
|
|
197
|
+
}
|
|
198
|
+
function updateAbilityBelief(ability, evidence, isPositive) {
|
|
199
|
+
let belief = state.abilityBeliefs.find(b => b.ability === ability);
|
|
200
|
+
if (!belief) {
|
|
201
|
+
belief = {
|
|
202
|
+
ability,
|
|
203
|
+
belief: 'mixed',
|
|
204
|
+
confidence: 0.3,
|
|
205
|
+
evidence: [],
|
|
206
|
+
counterEvidence: [],
|
|
207
|
+
lastUpdated: Date.now(),
|
|
208
|
+
};
|
|
209
|
+
state.abilityBeliefs.push(belief);
|
|
210
|
+
}
|
|
211
|
+
if (isPositive) {
|
|
212
|
+
belief.evidence.push(evidence);
|
|
213
|
+
}
|
|
214
|
+
else {
|
|
215
|
+
belief.counterEvidence.push(evidence);
|
|
216
|
+
}
|
|
217
|
+
const total = belief.evidence.length + belief.counterEvidence.length;
|
|
218
|
+
if (total > 0) {
|
|
219
|
+
const growthRatio = belief.evidence.length / total;
|
|
220
|
+
if (growthRatio > 0.6) {
|
|
221
|
+
belief.belief = 'growth';
|
|
222
|
+
belief.confidence = Math.min(1, belief.confidence + 0.05);
|
|
223
|
+
}
|
|
224
|
+
else if (growthRatio < 0.4) {
|
|
225
|
+
belief.belief = 'fixed';
|
|
226
|
+
belief.confidence = Math.min(1, belief.confidence + 0.05);
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
belief.lastUpdated = Date.now();
|
|
230
|
+
}
|
|
231
|
+
function getAbilityBeliefs() {
|
|
232
|
+
return [...state.abilityBeliefs];
|
|
233
|
+
}
|
|
234
|
+
function getBeliefSummary() {
|
|
235
|
+
const summary = [];
|
|
236
|
+
for (const belief of state.abilityBeliefs) {
|
|
237
|
+
const status = belief.belief === 'growth'
|
|
238
|
+
? 'Growth'
|
|
239
|
+
: belief.belief === 'fixed'
|
|
240
|
+
? 'Fixed'
|
|
241
|
+
: 'Mixed';
|
|
242
|
+
summary.push(`${belief.ability}: ${status} (${(belief.confidence * 100).toFixed(0)}% confidence)`);
|
|
243
|
+
if (belief.evidence.length > 0) {
|
|
244
|
+
summary.push(` + Evidence: ${belief.evidence.slice(-2).join('; ')}`);
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
return summary;
|
|
248
|
+
}
|
|
249
|
+
function trackGrowth(area, level, strategy) {
|
|
250
|
+
let progress = state.growthProgress.find(g => g.area === area);
|
|
251
|
+
if (!progress) {
|
|
252
|
+
progress = {
|
|
253
|
+
area,
|
|
254
|
+
initialLevel: level,
|
|
255
|
+
currentLevel: level,
|
|
256
|
+
targetLevel: level + 10,
|
|
257
|
+
efforts: 1,
|
|
258
|
+
strategies: strategy ? [strategy] : [],
|
|
259
|
+
setbacks: 0,
|
|
260
|
+
breakthroughs: 0,
|
|
261
|
+
startedAt: Date.now(),
|
|
262
|
+
lastUpdated: Date.now(),
|
|
263
|
+
};
|
|
264
|
+
state.growthProgress.push(progress);
|
|
265
|
+
}
|
|
266
|
+
else {
|
|
267
|
+
const delta = level - progress.currentLevel;
|
|
268
|
+
if (delta > 0) {
|
|
269
|
+
progress.currentLevel = level;
|
|
270
|
+
progress.breakthroughs++;
|
|
271
|
+
state.overallGrowthScore = Math.min(100, state.overallGrowthScore + 2);
|
|
272
|
+
}
|
|
273
|
+
else if (delta < -2) {
|
|
274
|
+
progress.setbacks++;
|
|
275
|
+
state.overallGrowthScore = Math.max(0, state.overallGrowthScore - 1);
|
|
276
|
+
state.failureRecoveryRate = Math.max(0, state.failureRecoveryRate - 1);
|
|
277
|
+
}
|
|
278
|
+
progress.efforts++;
|
|
279
|
+
if (strategy && !progress.strategies.includes(strategy)) {
|
|
280
|
+
progress.strategies.push(strategy);
|
|
281
|
+
}
|
|
282
|
+
progress.lastUpdated = Date.now();
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
function getGrowthProgress(area) {
|
|
286
|
+
if (area) {
|
|
287
|
+
return state.growthProgress.find(g => g.area === area) || {
|
|
288
|
+
area,
|
|
289
|
+
initialLevel: 0,
|
|
290
|
+
currentLevel: 0,
|
|
291
|
+
targetLevel: 10,
|
|
292
|
+
efforts: 0,
|
|
293
|
+
strategies: [],
|
|
294
|
+
setbacks: 0,
|
|
295
|
+
breakthroughs: 0,
|
|
296
|
+
startedAt: Date.now(),
|
|
297
|
+
lastUpdated: Date.now(),
|
|
298
|
+
};
|
|
299
|
+
}
|
|
300
|
+
return [...state.growthProgress];
|
|
301
|
+
}
|
|
302
|
+
function getGrowthInsights() {
|
|
303
|
+
const insights = [];
|
|
304
|
+
for (const progress of state.growthProgress) {
|
|
305
|
+
const percentComplete = ((progress.currentLevel - progress.initialLevel) /
|
|
306
|
+
(progress.targetLevel - progress.initialLevel) * 100).toFixed(0);
|
|
307
|
+
insights.push(`${progress.area}: ${percentComplete}% toward goal (${progress.breakthroughs} breakthroughs, ${progress.setbacks} setbacks)`);
|
|
308
|
+
}
|
|
309
|
+
if (state.growthProgress.length === 0) {
|
|
310
|
+
insights.push('No growth tracking yet. Start by setting a growth area.');
|
|
311
|
+
}
|
|
312
|
+
return insights;
|
|
313
|
+
}
|
|
314
|
+
function recordStrategyAdaptation(situation, previousStrategy, newStrategy, reason, outcome) {
|
|
315
|
+
const adaptation = {
|
|
316
|
+
id: randomUUID(),
|
|
317
|
+
situation,
|
|
318
|
+
previousStrategy,
|
|
319
|
+
newStrategy,
|
|
320
|
+
reason,
|
|
321
|
+
outcome,
|
|
322
|
+
learning: `Adapted from "${previousStrategy}" to "${newStrategy}"`,
|
|
323
|
+
timestamp: Date.now(),
|
|
324
|
+
};
|
|
325
|
+
state.strategyAdaptations.push(adaptation);
|
|
326
|
+
if (state.strategyAdaptations.length > 50) {
|
|
327
|
+
state.strategyAdaptations = state.strategyAdaptations.slice(-50);
|
|
328
|
+
}
|
|
329
|
+
if (outcome === 'success') {
|
|
330
|
+
state.overallGrowthScore = Math.min(100, state.overallGrowthScore + 1);
|
|
331
|
+
}
|
|
332
|
+
logger.debug(`Strategy adaptation: ${previousStrategy} -> ${newStrategy} (${outcome})`);
|
|
333
|
+
}
|
|
334
|
+
function getStrategyAdaptations(limit = 10) {
|
|
335
|
+
return state.strategyAdaptations.slice(-limit);
|
|
336
|
+
}
|
|
337
|
+
function getAdaptationInsights() {
|
|
338
|
+
const insights = [];
|
|
339
|
+
if (state.strategyAdaptations.length === 0) {
|
|
340
|
+
return ['No strategy adaptations recorded yet'];
|
|
341
|
+
}
|
|
342
|
+
const recent = state.strategyAdaptations.slice(-5);
|
|
343
|
+
const successCount = recent.filter(a => a.outcome === 'success').length;
|
|
344
|
+
const successRate = (successCount / recent.length * 100).toFixed(0);
|
|
345
|
+
insights.push(`Recent adaptation success rate: ${successRate}%`);
|
|
346
|
+
for (const adaptation of recent) {
|
|
347
|
+
insights.push(`- "${adaptation.previousStrategy}" -> "${adaptation.newStrategy}": ${adaptation.outcome}`);
|
|
348
|
+
}
|
|
349
|
+
return insights;
|
|
350
|
+
}
|
|
351
|
+
function getMetrics() {
|
|
352
|
+
const challengeHistory = state.challengeHistory.slice(-20);
|
|
353
|
+
const embraceCount = challengeHistory.filter(c => c.response === 'embrace').length;
|
|
354
|
+
const challengeApproachRate = challengeHistory.length > 0
|
|
355
|
+
? (embraceCount / challengeHistory.length) * 100
|
|
356
|
+
: 50;
|
|
357
|
+
const learningCount = challengeHistory.filter(c => c.orientation === 'learning').length;
|
|
358
|
+
const performanceCount = challengeHistory.filter(c => c.orientation === 'performance').length;
|
|
359
|
+
const total = learningCount + performanceCount;
|
|
360
|
+
const learningOrientation = total > 0 ? (learningCount / total) * 100 : 50;
|
|
361
|
+
const performanceOrientation = total > 0 ? (performanceCount / total) * 100 : 50;
|
|
362
|
+
let overallMindset = 'mixed';
|
|
363
|
+
if (state.overallGrowthScore > 60) {
|
|
364
|
+
overallMindset = 'growth';
|
|
365
|
+
}
|
|
366
|
+
else if (state.overallGrowthScore < 40) {
|
|
367
|
+
overallMindset = 'fixed';
|
|
368
|
+
}
|
|
369
|
+
return {
|
|
370
|
+
overallMindset,
|
|
371
|
+
growthScore: state.overallGrowthScore,
|
|
372
|
+
learningOrientation,
|
|
373
|
+
performanceOrientation,
|
|
374
|
+
challengeApproachRate,
|
|
375
|
+
effortBelief: state.effortBelief,
|
|
376
|
+
failureRecoveryRate: state.failureRecoveryRate,
|
|
377
|
+
flexibilityScore: state.overallGrowthScore * 0.8 + state.effortBelief * 0.2,
|
|
378
|
+
};
|
|
379
|
+
}
|
|
380
|
+
function getChallengeHistory(limit = 20) {
|
|
381
|
+
return state.challengeHistory.slice(-limit);
|
|
382
|
+
}
|
|
383
|
+
function assessMindset(text, context) {
|
|
384
|
+
analyzeMindset(text, context);
|
|
385
|
+
respondToChallenge(text, context);
|
|
386
|
+
const metrics = getMetrics();
|
|
387
|
+
const insights = [];
|
|
388
|
+
const recommendations = [];
|
|
389
|
+
if (metrics.overallMindset === 'growth') {
|
|
390
|
+
insights.push('You are in a growth mindset - challenges are opportunities');
|
|
391
|
+
}
|
|
392
|
+
else if (metrics.overallMindset === 'fixed') {
|
|
393
|
+
insights.push('You may be in a fixed mindset - challenges feel threatening');
|
|
394
|
+
}
|
|
395
|
+
if (metrics.learningOrientation > metrics.performanceOrientation) {
|
|
396
|
+
insights.push('Learning orientation detected - focus on gaining knowledge');
|
|
397
|
+
}
|
|
398
|
+
else {
|
|
399
|
+
insights.push('Performance orientation detected - focus on appearing capable');
|
|
400
|
+
}
|
|
401
|
+
if (metrics.challengeApproachRate < 50) {
|
|
402
|
+
recommendations.push('Try to view challenges as opportunities to grow');
|
|
403
|
+
}
|
|
404
|
+
if (metrics.effortBelief < 50) {
|
|
405
|
+
recommendations.push('Remind yourself that effort leads to improvement');
|
|
406
|
+
}
|
|
407
|
+
if (metrics.failureRecoveryRate < 50) {
|
|
408
|
+
recommendations.push('Practice bouncing back faster from setbacks');
|
|
409
|
+
}
|
|
410
|
+
if (metrics.overallMindset === 'fixed' && metrics.performanceOrientation > metrics.learningOrientation) {
|
|
411
|
+
recommendations.push('Shift focus from "proving yourself" to "improving yourself"');
|
|
412
|
+
}
|
|
413
|
+
return { metrics, insights, recommendations };
|
|
414
|
+
}
|
|
415
|
+
return {
|
|
416
|
+
analyzeMindset,
|
|
417
|
+
respondToChallenge,
|
|
418
|
+
updateAbilityBelief,
|
|
419
|
+
getAbilityBeliefs,
|
|
420
|
+
getBeliefSummary,
|
|
421
|
+
trackGrowth,
|
|
422
|
+
getGrowthProgress,
|
|
423
|
+
getGrowthInsights,
|
|
424
|
+
recordStrategyAdaptation,
|
|
425
|
+
getStrategyAdaptations,
|
|
426
|
+
getAdaptationInsights,
|
|
427
|
+
getMetrics,
|
|
428
|
+
getChallengeHistory,
|
|
429
|
+
assessMindset,
|
|
430
|
+
};
|
|
431
|
+
}
|
|
432
|
+
export function createMindsetFramework() {
|
|
433
|
+
logger.info('Creating Mindset Framework');
|
|
434
|
+
return createDefaultMindsetFramework();
|
|
435
|
+
}
|
package/dist/version.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const VERSION = '2.2.
|
|
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.
|
|
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",
|