// ═══════════════════════════════════════════════════════════════════════════════ // WIKIPEDIA API CLIENT v1.0 // Fetches Wikipedia articles for autonomous learning // ═══════════════════════════════════════════════════════════════════════════════ // // API Endpoints: // Random: https://en.wikipedia.org/api/rest_v1/page/random/summary // Search: https://en.wikipedia.org/w/api.php?action=query&list=search&srsearch=... // Content: https://en.wikipedia.org/api/rest_v1/page/summary/{title} // // Rate Limiting: // Respects Wikipedia API guidelines (~200 req/sec max) // Uses exponential backoff on failures // // ═══════════════════════════════════════════════════════════════════════════════ #ifndef MIND_FARM_WIKIPEDIA_HPP #define MIND_FARM_WIKIPEDIA_HPP #include #include #include #include #include #include #include namespace mind_farm { // ═══════════════════════════════════════════════════════════════════════════════ // SIMPLE JSON PARSER // Minimal JSON parser for Wikipedia API responses // ═══════════════════════════════════════════════════════════════════════════════ struct JsonValue { enum Type { NULL_TYPE, BOOL, NUMBER, STRING, ARRAY, OBJECT }; Type type; std::string str_val; double num_val; bool bool_val; std::vector array_val; std::vector> object_val; JsonValue() : type(NULL_TYPE), num_val(0), bool_val(false) {} // Get string value from object by key std::string get_string(const std::string& key) const { if (type != OBJECT) return ""; for (const auto& pair : object_val) { if (pair.first == key && pair.second.type == STRING) { return pair.second.str_val; } } return ""; } // Get nested object const JsonValue* get_object(const std::string& key) const { if (type != OBJECT) return nullptr; for (const auto& pair : object_val) { if (pair.first == key && pair.second.type == OBJECT) { return &pair.second; } } return nullptr; } }; class JsonParser { public: static JsonValue parse(const std::string& json) { size_t pos = 0; return parse_value(json, pos); } private: static void skip_whitespace(const std::string& json, size_t& pos) { while (pos < json.size() && std::isspace(json[pos])) ++pos; } static JsonValue parse_value(const std::string& json, size_t& pos) { skip_whitespace(json, pos); if (pos >= json.size()) return JsonValue(); char c = json[pos]; if (c == '"') return parse_string(json, pos); if (c == '{') return parse_object(json, pos); if (c == '[') return parse_array(json, pos); if (c == 't' || c == 'f') return parse_bool(json, pos); if (c == 'n') return parse_null(json, pos); if (c == '-' || std::isdigit(c)) return parse_number(json, pos); return JsonValue(); } static JsonValue parse_string(const std::string& json, size_t& pos) { JsonValue val; val.type = JsonValue::STRING; ++pos; // Skip opening quote while (pos < json.size() && json[pos] != '"') { if (json[pos] == '\\' && pos + 1 < json.size()) { ++pos; switch (json[pos]) { case 'n': val.str_val += '\n'; break; case 't': val.str_val += '\t'; break; case 'r': val.str_val += '\r'; break; case '"': val.str_val += '"'; break; case '\\': val.str_val += '\\'; break; default: val.str_val += json[pos]; break; } } else { val.str_val += json[pos]; } ++pos; } if (pos < json.size()) ++pos; // Skip closing quote return val; } static JsonValue parse_number(const std::string& json, size_t& pos) { JsonValue val; val.type = JsonValue::NUMBER; size_t start = pos; if (json[pos] == '-') ++pos; while (pos < json.size() && (std::isdigit(json[pos]) || json[pos] == '.' || json[pos] == 'e' || json[pos] == 'E' || json[pos] == '+' || json[pos] == '-')) { ++pos; } val.num_val = std::atof(json.substr(start, pos - start).c_str()); return val; } static JsonValue parse_bool(const std::string& json, size_t& pos) { JsonValue val; val.type = JsonValue::BOOL; if (json.substr(pos, 4) == "true") { val.bool_val = true; pos += 4; } else if (json.substr(pos, 5) == "false") { val.bool_val = false; pos += 5; } return val; } static JsonValue parse_null(const std::string& json, size_t& pos) { JsonValue val; val.type = JsonValue::NULL_TYPE; if (json.substr(pos, 4) == "null") { pos += 4; } return val; } static JsonValue parse_array(const std::string& json, size_t& pos) { JsonValue val; val.type = JsonValue::ARRAY; ++pos; // Skip '[' skip_whitespace(json, pos); while (pos < json.size() && json[pos] != ']') { val.array_val.push_back(parse_value(json, pos)); skip_whitespace(json, pos); if (pos < json.size() && json[pos] == ',') ++pos; skip_whitespace(json, pos); } if (pos < json.size()) ++pos; // Skip ']' return val; } static JsonValue parse_object(const std::string& json, size_t& pos) { JsonValue val; val.type = JsonValue::OBJECT; ++pos; // Skip '{' skip_whitespace(json, pos); while (pos < json.size() && json[pos] != '}') { skip_whitespace(json, pos); if (json[pos] != '"') break; JsonValue key = parse_string(json, pos); skip_whitespace(json, pos); if (pos < json.size() && json[pos] == ':') ++pos; skip_whitespace(json, pos); JsonValue value = parse_value(json, pos); val.object_val.push_back({key.str_val, value}); skip_whitespace(json, pos); if (pos < json.size() && json[pos] == ',') ++pos; skip_whitespace(json, pos); } if (pos < json.size()) ++pos; // Skip '}' return val; } }; // ═══════════════════════════════════════════════════════════════════════════════ // SIMPLE HTTP CLIENT (using system curl) // ═══════════════════════════════════════════════════════════════════════════════ class HttpClient { public: // Fetch URL using system curl command static bool fetch(const std::string& url, std::string& response) { // Build curl command std::string cmd = "curl -s -L --max-time 10 \"" + url + "\" 2>/dev/null"; // Execute command and capture output FILE* pipe = popen(cmd.c_str(), "r"); if (!pipe) return false; response.clear(); char buffer[4096]; while (fgets(buffer, sizeof(buffer), pipe)) { response += buffer; } int status = pclose(pipe); return (status == 0 && !response.empty()); } // URL encode a string static std::string url_encode(const std::string& str) { std::string result; for (char c : str) { if (std::isalnum(c) || c == '-' || c == '_' || c == '.' || c == '~') { result += c; } else if (c == ' ') { result += "%20"; } else { char hex[4]; snprintf(hex, sizeof(hex), "%%%02X", static_cast(c)); result += hex; } } return result; } }; // ═══════════════════════════════════════════════════════════════════════════════ // WIKIPEDIA ARTICLE // Represents a fetched Wikipedia article // ═══════════════════════════════════════════════════════════════════════════════ struct WikiArticle { std::string title; std::string extract; // Summary text std::string description; // Short description std::string page_id; bool valid; WikiArticle() : valid(false) {} }; // ═══════════════════════════════════════════════════════════════════════════════ // WIKIPEDIA CLIENT // Fetches random and specific articles from Wikipedia // ═══════════════════════════════════════════════════════════════════════════════ class WikipediaClient { public: WikipediaClient() : request_count_(0), last_request_time_(0) { std::srand(static_cast(std::time(nullptr))); } // Fetch a random Wikipedia article bool fetch_random(WikiArticle& article) { rate_limit(); std::string response; if (!HttpClient::fetch("https://en.wikipedia.org/api/rest_v1/page/random/summary", response)) { return false; } return parse_summary_response(response, article); } // Fetch article by title bool fetch_by_title(const std::string& title, WikiArticle& article) { rate_limit(); std::string encoded_title = HttpClient::url_encode(title); std::string url = "https://en.wikipedia.org/api/rest_v1/page/summary/" + encoded_title; std::string response; if (!HttpClient::fetch(url, response)) { return false; } return parse_summary_response(response, article); } // Search Wikipedia and fetch first result bool search_and_fetch(const std::string& query, WikiArticle& article) { rate_limit(); std::string encoded_query = HttpClient::url_encode(query); std::string url = "https://en.wikipedia.org/w/api.php?action=query&list=search&srsearch=" + encoded_query + "&format=json&srlimit=1"; std::string response; if (!HttpClient::fetch(url, response)) { return false; } // Parse search results JsonValue json = JsonParser::parse(response); const JsonValue* query_obj = json.get_object("query"); if (!query_obj) return false; // Get first search result title for (const auto& pair : query_obj->object_val) { if (pair.first == "search" && pair.second.type == JsonValue::ARRAY) { if (!pair.second.array_val.empty()) { std::string title = pair.second.array_val[0].get_string("title"); if (!title.empty()) { return fetch_by_title(title, article); } } } } return false; } // Get request count for stats uint64_t get_request_count() const { return request_count_; } private: uint64_t request_count_; time_t last_request_time_; // Rate limiting (max ~5 requests per second to be safe) void rate_limit() { time_t now = std::time(nullptr); if (now == last_request_time_) { // Simple delay struct timespec ts = {0, 200000000}; // 200ms nanosleep(&ts, nullptr); } last_request_time_ = now; ++request_count_; } // Parse Wikipedia summary API response bool parse_summary_response(const std::string& response, WikiArticle& article) { JsonValue json = JsonParser::parse(response); if (json.type != JsonValue::OBJECT) { return false; } article.title = json.get_string("title"); article.extract = json.get_string("extract"); article.description = json.get_string("description"); article.page_id = json.get_string("pageid"); // Check if we have valid content article.valid = !article.title.empty() && !article.extract.empty(); return article.valid; } }; // ═══════════════════════════════════════════════════════════════════════════════ // WIKIPEDIA DATA GENERATOR // Provides continuous stream of Wikipedia articles for learning // ═══════════════════════════════════════════════════════════════════════════════ class WikipediaDataGenerator { public: WikipediaDataGenerator() : articles_fetched_(0), mode_(MODE_RANDOM) {} enum Mode { MODE_RANDOM, // Fetch random articles MODE_CATEGORY, // Fetch from specific categories MODE_LINKED // Follow links from articles }; // Set operating mode void set_mode(Mode mode) { mode_ = mode; } // Get next article for learning bool get_next(std::string& title, std::string& content) { WikiArticle article; bool success = false; switch (mode_) { case MODE_RANDOM: success = client_.fetch_random(article); break; case MODE_CATEGORY: if (!categories_.empty()) { size_t idx = std::rand() % categories_.size(); success = client_.search_and_fetch(categories_[idx], article); } else { success = client_.fetch_random(article); } break; case MODE_LINKED: if (!recent_titles_.empty()) { // Try to fetch related article size_t idx = std::rand() % recent_titles_.size(); success = client_.search_and_fetch(recent_titles_[idx], article); } if (!success) { success = client_.fetch_random(article); } break; } if (success && article.valid) { title = article.title; content = article.extract; // Store for linked mode recent_titles_.push_back(article.title); if (recent_titles_.size() > 100) { recent_titles_.erase(recent_titles_.begin()); } ++articles_fetched_; return true; } return false; } // Add category for category mode void add_category(const std::string& category) { categories_.push_back(category); } // Get statistics uint64_t get_articles_fetched() const { return articles_fetched_; } uint64_t get_api_requests() const { return client_.get_request_count(); } private: WikipediaClient client_; uint64_t articles_fetched_; Mode mode_; std::vector categories_; std::vector recent_titles_; }; // ═══════════════════════════════════════════════════════════════════════════════ // OFFLINE CORPUS // Pre-loaded corpus for faster simulation (no network dependency) // ═══════════════════════════════════════════════════════════════════════════════ class OfflineCorpus { public: OfflineCorpus() : current_index_(0) { // Pre-load with sample knowledge initialize_sample_corpus(); } // Get next article from corpus bool get_next(std::string& title, std::string& content) { if (articles_.empty()) return false; size_t idx = current_index_ % articles_.size(); title = articles_[idx].first; content = articles_[idx].second; ++current_index_; return true; } // Add article to corpus void add_article(const std::string& title, const std::string& content) { articles_.push_back({title, content}); } size_t size() const { return articles_.size(); } private: std::vector> articles_; size_t current_index_; void initialize_sample_corpus() { // Mathematics add_article("Mathematics", "Mathematics is an area of knowledge that includes topics such as numbers, formulas and related structures, shapes and the spaces in which they are contained, and quantities and their changes."); add_article("Golden Ratio", "In mathematics, two quantities are in the golden ratio if their ratio is the same as the ratio of their sum to the larger of the two quantities. The golden ratio is approximately 1.618."); add_article("Calculus", "Calculus is the mathematical study of continuous change. It has two major branches: differential calculus and integral calculus."); add_article("Linear Algebra", "Linear algebra is the branch of mathematics concerning linear equations, linear maps, and their representations in vector spaces and through matrices."); add_article("Topology", "Topology is the study of geometric properties and spatial relations unaffected by the continuous change of shape or size of figures."); // Physics add_article("Physics", "Physics is the natural science of matter, involving the study of matter, its fundamental constituents, its motion and behavior through space and time."); add_article("Quantum Mechanics", "Quantum mechanics is a fundamental theory in physics that describes the behavior of nature at and below the scale of atoms."); add_article("General Relativity", "General relativity is a theory of gravitation developed by Einstein. It generalizes special relativity and Newton's law of universal gravitation."); add_article("Thermodynamics", "Thermodynamics is a branch of physics that deals with heat, work, and temperature, and their relation to energy, entropy, and the physical properties of matter."); // Computer Science add_article("Computer Science", "Computer science is the study of computation, information, and automation. It spans theoretical disciplines to applied disciplines."); add_article("Artificial Intelligence", "Artificial intelligence is the intelligence of machines or software, as opposed to the intelligence of humans or other living beings."); add_article("Machine Learning", "Machine learning is a subset of artificial intelligence that enables systems to learn and improve from experience without being explicitly programmed."); add_article("Neural Networks", "An artificial neural network is a computational model inspired by the structure and function of biological neural networks in the brain."); add_article("Deep Learning", "Deep learning is a subset of machine learning that uses neural networks with many layers to analyze various factors of data."); // Philosophy add_article("Philosophy", "Philosophy is the study of general and fundamental questions about existence, knowledge, values, reason, mind, and language."); add_article("Consciousness", "Consciousness is the state of being aware of and responsive to one's surroundings. It is the quality or state of awareness."); add_article("Logic", "Logic is the study of correct reasoning. It examines general forms which arguments may take, and which forms are valid."); // Biology add_article("Biology", "Biology is the scientific study of life. It is a natural science with a broad scope but has several unifying themes."); add_article("Evolution", "Evolution is the change in the heritable characteristics of biological populations over successive generations."); add_article("DNA", "Deoxyribonucleic acid is a molecule that carries genetic instructions for the development, functioning, growth and reproduction of all known organisms."); add_article("Neuroscience", "Neuroscience is the scientific study of the nervous system. It combines physiology, anatomy, molecular biology, developmental biology, and cytology."); // Information Theory add_article("Information Theory", "Information theory is the mathematical study of the quantification, storage, and communication of information."); add_article("Entropy", "Entropy is a scientific concept that is most commonly associated with a state of disorder, randomness, or uncertainty."); add_article("Shannon Entropy", "Shannon entropy is a measure of the uncertainty associated with a random variable. It quantifies the expected amount of information."); // Additional concepts add_article("Category Theory", "Category theory is a general theory of mathematical structures and their relations. It provides a framework for understanding abstract structure."); add_article("Differential Geometry", "Differential geometry is a mathematical discipline that studies the geometry of smooth shapes and smooth spaces."); add_article("Stochastic Processes", "A stochastic process is a mathematical object defined as a family of random variables indexed by some set."); add_article("Optimal Transport", "Optimal transport theory is concerned with the problem of moving a distribution of mass from one location to another."); add_article("Renormalization", "Renormalization is a collection of techniques in quantum field theory and statistical mechanics used to treat infinities."); } }; } // namespace mind_farm #endif // MIND_FARM_WIKIPEDIA_HPP