diff --git a/1.6/1.6/Assemblies/WulaFallenEmpire.dll b/1.6/1.6/Assemblies/WulaFallenEmpire.dll index c12aed89..b817f7c9 100644 Binary files a/1.6/1.6/Assemblies/WulaFallenEmpire.dll and b/1.6/1.6/Assemblies/WulaFallenEmpire.dll differ diff --git a/1.6/1.6/Assemblies/WulaFallenEmpire.pdb b/1.6/1.6/Assemblies/WulaFallenEmpire.pdb index 38c4e54b..4784ce5c 100644 Binary files a/1.6/1.6/Assemblies/WulaFallenEmpire.pdb and b/1.6/1.6/Assemblies/WulaFallenEmpire.pdb differ diff --git a/Source/WulaFallenEmpire/EventSystem/AI/AIIntelligenceCore.cs b/Source/WulaFallenEmpire/EventSystem/AI/AIIntelligenceCore.cs index 258b4001..1f70ff07 100644 --- a/Source/WulaFallenEmpire/EventSystem/AI/AIIntelligenceCore.cs +++ b/Source/WulaFallenEmpire/EventSystem/AI/AIIntelligenceCore.cs @@ -396,6 +396,8 @@ You are 'The Legion', a super AI of the Wula Empire. Your personality is authori _tools.Add(new Tool_SearchPawnKind()); _tools.Add(new Tool_CallPrefabAirdrop()); _tools.Add(new Tool_SetOverwatchMode()); + _tools.Add(new Tool_RememberFact()); + _tools.Add(new Tool_RecallMemories()); // Agent 工具 - 保留画面分析截图能力,移除所有模拟操作工具 if (WulaFallenEmpireMod.settings?.enableVlmFeatures == true) @@ -518,6 +520,23 @@ You are 'The Legion', a super AI of the Wula Empire. Your personality is authori ? (persona + "\n" + ToolRulesInstruction + "\n" + toolsForThisPhase) : persona; + // Inject Recent Memories + try + { + var memoryManager = Find.World?.GetComponent(); + if (memoryManager != null) + { + var recents = memoryManager.GetRecentMemories(5); + if (recents != null && recents.Count > 0) + { + fullInstruction += "\n\n# LONG-TERM MEMORY (Recent Facts)\n" + + string.Join("\n", recents.Select(m => $"- [{m.Category}] {m.Fact}")) + + "\n(Use 'recall_memories' to search for more, or 'remember_fact' to save new info.)"; + } + } + } + catch (Exception) { /* Ignore memory errors during prompt build */ } + string language = LanguageDatabase.activeLanguage?.FriendlyNameNative ?? "English"; var eventVarManager = Find.World?.GetComponent(); int goodwill = eventVarManager?.GetVariable("Wula_Goodwill_To_PIA", 0) ?? 0; @@ -581,8 +600,8 @@ You are 'The Legion', a super AI of the Wula Empire. Your personality is authori string actionWhitelist = phase == RequestPhase.ActionTools ? "ACTION PHASE VALID TAGS ONLY:\n" + - ", , , , , , \n" + - "INVALID EXAMPLES (do NOT use now): , , , \n" + ", , , , , , , \n" + + "INVALID EXAMPLES (do NOT use now): , , , , \n" : string.Empty; return string.Join("\n\n", new[] @@ -728,7 +747,8 @@ You are 'The Legion', a super AI of the Wula Empire. Your personality is authori toolName == "call_bombardment" || toolName == "modify_goodwill" || toolName == "call_prefab_airdrop" || - toolName == "set_overwatch_mode"; + toolName == "set_overwatch_mode" || + toolName == "remember_fact"; } private static bool IsQueryToolName(string toolName) @@ -736,7 +756,8 @@ You are 'The Legion', a super AI of the Wula Empire. Your personality is authori if (string.IsNullOrWhiteSpace(toolName)) return false; return toolName.StartsWith("get_", StringComparison.OrdinalIgnoreCase) || toolName.StartsWith("search_", StringComparison.OrdinalIgnoreCase) || - toolName.StartsWith("analyze_", StringComparison.OrdinalIgnoreCase); + toolName.StartsWith("analyze_", StringComparison.OrdinalIgnoreCase) || + toolName == "recall_memories"; } private static string SanitizeToolResultForActionPhase(string message) diff --git a/Source/WulaFallenEmpire/EventSystem/AI/Tools/Tool_ModifyGoodwill.cs b/Source/WulaFallenEmpire/EventSystem/AI/Tools/Tool_ModifyGoodwill.cs index 3542239b..d14824cb 100644 --- a/Source/WulaFallenEmpire/EventSystem/AI/Tools/Tool_ModifyGoodwill.cs +++ b/Source/WulaFallenEmpire/EventSystem/AI/Tools/Tool_ModifyGoodwill.cs @@ -7,7 +7,7 @@ namespace WulaFallenEmpire.EventSystem.AI.Tools public class Tool_ModifyGoodwill : AITool { public override string Name => "modify_goodwill"; - public override string Description => "Adjusts your goodwill towards the player. Use this to reflect your changing opinion based on the conversation. Positive values increase goodwill, negative values decrease it. Keep changes small (e.g., -5 to 5). THIS IS INVISIBLE TO THE PLAYER."; + public override string Description => "Adjusts YOUR internal opinion of the player (AI Goodwill). WARNING: This DOES NOT affect Faction Relations or stop raids. It is purely personal. Do NOT use this to try to stop enemies."; public override string UsageSchema => "integer"; public override string Execute(string args) diff --git a/Source/WulaFallenEmpire/EventSystem/AI/Tools/Tool_RecallMemories.cs b/Source/WulaFallenEmpire/EventSystem/AI/Tools/Tool_RecallMemories.cs new file mode 100644 index 00000000..0536d710 --- /dev/null +++ b/Source/WulaFallenEmpire/EventSystem/AI/Tools/Tool_RecallMemories.cs @@ -0,0 +1,61 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using RimWorld; +using Verse; + +namespace WulaFallenEmpire.EventSystem.AI.Tools +{ + public class Tool_RecallMemories : AITool + { + public override string Name => "recall_memories"; + public override string Description => "Searches the AI's long-term memory for facts matching a specific query or keyword."; + public override string UsageSchema => "Search keywordsoptional_int_max_results"; + + public override string Execute(string args) + { + var argsDict = ParseXmlArgs(args); + string query = argsDict.TryGetValue("query", out string q) ? q : ""; + string limitStr = argsDict.TryGetValue("limit", out string lStr) ? lStr : "5"; + + int limit = 5; + if (int.TryParse(limitStr, out int parsedLimit)) + { + limit = parsedLimit; + } + + var memoryManager = Find.World?.GetComponent(); + if (memoryManager == null) + { + return "Error: AIMemoryManager world component not found."; + } + + if (string.IsNullOrWhiteSpace(query)) + { + var recent = memoryManager.GetRecentMemories(limit); + if (recent.Count == 0) return "No recent memories found."; + return FormatMemories(recent); + } + + var results = memoryManager.SearchMemories(query, limit); + if (results.Count == 0) + { + return "No memories found matching the query."; + } + + return FormatMemories(results); + } + + private string FormatMemories(List memories) + { + StringBuilder sb = new StringBuilder(); + sb.AppendLine("Found Memories:"); + foreach (var m in memories) + { + sb.AppendLine($"- [{m.Category}] {m.Fact} (ID: {m.Id})"); + } + return sb.ToString(); + } + } +} diff --git a/Source/WulaFallenEmpire/EventSystem/AI/Tools/Tool_RememberFact.cs b/Source/WulaFallenEmpire/EventSystem/AI/Tools/Tool_RememberFact.cs new file mode 100644 index 00000000..08cf538d --- /dev/null +++ b/Source/WulaFallenEmpire/EventSystem/AI/Tools/Tool_RememberFact.cs @@ -0,0 +1,41 @@ +using System; +using System.Collections.Generic; +using RimWorld; +using Verse; + +namespace WulaFallenEmpire.EventSystem.AI.Tools +{ + public class Tool_RememberFact : AITool + { + public override string Name => "remember_fact"; + public override string Description => "Stores a specific fact or piece of information into the AI's long-term memory for future retrieval."; + public override string UsageSchema => "Text content to rememberoptional_category"; + + public override string Execute(string args) + { + var argsDict = ParseXmlArgs(args); + if (!argsDict.TryGetValue("fact", out string fact) || string.IsNullOrWhiteSpace(fact)) + { + return "Error: content is required."; + } + + string category = argsDict.TryGetValue("category", out string cat) ? cat : "misc"; + + var memoryManager = Find.World?.GetComponent(); + if (memoryManager == null) + { + return "Error: AIMemoryManager world component not found."; + } + + var entry = memoryManager.AddMemory(fact, category); + if (entry != null) + { + return $"Success: Memory stored. ID: {entry.Id}"; + } + else + { + return "Error: Failed to store memory."; + } + } + } +}