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"
22 return absl::ToUnixMillis(absl::Now());
26 static int counter = 0;
27 auto now = std::chrono::system_clock::now().time_since_epoch().count();
28 return absl::StrFormat(
"%lld_%d", now, counter++);
40 if (app_data_result.ok()) {
44 data_dir_ = std::filesystem::current_path() /
".yaze" /
"agent";
54 const std::filesystem::path& data_dir)
55 : data_dir_(data_dir),
56 prefs_file_(data_dir /
"preferences.json"),
57 patterns_file_(data_dir /
"patterns.json"),
58 projects_file_(data_dir /
"projects.json"),
59 memories_file_(data_dir /
"memories.json") {}
63 return absl::OkStatus();
79 return absl::OkStatus();
84 if (!status.ok())
return status;
87 if (!status.ok())
return status;
90 if (!status.ok())
return status;
93 if (!status.ok())
return status;
95 return absl::OkStatus();
101 const std::string& value) {
103 return absl::FailedPreconditionError(
"Service not initialized");
111 const std::string& key)
const {
125 return absl::FailedPreconditionError(
"Service not initialized");
135 const std::string& rom_hash,
136 const std::string& data,
139 return absl::FailedPreconditionError(
"Service not initialized");
154std::vector<LearnedKnowledgeService::ROMPattern>
156 const std::string& rom_hash)
const {
157 std::vector<ROMPattern> results;
160 bool type_match = type.empty() || pattern.pattern_type == type;
161 bool hash_match = rom_hash.empty() || pattern.rom_hash == rom_hash;
163 if (type_match && hash_match) {
164 results.push_back(pattern);
172 const std::string& type,
173 const std::string& rom_hash,
174 float new_confidence) {
178 if (pattern.pattern_type == type && pattern.rom_hash == rom_hash) {
179 pattern.confidence = new_confidence;
180 pattern.access_count++;
186 return absl::NotFoundError(
"Pattern not found");
195 const std::string& project_name,
196 const std::string& rom_hash,
197 const std::string& context) {
199 return absl::FailedPreconditionError(
"Service not initialized");
205 if (project.project_name == project_name) {
206 project.rom_hash = rom_hash;
207 project.context_data = context;
208 project.last_accessed = CurrentTimestamp();
226std::optional<LearnedKnowledgeService::ProjectContext>
229 if (project.project_name == project_name) {
236std::vector<LearnedKnowledgeService::ProjectContext>
244 const std::string& topic,
245 const std::string& summary,
246 const std::vector<std::string>& key_facts) {
248 return absl::FailedPreconditionError(
"Service not initialized");
252 memory.
id = GenerateRandomID();
253 memory.
topic = topic;
269std::vector<LearnedKnowledgeService::ConversationMemory>
271 std::vector<ConversationMemory> results;
273 std::string query_lower = query;
274 std::transform(query_lower.begin(), query_lower.end(), query_lower.begin(), ::tolower);
277 std::string topic_lower = memory.topic;
278 std::string summary_lower = memory.summary;
279 std::transform(topic_lower.begin(), topic_lower.end(), topic_lower.begin(), ::tolower);
280 std::transform(summary_lower.begin(), summary_lower.end(), summary_lower.begin(), ::tolower);
282 if (topic_lower.find(query_lower) != std::string::npos ||
283 summary_lower.find(query_lower) != std::string::npos) {
284 results.push_back(memory);
291std::vector<LearnedKnowledgeService::ConversationMemory>
293 std::vector<ConversationMemory> recent =
memories_;
296 std::sort(recent.begin(), recent.end(),
298 return a.created_at > b.created_at;
301 if (recent.size() >
static_cast<size_t>(limit)) {
302 recent.resize(limit);
312 nlohmann::json export_data;
318 export_data[
"patterns"] = nlohmann::json::array();
321 p[
"type"] = pattern.pattern_type;
322 p[
"rom_hash"] = pattern.rom_hash;
323 p[
"data"] = pattern.pattern_data;
324 p[
"confidence"] = pattern.confidence;
325 p[
"learned_at"] = pattern.learned_at;
326 p[
"access_count"] = pattern.access_count;
327 export_data[
"patterns"].push_back(p);
331 export_data[
"projects"] = nlohmann::json::array();
334 p[
"name"] = project.project_name;
335 p[
"rom_hash"] = project.rom_hash;
336 p[
"context"] = project.context_data;
337 p[
"last_accessed"] = project.last_accessed;
338 export_data[
"projects"].push_back(p);
342 export_data[
"memories"] = nlohmann::json::array();
346 m[
"topic"] = memory.topic;
347 m[
"summary"] = memory.summary;
348 m[
"key_facts"] = memory.key_facts;
349 m[
"created_at"] = memory.created_at;
350 m[
"access_count"] = memory.access_count;
351 export_data[
"memories"].push_back(m);
354 return export_data.dump(2);
359 auto data = nlohmann::json::parse(json_data);
362 if (data.contains(
"preferences")) {
363 for (
const auto& [key, value] : data[
"preferences"].items()) {
369 if (data.contains(
"patterns")) {
370 for (
const auto& p : data[
"patterns"]) {
372 pattern.pattern_type = p[
"type"];
373 pattern.rom_hash = p[
"rom_hash"];
374 pattern.pattern_data = p[
"data"];
375 pattern.confidence = p[
"confidence"];
376 pattern.learned_at = p[
"learned_at"];
377 pattern.access_count = p[
"access_count"];
383 if (data.contains(
"projects")) {
384 for (
const auto& p : data[
"projects"]) {
385 ProjectContext project;
386 project.project_name = p[
"name"];
387 project.rom_hash = p[
"rom_hash"];
388 project.context_data = p[
"context"];
389 project.last_accessed = p[
"last_accessed"];
395 if (data.contains(
"memories")) {
396 for (
const auto& m : data[
"memories"]) {
397 ConversationMemory memory;
399 memory.topic = m[
"topic"];
400 memory.summary = m[
"summary"];
401 memory.key_facts = m[
"key_facts"].get<std::vector<std::string>>();
402 memory.created_at = m[
"created_at"];
403 memory.access_count = m[
"access_count"];
409 }
catch (
const std::exception& e) {
410 return absl::InternalError(absl::StrCat(
"JSON parse error: ", e.what()));
415 return absl::UnimplementedError(
"JSON support not enabled. Build with -DYAZE_WITH_JSON=ON");
419 return absl::UnimplementedError(
"JSON support not enabled. Build with -DYAZE_WITH_JSON=ON");
441 int64_t earliest = CurrentTimestamp();
443 if (pattern.learned_at < earliest) {
444 earliest = pattern.learned_at;
448 if (memory.created_at < earliest) {
449 earliest = memory.created_at;
465 return absl::OkStatus();
470 if (!file.is_open()) {
471 return absl::InternalError(
"Failed to open preferences file");
477 for (
const auto& [key, value] : data.items()) {
481 return absl::OkStatus();
482 }
catch (
const std::exception& e) {
483 return absl::InternalError(absl::StrCat(
"Failed to load preferences: ", e.what()));
492 if (!file.is_open()) {
493 return absl::InternalError(
"Failed to open preferences file for writing");
496 file << data.dump(2);
497 return absl::OkStatus();
498 }
catch (
const std::exception& e) {
499 return absl::InternalError(absl::StrCat(
"Failed to save preferences: ", e.what()));
505 return absl::OkStatus();
513 for (
const auto& p : data) {
515 pattern.pattern_type = p[
"type"];
516 pattern.rom_hash = p[
"rom_hash"];
517 pattern.pattern_data = p[
"data"];
518 pattern.confidence = p[
"confidence"];
519 pattern.learned_at = p[
"learned_at"];
520 pattern.access_count = p.value(
"access_count", 0);
524 return absl::OkStatus();
525 }
catch (
const std::exception& e) {
526 return absl::InternalError(absl::StrCat(
"Failed to load patterns: ", e.what()));
532 nlohmann::json data = nlohmann::json::array();
536 p[
"type"] = pattern.pattern_type;
537 p[
"rom_hash"] = pattern.rom_hash;
538 p[
"data"] = pattern.pattern_data;
539 p[
"confidence"] = pattern.confidence;
540 p[
"learned_at"] = pattern.learned_at;
541 p[
"access_count"] = pattern.access_count;
546 file << data.dump(2);
547 return absl::OkStatus();
548 }
catch (
const std::exception& e) {
549 return absl::InternalError(absl::StrCat(
"Failed to save patterns: ", e.what()));
555 return absl::OkStatus();
563 for (
const auto& p : data) {
564 ProjectContext project;
565 project.project_name = p[
"name"];
566 project.rom_hash = p[
"rom_hash"];
567 project.context_data = p[
"context"];
568 project.last_accessed = p[
"last_accessed"];
572 return absl::OkStatus();
573 }
catch (
const std::exception& e) {
574 return absl::InternalError(absl::StrCat(
"Failed to load projects: ", e.what()));
580 nlohmann::json data = nlohmann::json::array();
584 p[
"name"] = project.project_name;
585 p[
"rom_hash"] = project.rom_hash;
586 p[
"context"] = project.context_data;
587 p[
"last_accessed"] = project.last_accessed;
592 file << data.dump(2);
593 return absl::OkStatus();
594 }
catch (
const std::exception& e) {
595 return absl::InternalError(absl::StrCat(
"Failed to save projects: ", e.what()));
601 nlohmann::json data = nlohmann::json::array();
606 m[
"topic"] = memory.topic;
607 m[
"summary"] = memory.summary;
608 m[
"key_facts"] = memory.key_facts;
609 m[
"created_at"] = memory.created_at;
610 m[
"access_count"] = memory.access_count;
615 file << data.dump(2);
616 return absl::OkStatus();
617 }
catch (
const std::exception& e) {
618 return absl::InternalError(absl::StrCat(
"Failed to save memories: ", e.what()));
624 return absl::OkStatus();
632 for (
const auto& m : data) {
633 ConversationMemory memory;
635 memory.topic = m[
"topic"];
636 memory.summary = m[
"summary"];
637 memory.key_facts = m[
"key_facts"].get<std::vector<std::string>>();
638 memory.created_at = m[
"created_at"];
639 memory.access_count = m.value(
"access_count", 0);
643 return absl::OkStatus();
644 }
catch (
const std::exception& e) {
645 return absl::InternalError(absl::StrCat(
"Failed to load memories: ", e.what()));
662 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