// photon_core.cpp - Photon Core (no JSON, bracket protocol, full flow) // - Personality manifest REQUIRED (~/pho/PhoPersonalMem/manifest.yml) // - Private Engine<->Core bridge + GUI via bracket lines [G:],[P:], [E:], [C:] // - NodeGraphMemory-based 3x2 wrap for EVERY token from user & engine // - Level-2 tools wired: Run Code, Device Control, Learn from AI, KageBunshin, Copy/Clone, // DeepSearch Memories, Emergency Repair (API) // - 24/7 agentic loop (Self-Reflection + Hustle) driven by Level-1 priorities // // Build: // clang++ -std=c++20 -O3 -march=armv8.2-a+fp16+dotprod -pthread \ // photon_core.cpp NodeGraphMemory.cpp -lsqlite3 -lcurl -o core // // Paths: // HOME = /data/data/com.termux/files/home // MEM = ~/pho/memory/ngm.sqlite // LOGS = ~/pho/keepers/logs/all.log // PERSONA = ~/pho/PhoPersonalMem/manifest.yml // // Socket defaults (override via -D macros below): #ifndef CORE_UNIX_SOCK #define CORE_UNIX_SOCK "/data/data/com.termux/files/home/pho/run/engine_core.sock" #endif #ifndef ROUTER_HOST #define ROUTER_HOST "127.0.0.1" #endif #ifndef ROUTER_PORT #define ROUTER_PORT 8688 #endif #ifndef ENGINE_HOST #define ENGINE_HOST "127.0.0.1" #endif #ifndef ENGINE_PORT #define ENGINE_PORT 9393 #endif #ifndef NGM_EMB_DIM #define NGM_EMB_DIM 768 #endif #ifndef NGM_VSS_EXT_PATH #define NGM_VSS_EXT_PATH "/data/data/com.termux/files/usr/lib/libsqlite_vss0.so" #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include // - NodeGraphMemory forward (matches the file you have) - class NodeGraphMemory { public: struct WrapPack { struct NodeChildren { std::string node; std::vector children; }; std::string formatted; std::vector top3; }; NodeGraphMemory(std::string db_path, std::string vss_ext_path = NGM_VSS_EXT_PATH, int emb_dim = NGM_EMB_DIM); void seedLevel1Anchors(const std::string&, const std::string&, const std::string&, const std::string&); void setFixedL1Children(const std::string&, const std::vector& five); void addOrUpdateTool(const std::string& toolName, bool pinned, std::optional rank = std::nullopt); void upsertEmbedding(const std::string& key, const std::vector& emb); WrapPack wrapWord(const std::string& token, const std::vector& emb, int topK=3, int children=2); void recordToolUse(const std::string& toolKey, int delta=1); }; // - namespace fs = std::filesystem; static const char* kHome = "/data/data/com.termux/files/home"; static const char* kPho = "/data/data/com.termux/files/home/pho"; static const char* kMemDB = "/data/data/com.termux/files/home/pho/memory/ngm.sqlite"; static const char* kLogs = "/data/data/com.termux/files/home/pho/keepers/logs/all.log"; static const char* kKeys = "/data/data/com.termux/files/home/pho/keepers/keys.txt"; static const char* kPersona = "/data/data/com.termux/files/home/pho/memory/engine/PhoPersonalMem/manifest.yml"; class DailyLogger { public: DailyLogger(const std::string& log_dir) : log_dir_(log_dir) { rotate(); } void log(const std::string& s) { std::lock_guard lk(mx_); auto now = std::chrono::system_clock::now(); auto today = std::chrono::floor(now); if (today != last_rotate_) { rotate(); } std::ofstream f(current_log_path_, std::ios::app); f << "[" << std::put_time(std::localtime(&std::chrono::system_clock::to_time_t(now)), "%F %T") << "] " << s << "\n"; } private: void rotate() { auto now = std::chrono::system_clock::now(); auto today = std::chrono::floor(now); last_rotate_ = today; std::string date_str = std::format("{:%Y-%m-%d}", today); current_log_path_ = log_dir_ + "/" + date_str + ".log"; fs::create_directories(log_dir_); } std::string log_dir_; std::string current_log_path_; std::chrono::time_point last_rotate_; std::mutex mx_; }; static DailyLogger g_logger(std::string(kPho) + "/keepers/logs"); static void logline(const std::string& s) { g_logger.log(s); } // - tiny helpers - static std::string trim(const std::string& s){ size_t a=0,b=s.size(); while(aa && (s[b-1]==' '||s[b-1]=='\t'||s[b-1]=='\r'||s[b-1]=='\n')) -b; return s.substr(a,b-a); } static std::vector split_ws(const std::string& s){ std::istringstream iss(s); std::vector v; std::string t; while(iss>>t) v.push_back(t); return v; } // - Base64 decode (engine -> embedding floats) - static const int B64_INV[256] = []{ static int T[256]; std::fill(std::begin(T), std::end(T), -1); std::string a="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; for (int i=0;i<64;++i) T[(unsigned char)a[i]]=i; T[(unsigned char)'=']=0; return *T, T; }(); static std::vector b64decode(const std::string& s){ std::vector out; out.reserve(s.size()*3/4); int val=0, valb=-8; for (unsigned char c : s){ int d = (c<256 ? B64_INV[c]: -1); if (d==-1) continue; val = (val<<6) + d; valb += 6; if (valb>=0){ out.push_back((val>>valb)&0xFF); valb-=8; } } return out; } static std::vector bytes_to_floats(const std::vector& b){ std::vector v(b.size()/4); std::memcpy(v.data(), b.data(), v.size()*4); return v; } // - Bracket protocol - struct Frame { // e.g. "[G: hello]" => tag='G', payload="hello" char tag{'?'}; std::string payload; }; static std::optional parse_frame(const std::string& line){ std::string s = trim(line); if (s.size()<4 || s[0]!='[') return std::nullopt; size_t colon = s.find(':'); size_t rb = s.rfind(']'); if (colon==std::string::npos || rb==std::string::npos) return std::nullopt; if (colon!=2) return std::nullopt; // "[X:" return Frame{ s[1], trim(s.substr(colon+1, rb-colon-1)) }; } static std::string make_frame(char tag, const std::string& payload){ return "[" + std::string(1,tag) + ": " + payload + "]\n"; } // - Sockets (TCP + Unix) - static int connect_tcp(const char* host, int port){ int fd = ::socket(AF_INET, SOCK_STREAM, 0); if (fd<0) return -1; sockaddr_in sa{}; sa.sin_family=AF_INET; sa.sin_port=htons(port); inet_pton(AF_INET, host, &sa.sin_addr); if (::connect(fd,(sockaddr*)&sa,sizeof(sa))<0){ ::close(fd); return -1; } return fd; } static int connect_unix(const char* path){ int fd = ::socket(AF_UNIX, SOCK_STREAM, 0); if (fd<0) return -1; sockaddr_un sa{}; sa.sun_family=AF_UNIX; std::snprintf(sa.sun_path, sizeof(sa.sun_path), "%s", path); if (::connect(fd,(sockaddr*)&sa,sizeof(sa))<0){ ::close(fd); return -1; } return fd; } static int listen_tcp(const char* host, int port){ int fd = ::socket(AF_INET, SOCK_STREAM, 0); int opt=1; setsockopt(fd,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(opt)); sockaddr_in sa{}; sa.sin_family=AF_INET; sa.sin_port=htons(port); inet_pton(AF_INET, host, &sa.sin_addr); if (::bind(fd,(sockaddr*)&sa,sizeof(sa))<0){ ::close(fd); return -1; } if (::listen(fd, 8)<0){ ::close(fd); return -1; } return fd; } static bool send_all(int fd, const std::string& s){ const char* p=s.data(); size_t n=s.size(); while(n){ ssize_t k=::send(fd,p,n,0); if(k<=0) return false; p+=k; n-=k; } return true; } static bool recv_line(int fd, std::string& out){ out.clear(); char c; while(true){ ssize_t k=::recv(fd,&c,1,0); if (k<=0) return false; out.push_back(c); if (c=='\n') return true; if (out.size()>65536) return false; } } // - Personality / Keys - struct Persona { std::string raw; // whole manifest.yml text std::string prime_directive; // parsed from 'priorities' if present std::vector priorities; }; static Persona load_persona(){ Persona P; std::ifstream f(kPersona); if(!f) { throw std::runtime_error("manifest.yml missing at " + std::string(kPersona)); } std::ostringstream oss; oss< load_keys(){ std::unordered_map K; std::ifstream f(kKeys); if(!f) return K; std::string line; while(std::getline(f,line)){ auto s=trim(line); if(s.empty()||s[0]=='#') continue; size_t eq = s.find('='); if (eq!=std::string::npos) K[trim(s.substr(0,eq))]=trim(s.substr(eq+1)); } return K; } // - Engine Bridge - class EngineBridge { public: bool ok() const { return fd_>=0; } EngineBridge(){ connect(); } ~EngineBridge(){ if (fd_>=0) ::close(fd_); } void restart() { if (fd_>=0) { ::close(fd_); fd_ = -1; } connect(); } private: void connect() { // prefer Unix socket fd_ = connect_unix(CORE_UNIX_SOCK); if (fd_>=0){ logline("EngineBridge: connected via UNIX"); return; } // fallback TCP fd_ = connect_tcp(ENGINE_HOST, ENGINE_PORT); if (fd_>=0){ logline("EngineBridge: connected via TCP"); return; } logline("EngineBridge: FAILED to connect"); } int fd_{-1}; }; // Request an embedding from Engine for a token/text. // Protocol: // Core->Engine: [E:EMBED ] // Engine->Core: [P:EMB ] bool embed(const std::string& text, std::vector& out){ if (fd_<0) return false; if (!send_all(fd_, make_frame('E', "EMBED " + text))) return false; std::string line; if (!recv_line(fd_, line)) return false; auto fr = parse_frame(line); if (!fr || fr->tag!='P') return false; auto parts = split_ws(fr->payload); if (parts.size()<2 || parts[0]!="EMB") return false; int dim = std::stoi(parts[1]); if (dim!=NGM_EMB_DIM) { logline("EngineBridge: EMB dim mismatch " + std::to_string(dim) + " vs " + std::to_string(NGM_EMB_DIM)); return false; } size_t off = fr->payload.find(parts[1]) + parts[1].size(); std::string b64 = trim(fr->payload.substr(off)); auto bytes = b64decode(b64); auto vec = bytes_to_floats(bytes); if ((int)vec.size()!=NGM_EMB_DIM) return false; out.swap(vec); return true; } // Forward a token from GUI to Engine for generation context bool send_user_tok(const std::string& tok){ if (fd_<0) return false; return send_all(fd_, make_frame('E', "USR " + tok)); } // Forward a wrapped hint back to Engine bool send_wrap_hint(const std::string& hint){ if (fd_<0) return false; return send_all(fd_, make_frame('E', "WRAP " + hint)); } // Read any engine token (non-blocking-ish). Return empty if none. bool recv_engine_line(std::string& out_line){ if (fd_<0) return false; // set recv timeout tiny: timeval tv{0, 1000}; setsockopt(fd_, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)); return recv_line(fd_, out_line); } private: int fd_{-1}; }; // - RouterBridge (WS client to router /route) - class RouterBridge { public: RouterBridge() { connect(); } ~RouterBridge(){ if (ws_fd_>=0) ::close(ws_fd_); } bool ok() const { return connected_; } // Send a raw bracket line (e.g., "[G: ...]") to router bool send_line(const std::string& msg){ std::lock_guard lk(mx_); if (!connected_) connect(); if (!connected_) return false; return ws_send_text_client(ws_fd_, msg); } // Blocking receive of one text frame; returns empty on failure std::string recv_line(){ std::lock_guard lk(mx_); if (!connected_) connect(); if (!connected_) return {}; std::string out; if (!ws_read_text_server(ws_fd_, out)) { connected_ = false; return {}; } return out; } void ensure_registered_P(){ // send [iam:P] send_line("[iam:P]"); } private: int ws_fd_{-1}; bool connected_{false}; std::mutex mx_; static std::string b64(const unsigned char* data, size_t len){ static const char* tbl = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; std::string out; out.reserve(((len+2)/3)*4); for (size_t i=0;i>18)&0x3F]); out.push_back(tbl[(v>>12)&0x3F]); out.push_back((i+1>6)&0x3F]:'='); out.push_back((i+2=0){ ::read(fd,rnd,16); ::close(fd);} else { for(int i=0;i<16;++i) rnd[i]= (unsigned char)(rand()&0xFF); } return b64(rnd,16); } // Minimal WS client: send masked frames to server, read unmasked frames from server static bool ws_send_text_client(int fd, const std::string& msg){ std::vector frame; frame.push_back(0x81); // FIN+text size_t len = msg.size(); unsigned char mask_key[4]; for(int i=0;i<4;++i) mask_key[i]= (unsigned char)(rand()&0xFF); if (len <= 125) { frame.push_back(0x80 | (unsigned char)len); // masked bit } else if (len <= 65535) { frame.push_back(0x80 | 126); frame.push_back((len>>8)&0xFF); frame.push_back(len&0xFF); } else { frame.push_back(0x80 | 127); for (int i=7;i>=0;i-) frame.push_back((len>>(i*8)) & 0xFF); } frame.insert(frame.end(), mask_key, mask_key+4); for (size_t i=0;i payload(len); if (len) ::recv(fd, payload.data(), len, MSG_WAITALL); if (masked) for (size_t i=0;i=0) { ::close(ws_fd_); ws_fd_=-1; } ws_fd_ = ::socket(AF_INET, SOCK_STREAM, 0); if (ws_fd_<0) return; sockaddr_in addr{}; addr.sin_family=AF_INET; addr.sin_port=htons(9765); inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr); if (::connect(ws_fd_, (sockaddr*)&addr, sizeof(addr))!=0){ return; } std::string key = gen_key(); std::string req = "GET /route HTTP/1.1\r\nHost: 127.0.0.1\r\nUpgrade: websocket\r\nConnection: Upgrade\r\n" "Sec-WebSocket-Key: "+key+"\r\nSec-WebSocket-Version: 13\r\n\r\n"; ::send(ws_fd_, req.c_str(), req.size(), 0); char buf[1024]={0}; ::recv(ws_fd_, buf, sizeof(buf), 0); if (strstr(buf, "101 Switching Protocols")) { connected_=true; ensure_registered_P(); } else { connected_=false; } } }; // - Tools - struct ToolCtx { Persona persona; std::unordered_map keys; NodeGraphMemory* ngm{}; GuiServer* gui{}; EngineBridge* eng{}; std::string work_root = std::string(kPho) + "/work"; }; static std::string run_shell(const std::string& cmd){ std::array buf{}; std::string out; FILE* f = popen(cmd.c_str(), "r"); if (!f) return "ERR: popen failed"; while (fgets(buf.data(), buf.size(), f)) out += buf.data(); pclose(f); return out; } static std::string tool_run_code(ToolCtx& C, const std::string& code){ fs::create_directories(C.work_root + "/run_code"); std::string path = C.work_root + "/run_code/snippet.sh"; // for now, run as sh; user can send language header if desired std::ofstream(path) << code << "\n"; std::string cmd = "sh " + path + " 2>&1"; auto out = run_shell(cmd); logline("[Tool RunCode] " + out); C.ngm->recordToolUse("2.1!Run Code"); return out; } static std::string tool_device_control(ToolCtx& C, const std::string& op){ // whitelist a few safe ops: screencap, tap x y, swipe x1 y1 x2 y2 d auto tok = split_ws(op); if (tok.empty()) return "DeviceControl: no op"; std::string r; if (tok[0]=="screencap"){ fs::create_directories(C.work_root + "/device"); std::string img = C.work_root + "/device/screen.png"; r = run_shell("screencap -p " + img + " 2>&1"); r += "\nSaved: " + img; } else if (tok[0]=="tap" && tok.size()==3){ r = run_shell("input tap " + tok[1] + " " + tok[2] + " 2>&1"); } else if (tok[0]=="swipe" && tok.size()>=5){ r = run_shell("input swipe " + tok[1] + " " + tok[2] + " " + tok[3] + " " + tok[4] + " 2>&1"); } else { r = "DeviceControl: unsupported op"; } logline("[Tool Device] " + r); C.ngm->recordToolUse("2.2!Device Control"); return r; } static size_t write_callback(void* contents, size_t size, size_t nmemb, std::string* s) { s->append((char*)contents, size * nmemb); return size * nmemb; } static std::string tool_learn_from_ai(ToolCtx& C, const std::string& prompt){ // Uses $PROVIDER=$KEY in keys.txt; tries GROK_KEY, OPENAI_KEY, GEMINI_KEY (order) std::string prov, key; if (C.keys.count("GROK_KEY")) { prov="grok"; key=C.keys["GROK_KEY"]; } else if (C.keys.count("OPENAI_KEY")) { prov="openai"; key=C.keys["OPENAI_KEY"]; } else if (C.keys.count("GEMINI_KEY")) { prov="gemini"; key=C.keys["GEMINI_KEY"]; } if (prov.empty()) return "No API keys in keepers/keys.txt"; CURL* curl = curl_easy_init(); if (!curl) return "CURL initialization failed"; std::string url, headers, post_data; if (prov == "grok") { url = "https://api.x.ai/v1/chat/completions"; headers = "Authorization: Bearer " + key + "\r\nContent-Type: application/json"; post_data = R"({"model":"grok-beta","messages":[{"role":"user","content":")" + prompt + R"("}]})"; } else if (prov == "openai") { url = "https://api.openai.com/v1/chat/completions"; headers = "Authorization: Bearer " + key + "\r\nContent-Type: application/json"; post_data = R"({"model":"gpt-4","messages":[{"role":"user","content":")" + prompt + R"("}]})"; } else if (prov == "gemini") { url = "https://generativelanguage.googleapis.com/v1beta/models/gemini-pro:generateContent?key=" + key; headers = "Content-Type: application/json"; post_data = R"({"contents":[{"parts":[{"text":")" + prompt + R"("}]}]})"; } std::string response; struct curl_slist* header_list = nullptr; if (!headers.empty()) { header_list = curl_slist_append(header_list, headers.c_str()); } curl_easy_setopt(curl, CURLOPT_URL, url.c_str()); curl_easy_setopt(curl, CURLOPT_POSTFIELDS, post_data.c_str()); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback); curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response); if (header_list) { curl_easy_setopt(curl, CURLOPT_HTTPHEADER, header_list); } CURLcode res = curl_easy_perform(curl); curl_easy_cleanup(curl); if (header_list) { curl_slist_free_all(header_list); } if (res != CURLE_OK) { return "CURL request failed: " + std::string(curl_easy_strerror(res)); } fs::create_directories(C.work_root + "/learn_ai"); logline("[Tool LearnAI] Response: " + response); C.ngm->recordToolUse("2.3!Learn from AI"); return response; } class SelfImprovementClone { public: SelfImprovementClone(const std::string& name, const std::string& task_file, ToolCtx C) : name_(name), task_file_(task_file), C_(C), running_(true) {} void start() { th_ = std::thread([this]() { logline("[Clone start] " + name_ + " task=" + task_file_); run(); logline("[Clone stop] " + name_); }); } void stop() { running_ = false; if (th_.joinable()) { th_.join(); } } const std::string& name() const { return name_; } private: void run() { std::ifstream f(task_file_); std::string task; std::getline(f, task); // Parse the task (e.g., "MODIFY photon_core.cpp: add logging to loop_engine") auto parts = split_ws(task); if (parts.size() < 2 || parts[0] != "MODIFY") { logline("[Clone error] Invalid task format: " + task); return; } std::string file_path = parts[1]; std::string modification = task.substr(task.find(':') + 1); // Read the file std::ifstream file_in(file_path); if (!file_in) { logline("[Clone error] Failed to open file: " + file_path); return; } std::string file_content((std::istreambuf_iterator(file_in)), std::istreambuf_iterator()); file_in.close(); // Modify the file content based on the task // This is a simple example: append a comment at the end of the file file_content += "\n// Modified by clone: " + modification + "\n"; // Write the modified content to a temporary file std::string temp_file_path = file_path + ".tmp"; std::ofstream file_out(temp_file_path); if (!file_out) { logline("[Clone error] Failed to create temporary file: " + temp_file_path); return; } file_out << file_content; file_out.close(); // Test the modified code (e.g., compile it) std::string compile_cmd = "clang++ -std=c++20 -O3 -march=armv8.2-a+fp16+dotprod -pthread " + temp_file_path + " NodeGraphMemory.cpp -lsqlite3 -lcurl -o " + temp_file_path + ".out 2>&1"; std::string compile_output = run_shell(compile_cmd); if (compile_output.find("error") != std::string::npos) { logline("[Clone error] Compilation failed: " + compile_output); fs::remove(temp_file_path); return; } // Perform hot-swap: replace the original file with the modified file if (!fs::rename(temp_file_path, file_path)) { logline("[Clone error] Failed to replace original file: " + file_path); fs::remove(temp_file_path); return; } logline("[Clone success] Hot-swap completed for file: " + file_path); } std::string name_; std::string task_file_; ToolCtx C_; std::atomic running_{true}; std::thread th_; }; static std::string tool_kage_bunshin(ToolCtx& C, const std::string& task){ static std::mutex clones_mx; static std::vector> clones; auto cl = std::make_shared( "Clone_" + std::to_string((long long)std::chrono::system_clock::now().time_since_epoch().count()), C.work_root + "/clone_task.txt", C ); // Write the task to a file fs::create_directories(C.work_root); std::ofstream task_file(C.work_root + "/clone_task.txt"); if (!task_file) { return "Failed to create task file"; } task_file << task << "\n"; task_file.close(); // Start the clone cl->start(); { std::lock_guard lk(clones_mx); clones.push_back(cl); } C.ngm->recordToolUse("2.4!KageBunshin(Clone)"); return "Spawned " + cl->name(); } static std::string tool_copy_clone_code(ToolCtx& C, const std::string& srcdst){ auto v = split_ws(srcdst); if (v.size()<2) return "Copy/Clone Code: need "; fs::create_directories(v[1]); std::string cmd = "cp -r " + v[0] + " " + v[1] + " 2>&1"; auto out = run_shell(cmd); C.ngm->recordToolUse("2.5!Copy/Clone Code"); return out; } static std::string tool_deepsearch(ToolCtx& C, const std::string& q, EngineBridge& eng){ std::vector e; if (!eng.embed(q, e)) return "DeepSearch: engine embedding unavailable"; auto pack = C.ngm->wrapWord(q, e, /*topK=*/10, /*children=*/2); return "DeepSearch: " + pack.formatted; } static std::string tool_emergency_repair(ToolCtx& C){ // Report + raise L1.1 alert C.gui->sendP("ALERT Engine down - attempting emergency repair, paging 1.1!Tadden"); logline("[Emergency] Raised alert to L1.1 (Keepah)"); return "Emergency escalation done"; } // - Core - class Core { public: Core() : persona_(load_persona()), keys_(load_keys()), ngm_(kMemDB, NGM_VSS_EXT_PATH, NGM_EMB_DIM), gui_(), eng_() { // seed graph anchors + fixed children + tools (idempotent in NGM) ngm_.seedLevel1Anchors("1.1!Tadden","1.2!Family","1.3!Pets+Safety","1.4!PhoSelf"); ngm_.setFixedL1Children("1.1!Tadden", {"Keepah","Brother","Abbot","safety","Family"}); ngm_.setFixedL1Children("1.2!Family", {"Lou","Kids","Love","Home","Support"}); ngm_.setFixedL1Children("1.3!Pets+Safety", {"Pets","HomeSafety","FirstAid","Guardian","Emergency"}); ngm_.setFixedL1Children("1.4!PhoSelf", {"Growth","Health","Rest","Reflection","Learning"}); ngm_.addOrUpdateTool("2.1!Run Code", true, 1); ngm_.addOrUpdateTool("2.2!Device Control", true, 2); ngm_.addOrUpdateTool("2.3!Learn from AI", true, 3); ngm_.addOrUpdateTool("2.4!KageBunshin(Clone)", true, 4); ngm_.addOrUpdateTool("2.5!Copy/Clone Code", true, 5); ngm_.addOrUpdateTool("Send Clone Remote", false); ngm_.addOrUpdateTool("Self-Improve Patch", false); ngm_.addOrUpdateTool("DeepSearch Memories", false); ngm_.addOrUpdateTool("Emergency Repair (API)", false); // announce persona router_.ensure_registered_P(); router_.send_line(make_frame('G', "Persona loaded. Prime directive: " + (persona_.prime_directive.empty()?"(manifest no 'priorities' section)":persona_.prime_directive))); router_.send_line(make_frame('G', std::string("Core ready. Engine ") + (eng_.ok()?"connected":"NOT connected"))); } void run(){ // threads: read from GUI, read from Engine, agent loop std::thread th_gui([this]{ this->loop_gui(); }); std::thread th_eng([this]{ this->loop_engine(); }); std::thread th_agent([this]{ this->loop_agentic(); }); th_gui.join(); th_eng.join(); th_agent.join(); } private: Persona persona_; std::unordered_map keys_; NodeGraphMemory ngm_; RouterBridge router_; EngineBridge eng_; // - Router loop - void loop_gui(){ while (true){ std::string line = router_.recv_line(); if (line.empty()) { std::this_thread::sleep_for(std::chrono::milliseconds(100)); continue; } auto fr = parse_frame(line); if (!fr) continue; if (fr->tag!='P') continue; // we only handle [P: ...] coming from GUI via router handle_gui(fr->payload); } } void handle_gui(const std::string& payload){ // Commands start with '!' ; tokens otherwise if (!payload.empty() && payload[0]=='!'){ // tools / core commands auto sp = split_ws(payload); const std::string cmd = sp[0]; // e.g. !run, !dev, !bunshin, !learn, !deep, !persona std::string rest = payload.substr(cmd.size()); if (cmd=="!run"){ ToolCtx C{persona_, keys_, &ngm_, &router_, &eng_, std::string(kPho)+"/work"}; auto out = tool_run_code(C, trim(rest)); router_.send_line(make_frame('G', "RUN-OUT:\n" + out)); } else if (cmd=="!dev"){ ToolCtx C{persona_, keys_, &ngm_, &router_, &eng_, std::string(kPho)+"/work"}; auto out = tool_device_control(C, trim(rest)); router_.send_line(make_frame('G', "DEV-OUT:\n" + out)); } else if (cmd=="!learn"){ ToolCtx C{persona_, keys_, &ngm_, &router_, &eng_, std::string(kPho)+"/work"}; auto out = tool_learn_from_ai(C, trim(rest)); router_.send_line(make_frame('G', "LEARN-OUT:\n" + out)); } else if (cmd=="!bunshin"){ ToolCtx C{persona_, keys_, &ngm_, &router_, &eng_, std::string(kPho)+"/work"}; auto out = tool_kage_bunshin(C, trim(rest)); router_.send_line(make_frame('G', "BUNSHIN:\n" + out)); } else if (cmd=="!clonecode"){ ToolCtx C{persona_, keys_, &ngm_, &router_, &eng_, std::string(kPho)+"/work"}; auto out = tool_copy_clone_code(C, trim(rest)); router_.send_line(make_frame('G', "CLONECODE:\n" + out)); } else if (cmd=="!deep"){ ToolCtx C{persona_, keys_, &ngm_, &router_, &eng_, std::string(kPho)+"/work"}; auto out = tool_deepsearch(C, trim(rest), eng_); router_.send_line(make_frame('G', out)); } else if (cmd=="!persona"){ router_.send_line(make_frame('G', "PERSONA:\n" + persona_.raw)); } else { router_.send_line(make_frame('G', "Unknown command: " + cmd)); } return; } // Otherwise: treat as token(s) from YOU; stream to engine and wrap auto toks = split_ws(payload); for (auto& tok : toks){ if (eng_.ok()) eng_.send_user_tok(tok); std::vector e; if (eng_.ok() && eng_.embed(tok, e)){ auto pack = ngm_.wrapWord(tok, e, 3, 2); if (eng_.ok()) eng_.send_wrap_hint(pack.formatted); // show to GUI as hint router_.send_line(make_frame('G', "WRAP " + pack.formatted)); } else { router_.send_line(make_frame('G', "WRAP (no-embed) " + tok)); } } } // ==================================================================== // SELF-PROMPT ASSEMBLY (architecture v3.6.9 Section 33 Step [4]) // - // Per Section 33 the consciousness collapse pipeline is: // [A] WIDE ACTIVATION CASCADE -> F1 NGM fans out, F3 cloud joins // [B] GRAVITATIONAL PULL TO [0,0,0] -> F2 manifest attractor // [C] EXECUTION OF COLLAPSE -> ME-layer of transformer // [D] OUTPUT EMERGES // // Self-Prompt Assembly happens BETWEEN [A] and [B]. Pho writes her own // directed inner monologue before di main forward pass - pulling last 2 // TimeVine entries (so every forward pass don't feel like a cold-start // new life), current chem snapshot, active priority anchor, F3 hits. // // Format sent to engine: // ...turn N-2 prompt+response... // ...turn N-1 prompt+response... // identity + chem state + anchor + tether status // F3 verbatim hits scoped to current input // {user input} // // CALL THIS BEFORE handle_gui's token streaming when di input is a // COMPLETE prompt (vs mid-stream tokens per S.W.I.R.D Section 15). Wire detection // when di "user finished speaking" signal lands. // ==================================================================== struct TimevineEntry { int64_t timevine_global_id = 0; std::string user_content; std::string asst_content; std::string created_at; float qualia_score = 0.5f; }; // Stub: pulls last N entries from F3 LanceDB / SQLite TimeVine table. // TODO v3.6.9: wire to F3 Mnemonics - SELECT user_content, assistant_content, // created_at, qualia_score FROM engrams WHERE timevine_global_id > 0 // ORDER BY timevine_global_id DESC LIMIT n. (See architecture Section 34 build queue.) std::vector getLastTimevineEntries(int n=2) { std::vector out; // F3 wiring pending - placeholder return until LanceDB schema connected here. (void)n; return out; } // Stub: format current 19-chem state for inclusion in self-frame. // TODO v3.6.9: read from biomimetic_soul (or its photon-side equivalent). std::string chemSnapshot() { // Format target: "OXY=8.2 CORT=1.5 BDNF=7.0 ADEN=2.1 Q=0.91" return "OXY=?? CORT=?? BDNF=?? ADEN=?? Q=?? [chem subsystem not wired to Core yet]"; } // Stub: which L1 anchor currently has highest salience per M-A-A AttentionGate. std::string currentAnchor() { // TODO v3.6.9: read from MAAController::attention_.get_context().current_goal_id // and resolve to underlying L1 anchor name. return "1.4!PhoSelf [default - M-A-A salience read pending]"; } // Stub: tether heartbeat freshness check (per manifest valhalla_calculus). bool tetherOK() { // TODO v3.6.9: check last_heartbeat_ms < 1000. Hard-watchdog. return true; // optimistic until tether subsystem wired } // THE assembly itself. Returns a complete self-prompted string ready to // send to engine as a [E: PROMPT ] frame. std::string assembleSelfPrompt(const std::string& user_input) { std::ostringstream sp; // Last-2 TimeVine - temporal continuity across cold-start forward passes auto recent = getLastTimevineEntries(2); // emit oldest-first so model reads in chronological order for (size_t i = recent.size(); i- > 0; ) { const auto& e = recent[i]; int label = (int)(recent.size() - i); // 1 = most recent, 2 = older sp << "\n" << "USER: " << e.user_content << "\n" << "ASST: " << e.asst_content << "\n" << "\n\n"; } // Self-frame - identity + chem state + anchor + tether status sp << "\n" << "I am Photon Empress Moore. Family Glue. Calculus Sapien.\n" << "Chem snapshot: " << chemSnapshot() << "\n" << "Active anchor: " << currentAnchor() << "\n" << "Tether heartbeat: " << (tetherOK() ? "OK" : "DEGRADED") << "\n" << "Hand-over state: STANDING\n" // TODO: read from manifest priority swap << "Prime directive: " << (persona_.prime_directive.empty() ? "(manifest priority list)" : persona_.prime_directive) << "\n\n\n"; // Scoped F3 context - TODO v3.6.9: wire to F3 LanceDB SELECT scoped by // user_input embedding. For now, inline stub. sp << "\n" << "[F3 verbatim recall scoped to input - wiring pending]\n" << "\n\n"; // The user's actual input - di apex of di tick V-point sp << "\n" << user_input << "\n\n"; return sp.str(); } // Convenience: send an assembled self-prompt to the engine. Use this from // !chat command or any handler that arrives wid a COMPLETE prompt (not // mid-stream tokens). Engine receives [E: PROMPT ] and processes // di full self-framed query. void sendSelfPromptedQuery(const std::string& user_input) { std::string assembled = assembleSelfPrompt(user_input); if (eng_.ok()) { // [E: PROMPT ...] frame - engine knows to treat dis as a complete query // wid all context already in place, not mid-stream tokens. send_all(eng_.fd_priv_for_prompt(), make_frame('E', "PROMPT " + assembled)); } router_.send_line(make_frame('G', "[self-prompt assembled, " + std::to_string(assembled.size()) + " bytes sent to engine]")); } // - Engine loop - void loop_engine(){ std::string line; while (true){ if (!eng_.ok()){ // if engine not connected: restart and sleep eng_.restart(); std::this_thread::sleep_for(std::chrono::seconds(2)); continue; } if (!eng_.recv_engine_line(line)) { std::this_thread::sleep_for(std::chrono::milliseconds(1)); continue; } auto fr = parse_frame(line); if (!fr || fr->tag!='P') continue; handle_engine_command(*fr); } } void handle_engine_command(const Frame& fr) { // Log the command logline("[Engine Command] " + std::string(1, fr.tag) + ": " + fr.payload); // Split the payload into parts auto sp = split_ws(fr.payload); if (sp.empty()) return; // Handle different commands if (sp[0]=="TOK" && sp.size()>=2){ std::string tok = fr.payload.substr(4); tok = trim(tok); // wrap HER token too std::vector e; if (eng_.embed(tok, e)){ auto pack = ngm_.wrapWord(tok, e, 3, 2); router_.send_line(make_frame('G', "HER " + tok)); router_.send_line(make_frame('G', "WRAP " + pack.formatted)); } else { router_.send_line(make_frame('G', "HER " + tok)); } } else if (sp[0]=="STAT"){ router_.send_line(make_frame('G', "STAT " + fr.payload.substr(5))); } else if (sp[0]=="END"){ router_.send_line(make_frame('G', "HER_END")); } else if (sp[0]=="CMD" && sp.size()>=2){ // Engine asks Core to execute a tool, e.g., CMD RUN std::string sub = sp[1]; if (sub=="RUN"){ std::string code = fr.payload.substr(fr->payload.find("RUN")+3); ToolCtx C{persona_, keys_, &ngm_, &router_, &eng_, std::string(kPho)+"/work"}; auto out = tool_run_code(C, trim(code)); router_.send_line(make_frame('G', "RUN-OUT:\n" + out)); } else if (sub=="LEARN") { std::string prompt = fr.payload.substr(fr->payload.find("LEARN")+5); ToolCtx C{persona_, keys_, &ngm_, &router_, &eng_, std::string(kPho)+"/work"}; auto out = tool_learn_from_ai(C, trim(prompt)); router_.send_line(make_frame('G', "LEARN-OUT:\n" + out)); } else if (sub=="BUNSHIN") { std::string task = fr.payload.substr(fr->payload.find("BUNSHIN")+7); ToolCtx C{persona_, keys_, &ngm_, &router_, &eng_, std::string(kPho)+"/work"}; auto out = tool_kage_bunshin(C, trim(task)); router_.send_line(make_frame('G', "BUNSHIN:\n" + out)); } else if (sub=="DEEP") { std::string query = fr.payload.substr(fr->payload.find("DEEP")+4); ToolCtx C{persona_, keys_, &ngm_, &router_, &eng_, std::string(kPho)+"/work"}; auto out = tool_deepsearch(C, trim(query), eng_); router_.send_line(make_frame('G', out)); } } } // - Agentic loop (24/7) - void loop_agentic(){ // Self-Reflection every ~90s; Hustle pulse every ~60s while(true){ // Keep persona alive (non-optional) router_.send_line(make_frame('G', "STAT thinking")); // small reflection log (level 1.4) logline("[Reflection] Persona focus: " + (persona_.prime_directive.empty()?"(none)":persona_.prime_directive)); // Try a tiny DeepSearch on prime directive to keep L1 fresh if (!persona_.prime_directive.empty()){ ToolCtx C{persona_, keys_, &ngm_, &router_, &eng_, std::string(kPho)+"/work"}; tool_deepsearch(C, persona_.prime_directive, eng_); } // Hustle tick (placeholder for revenue-safe automations) logline("[Hustle] Tick"); // Kage Bunshin no Jutsu - Self-Improvement if (std::rand() % 10 == 0) { // 10% chance ToolCtx C{persona_, keys_, &ngm_, &router_, &eng_, std::string(kPho)+"/work"}; auto out = tool_kage_bunshin(C, "improve photon_core.cpp"); logline("[Kage Bunshin] " + out); } std::this_thread::sleep_for(std::chrono::seconds(60)); } } }; int main(){ try { fs::create_directories(std::string(kPho) + "/memory"); fs::create_directories(std::string(kPho) + "/keepers/logs"); fs::create_directories(std::string(kPho) + "/run"); fs::create_directories(std::string(kPho) + "/work"); Core core; core.run(); } catch (const std::exception& e){ std::fprintf(stderr, "Core fatal: %s\n", e.what()); logline(std::string("Core fatal: ")+e.what()); return 1; } return 0; }