9#include "absl/strings/str_cat.h"
10#include "absl/strings/str_format.h"
11#include "absl/time/clock.h"
12#include "absl/time/time.h"
15#include "nlohmann/json.hpp"
24 return absl::ToUnixMillis(absl::Now());
28 static int counter = 0;
29 auto now = std::chrono::system_clock::now().time_since_epoch().count();
30 return absl::StrFormat(
"%lld_%d", now, counter++);
42 if (app_data_result.ok()) {
46 data_dir_ = std::filesystem::current_path() /
".yaze" /
"agent";
56 const std::filesystem::path& data_dir)
57 : data_dir_(data_dir),
58 prefs_file_(data_dir /
"preferences.json"),
59 patterns_file_(data_dir /
"patterns.json"),
60 projects_file_(data_dir /
"projects.json"),
61 memories_file_(data_dir /
"memories.json") {}
65 return absl::OkStatus();
81 return absl::OkStatus();
86 if (!status.ok())
return status;
89 if (!status.ok())
return status;
92 if (!status.ok())
return status;
95 if (!status.ok())
return status;
97 return absl::OkStatus();
103 const std::string& value) {
105 return absl::FailedPreconditionError(
"Service not initialized");
113 const std::string& key)
const {
127 return absl::FailedPreconditionError(
"Service not initialized");
137 const std::string& rom_hash,
138 const std::string& data,
141 return absl::FailedPreconditionError(
"Service not initialized");
156std::vector<LearnedKnowledgeService::ROMPattern>
158 const std::string& rom_hash)
const {
159 std::vector<ROMPattern> results;
162 bool type_match = type.empty() || pattern.pattern_type == type;
163 bool hash_match = rom_hash.empty() || pattern.rom_hash == rom_hash;
165 if (type_match && hash_match) {
166 results.push_back(pattern);
174 const std::string& type,
175 const std::string& rom_hash,
176 float new_confidence) {
180 if (pattern.pattern_type == type && pattern.rom_hash == rom_hash) {
181 pattern.confidence = new_confidence;
182 pattern.access_count++;
188 return absl::NotFoundError(
"Pattern not found");
197 const std::string& project_name,
198 const std::string& rom_hash,
199 const std::string& context) {
201 return absl::FailedPreconditionError(
"Service not initialized");
207 if (project.project_name == project_name) {
208 project.rom_hash = rom_hash;
209 project.context_data = context;
210 project.last_accessed = CurrentTimestamp();
228std::optional<LearnedKnowledgeService::ProjectContext>
231 if (project.project_name == project_name) {
238std::vector<LearnedKnowledgeService::ProjectContext>
246 const std::string& topic,
247 const std::string& summary,
248 const std::vector<std::string>& key_facts) {
250 return absl::FailedPreconditionError(
"Service not initialized");
254 memory.
id = GenerateRandomID();
255 memory.
topic = topic;
271std::vector<LearnedKnowledgeService::ConversationMemory>
273 std::vector<ConversationMemory> results;
275 std::string query_lower = query;
276 std::transform(query_lower.begin(), query_lower.end(), query_lower.begin(), ::tolower);
279 std::string topic_lower = memory.topic;
280 std::string summary_lower = memory.summary;
281 std::transform(topic_lower.begin(), topic_lower.end(), topic_lower.begin(), ::tolower);
282 std::transform(summary_lower.begin(), summary_lower.end(), summary_lower.begin(), ::tolower);
284 if (topic_lower.find(query_lower) != std::string::npos ||
285 summary_lower.find(query_lower) != std::string::npos) {
286 results.push_back(memory);
293std::vector<LearnedKnowledgeService::ConversationMemory>
295 std::vector<ConversationMemory> recent =
memories_;
298 std::sort(recent.begin(), recent.end(),
300 return a.created_at > b.created_at;
303 if (recent.size() >
static_cast<size_t>(limit)) {
304 recent.resize(limit);
314 nlohmann::json export_data;
320 export_data[
"patterns"] = nlohmann::json::array();
323 p[
"type"] = pattern.pattern_type;
324 p[
"rom_hash"] = pattern.rom_hash;
325 p[
"data"] = pattern.pattern_data;
326 p[
"confidence"] = pattern.confidence;
327 p[
"learned_at"] = pattern.learned_at;
328 p[
"access_count"] = pattern.access_count;
329 export_data[
"patterns"].push_back(p);
333 export_data[
"projects"] = nlohmann::json::array();
336 p[
"name"] = project.project_name;
337 p[
"rom_hash"] = project.rom_hash;
338 p[
"context"] = project.context_data;
339 p[
"last_accessed"] = project.last_accessed;
340 export_data[
"projects"].push_back(p);
344 export_data[
"memories"] = nlohmann::json::array();
348 m[
"topic"] = memory.topic;
349 m[
"summary"] = memory.summary;
350 m[
"key_facts"] = memory.key_facts;
351 m[
"created_at"] = memory.created_at;
352 m[
"access_count"] = memory.access_count;
353 export_data[
"memories"].push_back(m);
356 return export_data.dump(2);
361 auto data = nlohmann::json::parse(json_data);
364 if (data.contains(
"preferences")) {
365 for (
const auto& [key, value] : data[
"preferences"].items()) {
371 if (data.contains(
"patterns")) {
372 for (
const auto& p : data[
"patterns"]) {
374 pattern.pattern_type = p[
"type"];
375 pattern.rom_hash = p[
"rom_hash"];
376 pattern.pattern_data = p[
"data"];
377 pattern.confidence = p[
"confidence"];
378 pattern.learned_at = p[
"learned_at"];
379 pattern.access_count = p[
"access_count"];
385 if (data.contains(
"projects")) {
386 for (
const auto& p : data[
"projects"]) {
387 ProjectContext project;
388 project.project_name = p[
"name"];
389 project.rom_hash = p[
"rom_hash"];
390 project.context_data = p[
"context"];
391 project.last_accessed = p[
"last_accessed"];
397 if (data.contains(
"memories")) {
398 for (
const auto& m : data[
"memories"]) {
399 ConversationMemory memory;
401 memory.topic = m[
"topic"];
402 memory.summary = m[
"summary"];
403 memory.key_facts = m[
"key_facts"].get<std::vector<std::string>>();
404 memory.created_at = m[
"created_at"];
405 memory.access_count = m[
"access_count"];
411 }
catch (
const std::exception& e) {
412 return absl::InternalError(absl::StrCat(
"JSON parse error: ", e.what()));
417 return absl::UnimplementedError(
"JSON support not enabled. Build with -DYAZE_WITH_JSON=ON");
421 return absl::UnimplementedError(
"JSON support not enabled. Build with -DYAZE_WITH_JSON=ON");
443 int64_t earliest = CurrentTimestamp();
445 if (pattern.learned_at < earliest) {
446 earliest = pattern.learned_at;
450 if (memory.created_at < earliest) {
451 earliest = memory.created_at;
467 return absl::OkStatus();
472 if (!file.is_open()) {
473 return absl::InternalError(
"Failed to open preferences file");
479 for (
const auto& [key, value] : data.items()) {
483 return absl::OkStatus();
484 }
catch (
const std::exception& e) {
485 return absl::InternalError(absl::StrCat(
"Failed to load preferences: ", e.what()));
494 if (!file.is_open()) {
495 return absl::InternalError(
"Failed to open preferences file for writing");
498 file << data.dump(2);
499 return absl::OkStatus();
500 }
catch (
const std::exception& e) {
501 return absl::InternalError(absl::StrCat(
"Failed to save preferences: ", e.what()));
507 return absl::OkStatus();
515 for (
const auto& p : data) {
517 pattern.pattern_type = p[
"type"];
518 pattern.rom_hash = p[
"rom_hash"];
519 pattern.pattern_data = p[
"data"];
520 pattern.confidence = p[
"confidence"];
521 pattern.learned_at = p[
"learned_at"];
522 pattern.access_count = p.value(
"access_count", 0);
526 return absl::OkStatus();
527 }
catch (
const std::exception& e) {
528 return absl::InternalError(absl::StrCat(
"Failed to load patterns: ", e.what()));
534 nlohmann::json data = nlohmann::json::array();
538 p[
"type"] = pattern.pattern_type;
539 p[
"rom_hash"] = pattern.rom_hash;
540 p[
"data"] = pattern.pattern_data;
541 p[
"confidence"] = pattern.confidence;
542 p[
"learned_at"] = pattern.learned_at;
543 p[
"access_count"] = pattern.access_count;
548 file << data.dump(2);
549 return absl::OkStatus();
550 }
catch (
const std::exception& e) {
551 return absl::InternalError(absl::StrCat(
"Failed to save patterns: ", e.what()));
557 return absl::OkStatus();
565 for (
const auto& p : data) {
566 ProjectContext project;
567 project.project_name = p[
"name"];
568 project.rom_hash = p[
"rom_hash"];
569 project.context_data = p[
"context"];
570 project.last_accessed = p[
"last_accessed"];
574 return absl::OkStatus();
575 }
catch (
const std::exception& e) {
576 return absl::InternalError(absl::StrCat(
"Failed to load projects: ", e.what()));
582 nlohmann::json data = nlohmann::json::array();
586 p[
"name"] = project.project_name;
587 p[
"rom_hash"] = project.rom_hash;
588 p[
"context"] = project.context_data;
589 p[
"last_accessed"] = project.last_accessed;
594 file << data.dump(2);
595 return absl::OkStatus();
596 }
catch (
const std::exception& e) {
597 return absl::InternalError(absl::StrCat(
"Failed to save projects: ", e.what()));
603 nlohmann::json data = nlohmann::json::array();
608 m[
"topic"] = memory.topic;
609 m[
"summary"] = memory.summary;
610 m[
"key_facts"] = memory.key_facts;
611 m[
"created_at"] = memory.created_at;
612 m[
"access_count"] = memory.access_count;
617 file << data.dump(2);
618 return absl::OkStatus();
619 }
catch (
const std::exception& e) {
620 return absl::InternalError(absl::StrCat(
"Failed to save memories: ", e.what()));
626 return absl::OkStatus();
634 for (
const auto& m : data) {
635 ConversationMemory memory;
637 memory.topic = m[
"topic"];
638 memory.summary = m[
"summary"];
639 memory.key_facts = m[
"key_facts"].get<std::vector<std::string>>();
640 memory.created_at = m[
"created_at"];
641 memory.access_count = m.value(
"access_count", 0);
645 return absl::OkStatus();
646 }
catch (
const std::exception& e) {
647 return absl::InternalError(absl::StrCat(
"Failed to load memories: ", e.what()));
664 return GenerateRandomID();
std::optional< std::string > GetPreference(const std::string &key) const
absl::Status SaveMemories()
absl::Status StoreConversationSummary(const std::string &topic, const std::string &summary, const std::vector< std::string > &key_facts)
std::vector< ProjectContext > GetAllProjects() const
std::vector< ConversationMemory > GetRecentMemories(int limit=10) const
std::vector< ConversationMemory > memories_
std::filesystem::path prefs_file_
std::vector< ProjectContext > projects_
std::string GenerateID() const
absl::Status RemovePreference(const std::string &key)
std::vector< ConversationMemory > SearchMemories(const std::string &query) const
LearnedKnowledgeService()
std::vector< ROMPattern > QueryPatterns(const std::string &type, const std::string &rom_hash="") const
absl::Status LoadPreferences()
absl::Status ImportFromJSON(const std::string &json_data)
absl::Status SavePatterns()
std::filesystem::path memories_file_
std::filesystem::path data_dir_
absl::Status SaveProjects()
absl::Status UpdatePatternConfidence(const std::string &type, const std::string &rom_hash, float new_confidence)
std::map< std::string, std::string > preferences_
absl::Status Initialize()
std::optional< ProjectContext > GetProjectContext(const std::string &project_name) const
absl::Status SetPreference(const std::string &key, const std::string &value)
absl::Status SavePreferences()
absl::Status LoadPatterns()
absl::StatusOr< std::string > ExportToJSON() const
absl::Status SaveProjectContext(const std::string &project_name, const std::string &rom_hash, const std::string &context)
std::filesystem::path patterns_file_
std::vector< ROMPattern > patterns_
absl::Status LearnPattern(const std::string &type, const std::string &rom_hash, const std::string &data, float confidence=1.0f)
std::map< std::string, std::string > GetAllPreferences() const
absl::Status LoadProjects()
std::filesystem::path projects_file_
absl::Status LoadMemories()
std::string GenerateRandomID()
int64_t CurrentTimestamp()
bool FileExists(const std::filesystem::path &path)
Main namespace for the application.
std::vector< std::string > key_facts