diff --git a/1.6/1.6/Assemblies/WulaFallenEmpire.dll b/1.6/1.6/Assemblies/WulaFallenEmpire.dll
index f16137ea..e7f0e887 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/AIIntelligenceCore.cs b/Source/WulaFallenEmpire/EventSystem/AI/AIIntelligenceCore.cs
index ef55a9e6..d05ec25c 100644
--- a/Source/WulaFallenEmpire/EventSystem/AI/AIIntelligenceCore.cs
+++ b/Source/WulaFallenEmpire/EventSystem/AI/AIIntelligenceCore.cs
@@ -936,8 +936,6 @@ You are 'The Legion', a super AI of the Wula Empire. Your personality is authori
if (string.IsNullOrWhiteSpace(response)) return response;
string cleaned = response.Trim();
cleaned = Regex.Replace(cleaned, @".*?", "", RegexOptions.Singleline | RegexOptions.IgnoreCase);
- cleaned = Regex.Replace(cleaned, @"```json", "", RegexOptions.IgnoreCase);
- cleaned = cleaned.Replace("```", "");
return cleaned.Trim();
}
diff --git a/Source/WulaFallenEmpire/EventSystem/AI/Utils/JsonToolCallParser.cs b/Source/WulaFallenEmpire/EventSystem/AI/Utils/JsonToolCallParser.cs
index c833bd8b..41aca837 100644
--- a/Source/WulaFallenEmpire/EventSystem/AI/Utils/JsonToolCallParser.cs
+++ b/Source/WulaFallenEmpire/EventSystem/AI/Utils/JsonToolCallParser.cs
@@ -92,6 +92,11 @@ namespace WulaFallenEmpire.EventSystem.AI.Utils
}
}
+ if (TryParseToolCallsLoose(trimmed, out toolCalls, out jsonFragment))
+ {
+ return true;
+ }
+
return false;
}
@@ -123,6 +128,160 @@ namespace WulaFallenEmpire.EventSystem.AI.Utils
return false;
}
+ private static bool TryParseToolCallsLoose(string input, out List toolCalls, out string jsonFragment)
+ {
+ toolCalls = null;
+ jsonFragment = null;
+ if (string.IsNullOrWhiteSpace(input)) return false;
+
+ string cleaned = input.Trim();
+
+ int toolCallsIndex = IndexOfIgnoreCase(cleaned, "\"tool_calls\"");
+ if (toolCallsIndex < 0) return false;
+
+ int arrayStart = cleaned.IndexOf('[', toolCallsIndex);
+ if (arrayStart < 0) return false;
+
+ if (!TryExtractJsonBlock(cleaned, arrayStart, '[', ']', out string arrayBlock)) return false;
+
+ var callObjects = ExtractJsonObjects(arrayBlock);
+ if (callObjects.Count == 0) return false;
+
+ var parsedCalls = new List();
+ foreach (var callObj in callObjects)
+ {
+ if (callObj == null || callObj.Count == 0) continue;
+
+ string id = TryGetString(callObj, "id");
+ string name = null;
+ object argsObj = null;
+
+ if (TryGetValue(callObj, "function", out object fnObj) && fnObj is Dictionary fnDict)
+ {
+ name = TryGetString(fnDict, "name");
+ TryGetValue(fnDict, "arguments", out argsObj);
+ }
+ else
+ {
+ name = TryGetString(callObj, "name");
+ TryGetValue(callObj, "arguments", out argsObj);
+ }
+
+ if (string.IsNullOrWhiteSpace(name)) continue;
+
+ if (!TryNormalizeArguments(argsObj, out Dictionary args, out string argsJson))
+ {
+ args = new Dictionary(StringComparer.OrdinalIgnoreCase);
+ argsJson = "{}";
+ }
+
+ parsedCalls.Add(new ToolCallInfo
+ {
+ Id = id,
+ Name = name.Trim(),
+ Arguments = args,
+ ArgumentsJson = argsJson
+ });
+ }
+
+ if (parsedCalls.Count == 0) return false;
+
+ toolCalls = parsedCalls;
+ jsonFragment = arrayBlock;
+ return true;
+ }
+
+ private static List> ExtractJsonObjects(string input)
+ {
+ var objects = new List>();
+ if (string.IsNullOrWhiteSpace(input)) return objects;
+
+ int i = 0;
+ while (i < input.Length)
+ {
+ if (input[i] != '{')
+ {
+ i++;
+ continue;
+ }
+
+ if (!TryExtractJsonBlock(input, i, '{', '}', out string objBlock))
+ {
+ i++;
+ continue;
+ }
+
+ if (TryParseObject(objBlock, out Dictionary obj))
+ {
+ objects.Add(obj);
+ }
+
+ i += Math.Max(1, objBlock.Length);
+ }
+
+ return objects;
+ }
+
+ private static bool TryExtractJsonBlock(string input, int startIndex, char openChar, char closeChar, out string block)
+ {
+ block = null;
+ if (string.IsNullOrWhiteSpace(input) || startIndex < 0 || startIndex >= input.Length) return false;
+
+ int depth = 0;
+ bool inString = false;
+ bool escape = false;
+ int start = -1;
+
+ for (int i = startIndex; i < input.Length; i++)
+ {
+ char c = input[i];
+ if (escape)
+ {
+ escape = false;
+ }
+ else if (c == '\\')
+ {
+ if (inString) escape = true;
+ }
+ else if (c == '\"')
+ {
+ inString = !inString;
+ }
+
+ if (inString) continue;
+
+ if (c == openChar)
+ {
+ if (depth == 0)
+ {
+ start = i;
+ }
+ depth++;
+ continue;
+ }
+ if (c == closeChar)
+ {
+ depth--;
+ if (depth == 0 && start >= 0)
+ {
+ block = input.Substring(start, i - start + 1);
+ return true;
+ }
+ if (depth < 0)
+ {
+ return false;
+ }
+ }
+ }
+
+ return false;
+ }
+
+ private static int IndexOfIgnoreCase(string input, string value)
+ {
+ return input?.IndexOf(value ?? "", StringComparison.OrdinalIgnoreCase) ?? -1;
+ }
+
public static bool TryParseObject(string json, out Dictionary obj)
{
obj = null;