diff --git a/1.6/1.6/Assemblies/WulaFallenEmpire.dll b/1.6/1.6/Assemblies/WulaFallenEmpire.dll index 7a17183d..1caad44d 100644 Binary files a/1.6/1.6/Assemblies/WulaFallenEmpire.dll and b/1.6/1.6/Assemblies/WulaFallenEmpire.dll differ diff --git a/Source/WulaFallenEmpire/EventSystem/AI/SimpleAIClient.cs b/Source/WulaFallenEmpire/EventSystem/AI/SimpleAIClient.cs index 9f2544b8..3288bb22 100644 --- a/Source/WulaFallenEmpire/EventSystem/AI/SimpleAIClient.cs +++ b/Source/WulaFallenEmpire/EventSystem/AI/SimpleAIClient.cs @@ -37,7 +37,7 @@ namespace WulaFallenEmpire.EventSystem.AI StringBuilder jsonBuilder = new StringBuilder(); jsonBuilder.Append("{"); jsonBuilder.Append($"\"model\": \"{_model}\","); - jsonBuilder.Append("\"stream\": false,"); + jsonBuilder.Append("\"stream\": false,"); // We request non-stream, but handle stream if returned jsonBuilder.Append("\"messages\": ["); // System instruction @@ -108,55 +108,33 @@ namespace WulaFallenEmpire.EventSystem.AI { try { - // Robust parsing for "content": "..." allowing for whitespace variations - int contentIndex = json.IndexOf("\"content\""); - if (contentIndex == -1) return null; - - // Find the opening quote after "content" - int openQuoteIndex = -1; - for (int i = contentIndex + 9; i < json.Length; i++) + // Check for stream format (SSE) + // SSE lines start with "data: " + if (json.TrimStart().StartsWith("data:")) { - if (json[i] == '"') + StringBuilder fullContent = new StringBuilder(); + string[] lines = json.Split(new[] { "\n", "\r" }, StringSplitOptions.RemoveEmptyEntries); + foreach (string line in lines) { - openQuoteIndex = i; - break; + string trimmedLine = line.Trim(); + if (trimmedLine == "data: [DONE]") continue; + if (trimmedLine.StartsWith("data: ")) + { + string dataJson = trimmedLine.Substring(6); + // Extract content from this chunk + string chunkContent = ExtractJsonValue(dataJson, "content"); + if (!string.IsNullOrEmpty(chunkContent)) + { + fullContent.Append(chunkContent); + } + } } + return fullContent.ToString(); } - if (openQuoteIndex == -1) return null; - - int startIndex = openQuoteIndex + 1; - StringBuilder content = new StringBuilder(); - bool escaped = false; - - for (int i = startIndex; i < json.Length; i++) + else { - char c = json[i]; - if (escaped) - { - if (c == 'n') content.Append('\n'); - else if (c == 'r') content.Append('\r'); - else if (c == 't') content.Append('\t'); - else if (c == '"') content.Append('"'); - else if (c == '\\') content.Append('\\'); - else content.Append(c); // Literal - escaped = false; - } - else - { - if (c == '\\') - { - escaped = true; - } - else if (c == '"') - { - // End of string - return content.ToString(); - } - else - { - content.Append(c); - } - } + // Standard non-stream format + return ExtractJsonValue(json, "content"); } } catch (Exception ex) @@ -165,5 +143,57 @@ namespace WulaFallenEmpire.EventSystem.AI } return null; } + + private string ExtractJsonValue(string json, string key) + { + // Simple parser to find "key": "value" + // This is not a full JSON parser and assumes standard formatting + string keyPattern = $"\"{key}\""; + int keyIndex = json.IndexOf(keyPattern); + if (keyIndex == -1) return null; + + // Find the colon after the key + int colonIndex = json.IndexOf(':', keyIndex + keyPattern.Length); + if (colonIndex == -1) return null; + + // Find the opening quote of the value + int valueStart = json.IndexOf('"', colonIndex); + if (valueStart == -1) return null; + + // Extract string with escape handling + StringBuilder sb = new StringBuilder(); + bool escaped = false; + for (int i = valueStart + 1; i < json.Length; i++) + { + char c = json[i]; + if (escaped) + { + if (c == 'n') sb.Append('\n'); + else if (c == 'r') sb.Append('\r'); + else if (c == 't') sb.Append('\t'); + else if (c == '"') sb.Append('"'); + else if (c == '\\') sb.Append('\\'); + else sb.Append(c); // Literal + escaped = false; + } + else + { + if (c == '\\') + { + escaped = true; + } + else if (c == '"') + { + // End of string + return sb.ToString(); + } + else + { + sb.Append(c); + } + } + } + return null; + } } } \ No newline at end of file diff --git a/Source/WulaFallenEmpire/EventSystem/AI/Tools/Tool_SpawnResources.cs b/Source/WulaFallenEmpire/EventSystem/AI/Tools/Tool_SpawnResources.cs index 67158c32..a443b16d 100644 --- a/Source/WulaFallenEmpire/EventSystem/AI/Tools/Tool_SpawnResources.cs +++ b/Source/WulaFallenEmpire/EventSystem/AI/Tools/Tool_SpawnResources.cs @@ -103,7 +103,7 @@ namespace WulaFallenEmpire.EventSystem.AI.Tools Faction faction = Find.FactionManager.FirstFactionOfDef(FactionDef.Named("Wula_PIA_Legion_Faction")); if (faction != null) { - Messages.Message("Wula_ResourceDrop".Translate(faction.Name), new LookTargets(dropSpot, map), MessageTypeDefOf.PositiveEvent); + Messages.Message("Wula_ResourceDrop".Translate(faction.Name.Named("FACTION_name")), new LookTargets(dropSpot, map), MessageTypeDefOf.PositiveEvent); } resultLog.Length -= 2; // Remove trailing comma diff --git a/Source/WulaFallenEmpire/EventSystem/AI/UI/Dialog_AIConversation.cs b/Source/WulaFallenEmpire/EventSystem/AI/UI/Dialog_AIConversation.cs index c5f6087f..e8523306 100644 --- a/Source/WulaFallenEmpire/EventSystem/AI/UI/Dialog_AIConversation.cs +++ b/Source/WulaFallenEmpire/EventSystem/AI/UI/Dialog_AIConversation.cs @@ -506,7 +506,9 @@ When the player requests any form of resources, you MUST follow this multi-turn bool isLastMessage = i == filteredHistory.Count - 1; Text.Font = (isLastMessage && entry.role == "assistant") ? GameFont.Medium : GameFont.Small; - viewHeight += Text.CalcHeight(text, rect.width - 16f) + 15f; // Add padding + // Increase padding significantly for Medium font to prevent clipping + float padding = (isLastMessage && entry.role == "assistant") ? 30f : 15f; + viewHeight += Text.CalcHeight(text, rect.width - 16f) + padding; } Rect viewRect = new Rect(0f, 0f, rect.width - 16f, viewHeight); Widgets.BeginScrollView(rect, ref _scrollPosition, viewRect); @@ -520,7 +522,9 @@ When the player requests any form of resources, you MUST follow this multi-turn bool isLastMessage = i == filteredHistory.Count - 1; Text.Font = (isLastMessage && entry.role == "assistant") ? GameFont.Medium : GameFont.Small; - float height = Text.CalcHeight(text, viewRect.width) + 10f; // Increased padding + + float padding = (isLastMessage && entry.role == "assistant") ? 30f : 15f; + float height = Text.CalcHeight(text, viewRect.width) + padding; Rect labelRect = new Rect(0f, curY, viewRect.width, height); if (entry.role == "user") {