using System; using System.Collections; using System.Text; using UnityEngine; using UnityEngine.Networking; namespace Hallucinate.AI { [Serializable] public class Part { public string text; } [Serializable] public class Content { public Part[] parts; } [Serializable] public class Candidate { public Content content; } [Serializable] public class GeminiResponse { public Candidate[] candidates; } public class GeminiService : MonoBehaviour { public static GeminiService Instance { get; private set; } [SerializeField] private string apiKey = "AQ.Ab8RN6I2hU_p8yHiPNNHtWzYBiLugbPP22gC6lzTWaYEWj4v0g"; // Replace with your key [SerializeField] private string geminiURL = "https://generativelanguage.googleapis.com/v1beta/models/gemini-flash-latest:generateContent"; private void Awake() { if (Instance == null) { Instance = this; DontDestroyOnLoad(gameObject); } else { Destroy(gameObject); } } public void GetResponse(string persona, string prompt, Action onComplete) { StartCoroutine(PostRequest(persona, prompt, onComplete)); } private IEnumerator PostRequest(string persona, string prompt, Action onComplete) { var jsonBody = $@"{{ ""systemInstruction"": {{""parts"": [{{ ""text"": ""{persona}"" }}]}}, ""contents"": [{{""parts"": [{{ ""text"": ""{prompt}"" }}]}}], ""generationConfig"": {{ ""maxOutputTokens"": 60, ""temperature"": 0.7 }} }}"; var requestURL = $"{geminiURL}?key={apiKey}"; using (var request = new UnityWebRequest(requestURL, "POST")) { byte[] bodyRaw = Encoding.UTF8.GetBytes(jsonBody); request.uploadHandler = new UploadHandlerRaw(bodyRaw); request.downloadHandler = new DownloadHandlerBuffer(); request.SetRequestHeader("Content-Type", "application/json"); yield return request.SendWebRequest(); if (request.result == UnityWebRequest.Result.Success) { string rawResponse = request.downloadHandler.text; try { var response = JsonUtility.FromJson(rawResponse); if (response != null && response.candidates != null && response.candidates.Length > 0 && response.candidates[0].content != null && response.candidates[0].content.parts != null && response.candidates[0].content.parts.Length > 0) { onComplete?.Invoke(response.candidates[0].content.parts[0].text); } else { Debug.LogWarning($"[Gemini] Response structure invalid or blocked. Raw: {rawResponse}"); } } catch (Exception e) { Debug.LogError($"[Gemini] JSON Parse Error: {e.Message}\nRaw Response: {rawResponse}"); } } else { Debug.LogError($"[Gemini] API Error: {request.error}"); } } } } }