using System; using UnityEngine; namespace LLM.Commands { public static class LLMCommandParser { public static bool TryExtract(string rawReply, out string visibleText, out LLMCommandEnvelope envelope) { visibleText = rawReply ?? ""; envelope = null; if (string.IsNullOrWhiteSpace(rawReply)) return false; string cleaned = rawReply.Replace("```json", "").Replace("```", "").Trim(); if (TryParseEnvelope(cleaned, out envelope)) { visibleText = string.IsNullOrWhiteSpace(envelope.text) ? "" : envelope.text.Trim(); return true; } if (!TryExtractLastJsonObject(cleaned, out string json, out int startIndex)) return false; if (!TryParseEnvelope(json, out envelope)) return false; visibleText = string.IsNullOrWhiteSpace(envelope.text) ? cleaned.Substring(0, startIndex).Trim() : envelope.text.Trim(); return true; } private static bool TryParseEnvelope(string json, out LLMCommandEnvelope envelope) { envelope = null; try { envelope = JsonUtility.FromJson(json); } catch (Exception) { envelope = null; } if (envelope == null) return false; if (envelope.commands == null && string.IsNullOrWhiteSpace(envelope.text)) return false; return true; } private static bool TryExtractLastJsonObject(string input, out string json, out int startIndex) { json = null; startIndex = -1; if (string.IsNullOrEmpty(input)) return false; int end = input.LastIndexOf('}'); if (end < 0) return false; int depth = 0; for (int i = end; i >= 0; i--) { char c = input[i]; if (c == '}') depth++; else if (c == '{') { depth--; if (depth == 0) { startIndex = i; json = input.Substring(i, end - i + 1); return true; } } } return false; } } }