using UnityEngine;
using UnityEditor;
using System.Linq;
using LLM.Editor.Core;
using LLM.Editor.Data;
using LLM.Editor.Helper;
using LLM.Editor.Commands;
using Newtonsoft.Json.Linq;
using System.Threading.Tasks;
using System.Collections.Generic;
namespace LLM.Editor.Client
{
///
/// A mock client that simulates an LLM response for testing purposes.
/// It now reads from an external JSON file to handle complex, multi-step test cases.
///
public class DummyApiClient : ILlmApiClient
{
[System.Serializable]
private class CommandResponse { public List commands; }
private static DummyTestCase _activeTestCase;
private static int _activeResponseStep;
public Task SendPrompt(string prompt, List stagedContext)
{
var responseSheet = LoadResponseSheet();
if (responseSheet == null)
{
DisplayError("Could not load DummyResponses.json. Make sure it exists in a Resources folder.");
return Task.CompletedTask;
}
// Find a test case whose trigger phrase is in the user's prompt.
_activeTestCase = responseSheet.testCases.FirstOrDefault(
c => prompt.ToLower().Contains(c.triggerPhrase.ToLower())
);
if (_activeTestCase != null)
{
Debug.Log($"[DummyApiClient] Triggered test case for: '{_activeTestCase.triggerPhrase}'");
_activeResponseStep = 0; // Start at the first response
ExecuteStep();
}
else
{
// Fallback to a default response if no test case matches.
ExecuteCommandsFromJson(GetDefaultResponse());
}
return Task.CompletedTask;
}
public Task SendFollowUp(string detailedContext)
{
if (_activeTestCase != null)
{
_activeResponseStep++; // Move to the next response
Debug.Log($"[DummyApiClient] Executing follow-up step #{_activeResponseStep + 1} for test case: '{_activeTestCase.triggerPhrase}'");
ExecuteStep();
}
else
{
Debug.LogWarning("[DummyApiClient] Received a follow-up call, but no active test case was found.");
ExecuteCommandsFromJson(GetDefaultResponse());
}
return Task.CompletedTask;
}
private static void ExecuteStep()
{
if (_activeTestCase?.responses == null || _activeResponseStep >= _activeTestCase.responses.Count)
{
Debug.Log("[DummyApiClient] Test case finished or has no more steps.");
_activeTestCase = null; // End the test case
return;
}
var jsonResponse = _activeTestCase.responses[_activeResponseStep];
ExecuteCommandsFromJson(jsonResponse);
}
private static void ExecuteCommandsFromJson(string json)
{
var commandResponse = json.FromJson();
if (commandResponse?.commands != null)
{
CommandExecutor.SetQueue(commandResponse.commands);
CommandExecutor.ExecuteNextCommand();
}
else
{
DisplayError($"Failed to parse command structure from dummy JSON response: {json}");
}
}
private static DummyResponseSheet LoadResponseSheet()
{
TextAsset textAsset;
var allMatches = AssetDatabase.FindAssets("t:textasset DummyResponses");
foreach (var match in allMatches)
{
var path = AssetDatabase.GUIDToAssetPath(match);
textAsset = AssetDatabase.LoadAssetAtPath(path);
if (textAsset)
{
return textAsset.text.FromJson();
}
}
textAsset = Resources.Load($"DummyResponses");
return !textAsset ? null : textAsset.text.FromJson();
}
private static void DisplayError(string message)
{
var errorParams = new DisplayMessageParams { outcome = CommandOutcome.Error, message = $"[Dummy Client Error] {message}" };
var commandData = new CommandData { commandName = nameof(DisplayMessageCommand), jsonData = new JObject(errorParams) };
CommandExecutor.SetQueue(new List { commandData });
CommandExecutor.ExecuteNextCommand();
}
private static string GetDefaultResponse()
{
return @"{
""commands"": [
{
""commandName"": ""DisplayMessageCommand"",
""jsonData"": {
""outcome"": ""Success"",
""message"": ""[Dummy] No specific test case was triggered by your prompt.""
}
}
]
}";
}
}
}