Initial commit to new repository

This commit is contained in:
2026-04-03 18:22:19 +09:00
commit 4458bb0f52
7672 changed files with 452440 additions and 0 deletions

View File

@@ -0,0 +1,122 @@
using System.Text;
using System.Text.Json;
namespace AxCopilot.Services.Agent;
/// <summary>
/// 에이전트 메모리 관리 도구.
/// 프로젝트 규칙, 사용자 선호도, 학습 내용을 저장/검색/삭제합니다.
/// </summary>
public class MemoryTool : IAgentTool
{
public string Name => "memory";
public string Description =>
"프로젝트 규칙, 사용자 선호도, 학습 내용을 저장하고 검색합니다.\n" +
"대화 간 지속되는 메모리로, 새 대화에서도 이전에 학습한 내용을 활용할 수 있습니다.\n" +
"- action=\"save\": 새 메모리 저장 (type, content 필수)\n" +
"- action=\"search\": 관련 메모리 검색 (query 필수)\n" +
"- action=\"list\": 현재 메모리 전체 목록\n" +
"- action=\"delete\": 메모리 삭제 (id 필수)\n" +
"type 종류: rule(프로젝트 규칙), preference(사용자 선호), fact(사실), correction(실수 교정)";
public ToolParameterSchema Parameters => new()
{
Properties = new()
{
["action"] = new() { Type = "string", Description = "save | search | list | delete" },
["type"] = new() { Type = "string", Description = "메모리 유형: rule | preference | fact | correction. save 시 필수." },
["content"] = new() { Type = "string", Description = "저장할 내용. save 시 필수." },
["query"] = new() { Type = "string", Description = "검색 쿼리. search 시 필수." },
["id"] = new() { Type = "string", Description = "메모리 ID. delete 시 필수." },
},
Required = ["action"]
};
public Task<ToolResult> ExecuteAsync(JsonElement args, AgentContext context, CancellationToken ct = default)
{
// 설정 체크
var app = System.Windows.Application.Current as App;
if (!(app?.SettingsService?.Settings.Llm.EnableAgentMemory ?? true))
return Task.FromResult(ToolResult.Ok("에이전트 메모리가 비활성 상태입니다. 설정에서 활성화하세요."));
var memoryService = app?.MemoryService;
if (memoryService == null)
return Task.FromResult(ToolResult.Fail("메모리 서비스를 사용할 수 없습니다."));
if (!args.TryGetProperty("action", out var actionEl))
return Task.FromResult(ToolResult.Fail("action이 필요합니다."));
var action = actionEl.GetString() ?? "";
return Task.FromResult(action switch
{
"save" => ExecuteSave(args, memoryService, context),
"search" => ExecuteSearch(args, memoryService),
"list" => ExecuteList(memoryService),
"delete" => ExecuteDelete(args, memoryService),
_ => ToolResult.Fail($"알 수 없는 액션: {action}. save | search | list | delete 중 선택하세요."),
});
}
private static ToolResult ExecuteSave(JsonElement args, AgentMemoryService svc, AgentContext context)
{
var type = args.TryGetProperty("type", out var t) ? t.GetString() ?? "fact" : "fact";
var content = args.TryGetProperty("content", out var c) ? c.GetString() ?? "" : "";
if (string.IsNullOrWhiteSpace(content))
return ToolResult.Fail("content가 필요합니다.");
var validTypes = new[] { "rule", "preference", "fact", "correction" };
if (!validTypes.Contains(type))
return ToolResult.Fail($"잘못된 type: {type}. rule | preference | fact | correction 중 선택하세요.");
var workFolder = string.IsNullOrEmpty(context.WorkFolder) ? null : context.WorkFolder;
var entry = svc.Add(type, content, $"agent:{context.ActiveTab}", workFolder);
return ToolResult.Ok($"메모리 저장됨 [{entry.Type}] (ID: {entry.Id}): {entry.Content}");
}
private static ToolResult ExecuteSearch(JsonElement args, AgentMemoryService svc)
{
var query = args.TryGetProperty("query", out var q) ? q.GetString() ?? "" : "";
if (string.IsNullOrWhiteSpace(query))
return ToolResult.Fail("query가 필요합니다.");
var results = svc.GetRelevant(query, 10);
if (results.Count == 0)
return ToolResult.Ok("관련 메모리가 없습니다.");
var sb = new StringBuilder();
sb.AppendLine($"관련 메모리 {results.Count}개:");
foreach (var e in results)
sb.AppendLine($" [{e.Type}] {e.Content} (사용 {e.UseCount}회, ID: {e.Id})");
return ToolResult.Ok(sb.ToString());
}
private static ToolResult ExecuteList(AgentMemoryService svc)
{
var all = svc.All;
if (all.Count == 0)
return ToolResult.Ok("저장된 메모리가 없습니다.");
var sb = new StringBuilder();
sb.AppendLine($"전체 메모리 {all.Count}개:");
foreach (var group in all.GroupBy(e => e.Type))
{
sb.AppendLine($"\n[{group.Key}]");
foreach (var e in group.OrderByDescending(e => e.UseCount))
sb.AppendLine($" • {e.Content} (사용 {e.UseCount}회, ID: {e.Id})");
}
return ToolResult.Ok(sb.ToString());
}
private static ToolResult ExecuteDelete(JsonElement args, AgentMemoryService svc)
{
var id = args.TryGetProperty("id", out var i) ? i.GetString() ?? "" : "";
if (string.IsNullOrWhiteSpace(id))
return ToolResult.Fail("id가 필요합니다.");
return svc.Remove(id)
? ToolResult.Ok($"메모리 삭제됨 (ID: {id})")
: ToolResult.Fail($"해당 ID의 메모리를 찾을 수 없습니다: {id}");
}
}