Source identity
| Field | Recorded value |
|---|---|
| Source type | GitHub source |
| Original record | Janady13/complete-agi-core / mind_farm/include/persistence.hpp |
| Date | Not specified in source |
| Repository | Janady13/complete-agi-core |
| Revision | 33aa84f2aa61cedbe010240ada7f4efbdfe795a7 |
| Branch | claude/improve-math-logic-ehIW1 |
| Path or archive member | mind_farm/include/persistence.hpp |
| Original SHA-256 | 282b3eaa23a2d6e8ea0d3980f806b180658532db9abc7c2040496fb8e264ffb4 |
| Git blob SHA | 290f9298f68e1eebe53f67bf5aa41ccabbd4063b |
| Reading-copy SHA-256 | 282b3eaa23a2d6e8ea0d3980f806b180658532db9abc7c2040496fb8e264ffb4 |
Recovered source transcript
Download complete source text ↓811 lines · 26.0 KB
/**
* persistence.hpp - SQLite Persistence Layer for AGI State
*
* Provides unified storage for:
* - Consciousness history (tick-by-tick phi values)
* - Knowledge graph (concepts, relations, embeddings)
* - Learning state (weights, gradients, optimizer state)
* - System metrics (performance, health)
*
* Thread-safe with connection pooling.
*/
#ifndef PERSISTENCE_HPP
#define PERSISTENCE_HPP
#include <string>
#include <vector>
#include <memory>
#include <mutex>
#include <array>
#include <chrono>
#include <functional>
#include <cstring>
// SQLite3 forward declaration (header-only mode)
struct sqlite3;
struct sqlite3_stmt;
namespace mind_farm {
//=============================================================================
// DATABASE SCHEMA (SQL)
//=============================================================================
constexpr const char* SCHEMA_SQL = R"SQL(
-- Consciousness history: tick-by-tick state
CREATE TABLE IF NOT EXISTS consciousness_history (
tick INTEGER PRIMARY KEY,
timestamp INTEGER NOT NULL,
phi REAL NOT NULL,
phi_substrate REAL,
phi_neural REAL,
phi_learning REAL,
phi_consciousness REAL,
stability REAL,
coherence REAL,
integrated_info REAL,
layer_states BLOB, -- 7 doubles packed
created_at TEXT DEFAULT (datetime('now'))
);
-- Knowledge graph nodes
CREATE TABLE IF NOT EXISTS knowledge_nodes (
id INTEGER PRIMARY KEY AUTOINCREMENT,
concept TEXT UNIQUE NOT NULL,
domain TEXT,
category TEXT,
confidence REAL DEFAULT 0.5,
importance REAL DEFAULT 0.5,
access_count INTEGER DEFAULT 0,
embedding BLOB, -- Vector embedding (256 floats)
created_at TEXT DEFAULT (datetime('now')),
last_accessed TEXT DEFAULT (datetime('now')),
last_reinforced TEXT
);
-- Knowledge graph edges (relations between concepts)
CREATE TABLE IF NOT EXISTS knowledge_edges (
id INTEGER PRIMARY KEY AUTOINCREMENT,
source_id INTEGER NOT NULL,
target_id INTEGER NOT NULL,
relation TEXT NOT NULL,
strength REAL DEFAULT 0.5,
evidence_count INTEGER DEFAULT 1,
created_at TEXT DEFAULT (datetime('now')),
FOREIGN KEY (source_id) REFERENCES knowledge_nodes(id),
FOREIGN KEY (target_id) REFERENCES knowledge_nodes(id),
UNIQUE(source_id, target_id, relation)
);
-- Learning state snapshots
CREATE TABLE IF NOT EXISTS learning_state (
id INTEGER PRIMARY KEY AUTOINCREMENT,
checkpoint_name TEXT,
tick INTEGER NOT NULL,
layer_id INTEGER NOT NULL,
weights BLOB, -- Serialized weights
gradients BLOB, -- Serialized gradients
optimizer_state BLOB, -- Adam m/v vectors
loss REAL,
created_at TEXT DEFAULT (datetime('now'))
);
-- System metrics (for monitoring)
CREATE TABLE IF NOT EXISTS system_metrics (
id INTEGER PRIMARY KEY AUTOINCREMENT,
timestamp INTEGER NOT NULL,
ticks_per_second REAL,
memory_used_mb REAL,
cpu_percent REAL,
active_generators INTEGER,
active_agents INTEGER,
knowledge_nodes_count INTEGER,
total_ticks INTEGER,
global_phi REAL,
created_at TEXT DEFAULT (datetime('now'))
);
-- Spaced repetition schedule
CREATE TABLE IF NOT EXISTS repetition_schedule (
id INTEGER PRIMARY KEY AUTOINCREMENT,
concept_id INTEGER NOT NULL,
repetition_number INTEGER DEFAULT 0,
easiness_factor REAL DEFAULT 2.5,
interval_days REAL DEFAULT 1.0,
next_review TEXT,
last_review TEXT,
last_quality INTEGER, -- 0-5 rating
FOREIGN KEY (concept_id) REFERENCES knowledge_nodes(id)
);
-- Agent state (Pantheon agents)
CREATE TABLE IF NOT EXISTS agent_state (
id INTEGER PRIMARY KEY AUTOINCREMENT,
agent_name TEXT UNIQUE NOT NULL,
tier INTEGER,
domain TEXT,
phi REAL DEFAULT 0.5,
activation REAL DEFAULT 0.0,
total_ticks INTEGER DEFAULT 0,
total_actions INTEGER DEFAULT 0,
state_json TEXT,
created_at TEXT DEFAULT (datetime('now')),
updated_at TEXT DEFAULT (datetime('now'))
);
-- Create indexes for performance
CREATE INDEX IF NOT EXISTS idx_consciousness_timestamp ON consciousness_history(timestamp);
CREATE INDEX IF NOT EXISTS idx_knowledge_domain ON knowledge_nodes(domain);
CREATE INDEX IF NOT EXISTS idx_knowledge_category ON knowledge_nodes(category);
CREATE INDEX IF NOT EXISTS idx_knowledge_confidence ON knowledge_nodes(confidence);
CREATE INDEX IF NOT EXISTS idx_edges_source ON knowledge_edges(source_id);
CREATE INDEX IF NOT EXISTS idx_edges_target ON knowledge_edges(target_id);
CREATE INDEX IF NOT EXISTS idx_edges_relation ON knowledge_edges(relation);
CREATE INDEX IF NOT EXISTS idx_metrics_timestamp ON system_metrics(timestamp);
CREATE INDEX IF NOT EXISTS idx_repetition_next ON repetition_schedule(next_review);
)SQL";
//=============================================================================
// DATA STRUCTURES
//=============================================================================
struct ConsciousnessRecord {
int64_t tick;
int64_t timestamp;
double phi;
double phi_substrate;
double phi_neural;
double phi_learning;
double phi_consciousness;
double stability;
double coherence;
double integrated_info;
std::array<double, 7> layer_states;
};
struct KnowledgeNode {
int64_t id;
std::string concept;
std::string domain;
std::string category;
double confidence;
double importance;
int64_t access_count;
std::vector<float> embedding; // 256 floats
std::string created_at;
std::string last_accessed;
};
struct KnowledgeEdge {
int64_t id;
int64_t source_id;
int64_t target_id;
std::string relation;
double strength;
int64_t evidence_count;
};
struct SystemMetrics {
int64_t timestamp;
double ticks_per_second;
double memory_used_mb;
double cpu_percent;
int active_generators;
int active_agents;
int knowledge_nodes_count;
int64_t total_ticks;
double global_phi;
};
struct RepetitionSchedule {
int64_t id;
int64_t concept_id;
int repetition_number;
double easiness_factor;
double interval_days;
std::string next_review;
std::string last_review;
int last_quality;
};
//=============================================================================
// SQLITE WRAPPER (Header-only implementation)
//=============================================================================
// External function declarations (link with sqlite3)
extern "C" {
int sqlite3_open(const char* filename, sqlite3** ppDb);
int sqlite3_close(sqlite3* db);
int sqlite3_exec(sqlite3* db, const char* sql, int (*callback)(void*,int,char**,char**), void* arg, char** errmsg);
void sqlite3_free(void* ptr);
int sqlite3_prepare_v2(sqlite3* db, const char* sql, int nByte, sqlite3_stmt** ppStmt, const char** pzTail);
int sqlite3_step(sqlite3_stmt* stmt);
int sqlite3_finalize(sqlite3_stmt* stmt);
int sqlite3_reset(sqlite3_stmt* stmt);
int sqlite3_bind_int64(sqlite3_stmt* stmt, int i, int64_t val);
int sqlite3_bind_double(sqlite3_stmt* stmt, int i, double val);
int sqlite3_bind_text(sqlite3_stmt* stmt, int i, const char* val, int n, void(*)(void*));
int sqlite3_bind_blob(sqlite3_stmt* stmt, int i, const void* val, int n, void(*)(void*));
int sqlite3_bind_null(sqlite3_stmt* stmt, int i);
int64_t sqlite3_column_int64(sqlite3_stmt* stmt, int col);
double sqlite3_column_double(sqlite3_stmt* stmt, int col);
const unsigned char* sqlite3_column_text(sqlite3_stmt* stmt, int col);
const void* sqlite3_column_blob(sqlite3_stmt* stmt, int col);
int sqlite3_column_bytes(sqlite3_stmt* stmt, int col);
int sqlite3_column_type(sqlite3_stmt* stmt, int col);
int64_t sqlite3_last_insert_rowid(sqlite3* db);
const char* sqlite3_errmsg(sqlite3* db);
}
#define SQLITE_OK 0
#define SQLITE_ROW 100
#define SQLITE_DONE 101
#define SQLITE_TRANSIENT ((void(*)(void*))-1)
class Database {
private:
sqlite3* db_;
std::mutex mutex_;
std::string path_;
bool initialized_;
public:
Database() : db_(nullptr), initialized_(false) {}
~Database() {
close();
}
bool open(const std::string& path) {
std::lock_guard<std::mutex> lock(mutex_);
if (db_) close();
path_ = path;
int rc = sqlite3_open(path.c_str(), &db_);
if (rc != SQLITE_OK) {
db_ = nullptr;
return false;
}
// Enable WAL mode for better concurrency
char* err = nullptr;
sqlite3_exec(db_, "PRAGMA journal_mode=WAL;", nullptr, nullptr, &err);
if (err) sqlite3_free(err);
// Enable foreign keys
sqlite3_exec(db_, "PRAGMA foreign_keys=ON;", nullptr, nullptr, &err);
if (err) sqlite3_free(err);
initialized_ = true;
return true;
}
bool initialize_schema() {
if (!db_) return false;
char* err = nullptr;
int rc = sqlite3_exec(db_, SCHEMA_SQL, nullptr, nullptr, &err);
if (err) {
sqlite3_free(err);
return false;
}
return rc == SQLITE_OK;
}
void close() {
if (db_) {
sqlite3_close(db_);
db_ = nullptr;
}
initialized_ = false;
}
bool is_open() const { return db_ != nullptr; }
sqlite3* handle() { return db_; }
std::mutex& get_mutex() { return mutex_; }
// Execute simple SQL
bool execute(const std::string& sql) {
std::lock_guard<std::mutex> lock(mutex_);
char* err = nullptr;
int rc = sqlite3_exec(db_, sql.c_str(), nullptr, nullptr, &err);
if (err) sqlite3_free(err);
return rc == SQLITE_OK;
}
// Transaction helpers
bool begin_transaction() {
return execute("BEGIN TRANSACTION;");
}
bool commit() {
return execute("COMMIT;");
}
bool rollback() {
return execute("ROLLBACK;");
}
// Get last insert ID
int64_t last_insert_id() {
return sqlite3_last_insert_rowid(db_);
}
// Error message
std::string error_message() {
return db_ ? sqlite3_errmsg(db_) : "Database not open";
}
};
//=============================================================================
// CONSCIOUSNESS HISTORY REPOSITORY
//=============================================================================
class ConsciousnessRepository {
private:
Database& db_;
public:
explicit ConsciousnessRepository(Database& db) : db_(db) {}
bool insert(const ConsciousnessRecord& record) {
std::lock_guard<std::mutex> lock(db_.get_mutex());
const char* sql = R"SQL(
INSERT INTO consciousness_history
(tick, timestamp, phi, phi_substrate, phi_neural, phi_learning,
phi_consciousness, stability, coherence, integrated_info, layer_states)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
)SQL";
sqlite3_stmt* stmt;
if (sqlite3_prepare_v2(db_.handle(), sql, -1, &stmt, nullptr) != SQLITE_OK) {
return false;
}
sqlite3_bind_int64(stmt, 1, record.tick);
sqlite3_bind_int64(stmt, 2, record.timestamp);
sqlite3_bind_double(stmt, 3, record.phi);
sqlite3_bind_double(stmt, 4, record.phi_substrate);
sqlite3_bind_double(stmt, 5, record.phi_neural);
sqlite3_bind_double(stmt, 6, record.phi_learning);
sqlite3_bind_double(stmt, 7, record.phi_consciousness);
sqlite3_bind_double(stmt, 8, record.stability);
sqlite3_bind_double(stmt, 9, record.coherence);
sqlite3_bind_double(stmt, 10, record.integrated_info);
sqlite3_bind_blob(stmt, 11, record.layer_states.data(),
record.layer_states.size() * sizeof(double), SQLITE_TRANSIENT);
int rc = sqlite3_step(stmt);
sqlite3_finalize(stmt);
return rc == SQLITE_DONE;
}
std::vector<ConsciousnessRecord> get_range(int64_t start_tick, int64_t end_tick) {
std::lock_guard<std::mutex> lock(db_.get_mutex());
std::vector<ConsciousnessRecord> records;
const char* sql = R"SQL(
SELECT tick, timestamp, phi, phi_substrate, phi_neural, phi_learning,
phi_consciousness, stability, coherence, integrated_info, layer_states
FROM consciousness_history
WHERE tick >= ? AND tick <= ?
ORDER BY tick
)SQL";
sqlite3_stmt* stmt;
if (sqlite3_prepare_v2(db_.handle(), sql, -1, &stmt, nullptr) != SQLITE_OK) {
return records;
}
sqlite3_bind_int64(stmt, 1, start_tick);
sqlite3_bind_int64(stmt, 2, end_tick);
while (sqlite3_step(stmt) == SQLITE_ROW) {
ConsciousnessRecord r;
r.tick = sqlite3_column_int64(stmt, 0);
r.timestamp = sqlite3_column_int64(stmt, 1);
r.phi = sqlite3_column_double(stmt, 2);
r.phi_substrate = sqlite3_column_double(stmt, 3);
r.phi_neural = sqlite3_column_double(stmt, 4);
r.phi_learning = sqlite3_column_double(stmt, 5);
r.phi_consciousness = sqlite3_column_double(stmt, 6);
r.stability = sqlite3_column_double(stmt, 7);
r.coherence = sqlite3_column_double(stmt, 8);
r.integrated_info = sqlite3_column_double(stmt, 9);
const void* blob = sqlite3_column_blob(stmt, 10);
int blob_size = sqlite3_column_bytes(stmt, 10);
if (blob && blob_size == 7 * sizeof(double)) {
std::memcpy(r.layer_states.data(), blob, blob_size);
}
records.push_back(r);
}
sqlite3_finalize(stmt);
return records;
}
ConsciousnessRecord get_latest() {
std::lock_guard<std::mutex> lock(db_.get_mutex());
ConsciousnessRecord r{};
const char* sql = R"SQL(
SELECT tick, timestamp, phi, phi_substrate, phi_neural, phi_learning,
phi_consciousness, stability, coherence, integrated_info, layer_states
FROM consciousness_history
ORDER BY tick DESC LIMIT 1
)SQL";
sqlite3_stmt* stmt;
if (sqlite3_prepare_v2(db_.handle(), sql, -1, &stmt, nullptr) != SQLITE_OK) {
return r;
}
if (sqlite3_step(stmt) == SQLITE_ROW) {
r.tick = sqlite3_column_int64(stmt, 0);
r.timestamp = sqlite3_column_int64(stmt, 1);
r.phi = sqlite3_column_double(stmt, 2);
r.phi_substrate = sqlite3_column_double(stmt, 3);
r.phi_neural = sqlite3_column_double(stmt, 4);
r.phi_learning = sqlite3_column_double(stmt, 5);
r.phi_consciousness = sqlite3_column_double(stmt, 6);
r.stability = sqlite3_column_double(stmt, 7);
r.coherence = sqlite3_column_double(stmt, 8);
r.integrated_info = sqlite3_column_double(stmt, 9);
const void* blob = sqlite3_column_blob(stmt, 10);
int blob_size = sqlite3_column_bytes(stmt, 10);
if (blob && blob_size == 7 * sizeof(double)) {
std::memcpy(r.layer_states.data(), blob, blob_size);
}
}
sqlite3_finalize(stmt);
return r;
}
double get_average_phi(int64_t last_n_ticks) {
std::lock_guard<std::mutex> lock(db_.get_mutex());
const char* sql = R"SQL(
SELECT AVG(phi) FROM (
SELECT phi FROM consciousness_history
ORDER BY tick DESC LIMIT ?
)
)SQL";
sqlite3_stmt* stmt;
if (sqlite3_prepare_v2(db_.handle(), sql, -1, &stmt, nullptr) != SQLITE_OK) {
return 0.5;
}
sqlite3_bind_int64(stmt, 1, last_n_ticks);
double avg = 0.5;
if (sqlite3_step(stmt) == SQLITE_ROW) {
avg = sqlite3_column_double(stmt, 0);
}
sqlite3_finalize(stmt);
return avg;
}
};
//=============================================================================
// KNOWLEDGE GRAPH REPOSITORY
//=============================================================================
class KnowledgeRepository {
private:
Database& db_;
public:
explicit KnowledgeRepository(Database& db) : db_(db) {}
int64_t insert_node(const KnowledgeNode& node) {
std::lock_guard<std::mutex> lock(db_.get_mutex());
const char* sql = R"SQL(
INSERT OR REPLACE INTO knowledge_nodes
(concept, domain, category, confidence, importance, embedding)
VALUES (?, ?, ?, ?, ?, ?)
)SQL";
sqlite3_stmt* stmt;
if (sqlite3_prepare_v2(db_.handle(), sql, -1, &stmt, nullptr) != SQLITE_OK) {
return -1;
}
sqlite3_bind_text(stmt, 1, node.concept.c_str(), -1, SQLITE_TRANSIENT);
sqlite3_bind_text(stmt, 2, node.domain.c_str(), -1, SQLITE_TRANSIENT);
sqlite3_bind_text(stmt, 3, node.category.c_str(), -1, SQLITE_TRANSIENT);
sqlite3_bind_double(stmt, 4, node.confidence);
sqlite3_bind_double(stmt, 5, node.importance);
if (!node.embedding.empty()) {
sqlite3_bind_blob(stmt, 6, node.embedding.data(),
node.embedding.size() * sizeof(float), SQLITE_TRANSIENT);
} else {
sqlite3_bind_null(stmt, 6);
}
int rc = sqlite3_step(stmt);
sqlite3_finalize(stmt);
if (rc == SQLITE_DONE) {
return db_.last_insert_id();
}
return -1;
}
bool insert_edge(const KnowledgeEdge& edge) {
std::lock_guard<std::mutex> lock(db_.get_mutex());
const char* sql = R"SQL(
INSERT OR REPLACE INTO knowledge_edges
(source_id, target_id, relation, strength, evidence_count)
VALUES (?, ?, ?, ?, ?)
)SQL";
sqlite3_stmt* stmt;
if (sqlite3_prepare_v2(db_.handle(), sql, -1, &stmt, nullptr) != SQLITE_OK) {
return false;
}
sqlite3_bind_int64(stmt, 1, edge.source_id);
sqlite3_bind_int64(stmt, 2, edge.target_id);
sqlite3_bind_text(stmt, 3, edge.relation.c_str(), -1, SQLITE_TRANSIENT);
sqlite3_bind_double(stmt, 4, edge.strength);
sqlite3_bind_int64(stmt, 5, edge.evidence_count);
int rc = sqlite3_step(stmt);
sqlite3_finalize(stmt);
return rc == SQLITE_DONE;
}
KnowledgeNode get_node_by_concept(const std::string& concept) {
std::lock_guard<std::mutex> lock(db_.get_mutex());
KnowledgeNode node{};
const char* sql = R"SQL(
SELECT id, concept, domain, category, confidence, importance,
access_count, embedding, created_at, last_accessed
FROM knowledge_nodes WHERE concept = ?
)SQL";
sqlite3_stmt* stmt;
if (sqlite3_prepare_v2(db_.handle(), sql, -1, &stmt, nullptr) != SQLITE_OK) {
return node;
}
sqlite3_bind_text(stmt, 1, concept.c_str(), -1, SQLITE_TRANSIENT);
if (sqlite3_step(stmt) == SQLITE_ROW) {
node.id = sqlite3_column_int64(stmt, 0);
node.concept = reinterpret_cast<const char*>(sqlite3_column_text(stmt, 1));
node.domain = reinterpret_cast<const char*>(sqlite3_column_text(stmt, 2));
node.category = reinterpret_cast<const char*>(sqlite3_column_text(stmt, 3));
node.confidence = sqlite3_column_double(stmt, 4);
node.importance = sqlite3_column_double(stmt, 5);
node.access_count = sqlite3_column_int64(stmt, 6);
const void* blob = sqlite3_column_blob(stmt, 7);
int blob_size = sqlite3_column_bytes(stmt, 7);
if (blob && blob_size > 0) {
node.embedding.resize(blob_size / sizeof(float));
std::memcpy(node.embedding.data(), blob, blob_size);
}
node.created_at = reinterpret_cast<const char*>(sqlite3_column_text(stmt, 8));
node.last_accessed = reinterpret_cast<const char*>(sqlite3_column_text(stmt, 9));
// Update access count
update_access(node.id);
}
sqlite3_finalize(stmt);
return node;
}
std::vector<KnowledgeEdge> get_edges_from(int64_t node_id) {
std::lock_guard<std::mutex> lock(db_.get_mutex());
std::vector<KnowledgeEdge> edges;
const char* sql = R"SQL(
SELECT id, source_id, target_id, relation, strength, evidence_count
FROM knowledge_edges WHERE source_id = ?
)SQL";
sqlite3_stmt* stmt;
if (sqlite3_prepare_v2(db_.handle(), sql, -1, &stmt, nullptr) != SQLITE_OK) {
return edges;
}
sqlite3_bind_int64(stmt, 1, node_id);
while (sqlite3_step(stmt) == SQLITE_ROW) {
KnowledgeEdge e;
e.id = sqlite3_column_int64(stmt, 0);
e.source_id = sqlite3_column_int64(stmt, 1);
e.target_id = sqlite3_column_int64(stmt, 2);
e.relation = reinterpret_cast<const char*>(sqlite3_column_text(stmt, 3));
e.strength = sqlite3_column_double(stmt, 4);
e.evidence_count = sqlite3_column_int64(stmt, 5);
edges.push_back(e);
}
sqlite3_finalize(stmt);
return edges;
}
int64_t get_node_count() {
std::lock_guard<std::mutex> lock(db_.get_mutex());
const char* sql = "SELECT COUNT(*) FROM knowledge_nodes";
sqlite3_stmt* stmt;
if (sqlite3_prepare_v2(db_.handle(), sql, -1, &stmt, nullptr) != SQLITE_OK) {
return 0;
}
int64_t count = 0;
if (sqlite3_step(stmt) == SQLITE_ROW) {
count = sqlite3_column_int64(stmt, 0);
}
sqlite3_finalize(stmt);
return count;
}
private:
void update_access(int64_t node_id) {
const char* sql = R"SQL(
UPDATE knowledge_nodes
SET access_count = access_count + 1,
last_accessed = datetime('now')
WHERE id = ?
)SQL";
sqlite3_stmt* stmt;
if (sqlite3_prepare_v2(db_.handle(), sql, -1, &stmt, nullptr) == SQLITE_OK) {
sqlite3_bind_int64(stmt, 1, node_id);
sqlite3_step(stmt);
sqlite3_finalize(stmt);
}
}
};
//=============================================================================
// METRICS REPOSITORY
//=============================================================================
class MetricsRepository {
private:
Database& db_;
public:
explicit MetricsRepository(Database& db) : db_(db) {}
bool insert(const SystemMetrics& metrics) {
std::lock_guard<std::mutex> lock(db_.get_mutex());
const char* sql = R"SQL(
INSERT INTO system_metrics
(timestamp, ticks_per_second, memory_used_mb, cpu_percent,
active_generators, active_agents, knowledge_nodes_count,
total_ticks, global_phi)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
)SQL";
sqlite3_stmt* stmt;
if (sqlite3_prepare_v2(db_.handle(), sql, -1, &stmt, nullptr) != SQLITE_OK) {
return false;
}
sqlite3_bind_int64(stmt, 1, metrics.timestamp);
sqlite3_bind_double(stmt, 2, metrics.ticks_per_second);
sqlite3_bind_double(stmt, 3, metrics.memory_used_mb);
sqlite3_bind_double(stmt, 4, metrics.cpu_percent);
sqlite3_bind_int64(stmt, 5, metrics.active_generators);
sqlite3_bind_int64(stmt, 6, metrics.active_agents);
sqlite3_bind_int64(stmt, 7, metrics.knowledge_nodes_count);
sqlite3_bind_int64(stmt, 8, metrics.total_ticks);
sqlite3_bind_double(stmt, 9, metrics.global_phi);
int rc = sqlite3_step(stmt);
sqlite3_finalize(stmt);
return rc == SQLITE_DONE;
}
SystemMetrics get_latest() {
std::lock_guard<std::mutex> lock(db_.get_mutex());
SystemMetrics m{};
const char* sql = R"SQL(
SELECT timestamp, ticks_per_second, memory_used_mb, cpu_percent,
active_generators, active_agents, knowledge_nodes_count,
total_ticks, global_phi
FROM system_metrics ORDER BY timestamp DESC LIMIT 1
)SQL";
sqlite3_stmt* stmt;
if (sqlite3_prepare_v2(db_.handle(), sql, -1, &stmt, nullptr) != SQLITE_OK) {
return m;
}
if (sqlite3_step(stmt) == SQLITE_ROW) {
m.timestamp = sqlite3_column_int64(stmt, 0);
m.ticks_per_second = sqlite3_column_double(stmt, 1);
m.memory_used_mb = sqlite3_column_double(stmt, 2);
m.cpu_percent = sqlite3_column_double(stmt, 3);
m.active_generators = sqlite3_column_int64(stmt, 4);
m.active_agents = sqlite3_column_int64(stmt, 5);
m.knowledge_nodes_count = sqlite3_column_int64(stmt, 6);
m.total_ticks = sqlite3_column_int64(stmt, 7);
m.global_phi = sqlite3_column_double(stmt, 8);
}
sqlite3_finalize(stmt);
return m;
}
};
//=============================================================================
// UNIFIED PERSISTENCE MANAGER
//=============================================================================
class PersistenceManager {
private:
Database db_;
std::unique_ptr<ConsciousnessRepository> consciousness_repo_;
std::unique_ptr<KnowledgeRepository> knowledge_repo_;
std::unique_ptr<MetricsRepository> metrics_repo_;
public:
PersistenceManager() = default;
bool initialize(const std::string& db_path) {
if (!db_.open(db_path)) {
return false;
}
if (!db_.initialize_schema()) {
return false;
}
consciousness_repo_ = std::make_unique<ConsciousnessRepository>(db_);
knowledge_repo_ = std::make_unique<KnowledgeRepository>(db_);
metrics_repo_ = std::make_unique<MetricsRepository>(db_);
return true;
}
ConsciousnessRepository& consciousness() { return *consciousness_repo_; }
KnowledgeRepository& knowledge() { return *knowledge_repo_; }
MetricsRepository& metrics() { return *metrics_repo_; }
Database& database() { return db_; }
void close() {
db_.close();
}
};
// Global persistence instance
inline PersistenceManager& get_persistence() {
static PersistenceManager instance;
return instance;
}
} // namespace mind_farm
#endif // PERSISTENCE_HPP