zc
This commit is contained in:
@@ -10,7 +10,7 @@ namespace WulaFallenEmpire.EventSystem.AI
|
||||
public class AIHistoryManager : WorldComponent
|
||||
{
|
||||
private string _saveId;
|
||||
private Dictionary<string, List<(string role, string message)>> _cache = new Dictionary<string, List<(string role, string message)>>();
|
||||
private Dictionary<string, List<ApiMessage>> _cache = new Dictionary<string, List<ApiMessage>>();
|
||||
|
||||
public AIHistoryManager(World world) : base(world)
|
||||
{
|
||||
@@ -35,7 +35,7 @@ namespace WulaFallenEmpire.EventSystem.AI
|
||||
return Path.Combine(GetSaveDirectory(), $"{_saveId}_{eventDefName}.json");
|
||||
}
|
||||
|
||||
public List<(string role, string message)> GetHistory(string eventDefName)
|
||||
public List<ApiMessage> GetHistory(string eventDefName)
|
||||
{
|
||||
if (_cache.TryGetValue(eventDefName, out var cachedHistory))
|
||||
{
|
||||
@@ -61,10 +61,10 @@ namespace WulaFallenEmpire.EventSystem.AI
|
||||
}
|
||||
}
|
||||
|
||||
return new List<(string role, string message)>();
|
||||
return new List<ApiMessage>();
|
||||
}
|
||||
|
||||
public void SaveHistory(string eventDefName, List<(string role, string message)> history)
|
||||
public void SaveHistory(string eventDefName, List<ApiMessage> history)
|
||||
{
|
||||
_cache[eventDefName] = history;
|
||||
string path = GetFilePath(eventDefName);
|
||||
@@ -93,7 +93,7 @@ namespace WulaFallenEmpire.EventSystem.AI
|
||||
|
||||
public static class SimpleJsonParser
|
||||
{
|
||||
public static string Serialize(List<(string role, string message)> history)
|
||||
public static string Serialize(List<ApiMessage> history)
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.Append("[");
|
||||
@@ -102,7 +102,8 @@ namespace WulaFallenEmpire.EventSystem.AI
|
||||
var item = history[i];
|
||||
sb.Append("{");
|
||||
sb.Append($"\"role\":\"{Escape(item.role)}\",");
|
||||
sb.Append($"\"message\":\"{Escape(item.message)}\"");
|
||||
sb.Append($"\"content\":\"{Escape(item.content)}\"");
|
||||
// Note: tool_calls are not serialized for history to keep it simple.
|
||||
sb.Append("}");
|
||||
if (i < history.Count - 1) sb.Append(",");
|
||||
}
|
||||
@@ -110,13 +111,11 @@ namespace WulaFallenEmpire.EventSystem.AI
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
public static List<(string role, string message)> Deserialize(string json)
|
||||
public static List<ApiMessage> Deserialize(string json)
|
||||
{
|
||||
var result = new List<(string role, string message)>();
|
||||
var result = new List<ApiMessage>();
|
||||
if (string.IsNullOrEmpty(json)) return result;
|
||||
|
||||
// Very basic parser, assumes standard format produced by Serialize
|
||||
// Remove outer brackets
|
||||
json = json.Trim();
|
||||
if (json.StartsWith("[") && json.EndsWith("]"))
|
||||
{
|
||||
@@ -124,10 +123,6 @@ namespace WulaFallenEmpire.EventSystem.AI
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(json)) return result;
|
||||
|
||||
// Split by objects
|
||||
// This is fragile if objects contain nested objects or escaped braces, but for this specific structure it's fine
|
||||
// We are splitting by "},{" which is risky. Better to iterate.
|
||||
|
||||
int depth = 0;
|
||||
int start = 0;
|
||||
@@ -153,16 +148,10 @@ namespace WulaFallenEmpire.EventSystem.AI
|
||||
return result;
|
||||
}
|
||||
|
||||
private static (string role, string message) ParseObject(string json)
|
||||
public static Dictionary<string, string> Parse(string json)
|
||||
{
|
||||
string role = null;
|
||||
string message = null;
|
||||
|
||||
// Remove braces
|
||||
var dict = new Dictionary<string, string>();
|
||||
json = json.Trim('{', '}');
|
||||
|
||||
// Split by key-value pairs, respecting quotes
|
||||
// Again, simple parsing
|
||||
var parts = SplitByComma(json);
|
||||
foreach (var part in parts)
|
||||
{
|
||||
@@ -171,17 +160,48 @@ namespace WulaFallenEmpire.EventSystem.AI
|
||||
{
|
||||
string key = Unescape(kv[0].Trim().Trim('"'));
|
||||
string val = Unescape(kv[1].Trim().Trim('"'));
|
||||
if (key == "role") role = val;
|
||||
if (key == "message") message = val;
|
||||
dict[key] = val;
|
||||
}
|
||||
}
|
||||
return dict;
|
||||
}
|
||||
|
||||
public static List<Dictionary<string, string>> ParseArray(string json)
|
||||
{
|
||||
var list = new List<Dictionary<string, string>>();
|
||||
json = json.Trim('[', ']');
|
||||
int depth = 0;
|
||||
int start = 0;
|
||||
for (int i = 0; i < json.Length; i++)
|
||||
{
|
||||
if (json[i] == '{')
|
||||
{
|
||||
if (depth == 0) start = i;
|
||||
depth++;
|
||||
}
|
||||
else if (json[i] == '}')
|
||||
{
|
||||
depth--;
|
||||
if (depth == 0)
|
||||
{
|
||||
list.Add(Parse(json.Substring(start, i - start + 1)));
|
||||
}
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
return (role, message);
|
||||
private static ApiMessage ParseObject(string json)
|
||||
{
|
||||
var msg = new ApiMessage();
|
||||
var dict = Parse(json);
|
||||
if (dict.TryGetValue("role", out string r)) msg.role = r;
|
||||
if (dict.TryGetValue("content", out string c)) msg.content = c;
|
||||
return msg;
|
||||
}
|
||||
|
||||
private static string[] SplitByComma(string input)
|
||||
{
|
||||
// Split by comma but ignore commas inside quotes
|
||||
var list = new List<string>();
|
||||
bool inQuote = false;
|
||||
int start = 0;
|
||||
@@ -200,7 +220,6 @@ namespace WulaFallenEmpire.EventSystem.AI
|
||||
|
||||
private static string[] SplitByColon(string input)
|
||||
{
|
||||
// Split by first colon outside quotes
|
||||
bool inQuote = false;
|
||||
for (int i = 0; i < input.Length; i++)
|
||||
{
|
||||
@@ -219,7 +238,7 @@ namespace WulaFallenEmpire.EventSystem.AI
|
||||
return s.Replace("\\", "\\\\").Replace("\"", "\\\"").Replace("\n", "\\n").Replace("\r", "\\r");
|
||||
}
|
||||
|
||||
private static string Unescape(string s)
|
||||
public static string Unescape(string s) // Changed to public
|
||||
{
|
||||
if (s == null) return "";
|
||||
return s.Replace("\\r", "\r").Replace("\\n", "\n").Replace("\\\"", "\"").Replace("\\\\", "\\");
|
||||
|
||||
Reference in New Issue
Block a user