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.
@@ -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
@@ -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 dispatchResult = await this.dispatcher.dispatch(dispatcherCalls);
572
- for (const r of dispatchResult.results) {
573
- results.push({
574
- name: r.name,
575
- success: r.success,
576
- data: r.data,
577
- error: r.error,
578
- duration: r.duration,
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
- this.metrics.toolFailures++;
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 metrics = brain.getMetrics();
913
- const phi = metrics.avgPhi;
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "genesis-ai-cli",
3
- "version": "8.0.1",
3
+ "version": "8.2.0",
4
4
  "description": "Fully Autonomous AI System - Self-funding, Self-deploying, Production Memory, A2A Protocol & Governance",
5
5
  "main": "dist/src/index.js",
6
6
  "types": "dist/src/index.d.ts",