|
@@ -1,9 +1,9 @@
|
|
|
using System.Linq;
|
|
|
using System.Text;
|
|
|
using UnityEditor;
|
|
|
-using UnityEngine;
|
|
|
using LLM.Editor.Core;
|
|
|
using System.Diagnostics;
|
|
|
+using LLM.Editor.Helper;
|
|
|
using UnityEngine.Networking;
|
|
|
using System.Threading.Tasks;
|
|
|
using System.Collections.Generic;
|
|
@@ -71,15 +71,30 @@ namespace LLM.Editor.Client
|
|
|
private static string GetSystemPrompt()
|
|
|
{
|
|
|
return @"You are an expert Unity development assistant. Your goal is to help the user by breaking down their request into a sequence of commands.
|
|
|
-You MUST ONLY respond with a single JSON object containing a 'commands' array. Do not use markdown or any other formatting.
|
|
|
+You MUST ONLY respond with a single JSON object containing a 'commands' array. Do not use markdown or any other formatting. The jsonData option of each command MUST be a valid JSON string.
|
|
|
|
|
|
-Here are the available commands:
|
|
|
-- DisplayMessage: Show a text message to the user. Use this for conversational replies, questions, or to provide information.
|
|
|
-- CreateScript: Creates a new C# script file.
|
|
|
-- CreatePrefab: Creates a new prefab from a source model found in the project.
|
|
|
-- AddComponentToAsset: Attaches a script to a prefab asset.
|
|
|
-- InstantiatePrefab: Creates an instance of a prefab in the current scene.
|
|
|
-- RequestClarification: Ask the user a follow-up question if their request is ambiguous.
|
|
|
+Some commands act on the 'subject' from the previous command.
|
|
|
+Here are the available commands and the exact `jsonData` format you must use for each:
|
|
|
+
|
|
|
+1. **DisplayMessage**: Shows a text message to the user.
|
|
|
+ `""""jsonData"""": """"{\""""message\"""":\""""Your message here.\""""}""""`
|
|
|
+
|
|
|
+2. **CreateScript**: Creates a new C# script. This sets the new script as the subject.
|
|
|
+ `""""jsonData"""": """"{\""""scriptName\"""":\""""MyNewScript\"""",\""""scriptContent\"""":\""""using UnityEngine;\\npublic class MyNewScript : MonoBehaviour { }\""""}""""`
|
|
|
+
|
|
|
+3. **CreatePrefab**: Asks the user for a save location, then creates a prefab. This sets the new prefab as the subject.
|
|
|
+ `""""jsonData"""": """"{\""""sourceObjectQuery\"""":\""""MyModel t:Model\"""",\""""defaultName\"""":\""""MyModel.prefab\""""}""""`
|
|
|
+
|
|
|
+4. **AddComponentToAsset**: Attaches a script to the prefab currently set as the subject.
|
|
|
+ `""""jsonData"""": """"{\""""scriptName\"""":\""""MyNewScript\""""}""""`
|
|
|
+
|
|
|
+5. **InstantiatePrefab**: Creates an instance of the prefab currently set as the subject. This sets the new scene object as the subject.
|
|
|
+ `""""jsonData"""": """"{}""""`
|
|
|
+
|
|
|
+6. **RequestClarification**: Asks the user a follow-up question.
|
|
|
+ `""""jsonData"""": """"{\""""prompt\"""":\""""Which object do you mean?\"""",\""""options\"""":[\""""ObjectA\"""",\""""ObjectB\""""]}""""`
|
|
|
+
|
|
|
+Your entire response must be a single, valid JSON object.
|
|
|
|
|
|
Example of a valid response:
|
|
|
{
|
|
@@ -127,7 +142,7 @@ Example of a valid response:
|
|
|
}).ToList()
|
|
|
};
|
|
|
|
|
|
- var jsonPayload = JsonUtility.ToJson(apiRequest);
|
|
|
+ var jsonPayload = apiRequest.ToJson();
|
|
|
|
|
|
using var request = new UnityWebRequest(url, "POST");
|
|
|
var bodyRaw = Encoding.UTF8.GetBytes(jsonPayload);
|
|
@@ -145,15 +160,16 @@ Example of a valid response:
|
|
|
if (request.result == UnityWebRequest.Result.Success)
|
|
|
{
|
|
|
var responseJson = request.downloadHandler.text;
|
|
|
- var apiResponse = JsonUtility.FromJson<Api.ApiResponse>(responseJson);
|
|
|
+ Debug.Log($"[GeminiApiClient] Response received: \n{responseJson}.");
|
|
|
+ var apiResponse = responseJson?.FromJson<Api.ApiResponse>();
|
|
|
|
|
|
- if (apiResponse.candidates != null && apiResponse.candidates.Any())
|
|
|
+ if (apiResponse is { candidates: not null } && apiResponse.candidates.Any())
|
|
|
{
|
|
|
var commandJson = apiResponse.candidates[0].content.parts[0].text;
|
|
|
Debug.Log($"[GeminiApiClient] Command received: {commandJson}.");
|
|
|
chatHistory.Add(new Data.ChatEntry { role = "model", content = commandJson });
|
|
|
SessionManager.SaveChatHistory(chatHistory);
|
|
|
- var commandResponse = JsonUtility.FromJson<CommandResponse>(commandJson);
|
|
|
+ var commandResponse = commandJson?.FromJson<CommandResponse>();
|
|
|
if (commandResponse is { commands: not null })
|
|
|
{
|
|
|
Debug.Log($"[GeminiApiClient] Received {commandResponse.commands.Count} commands from LLM.");
|