GatherContextCommand.cs 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. using UnityEditor;
  2. using UnityEngine;
  3. using LLM.Editor.Data;
  4. using LLM.Editor.Helper;
  5. using LLM.Editor.Analysis;
  6. using System.Collections.Generic;
  7. namespace LLM.Editor.Commands
  8. {
  9. /// <summary>
  10. /// The master "tool" command. It receives a batch of data requests from the LLM,
  11. /// dispatches them to the appropriate Context Providers, and aggregates the results.
  12. /// </summary>
  13. public class GatherContextCommand : ICommand
  14. {
  15. private readonly GatherContextParams _params;
  16. public GatherContextCommand(string jsonParams)
  17. {
  18. _params = jsonParams?.FromJson<GatherContextParams>();
  19. }
  20. public CommandOutcome Execute(CommandContext context)
  21. {
  22. if (_params?.requests == null || _params.requests.Count == 0)
  23. {
  24. Debug.LogError("[GatherContextCommand] No requests found in parameters.");
  25. return CommandOutcome.Error;
  26. }
  27. var results = new Dictionary<string, object>();
  28. foreach (var request in _params.requests)
  29. {
  30. var targetObject = ResolveIdentifier(request.subjectIdentifier);
  31. var provider = ContextProviderRegistry.GetProvider(request.dataType);
  32. if (provider == null)
  33. {
  34. Debug.LogWarning($"[GatherContextCommand] No context provider found for dataType '{request.dataType}'. Skipping request for key '{request.contextKey}'.");
  35. results[request.contextKey] = $"Error: No provider for dataType '{request.dataType}'";
  36. continue;
  37. }
  38. var contextData = provider.GetContext(targetObject, request.qualifier);
  39. results[request.contextKey] = contextData;
  40. }
  41. var aggregatedContextJson = results.ToJson(true);
  42. context.CurrentSubject = aggregatedContextJson;
  43. Debug.Log($"[GatherContextCommand] Successfully gathered context for {_params.requests.Count} request(s). Pausing for next API call.");
  44. Debug.Log($"Aggregated Context:\n{aggregatedContextJson}");
  45. return CommandOutcome.AwaitingNextTurn;
  46. }
  47. /// <summary>
  48. /// Resolves an identifier string to a Unity Object.
  49. /// The identifier can be an InstanceID, a GUID, or an asset path.
  50. /// </summary>
  51. private static Object ResolveIdentifier(string identifier)
  52. {
  53. if (string.IsNullOrEmpty(identifier)) return null;
  54. // Priority 1: Try parsing as an InstanceID for scene objects
  55. if (int.TryParse(identifier, out var instanceId))
  56. {
  57. var obj = EditorUtility.InstanceIDToObject(instanceId);
  58. if (obj) return obj;
  59. }
  60. // Priority 2: Try resolving as a GUID for project assets
  61. var path = AssetDatabase.GUIDToAssetPath(identifier);
  62. if (!string.IsNullOrEmpty(path))
  63. {
  64. return AssetDatabase.LoadAssetAtPath<Object>(path);
  65. }
  66. // Priority 3: Assume it's a direct asset path
  67. if (System.IO.File.Exists(identifier) || System.IO.Directory.Exists(identifier))
  68. {
  69. return AssetDatabase.LoadAssetAtPath<Object>(identifier);
  70. }
  71. Debug.LogWarning($"[GatherContextCommand] Could not resolve identifier '{identifier}' to a Unity Object.");
  72. return null;
  73. }
  74. }
  75. }