genesis-ai-cli 8.0.1 → 8.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/src/brain/index.d.ts +23 -0
- package/dist/src/brain/index.js +104 -11
- package/dist/src/brain/persistence.d.ts +105 -0
- package/dist/src/brain/persistence.js +351 -0
- package/dist/src/index.js +10 -2
- package/package.json +1 -1
|
@@ -53,6 +53,10 @@ export declare class Brain {
|
|
|
53
53
|
private stateStore;
|
|
54
54
|
private worldModel;
|
|
55
55
|
private darwinGodel;
|
|
56
|
+
private persistence;
|
|
57
|
+
private toolCache;
|
|
58
|
+
private readonly TOOL_CACHE_TTL;
|
|
59
|
+
private readonly TOOL_CACHE_MAX_SIZE;
|
|
56
60
|
private running;
|
|
57
61
|
private currentState;
|
|
58
62
|
private systemPrompt;
|
|
@@ -117,8 +121,17 @@ export declare class Brain {
|
|
|
117
121
|
private stepGrounding;
|
|
118
122
|
/**
|
|
119
123
|
* Tools module: execute tool calls
|
|
124
|
+
* v8.2: Added caching for repeated tool calls
|
|
120
125
|
*/
|
|
121
126
|
private stepTools;
|
|
127
|
+
/**
|
|
128
|
+
* v8.2: Clean expired entries from tool cache
|
|
129
|
+
*/
|
|
130
|
+
private cleanToolCache;
|
|
131
|
+
/**
|
|
132
|
+
* v8.2: Generate cache key from tool call
|
|
133
|
+
*/
|
|
134
|
+
private getToolCacheKey;
|
|
122
135
|
/**
|
|
123
136
|
* Healing module: recover from errors
|
|
124
137
|
*/
|
|
@@ -193,6 +206,7 @@ export declare class Brain {
|
|
|
193
206
|
private createInitialMetrics;
|
|
194
207
|
/**
|
|
195
208
|
* Update metrics after a cycle
|
|
209
|
+
* v8.1: Also persist metrics to disk
|
|
196
210
|
*/
|
|
197
211
|
private updateMetrics;
|
|
198
212
|
/**
|
|
@@ -213,6 +227,7 @@ export declare class Brain {
|
|
|
213
227
|
private emit;
|
|
214
228
|
/**
|
|
215
229
|
* Get brain status
|
|
230
|
+
* v8.1: Includes persisted consciousness stats
|
|
216
231
|
*/
|
|
217
232
|
getStatus(): {
|
|
218
233
|
running: boolean;
|
|
@@ -221,6 +236,14 @@ export declare class Brain {
|
|
|
221
236
|
lastState: BrainState | null;
|
|
222
237
|
metrics: BrainMetrics;
|
|
223
238
|
moduleStates: Record<string, boolean>;
|
|
239
|
+
persisted: {
|
|
240
|
+
peakPhi: number;
|
|
241
|
+
avgPhi: number;
|
|
242
|
+
totalIgnitions: number;
|
|
243
|
+
totalBroadcasts: number;
|
|
244
|
+
totalSessions: number;
|
|
245
|
+
totalUptime: number;
|
|
246
|
+
};
|
|
224
247
|
};
|
|
225
248
|
/**
|
|
226
249
|
* Get configuration
|
package/dist/src/brain/index.js
CHANGED
|
@@ -75,6 +75,8 @@ const index_js_6 = require("../kernel/index.js");
|
|
|
75
75
|
const index_js_7 = require("../persistence/index.js");
|
|
76
76
|
const index_js_8 = require("../world-model/index.js");
|
|
77
77
|
const index_js_9 = require("../self-modification/index.js");
|
|
78
|
+
// v8.1: Brain State Persistence
|
|
79
|
+
const persistence_js_1 = require("./persistence.js");
|
|
78
80
|
// ============================================================================
|
|
79
81
|
// Brain Class
|
|
80
82
|
// ============================================================================
|
|
@@ -95,6 +97,12 @@ class Brain {
|
|
|
95
97
|
stateStore = null;
|
|
96
98
|
worldModel = null;
|
|
97
99
|
darwinGodel = null;
|
|
100
|
+
// v8.1: State Persistence
|
|
101
|
+
persistence;
|
|
102
|
+
// v8.2: Tool Results Cache (approved self-modification)
|
|
103
|
+
toolCache = new Map();
|
|
104
|
+
TOOL_CACHE_TTL = 60000; // 1 minute TTL
|
|
105
|
+
TOOL_CACHE_MAX_SIZE = 100;
|
|
98
106
|
// State
|
|
99
107
|
running = false;
|
|
100
108
|
currentState = null;
|
|
@@ -139,6 +147,9 @@ class Brain {
|
|
|
139
147
|
thinkingBudget: 4096,
|
|
140
148
|
});
|
|
141
149
|
}
|
|
150
|
+
// v8.1: Initialize state persistence and load persisted metrics
|
|
151
|
+
this.persistence = (0, persistence_js_1.getBrainStatePersistence)();
|
|
152
|
+
this.metrics = { ...this.metrics, ...this.persistence.getMetrics() };
|
|
142
153
|
// v7.13: Initialize full module integration (lazy - on first use)
|
|
143
154
|
this.initializeV713Modules();
|
|
144
155
|
}
|
|
@@ -556,6 +567,7 @@ class Brain {
|
|
|
556
567
|
}
|
|
557
568
|
/**
|
|
558
569
|
* Tools module: execute tool calls
|
|
570
|
+
* v8.2: Added caching for repeated tool calls
|
|
559
571
|
*/
|
|
560
572
|
async stepTools(state) {
|
|
561
573
|
if (state.toolCalls.length === 0) {
|
|
@@ -567,21 +579,44 @@ class Brain {
|
|
|
567
579
|
// Parse tool calls for dispatcher
|
|
568
580
|
const dispatcherCalls = this.dispatcher.parseToolCalls(state.response);
|
|
569
581
|
const results = [];
|
|
582
|
+
// v8.2: Check cache and clean expired entries
|
|
583
|
+
this.cleanToolCache();
|
|
570
584
|
if (dispatcherCalls.length > 0) {
|
|
571
|
-
const
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
});
|
|
580
|
-
if (r.success) {
|
|
585
|
+
const uncachedCalls = [];
|
|
586
|
+
// v8.2: Check cache for each call
|
|
587
|
+
for (const call of dispatcherCalls) {
|
|
588
|
+
const cacheKey = this.getToolCacheKey(call);
|
|
589
|
+
const cached = this.toolCache.get(cacheKey);
|
|
590
|
+
if (cached && (Date.now() - cached.timestamp) < this.TOOL_CACHE_TTL) {
|
|
591
|
+
// Cache hit
|
|
592
|
+
results.push({ ...cached.result, cached: true });
|
|
581
593
|
this.metrics.toolSuccesses++;
|
|
582
594
|
}
|
|
583
595
|
else {
|
|
584
|
-
|
|
596
|
+
uncachedCalls.push(call);
|
|
597
|
+
}
|
|
598
|
+
}
|
|
599
|
+
// Execute uncached calls
|
|
600
|
+
if (uncachedCalls.length > 0) {
|
|
601
|
+
const dispatchResult = await this.dispatcher.dispatch(uncachedCalls);
|
|
602
|
+
for (const r of dispatchResult.results) {
|
|
603
|
+
const result = {
|
|
604
|
+
name: r.name,
|
|
605
|
+
success: r.success,
|
|
606
|
+
data: r.data,
|
|
607
|
+
error: r.error,
|
|
608
|
+
duration: r.duration,
|
|
609
|
+
};
|
|
610
|
+
results.push(result);
|
|
611
|
+
// v8.2: Cache successful results
|
|
612
|
+
if (r.success) {
|
|
613
|
+
const cacheKey = this.getToolCacheKey({ name: r.name, arguments: {} });
|
|
614
|
+
this.toolCache.set(cacheKey, { result, timestamp: Date.now() });
|
|
615
|
+
this.metrics.toolSuccesses++;
|
|
616
|
+
}
|
|
617
|
+
else {
|
|
618
|
+
this.metrics.toolFailures++;
|
|
619
|
+
}
|
|
585
620
|
}
|
|
586
621
|
}
|
|
587
622
|
}
|
|
@@ -603,6 +638,34 @@ class Brain {
|
|
|
603
638
|
reason: 'tool_results',
|
|
604
639
|
};
|
|
605
640
|
}
|
|
641
|
+
/**
|
|
642
|
+
* v8.2: Clean expired entries from tool cache
|
|
643
|
+
*/
|
|
644
|
+
cleanToolCache() {
|
|
645
|
+
const now = Date.now();
|
|
646
|
+
// Remove expired entries
|
|
647
|
+
for (const [key, entry] of this.toolCache.entries()) {
|
|
648
|
+
if (now - entry.timestamp > this.TOOL_CACHE_TTL) {
|
|
649
|
+
this.toolCache.delete(key);
|
|
650
|
+
}
|
|
651
|
+
}
|
|
652
|
+
// Enforce max size (LRU-style: remove oldest entries)
|
|
653
|
+
if (this.toolCache.size > this.TOOL_CACHE_MAX_SIZE) {
|
|
654
|
+
const entries = Array.from(this.toolCache.entries())
|
|
655
|
+
.sort((a, b) => a[1].timestamp - b[1].timestamp);
|
|
656
|
+
const toRemove = entries.slice(0, this.toolCache.size - this.TOOL_CACHE_MAX_SIZE);
|
|
657
|
+
for (const [key] of toRemove) {
|
|
658
|
+
this.toolCache.delete(key);
|
|
659
|
+
}
|
|
660
|
+
}
|
|
661
|
+
}
|
|
662
|
+
/**
|
|
663
|
+
* v8.2: Generate cache key from tool call
|
|
664
|
+
*/
|
|
665
|
+
getToolCacheKey(call) {
|
|
666
|
+
const argsStr = call.arguments ? JSON.stringify(call.arguments) : '';
|
|
667
|
+
return `${call.name}:${argsStr}`;
|
|
668
|
+
}
|
|
606
669
|
/**
|
|
607
670
|
* Healing module: recover from errors
|
|
608
671
|
*/
|
|
@@ -1374,6 +1437,7 @@ class Brain {
|
|
|
1374
1437
|
}
|
|
1375
1438
|
/**
|
|
1376
1439
|
* Update metrics after a cycle
|
|
1440
|
+
* v8.1: Also persist metrics to disk
|
|
1377
1441
|
*/
|
|
1378
1442
|
updateMetrics(state, transitions) {
|
|
1379
1443
|
const cycleTime = Date.now() - state.startTime;
|
|
@@ -1397,6 +1461,23 @@ class Brain {
|
|
|
1397
1461
|
this.metrics.moduleTransitions[module] =
|
|
1398
1462
|
(this.metrics.moduleTransitions[module] || 0) + 1;
|
|
1399
1463
|
}
|
|
1464
|
+
// v8.1: Persist metrics and phi to disk
|
|
1465
|
+
this.persistence.updateMetrics({
|
|
1466
|
+
totalCycles: 1,
|
|
1467
|
+
successfulCycles: state.error ? 0 : 1,
|
|
1468
|
+
failedCycles: state.error ? 1 : 0,
|
|
1469
|
+
avgCycleTime: cycleTime,
|
|
1470
|
+
memoryRecalls: state.context.immediate.length + state.context.episodic.length,
|
|
1471
|
+
toolExecutions: state.toolResults.length,
|
|
1472
|
+
toolSuccesses: state.toolResults.filter(r => r.success).length,
|
|
1473
|
+
toolFailures: state.toolResults.filter(r => !r.success).length,
|
|
1474
|
+
healingAttempts: state.healingAttempts,
|
|
1475
|
+
});
|
|
1476
|
+
this.persistence.recordPhi(state.phi, state.query.slice(0, 50));
|
|
1477
|
+
if (state.ignited) {
|
|
1478
|
+
this.persistence.recordBroadcast();
|
|
1479
|
+
}
|
|
1480
|
+
this.persistence.save();
|
|
1400
1481
|
}
|
|
1401
1482
|
/**
|
|
1402
1483
|
* Get current metrics
|
|
@@ -1438,8 +1519,11 @@ class Brain {
|
|
|
1438
1519
|
// ============================================================================
|
|
1439
1520
|
/**
|
|
1440
1521
|
* Get brain status
|
|
1522
|
+
* v8.1: Includes persisted consciousness stats
|
|
1441
1523
|
*/
|
|
1442
1524
|
getStatus() {
|
|
1525
|
+
const consciousnessStats = this.persistence.getConsciousnessStats();
|
|
1526
|
+
const persistedState = this.persistence.getState();
|
|
1443
1527
|
return {
|
|
1444
1528
|
running: this.running,
|
|
1445
1529
|
phi: this.getCurrentPhi(),
|
|
@@ -1461,6 +1545,15 @@ class Brain {
|
|
|
1461
1545
|
worldModel: this.worldModel !== null,
|
|
1462
1546
|
selfModify: this.darwinGodel !== null,
|
|
1463
1547
|
},
|
|
1548
|
+
// v8.1: Persisted stats across sessions
|
|
1549
|
+
persisted: {
|
|
1550
|
+
peakPhi: consciousnessStats.peakPhi,
|
|
1551
|
+
avgPhi: consciousnessStats.avgPhi,
|
|
1552
|
+
totalIgnitions: consciousnessStats.totalIgnitions,
|
|
1553
|
+
totalBroadcasts: consciousnessStats.totalBroadcasts,
|
|
1554
|
+
totalSessions: persistedState.sessions.total,
|
|
1555
|
+
totalUptime: persistedState.sessions.totalUptime,
|
|
1556
|
+
},
|
|
1464
1557
|
};
|
|
1465
1558
|
}
|
|
1466
1559
|
/**
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Genesis v8.1 - Brain State Persistence
|
|
3
|
+
*
|
|
4
|
+
* Persists brain metrics and consciousness state between CLI invocations.
|
|
5
|
+
* State is saved to ~/.genesis/brain-state.json
|
|
6
|
+
*
|
|
7
|
+
* Features:
|
|
8
|
+
* - Auto-save after each brain cycle
|
|
9
|
+
* - Load state on startup
|
|
10
|
+
* - Track cumulative metrics across sessions
|
|
11
|
+
* - Persist phi history for consciousness continuity
|
|
12
|
+
*/
|
|
13
|
+
import { BrainMetrics } from './types.js';
|
|
14
|
+
export interface PersistedBrainState {
|
|
15
|
+
version: string;
|
|
16
|
+
created: string;
|
|
17
|
+
lastModified: string;
|
|
18
|
+
metrics: BrainMetrics;
|
|
19
|
+
consciousness: {
|
|
20
|
+
currentPhi: number;
|
|
21
|
+
peakPhi: number;
|
|
22
|
+
avgPhi: number;
|
|
23
|
+
phiHistory: PhiSnapshot[];
|
|
24
|
+
totalIgnitions: number;
|
|
25
|
+
totalBroadcasts: number;
|
|
26
|
+
consciousnessViolations: number;
|
|
27
|
+
};
|
|
28
|
+
sessions: {
|
|
29
|
+
total: number;
|
|
30
|
+
totalUptime: number;
|
|
31
|
+
lastSessionId: string;
|
|
32
|
+
lastSessionStart: string;
|
|
33
|
+
lastSessionEnd: string;
|
|
34
|
+
};
|
|
35
|
+
memory: {
|
|
36
|
+
totalRecalls: number;
|
|
37
|
+
totalAnticipations: number;
|
|
38
|
+
cumulativeReuseRate: number;
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
export interface PhiSnapshot {
|
|
42
|
+
timestamp: string;
|
|
43
|
+
phi: number;
|
|
44
|
+
ignited: boolean;
|
|
45
|
+
trigger?: string;
|
|
46
|
+
}
|
|
47
|
+
export declare class BrainStatePersistence {
|
|
48
|
+
private dataDir;
|
|
49
|
+
private statePath;
|
|
50
|
+
private state;
|
|
51
|
+
private dirty;
|
|
52
|
+
private sessionId;
|
|
53
|
+
private sessionStart;
|
|
54
|
+
constructor(dataDir?: string);
|
|
55
|
+
/**
|
|
56
|
+
* Load brain state from disk
|
|
57
|
+
*/
|
|
58
|
+
private load;
|
|
59
|
+
/**
|
|
60
|
+
* Save brain state to disk
|
|
61
|
+
*/
|
|
62
|
+
save(): boolean;
|
|
63
|
+
/**
|
|
64
|
+
* Update metrics after a brain cycle
|
|
65
|
+
*/
|
|
66
|
+
updateMetrics(metrics: Partial<BrainMetrics>): void;
|
|
67
|
+
/**
|
|
68
|
+
* Record a phi snapshot
|
|
69
|
+
*/
|
|
70
|
+
recordPhi(phi: number, trigger?: string): void;
|
|
71
|
+
/**
|
|
72
|
+
* Record a broadcast event
|
|
73
|
+
*/
|
|
74
|
+
recordBroadcast(): void;
|
|
75
|
+
/**
|
|
76
|
+
* Record a consciousness violation
|
|
77
|
+
*/
|
|
78
|
+
recordViolation(): void;
|
|
79
|
+
/**
|
|
80
|
+
* Get current persisted state
|
|
81
|
+
*/
|
|
82
|
+
getState(): PersistedBrainState;
|
|
83
|
+
/**
|
|
84
|
+
* Get persisted metrics
|
|
85
|
+
*/
|
|
86
|
+
getMetrics(): BrainMetrics;
|
|
87
|
+
/**
|
|
88
|
+
* Get consciousness stats
|
|
89
|
+
*/
|
|
90
|
+
getConsciousnessStats(): PersistedBrainState['consciousness'];
|
|
91
|
+
/**
|
|
92
|
+
* Get current phi (persisted)
|
|
93
|
+
*/
|
|
94
|
+
getCurrentPhi(): number;
|
|
95
|
+
/**
|
|
96
|
+
* Reset all state (fresh start)
|
|
97
|
+
*/
|
|
98
|
+
reset(): void;
|
|
99
|
+
private ensureDataDir;
|
|
100
|
+
private generateSessionId;
|
|
101
|
+
private createInitialState;
|
|
102
|
+
private migrate;
|
|
103
|
+
}
|
|
104
|
+
export declare function getBrainStatePersistence(dataDir?: string): BrainStatePersistence;
|
|
105
|
+
export declare function resetBrainStatePersistence(): void;
|
|
@@ -0,0 +1,351 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Genesis v8.1 - Brain State Persistence
|
|
4
|
+
*
|
|
5
|
+
* Persists brain metrics and consciousness state between CLI invocations.
|
|
6
|
+
* State is saved to ~/.genesis/brain-state.json
|
|
7
|
+
*
|
|
8
|
+
* Features:
|
|
9
|
+
* - Auto-save after each brain cycle
|
|
10
|
+
* - Load state on startup
|
|
11
|
+
* - Track cumulative metrics across sessions
|
|
12
|
+
* - Persist phi history for consciousness continuity
|
|
13
|
+
*/
|
|
14
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
15
|
+
if (k2 === undefined) k2 = k;
|
|
16
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
17
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
18
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
19
|
+
}
|
|
20
|
+
Object.defineProperty(o, k2, desc);
|
|
21
|
+
}) : (function(o, m, k, k2) {
|
|
22
|
+
if (k2 === undefined) k2 = k;
|
|
23
|
+
o[k2] = m[k];
|
|
24
|
+
}));
|
|
25
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
26
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
27
|
+
}) : function(o, v) {
|
|
28
|
+
o["default"] = v;
|
|
29
|
+
});
|
|
30
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
31
|
+
var ownKeys = function(o) {
|
|
32
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
33
|
+
var ar = [];
|
|
34
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
35
|
+
return ar;
|
|
36
|
+
};
|
|
37
|
+
return ownKeys(o);
|
|
38
|
+
};
|
|
39
|
+
return function (mod) {
|
|
40
|
+
if (mod && mod.__esModule) return mod;
|
|
41
|
+
var result = {};
|
|
42
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
43
|
+
__setModuleDefault(result, mod);
|
|
44
|
+
return result;
|
|
45
|
+
};
|
|
46
|
+
})();
|
|
47
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
48
|
+
exports.BrainStatePersistence = void 0;
|
|
49
|
+
exports.getBrainStatePersistence = getBrainStatePersistence;
|
|
50
|
+
exports.resetBrainStatePersistence = resetBrainStatePersistence;
|
|
51
|
+
const fs = __importStar(require("fs"));
|
|
52
|
+
const path = __importStar(require("path"));
|
|
53
|
+
// ============================================================================
|
|
54
|
+
// Constants
|
|
55
|
+
// ============================================================================
|
|
56
|
+
const DEFAULT_DATA_DIR = path.join(process.env.HOME || '.', '.genesis');
|
|
57
|
+
const BRAIN_STATE_FILE = 'brain-state.json';
|
|
58
|
+
const PHI_HISTORY_MAX = 100; // Keep last 100 phi readings
|
|
59
|
+
const VERSION = '8.1.0';
|
|
60
|
+
// ============================================================================
|
|
61
|
+
// Brain State Persistence Class
|
|
62
|
+
// ============================================================================
|
|
63
|
+
class BrainStatePersistence {
|
|
64
|
+
dataDir;
|
|
65
|
+
statePath;
|
|
66
|
+
state;
|
|
67
|
+
dirty = false;
|
|
68
|
+
sessionId;
|
|
69
|
+
sessionStart;
|
|
70
|
+
constructor(dataDir) {
|
|
71
|
+
this.dataDir = dataDir || DEFAULT_DATA_DIR;
|
|
72
|
+
this.statePath = path.join(this.dataDir, BRAIN_STATE_FILE);
|
|
73
|
+
this.sessionId = this.generateSessionId();
|
|
74
|
+
this.sessionStart = new Date();
|
|
75
|
+
// Ensure data directory exists
|
|
76
|
+
this.ensureDataDir();
|
|
77
|
+
// Load or create initial state
|
|
78
|
+
this.state = this.load();
|
|
79
|
+
// Update session info
|
|
80
|
+
this.state.sessions.total++;
|
|
81
|
+
this.state.sessions.lastSessionId = this.sessionId;
|
|
82
|
+
this.state.sessions.lastSessionStart = this.sessionStart.toISOString();
|
|
83
|
+
this.dirty = true;
|
|
84
|
+
}
|
|
85
|
+
// ============================================================================
|
|
86
|
+
// Core Operations
|
|
87
|
+
// ============================================================================
|
|
88
|
+
/**
|
|
89
|
+
* Load brain state from disk
|
|
90
|
+
*/
|
|
91
|
+
load() {
|
|
92
|
+
try {
|
|
93
|
+
if (fs.existsSync(this.statePath)) {
|
|
94
|
+
const raw = fs.readFileSync(this.statePath, 'utf-8');
|
|
95
|
+
const state = JSON.parse(raw);
|
|
96
|
+
// Validate version and migrate if needed
|
|
97
|
+
if (state.version !== VERSION) {
|
|
98
|
+
return this.migrate(state);
|
|
99
|
+
}
|
|
100
|
+
return state;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
catch (error) {
|
|
104
|
+
console.error('[BrainPersistence] Failed to load state:', error);
|
|
105
|
+
}
|
|
106
|
+
return this.createInitialState();
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Save brain state to disk
|
|
110
|
+
*/
|
|
111
|
+
save() {
|
|
112
|
+
if (!this.dirty)
|
|
113
|
+
return true;
|
|
114
|
+
try {
|
|
115
|
+
this.state.lastModified = new Date().toISOString();
|
|
116
|
+
this.state.sessions.lastSessionEnd = new Date().toISOString();
|
|
117
|
+
this.state.sessions.totalUptime += Date.now() - this.sessionStart.getTime();
|
|
118
|
+
const json = JSON.stringify(this.state, null, 2);
|
|
119
|
+
fs.writeFileSync(this.statePath, json, 'utf-8');
|
|
120
|
+
this.dirty = false;
|
|
121
|
+
return true;
|
|
122
|
+
}
|
|
123
|
+
catch (error) {
|
|
124
|
+
console.error('[BrainPersistence] Failed to save state:', error);
|
|
125
|
+
return false;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Update metrics after a brain cycle
|
|
130
|
+
*/
|
|
131
|
+
updateMetrics(metrics) {
|
|
132
|
+
// Merge metrics (cumulative)
|
|
133
|
+
const m = this.state.metrics;
|
|
134
|
+
if (metrics.totalCycles !== undefined)
|
|
135
|
+
m.totalCycles += metrics.totalCycles;
|
|
136
|
+
if (metrics.successfulCycles !== undefined)
|
|
137
|
+
m.successfulCycles += metrics.successfulCycles;
|
|
138
|
+
if (metrics.failedCycles !== undefined)
|
|
139
|
+
m.failedCycles += metrics.failedCycles;
|
|
140
|
+
if (metrics.memoryRecalls !== undefined)
|
|
141
|
+
m.memoryRecalls += metrics.memoryRecalls;
|
|
142
|
+
if (metrics.anticipationHits !== undefined)
|
|
143
|
+
m.anticipationHits += metrics.anticipationHits;
|
|
144
|
+
if (metrics.anticipationMisses !== undefined)
|
|
145
|
+
m.anticipationMisses += metrics.anticipationMisses;
|
|
146
|
+
if (metrics.groundingChecks !== undefined)
|
|
147
|
+
m.groundingChecks += metrics.groundingChecks;
|
|
148
|
+
if (metrics.groundingPasses !== undefined)
|
|
149
|
+
m.groundingPasses += metrics.groundingPasses;
|
|
150
|
+
if (metrics.groundingFailures !== undefined)
|
|
151
|
+
m.groundingFailures += metrics.groundingFailures;
|
|
152
|
+
if (metrics.humanConsultations !== undefined)
|
|
153
|
+
m.humanConsultations += metrics.humanConsultations;
|
|
154
|
+
if (metrics.toolExecutions !== undefined)
|
|
155
|
+
m.toolExecutions += metrics.toolExecutions;
|
|
156
|
+
if (metrics.toolSuccesses !== undefined)
|
|
157
|
+
m.toolSuccesses += metrics.toolSuccesses;
|
|
158
|
+
if (metrics.toolFailures !== undefined)
|
|
159
|
+
m.toolFailures += metrics.toolFailures;
|
|
160
|
+
if (metrics.healingAttempts !== undefined)
|
|
161
|
+
m.healingAttempts += metrics.healingAttempts;
|
|
162
|
+
if (metrics.healingSuccesses !== undefined)
|
|
163
|
+
m.healingSuccesses += metrics.healingSuccesses;
|
|
164
|
+
if (metrics.healingFailures !== undefined)
|
|
165
|
+
m.healingFailures += metrics.healingFailures;
|
|
166
|
+
// Update avg cycle time (weighted average)
|
|
167
|
+
if (metrics.avgCycleTime !== undefined && metrics.totalCycles !== undefined) {
|
|
168
|
+
const totalTime = m.avgCycleTime * (m.totalCycles - metrics.totalCycles) +
|
|
169
|
+
metrics.avgCycleTime * metrics.totalCycles;
|
|
170
|
+
m.avgCycleTime = m.totalCycles > 0 ? totalTime / m.totalCycles : 0;
|
|
171
|
+
}
|
|
172
|
+
this.dirty = true;
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Record a phi snapshot
|
|
176
|
+
*/
|
|
177
|
+
recordPhi(phi, trigger) {
|
|
178
|
+
const snapshot = {
|
|
179
|
+
timestamp: new Date().toISOString(),
|
|
180
|
+
phi,
|
|
181
|
+
ignited: phi >= 0.3,
|
|
182
|
+
trigger,
|
|
183
|
+
};
|
|
184
|
+
// Update consciousness tracking
|
|
185
|
+
const c = this.state.consciousness;
|
|
186
|
+
c.currentPhi = phi;
|
|
187
|
+
if (phi > c.peakPhi)
|
|
188
|
+
c.peakPhi = phi;
|
|
189
|
+
// Update running average
|
|
190
|
+
const historyLen = c.phiHistory.length;
|
|
191
|
+
c.avgPhi = historyLen > 0
|
|
192
|
+
? (c.avgPhi * historyLen + phi) / (historyLen + 1)
|
|
193
|
+
: phi;
|
|
194
|
+
// Track ignitions
|
|
195
|
+
if (snapshot.ignited) {
|
|
196
|
+
c.totalIgnitions++;
|
|
197
|
+
}
|
|
198
|
+
// Add to history (keep last N)
|
|
199
|
+
c.phiHistory.push(snapshot);
|
|
200
|
+
if (c.phiHistory.length > PHI_HISTORY_MAX) {
|
|
201
|
+
c.phiHistory.shift();
|
|
202
|
+
}
|
|
203
|
+
this.dirty = true;
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* Record a broadcast event
|
|
207
|
+
*/
|
|
208
|
+
recordBroadcast() {
|
|
209
|
+
this.state.consciousness.totalBroadcasts++;
|
|
210
|
+
this.dirty = true;
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* Record a consciousness violation
|
|
214
|
+
*/
|
|
215
|
+
recordViolation() {
|
|
216
|
+
this.state.consciousness.consciousnessViolations++;
|
|
217
|
+
this.dirty = true;
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* Get current persisted state
|
|
221
|
+
*/
|
|
222
|
+
getState() {
|
|
223
|
+
return { ...this.state };
|
|
224
|
+
}
|
|
225
|
+
/**
|
|
226
|
+
* Get persisted metrics
|
|
227
|
+
*/
|
|
228
|
+
getMetrics() {
|
|
229
|
+
return { ...this.state.metrics };
|
|
230
|
+
}
|
|
231
|
+
/**
|
|
232
|
+
* Get consciousness stats
|
|
233
|
+
*/
|
|
234
|
+
getConsciousnessStats() {
|
|
235
|
+
return { ...this.state.consciousness };
|
|
236
|
+
}
|
|
237
|
+
/**
|
|
238
|
+
* Get current phi (persisted)
|
|
239
|
+
*/
|
|
240
|
+
getCurrentPhi() {
|
|
241
|
+
return this.state.consciousness.currentPhi;
|
|
242
|
+
}
|
|
243
|
+
/**
|
|
244
|
+
* Reset all state (fresh start)
|
|
245
|
+
*/
|
|
246
|
+
reset() {
|
|
247
|
+
this.state = this.createInitialState();
|
|
248
|
+
this.dirty = true;
|
|
249
|
+
this.save();
|
|
250
|
+
}
|
|
251
|
+
// ============================================================================
|
|
252
|
+
// Helpers
|
|
253
|
+
// ============================================================================
|
|
254
|
+
ensureDataDir() {
|
|
255
|
+
if (!fs.existsSync(this.dataDir)) {
|
|
256
|
+
fs.mkdirSync(this.dataDir, { recursive: true });
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
generateSessionId() {
|
|
260
|
+
return `session-${Date.now()}-${Math.random().toString(36).substring(2, 8)}`;
|
|
261
|
+
}
|
|
262
|
+
createInitialState() {
|
|
263
|
+
return {
|
|
264
|
+
version: VERSION,
|
|
265
|
+
created: new Date().toISOString(),
|
|
266
|
+
lastModified: new Date().toISOString(),
|
|
267
|
+
metrics: {
|
|
268
|
+
totalCycles: 0,
|
|
269
|
+
successfulCycles: 0,
|
|
270
|
+
failedCycles: 0,
|
|
271
|
+
avgCycleTime: 0,
|
|
272
|
+
memoryRecalls: 0,
|
|
273
|
+
memoryReuseRate: 0,
|
|
274
|
+
anticipationHits: 0,
|
|
275
|
+
anticipationMisses: 0,
|
|
276
|
+
groundingChecks: 0,
|
|
277
|
+
groundingPasses: 0,
|
|
278
|
+
groundingFailures: 0,
|
|
279
|
+
humanConsultations: 0,
|
|
280
|
+
toolExecutions: 0,
|
|
281
|
+
toolSuccesses: 0,
|
|
282
|
+
toolFailures: 0,
|
|
283
|
+
healingAttempts: 0,
|
|
284
|
+
healingSuccesses: 0,
|
|
285
|
+
healingFailures: 0,
|
|
286
|
+
avgPhi: 0,
|
|
287
|
+
phiViolations: 0,
|
|
288
|
+
broadcasts: 0,
|
|
289
|
+
moduleTransitions: {},
|
|
290
|
+
},
|
|
291
|
+
consciousness: {
|
|
292
|
+
currentPhi: 0,
|
|
293
|
+
peakPhi: 0,
|
|
294
|
+
avgPhi: 0,
|
|
295
|
+
phiHistory: [],
|
|
296
|
+
totalIgnitions: 0,
|
|
297
|
+
totalBroadcasts: 0,
|
|
298
|
+
consciousnessViolations: 0,
|
|
299
|
+
},
|
|
300
|
+
sessions: {
|
|
301
|
+
total: 0,
|
|
302
|
+
totalUptime: 0,
|
|
303
|
+
lastSessionId: '',
|
|
304
|
+
lastSessionStart: '',
|
|
305
|
+
lastSessionEnd: '',
|
|
306
|
+
},
|
|
307
|
+
memory: {
|
|
308
|
+
totalRecalls: 0,
|
|
309
|
+
totalAnticipations: 0,
|
|
310
|
+
cumulativeReuseRate: 0,
|
|
311
|
+
},
|
|
312
|
+
};
|
|
313
|
+
}
|
|
314
|
+
migrate(oldState) {
|
|
315
|
+
// Migrate from older versions
|
|
316
|
+
const newState = this.createInitialState();
|
|
317
|
+
// Preserve what we can
|
|
318
|
+
if (oldState.metrics) {
|
|
319
|
+
newState.metrics = { ...newState.metrics, ...oldState.metrics };
|
|
320
|
+
}
|
|
321
|
+
if (oldState.consciousness) {
|
|
322
|
+
newState.consciousness = { ...newState.consciousness, ...oldState.consciousness };
|
|
323
|
+
}
|
|
324
|
+
if (oldState.sessions) {
|
|
325
|
+
newState.sessions = { ...newState.sessions, ...oldState.sessions };
|
|
326
|
+
}
|
|
327
|
+
if (oldState.memory) {
|
|
328
|
+
newState.memory = { ...newState.memory, ...oldState.memory };
|
|
329
|
+
}
|
|
330
|
+
newState.version = VERSION;
|
|
331
|
+
newState.created = oldState.created || newState.created;
|
|
332
|
+
return newState;
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
exports.BrainStatePersistence = BrainStatePersistence;
|
|
336
|
+
// ============================================================================
|
|
337
|
+
// Singleton Instance
|
|
338
|
+
// ============================================================================
|
|
339
|
+
let persistenceInstance = null;
|
|
340
|
+
function getBrainStatePersistence(dataDir) {
|
|
341
|
+
if (!persistenceInstance) {
|
|
342
|
+
persistenceInstance = new BrainStatePersistence(dataDir);
|
|
343
|
+
}
|
|
344
|
+
return persistenceInstance;
|
|
345
|
+
}
|
|
346
|
+
function resetBrainStatePersistence() {
|
|
347
|
+
if (persistenceInstance) {
|
|
348
|
+
persistenceInstance.save();
|
|
349
|
+
}
|
|
350
|
+
persistenceInstance = null;
|
|
351
|
+
}
|
package/dist/src/index.js
CHANGED
|
@@ -909,8 +909,8 @@ async function cmdBrain(subcommand, options) {
|
|
|
909
909
|
return;
|
|
910
910
|
}
|
|
911
911
|
if (subcommand === 'phi') {
|
|
912
|
-
const
|
|
913
|
-
const phi =
|
|
912
|
+
const status = brain.getStatus();
|
|
913
|
+
const phi = status.persisted.avgPhi; // v8.1: Use persisted phi
|
|
914
914
|
console.log(c('\n=== CONSCIOUSNESS LEVEL (φ) ===\n', 'bold'));
|
|
915
915
|
// Visual bar
|
|
916
916
|
const width = 30;
|
|
@@ -930,6 +930,14 @@ async function cmdBrain(subcommand, options) {
|
|
|
930
930
|
console.log(` Level: ${c(bar, 'dim')} LOW`);
|
|
931
931
|
console.log(` Status: ${c('Local processing - no broadcasting', 'dim')}`);
|
|
932
932
|
}
|
|
933
|
+
// v8.1: Show persisted consciousness history
|
|
934
|
+
console.log();
|
|
935
|
+
console.log(c('History (persisted):', 'cyan'));
|
|
936
|
+
console.log(` Peak φ: ${status.persisted.peakPhi.toFixed(3)}`);
|
|
937
|
+
console.log(` Avg φ: ${status.persisted.avgPhi.toFixed(3)}`);
|
|
938
|
+
console.log(` Ignitions: ${status.persisted.totalIgnitions} (φ > 0.3 events)`);
|
|
939
|
+
console.log(` Broadcasts: ${status.persisted.totalBroadcasts}`);
|
|
940
|
+
console.log(` Sessions: ${status.persisted.totalSessions}`);
|
|
933
941
|
console.log();
|
|
934
942
|
console.log(c('Theory:', 'dim'));
|
|
935
943
|
console.log(' φ (phi) measures integrated information (IIT 4.0)');
|
package/package.json
CHANGED