ict.shenzhi/Assets/deepseek/Runtime/UI/DeepSeekChatController.cs

107 lines
3.8 KiB
C#

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<ChatMessage> history = new();
private readonly Action<ChatMessage, bool> onMessageUpdate;
private readonly Action<string> onStreamingUpdate;
private readonly string selectedModelName;
private readonly bool useStreaming;
private string currentStreamContent = "";
public DeepSeekChatController(IDeepSeekApi api, string modelName, Action<ChatMessage, bool> messageCallback, Action<string> 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}");
}
}
}
}