DummyApiClient.cs 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. using UnityEngine;
  2. using UnityEditor;
  3. using System.Linq;
  4. using LLM.Editor.Core;
  5. using LLM.Editor.Data;
  6. using LLM.Editor.Helper;
  7. using LLM.Editor.Commands;
  8. using Newtonsoft.Json.Linq;
  9. using System.Threading.Tasks;
  10. using System.Collections.Generic;
  11. namespace LLM.Editor.Client
  12. {
  13. /// <summary>
  14. /// A mock client that simulates an LLM response for testing purposes.
  15. /// It now reads from an external JSON file to handle complex, multi-step test cases.
  16. /// </summary>
  17. public class DummyApiClient : ILlmApiClient
  18. {
  19. [System.Serializable]
  20. private class CommandResponse { public List<CommandData> commands; }
  21. private static DummyTestCase _activeTestCase;
  22. private static int _activeResponseStep;
  23. public Task SendPrompt(string prompt, List<Object> stagedContext)
  24. {
  25. var responseSheet = LoadResponseSheet();
  26. if (responseSheet == null)
  27. {
  28. DisplayError("Could not load DummyResponses.json. Make sure it exists in a Resources folder.");
  29. return Task.CompletedTask;
  30. }
  31. // Find a test case whose trigger phrase is in the user's prompt.
  32. _activeTestCase = responseSheet.testCases.FirstOrDefault(
  33. c => prompt.ToLower().Contains(c.triggerPhrase.ToLower())
  34. );
  35. if (_activeTestCase != null)
  36. {
  37. Debug.Log($"[DummyApiClient] Triggered test case for: '{_activeTestCase.triggerPhrase}'");
  38. _activeResponseStep = 0; // Start at the first response
  39. ExecuteStep();
  40. }
  41. else
  42. {
  43. // Fallback to a default response if no test case matches.
  44. ExecuteCommandsFromJson(GetDefaultResponse());
  45. }
  46. return Task.CompletedTask;
  47. }
  48. public Task SendFollowUp(string detailedContext)
  49. {
  50. if (_activeTestCase != null)
  51. {
  52. _activeResponseStep++; // Move to the next response
  53. Debug.Log($"[DummyApiClient] Executing follow-up step #{_activeResponseStep + 1} for test case: '{_activeTestCase.triggerPhrase}'");
  54. ExecuteStep();
  55. }
  56. else
  57. {
  58. Debug.LogWarning("[DummyApiClient] Received a follow-up call, but no active test case was found.");
  59. ExecuteCommandsFromJson(GetDefaultResponse());
  60. }
  61. return Task.CompletedTask;
  62. }
  63. private static void ExecuteStep()
  64. {
  65. if (_activeTestCase?.responses == null || _activeResponseStep >= _activeTestCase.responses.Count)
  66. {
  67. Debug.Log("[DummyApiClient] Test case finished or has no more steps.");
  68. _activeTestCase = null; // End the test case
  69. return;
  70. }
  71. var jsonResponse = _activeTestCase.responses[_activeResponseStep];
  72. ExecuteCommandsFromJson(jsonResponse);
  73. }
  74. private static void ExecuteCommandsFromJson(string json)
  75. {
  76. var commandResponse = json.FromJson<CommandResponse>();
  77. if (commandResponse?.commands != null)
  78. {
  79. CommandExecutor.SetQueue(commandResponse.commands);
  80. CommandExecutor.ExecuteNextCommand();
  81. }
  82. else
  83. {
  84. DisplayError($"Failed to parse command structure from dummy JSON response: {json}");
  85. }
  86. }
  87. private static DummyResponseSheet LoadResponseSheet()
  88. {
  89. TextAsset textAsset;
  90. var allMatches = AssetDatabase.FindAssets("t:textasset DummyResponses");
  91. foreach (var match in allMatches)
  92. {
  93. var path = AssetDatabase.GUIDToAssetPath(match);
  94. textAsset = AssetDatabase.LoadAssetAtPath<TextAsset>(path);
  95. if (textAsset)
  96. {
  97. return textAsset.text.FromJson<DummyResponseSheet>();
  98. }
  99. }
  100. textAsset = Resources.Load<TextAsset>($"DummyResponses");
  101. return !textAsset ? null : textAsset.text.FromJson<DummyResponseSheet>();
  102. }
  103. private static void DisplayError(string message)
  104. {
  105. var errorParams = new DisplayMessageParams { outcome = CommandOutcome.Error, message = $"[Dummy Client Error] {message}" };
  106. var commandData = new CommandData { commandName = nameof(DisplayMessageCommand), jsonData = new JObject(errorParams) };
  107. CommandExecutor.SetQueue(new List<CommandData> { commandData });
  108. CommandExecutor.ExecuteNextCommand();
  109. }
  110. private static string GetDefaultResponse()
  111. {
  112. return @"{
  113. ""commands"": [
  114. {
  115. ""commandName"": ""DisplayMessageCommand"",
  116. ""jsonData"": {
  117. ""outcome"": ""Success"",
  118. ""message"": ""[Dummy] No specific test case was triggered by your prompt.""
  119. }
  120. }
  121. ]
  122. }";
  123. }
  124. }
  125. }