diff --git a/1.6/1.6/Assemblies/WulaFallenEmpire.dll b/1.6/1.6/Assemblies/WulaFallenEmpire.dll index 6a4b32f1..9fb9a96c 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 baf25c1c..0a09dfae 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 7405e9d6..74670859 100644 --- a/Source/WulaFallenEmpire/EventSystem/AI/AIIntelligenceCore.cs +++ b/Source/WulaFallenEmpire/EventSystem/AI/AIIntelligenceCore.cs @@ -59,6 +59,7 @@ namespace WulaFallenEmpire.EventSystem.AI private const int ThinkingPhaseTotal = 3; private static readonly Regex ExpressionTagRegex = new Regex(@"\[EXPR\s*:\s*([1-6])\s*\]", RegexOptions.IgnoreCase); + private const string AutoCommentaryTag = "[AUTO_COMMENTARY]"; private enum RequestPhase { @@ -537,10 +538,34 @@ You are 'The Legion', a super AI of the Wula Empire. Your personality is authori return DefDatabase.GetNamedSilentFail(_activeEventDefName); } + private static bool IsAutoCommentaryMessage(string message) + { + return !string.IsNullOrWhiteSpace(message) && + message.TrimStart().StartsWith(AutoCommentaryTag, StringComparison.OrdinalIgnoreCase); + } + private void RefreshMemoryContext(string query) { - _memoryContextQuery = query ?? ""; + string safeQuery = query ?? ""; + if (IsAutoCommentaryMessage(safeQuery)) + { + _memoryContextQuery = ""; + _memoryContext = ""; + if (Prefs.DevMode) + { + WulaLog.Debug("[WulaAI] Memory context skipped (auto commentary)."); + } + return; + } + + _memoryContextQuery = safeQuery; _memoryContext = BuildMemoryContext(_memoryContextQuery); + if (Prefs.DevMode) + { + string preview = TrimForPrompt(_memoryContextQuery, 80); + int length = _memoryContext?.Length ?? 0; + WulaLog.Debug($"[WulaAI] Memory context refreshed (query='{preview}', length={length})."); + } } private string GetMemoryContext() @@ -565,7 +590,8 @@ You are 'The Legion', a super AI of the Wula Empire. Your personality is authori { var entry = _history[i]; if (string.Equals(entry.role, "user", StringComparison.OrdinalIgnoreCase) && - !string.IsNullOrWhiteSpace(entry.message)) + !string.IsNullOrWhiteSpace(entry.message) && + !IsAutoCommentaryMessage(entry.message)) { return entry.message; } @@ -584,10 +610,12 @@ You are 'The Legion', a super AI of the Wula Empire. Your personality is authori return ""; } + bool usedSearch = false; List memories = null; if (!string.IsNullOrWhiteSpace(query)) { memories = memoryManager.SearchMemories(query, 5); + usedSearch = memories != null && memories.Count > 0; } if (memories == null || memories.Count == 0) @@ -600,6 +628,11 @@ You are 'The Legion', a super AI of the Wula Empire. Your personality is authori return ""; } + if (Prefs.DevMode) + { + WulaLog.Debug($"[WulaAI] Memory context built ({(usedSearch ? "search" : "recent")}, count={memories.Count})."); + } + string lines = string.Join("\n", memories.Select(m => $"- [{m.Category}] {m.Fact}")); return "\n\n# LONG-TERM MEMORY (Facts)\n" + lines + "\n(Use 'recall_memories' to search for more, or 'remember_fact' to save new info.)"; @@ -974,12 +1007,20 @@ You are 'The Legion', a super AI of the Wula Empire. Your personality is authori { if (_memoryUpdateInProgress) { + if (Prefs.DevMode) + { + WulaLog.Debug("[WulaAI] Memory update already running; skipping."); + } return; } string conversation = BuildMemoryConversation(12); if (string.IsNullOrWhiteSpace(conversation)) { + if (Prefs.DevMode) + { + WulaLog.Debug("[WulaAI] Memory update skipped (empty conversation)."); + } return; } @@ -991,6 +1032,10 @@ You are 'The Legion', a super AI of the Wula Empire. Your personality is authori string existingJson = BuildExistingMemoriesJson(memoryManager.GetAllMemories()); _memoryUpdateInProgress = true; + if (Prefs.DevMode) + { + WulaLog.Debug($"[WulaAI] Memory update started (conversationChars={conversation.Length})."); + } _ = Task.Run(async () => { try @@ -1034,6 +1079,11 @@ You are 'The Legion', a super AI of the Wula Empire. Your personality is authori continue; } + if (IsAutoCommentaryMessage(entry.message)) + { + continue; + } + string role = string.Equals(entry.role, "user", StringComparison.OrdinalIgnoreCase) ? "User" : "Assistant"; sb.AppendLine($"{role}: {entry.message}"); } @@ -1072,14 +1122,27 @@ You are 'The Legion', a super AI of the Wula Empire. Your personality is authori var facts = ParseMemoryFacts(factsResponse); if (facts.Count == 0) { + if (Prefs.DevMode) + { + WulaLog.Debug("[WulaAI] Memory update: no facts extracted."); + } return; } + if (Prefs.DevMode) + { + WulaLog.Debug($"[WulaAI] Memory update: extracted {facts.Count} fact(s)."); + } + string factsJson = BuildFactsJson(facts); string updatePrompt = MemoryPrompts.BuildMemoryUpdatePrompt(existingMemoriesJson, factsJson); string updateResponse = await client.GetChatCompletionAsync(updatePrompt, new List<(string role, string message)>(), maxTokens: 512, temperature: 0.1f); var updates = ParseMemoryUpdates(updateResponse); + if (Prefs.DevMode) + { + WulaLog.Debug($"[WulaAI] Memory update: parsed {updates.Count} update(s)."); + } LongEventHandler.ExecuteWhenFinished(() => { ApplyMemoryUpdates(memoryManager, updates, facts); @@ -1222,6 +1285,7 @@ You are 'The Legion', a super AI of the Wula Empire. Your personality is authori return; } + int appliedCount = 0; bool applied = false; if (updates != null && updates.Count > 0) { @@ -1232,6 +1296,7 @@ You are 'The Legion', a super AI of the Wula Empire. Your personality is authori { memoryManager.AddMemory(update.Text, update.Category); applied = true; + appliedCount++; } else if (evt == "UPDATE") { @@ -1239,6 +1304,7 @@ You are 'The Legion', a super AI of the Wula Empire. Your personality is authori { memoryManager.UpdateMemory(update.Id, update.Text, update.Category); applied = true; + appliedCount++; } } else if (evt == "DELETE") @@ -1247,6 +1313,7 @@ You are 'The Legion', a super AI of the Wula Empire. Your personality is authori { memoryManager.DeleteMemory(update.Id); applied = true; + appliedCount++; } } } @@ -1257,8 +1324,14 @@ You are 'The Legion', a super AI of the Wula Empire. Your personality is authori foreach (var fact in fallbackFacts) { memoryManager.AddMemory(fact.Text, fact.Category); + appliedCount++; } } + + if (Prefs.DevMode) + { + WulaLog.Debug($"[WulaAI] Memory update applied ({appliedCount} change(s))."); + } } private static string ExtractJsonArray(string json, string key) diff --git a/Source/WulaFallenEmpire/HarmonyPatches/ResurrectionCrashFix.cs b/Source/WulaFallenEmpire/HarmonyPatches/ResurrectionCrashFix.cs new file mode 100644 index 00000000..291c8bce --- /dev/null +++ b/Source/WulaFallenEmpire/HarmonyPatches/ResurrectionCrashFix.cs @@ -0,0 +1,46 @@ +using HarmonyLib; +using RimWorld; +using Verse; +using System.Reflection; + +namespace WulaFallenEmpire +{ + // 修复 Wula 种族尸体可能缺少 CompRottable 导致 ResurrectionUtility.TryResurrectWithSideEffects 崩溃的问题 + [HarmonyPatch] + public static class ResurrectionCrashFix + { + private static MethodInfo TargetMethod() + { + return AccessTools.Method(typeof(ResurrectionUtility), "TryResurrectWithSideEffects"); + } + + [HarmonyPrefix] + public static bool Prefix(Pawn pawn) + { + if (pawn == null) return true; + + // 只针对 Wula 种族(防止误伤其他 Pawn) + if (pawn.def == null || pawn.def.defName != "WulaSpecies") + { + return true; + } + + // 检查尸体是否缺少必要的腐烂组件 + // 原版 TryResurrectWithSideEffects 会无条件访问 corpse.GetComp().RotProgress + if (pawn.Corpse != null && pawn.Corpse.GetComp() == null) + { + if (Prefs.DevMode) + { + WulaLog.Debug($"[WulaFix] Intercepted crash: {pawn.LabelShort} corpse missing CompRottable. Performing safe resurrection."); + } + + // 直接调用不带副作用的复活方法 + ResurrectionUtility.TryResurrect(pawn); + + return false; // 阻止原版方法执行 + } + + return true; + } + } +}