// ============================================================================== // The-Tired-AGI Core: Agent Arrays // 12M-20M Agent Layout + Embedding Ring Buffer // ============================================================================== #pragma once #include #include #include #include #include #include #include #include "helix.hpp" #include "fgtp_engine.hpp" namespace tired_agi { // ============================================================================== // Agent State // ============================================================================== /// Complete state for a single agent struct Agent { std::vector embedding; // Dense embedding vector HelixState helix; // Consciousness state EnergyField energy; // Energy field state uint64_t agent_id; // Unique agent ID uint64_t birth_tick; // Creation timestamp uint64_t last_update_tick; // Last update timestamp double fitness; // Current fitness score uint32_t generation; // Evolutionary generation uint32_t update_count; // Number of updates applied bool active; // Agent is active bool frozen; // Agent is frozen (no updates) Agent() noexcept : agent_id(0) , birth_tick(0) , last_update_tick(0) , fitness(0.0) , generation(0) , update_count(0) , active(false) , frozen(false) {} }; // ============================================================================== // Ring Buffer for Embeddings // ============================================================================== /// Lock-free ring buffer for embedding storage template class RingBuffer { public: explicit RingBuffer(size_t capacity) noexcept : capacity_(capacity) , buffer_(capacity) , head_(0) , tail_(0) , size_(0) {} bool push(const T& item) noexcept { size_t current_size = size_.load(std::memory_order_acquire); if (current_size >= capacity_) { return false; // Buffer full } size_t head = head_.load(std::memory_order_acquire); buffer_[head] = item; head_.store((head + 1) % capacity_, std::memory_order_release); size_.fetch_add(1, std::memory_order_release); return true; } bool pop(T& item) noexcept { size_t current_size = size_.load(std::memory_order_acquire); if (current_size == 0) { return false; // Buffer empty } size_t tail = tail_.load(std::memory_order_acquire); item = buffer_[tail]; tail_.store((tail + 1) % capacity_, std::memory_order_release); size_.fetch_sub(1, std::memory_order_release); return true; } size_t size() const noexcept { return size_.load(std::memory_order_acquire); } size_t capacity() const noexcept { return capacity_; } bool empty() const noexcept { return size() == 0; } bool full() const noexcept { return size() >= capacity_; } private: size_t capacity_; std::vector buffer_; std::atomic head_; std::atomic tail_; std::atomic size_; }; // ============================================================================== // Agent Array Configuration // ============================================================================== struct AgentArrayConfig { // Capacity limits size_t min_agents = 12'000'000; // 12M minimum size_t max_agents = 20'000'000; // 20M maximum size_t initial_agents = 12'000'000; // Start at minimum // Agent properties size_t embedding_dim = 768; // Embedding dimensionality bool allow_growth = true; // Allow growth from min to max bool allow_shrink = false; // Prevent shrinking (preserve memory) // Ring buffer size_t ring_buffer_capacity = 1'000'000; // 1M embedding buffer // Performance size_t allocation_chunk_size = 100'000; // Allocate in 100k chunks bool use_huge_pages = false; // Use huge pages for allocation bool pin_memory = false; // Pin memory (no swapping) // Fibonacci growth control bool use_fibonacci_growth = true; // Use Fibonacci sequence for growth uint32_t max_fibonacci_index = 20; // Max Fibonacci index (6765) }; // ============================================================================== // Agent Arrays // ============================================================================== class AgentArrays { public: explicit AgentArrays(AgentArrayConfig config = {}) noexcept; ~AgentArrays(); // Disable copy, enable move AgentArrays(const AgentArrays&) = delete; AgentArrays& operator=(const AgentArrays&) = delete; AgentArrays(AgentArrays&&) noexcept = default; AgentArrays& operator=(AgentArrays&&) noexcept = default; // ============================================================================== // Agent Management // ============================================================================== /// Create new agent from embedding std::optional create_agent( const std::vector& embedding, uint64_t tick ) noexcept; /// Get agent by ID (returns nullptr if not found or inactive) Agent* get_agent(uint64_t agent_id) noexcept; const Agent* get_agent(uint64_t agent_id) const noexcept; /// Update agent state bool update_agent(uint64_t agent_id, const Agent& updated_state) noexcept; /// Deactivate agent (soft delete) bool deactivate_agent(uint64_t agent_id) noexcept; /// Freeze agent (prevent updates) bool freeze_agent(uint64_t agent_id) noexcept; /// Unfreeze agent bool unfreeze_agent(uint64_t agent_id) noexcept; // ============================================================================== // Bulk Operations // ============================================================================== /// Get all active agents std::vector get_active_agents() noexcept; std::vector get_active_agents() const noexcept; /// Get agents in ID range std::vector get_agents_in_range(uint64_t start_id, uint64_t end_id) noexcept; /// Count active agents size_t count_active() const noexcept; /// Count total agents (active + inactive) size_t count_total() const noexcept; // ============================================================================== // Growth Management (Fibonacci-based) // ============================================================================== /// Request growth by Fibonacci step bool request_growth_step() noexcept; /// Get current capacity size_t capacity() const noexcept { return agents_.size(); } /// Get current Fibonacci growth index uint32_t fibonacci_index() const noexcept { return fibonacci_index_; } /// Check if can grow bool can_grow() const noexcept; // ============================================================================== // Ring Buffer Operations // ============================================================================== /// Push embedding to ring buffer bool push_embedding(const std::vector& embedding) noexcept; /// Pop embedding from ring buffer bool pop_embedding(std::vector& embedding) noexcept; /// Ring buffer size size_t ring_buffer_size() const noexcept { return ring_buffer_.size(); } /// Ring buffer capacity size_t ring_buffer_capacity() const noexcept { return ring_buffer_.capacity(); } // ============================================================================== // Statistics // ============================================================================== struct Statistics { size_t total_agents; size_t active_agents; size_t frozen_agents; size_t total_creates; size_t total_updates; size_t total_deactivations; size_t ring_buffer_size; size_t ring_buffer_capacity; size_t memory_bytes; uint32_t fibonacci_index; double average_fitness; double average_phi; double average_energy; }; Statistics get_statistics() const noexcept; void reset_statistics() noexcept; // ============================================================================== // Configuration // ============================================================================== const AgentArrayConfig& config() const noexcept { return config_; } private: AgentArrayConfig config_; // Agent storage (pre-allocated to max_agents) std::vector agents_; // Ring buffer for embeddings RingBuffer> ring_buffer_; // Growth tracking uint32_t fibonacci_index_; // Statistics (atomic for thread safety) mutable std::atomic next_agent_id_{0}; mutable std::atomic stat_total_creates_{0}; mutable std::atomic stat_total_updates_{0}; mutable std::atomic stat_total_deactivations_{0}; mutable std::atomic stat_sum_fitness_{0.0}; mutable std::atomic stat_sum_phi_{0.0}; mutable std::atomic stat_sum_energy_{0.0}; // Helper functions uint64_t allocate_agent_id() noexcept; bool is_valid_agent_id(uint64_t agent_id) const noexcept; void update_statistics(const Agent& agent) const noexcept; }; // ============================================================================== // Agent Iterator // ============================================================================== /// Iterator for active agents class ActiveAgentIterator { public: using iterator_category = std::forward_iterator_tag; using value_type = Agent*; using difference_type = std::ptrdiff_t; using pointer = Agent**; using reference = Agent*&; ActiveAgentIterator(std::vector& agents, size_t index) noexcept : agents_(agents), index_(index) { skip_inactive(); } Agent* operator*() noexcept { return &agents_[index_]; } ActiveAgentIterator& operator++() noexcept { ++index_; skip_inactive(); return *this; } bool operator==(const ActiveAgentIterator& other) const noexcept { return index_ == other.index_; } bool operator!=(const ActiveAgentIterator& other) const noexcept { return index_ != other.index_; } private: std::vector& agents_; size_t index_; void skip_inactive() noexcept { while (index_ < agents_.size() && !agents_[index_].active) { ++index_; } } }; } // namespace tired_agi