using System; using System.Collections.Generic; using UnityEngine; namespace YagizEraslan.DeepSeek.Unity { public class DeepSeekChatController { private readonly DeepSeekStreamingApi streamingApi; private readonly DeepSeekApi deepSeekApi; private readonly List history = new(); private readonly Action onMessageUpdate; private readonly Action onStreamingUpdate; private readonly string selectedModelName; private readonly bool useStreaming; private string currentStreamContent = ""; public DeepSeekChatController(IDeepSeekApi api, string modelName, Action messageCallback, Action streamingCallback, bool useStreaming) { var concreteApi = api as DeepSeekApi; if (concreteApi == null) { Debug.LogError("DeepSeekChatController requires DeepSeekApi instance, not just IDeepSeekApi interface!"); } this.deepSeekApi = concreteApi; this.deepSeekApi = concreteApi; this.streamingApi = new DeepSeekStreamingApi(); this.selectedModelName = modelName; this.onMessageUpdate = messageCallback; this.onStreamingUpdate = streamingCallback; this.useStreaming = useStreaming; } public void SendUserMessage(string userMessage) { if (string.IsNullOrWhiteSpace(userMessage)) { Debug.LogWarning("User message is empty."); return; } var userChat = new ChatMessage { role = "user", content = userMessage }; history.Add(userChat); onMessageUpdate?.Invoke(userChat, true); var request = new ChatCompletionRequest { model = selectedModelName, messages = history.ToArray(), stream = useStreaming }; if (useStreaming) { currentStreamContent = ""; // Create placeholder AI message in UI BEFORE starting the stream var aiMessage = new ChatMessage { role = "assistant", content = "" // start with empty }; onMessageUpdate?.Invoke(aiMessage, false); // 👈 this instantiates the UI prefab and assigns activeStreamingText streamingApi.CreateChatCompletionStream( request, deepSeekApi.ApiKey, partialToken => { currentStreamContent += partialToken; onStreamingUpdate?.Invoke(currentStreamContent); }); }else { HandleFullResponse(request); } } private async void HandleFullResponse(ChatCompletionRequest request) { try { var awaitedResponse = await deepSeekApi.CreateChatCompletion(request); if (awaitedResponse != null && awaitedResponse.choices != null && awaitedResponse.choices.Length > 0) { var aiMessage = awaitedResponse.choices[0].message; history.Add(aiMessage); onMessageUpdate?.Invoke(aiMessage, false); } else { Debug.LogWarning("No response choices received from DeepSeek API."); } } catch (Exception ex) { Debug.LogError($"Error while sending message to DeepSeek API: {ex.Message}"); } } } }