Improves /chat/ endpoint client.
This commit is contained in:
@@ -52,7 +52,7 @@ namespace PPGIA.X540.Project3.API
|
||||
byte[] bodyRaw = EncodePayload(payload);
|
||||
Debug.Log($"Payload size: {bodyRaw.Length} bytes - {payload}");
|
||||
request.uploadHandler = new UploadHandlerRaw(bodyRaw);
|
||||
}
|
||||
}
|
||||
|
||||
request.downloadHandler = new DownloadHandlerBuffer();
|
||||
|
||||
@@ -86,7 +86,7 @@ Response Body: {body}";
|
||||
}
|
||||
|
||||
internal static IEnumerator CallEndpointWithGetCoroutine(
|
||||
string url, float timeoutInSeconds,
|
||||
string url, float timeoutInSeconds,
|
||||
Action<UnityWebRequest> callbackOnSuccess)
|
||||
{
|
||||
yield return CallEndpointCoroutine(
|
||||
@@ -94,7 +94,7 @@ Response Body: {body}";
|
||||
}
|
||||
|
||||
internal static IEnumerator CallEndpointWithPostCoroutine(
|
||||
string url, float timeoutInSeconds, object payload,
|
||||
string url, float timeoutInSeconds, object payload,
|
||||
Action<UnityWebRequest> callbackOnSuccess)
|
||||
{
|
||||
yield return CallEndpointCoroutine(
|
||||
@@ -102,7 +102,7 @@ Response Body: {body}";
|
||||
}
|
||||
|
||||
internal static IEnumerator CallEndpointWithPutCoroutine(
|
||||
string url, float timeoutInSeconds, object payload,
|
||||
string url, float timeoutInSeconds, object payload,
|
||||
Action<UnityWebRequest> callbackOnSuccess)
|
||||
{
|
||||
yield return CallEndpointCoroutine(
|
||||
@@ -110,58 +110,43 @@ Response Body: {body}";
|
||||
}
|
||||
|
||||
internal static IEnumerator CallEndpointWithDeleteCoroutine(
|
||||
string url, float timeoutInSeconds,
|
||||
string url, float timeoutInSeconds,
|
||||
Action<UnityWebRequest> callbackOnSuccess)
|
||||
{
|
||||
yield return CallEndpointCoroutine(
|
||||
url, "DELETE", null, timeoutInSeconds, callbackOnSuccess);
|
||||
}
|
||||
|
||||
internal static IEnumerator ReadAudioResponseCoroutine(
|
||||
UnityWebRequest request,
|
||||
internal static IEnumerator DownloadAudioCoroutine(
|
||||
string url,
|
||||
float timeoutInSeconds,
|
||||
Action<AudioClip> callbackOnSuccess)
|
||||
{
|
||||
byte[] audioBytes = request.downloadHandler.data;
|
||||
if (audioBytes == null || audioBytes.Length == 0)
|
||||
using (UnityWebRequest mmRequest =
|
||||
UnityWebRequestMultimedia.GetAudioClip(url, AudioType.OGGVORBIS))
|
||||
{
|
||||
Debug.LogError("No audio data received.");
|
||||
yield break;
|
||||
}
|
||||
|
||||
// Save temporarily to file for loading as AudioClip
|
||||
string tempPath = Path.Combine(Application.persistentDataPath, "tts_temp.ogg");
|
||||
File.WriteAllBytes(tempPath, audioBytes);
|
||||
|
||||
using (var file = UnityWebRequestMultimedia.GetAudioClip(
|
||||
"file://" + tempPath, AudioType.OGGVORBIS))
|
||||
{
|
||||
yield return file.SendWebRequest();
|
||||
|
||||
if (file.result == UnityWebRequest.Result.Success)
|
||||
var op = mmRequest.SendWebRequest();
|
||||
yield return WaitForTimeout(op, timeoutInSeconds, () =>
|
||||
{
|
||||
AudioClip clip = DownloadHandlerAudioClip.GetContent(file);
|
||||
callbackOnSuccess?.Invoke(clip);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogError($"Error loading AudioClip: {file.error}");
|
||||
}
|
||||
}
|
||||
Debug.LogError("Request timed out.");
|
||||
});
|
||||
|
||||
// Remove temporary file
|
||||
File.Delete(tempPath);
|
||||
if (mmRequest.result != UnityWebRequest.Result.Success)
|
||||
{
|
||||
Debug.LogError($"Error loading audio: {mmRequest.error}");
|
||||
yield break;
|
||||
}
|
||||
|
||||
AudioClip clip = DownloadHandlerAudioClip.GetContent(mmRequest);
|
||||
if (clip == null)
|
||||
{
|
||||
Debug.LogError("AudioClip is null after download.");
|
||||
yield break;
|
||||
}
|
||||
|
||||
callbackOnSuccess?.Invoke(clip);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal enum Environment
|
||||
{
|
||||
Development,
|
||||
Production
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
internal struct ChatServicePayload
|
||||
{
|
||||
public string message;
|
||||
}
|
||||
}
|
||||
@@ -90,6 +90,8 @@ namespace PPGIA.X540.Project3.API
|
||||
[ContextMenu("Initiate Session")]
|
||||
public void InitiateSession()
|
||||
{
|
||||
StopAllCoroutines();
|
||||
|
||||
var url = EndpointUrl(_sessionInitEndpoint, _clientId);
|
||||
|
||||
StartCoroutine(ApiClient.CallEndpointWithPostCoroutine(
|
||||
@@ -103,13 +105,15 @@ namespace PPGIA.X540.Project3.API
|
||||
|
||||
[ContextMenu("Close Session")]
|
||||
public void CloseSession()
|
||||
{
|
||||
{
|
||||
if (_session == null)
|
||||
{
|
||||
Debug.LogWarning("No active session to close.");
|
||||
return;
|
||||
}
|
||||
|
||||
StopAllCoroutines();
|
||||
|
||||
var url = EndpointUrl(_sessionCloseEndpoint, _session.SessionId);
|
||||
|
||||
StartCoroutine(ApiClient.CallEndpointWithDeleteCoroutine(
|
||||
@@ -130,6 +134,8 @@ namespace PPGIA.X540.Project3.API
|
||||
return;
|
||||
}
|
||||
|
||||
StopAllCoroutines();
|
||||
|
||||
// Build the endpoint URL and payload
|
||||
var url = EndpointUrl(_chatEndpoint, _session.SessionId);
|
||||
var payload = new ChatServicePayload { message = _query };
|
||||
@@ -138,8 +144,18 @@ namespace PPGIA.X540.Project3.API
|
||||
StartCoroutine(ApiClient.CallEndpointWithPostCoroutine(
|
||||
url, _timeoutInSeconds, payload, (request) =>
|
||||
{
|
||||
StartCoroutine(ApiClient.ReadAudioResponseCoroutine(
|
||||
request, (audioClip) =>
|
||||
var body = request.downloadHandler?.text ?? string.Empty;
|
||||
var response = ApiModel.FromJson<ChatServiceResponse>(body);
|
||||
var audioUrl = response?.AudioUrl;
|
||||
if (string.IsNullOrEmpty(audioUrl))
|
||||
{
|
||||
Debug.LogWarning("No audio URL in response.");
|
||||
return;
|
||||
}
|
||||
|
||||
Debug.Log($"Downloading audio from: {audioUrl}");
|
||||
StartCoroutine(ApiClient.DownloadAudioCoroutine(
|
||||
audioUrl, _timeoutInSeconds, (audioClip) =>
|
||||
{
|
||||
if (audioClip == null)
|
||||
{
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
using System;
|
||||
|
||||
using UnityEngine;
|
||||
|
||||
|
||||
namespace PPGIA.X540.Project3.API
|
||||
{
|
||||
[Serializable]
|
||||
public class ApiModel
|
||||
{
|
||||
public static T FromJson<T>(string json) =>
|
||||
JsonUtility.FromJson<T>(json);
|
||||
|
||||
public static string ToJson<T>(T obj) =>
|
||||
JsonUtility.ToJson(obj);
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public class Session: ApiModel
|
||||
{
|
||||
public string session_id;
|
||||
public string created_at;
|
||||
|
||||
// Optional convenience properties with C#-style names:
|
||||
public string SessionId => session_id;
|
||||
public DateTime CreatedAt => DateTime.Parse(created_at);
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public class ChatServicePayload : ApiModel
|
||||
{
|
||||
public string message;
|
||||
}
|
||||
|
||||
public class ChatServiceResponse : ApiModel
|
||||
{
|
||||
public string session_id;
|
||||
public string message;
|
||||
public string audio_url;
|
||||
public string audio_key;
|
||||
public int expires_in;
|
||||
|
||||
// Optional convenience properties with C#-style names:
|
||||
public string SessionId => session_id;
|
||||
public string Message => message;
|
||||
public string AudioUrl => audio_url;
|
||||
public string AudioKey => audio_key;
|
||||
public int ExpiresIn => expires_in;
|
||||
}
|
||||
|
||||
internal enum Environment
|
||||
{
|
||||
Development,
|
||||
Production
|
||||
}
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a9e9a88d8a4978c4ba0e6bf106276b7a
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,21 +0,0 @@
|
||||
using System;
|
||||
|
||||
using UnityEngine;
|
||||
|
||||
|
||||
namespace PPGIA.X540.Project3.API
|
||||
{
|
||||
[Serializable]
|
||||
public class Session
|
||||
{
|
||||
public string session_id;
|
||||
public string created_at;
|
||||
|
||||
// Optional convenience properties with C#-style names:
|
||||
public string SessionId => session_id;
|
||||
public DateTime CreatedAt => DateTime.Parse(created_at);
|
||||
|
||||
public static Session FromJson(string json) =>
|
||||
JsonUtility.FromJson<Session>(json);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user