commit
7ced01ef2f
|
|
@ -16,7 +16,7 @@ public interface IRealTimeCompletion
|
|||
Action<List<RoleDialogModel>> onModelResponseDone,
|
||||
Action<string> onConversationItemCreated,
|
||||
Action<RoleDialogModel> onInputAudioTranscriptionCompleted,
|
||||
Action onUserInterrupted);
|
||||
Action onInterruptionDetected);
|
||||
Task AppenAudioBuffer(string message);
|
||||
Task AppenAudioBuffer(ArraySegment<byte> data, int length);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,3 @@
|
|||
using System.Collections.Concurrent;
|
||||
|
||||
namespace BotSharp.Abstraction.Realtime.Models;
|
||||
|
||||
public class RealtimeHubConnection
|
||||
|
|
|
|||
|
|
@ -7,9 +7,11 @@ public class RealtimeModelSettings
|
|||
public bool InterruptResponse { get; set; } = true;
|
||||
public string InputAudioFormat { get; set; } = "g711_ulaw";
|
||||
public string OutputAudioFormat { get; set; } = "g711_ulaw";
|
||||
public bool InputAudioTranscribe { get; set; } = false;
|
||||
public string Voice { get; set; } = "alloy";
|
||||
public float Temperature { get; set; } = 0.8f;
|
||||
public int MaxResponseOutputTokens { get; set; } = 512;
|
||||
public int ModelResponseTimeout { get; set; } = 30;
|
||||
public AudioTranscription InputAudioTranscription { get; set; } = new();
|
||||
public ModelTurnDetection TurnDetection { get; set; } = new();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -139,7 +139,7 @@ public class RealtimeHub : IRealtimeHub
|
|||
await hook.OnMessageReceived(message);
|
||||
}
|
||||
},
|
||||
onUserInterrupted: async () =>
|
||||
onInterruptionDetected: async () =>
|
||||
{
|
||||
if (settings.InterruptResponse)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ public class RealTimeCompletionProvider : IRealTimeCompletion
|
|||
Action<List<RoleDialogModel>> onModelResponseDone,
|
||||
Action<string> onConversationItemCreated,
|
||||
Action<RoleDialogModel> onInputAudioTranscriptionCompleted,
|
||||
Action onUserInterrupted)
|
||||
Action onInterruptionDetected)
|
||||
{
|
||||
var realtimeModelSettings = _services.GetRequiredService<RealtimeModelSettings>();
|
||||
_model = realtimeModelSettings.Model;
|
||||
|
|
@ -62,7 +62,7 @@ public class RealTimeCompletionProvider : IRealTimeCompletion
|
|||
onModelResponseDone,
|
||||
onConversationItemCreated,
|
||||
onInputAudioTranscriptionCompleted,
|
||||
onUserInterrupted);
|
||||
onInterruptionDetected);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -139,11 +139,12 @@ public class RealTimeCompletionProvider : IRealTimeCompletion
|
|||
Action<List<RoleDialogModel>> onModelResponseDone,
|
||||
Action<string> onConversationItemCreated,
|
||||
Action<RoleDialogModel> onUserAudioTranscriptionCompleted,
|
||||
Action onUserInterrupted)
|
||||
Action onInterruptionDetected)
|
||||
{
|
||||
var buffer = new byte[1024 * 32];
|
||||
// Model response timeout
|
||||
var timeout = 30;
|
||||
var settings = _services.GetRequiredService<RealtimeModelSettings>();
|
||||
var timeout = settings.ModelResponseTimeout;
|
||||
WebSocketReceiveResult? result = default;
|
||||
|
||||
do
|
||||
|
|
@ -241,7 +242,7 @@ public class RealTimeCompletionProvider : IRealTimeCompletion
|
|||
else if (response.Type == "input_audio_buffer.speech_started")
|
||||
{
|
||||
// Handle user interuption
|
||||
onUserInterrupted();
|
||||
onInterruptionDetected();
|
||||
}
|
||||
|
||||
} while (!result.CloseStatus.HasValue);
|
||||
|
|
@ -290,9 +291,6 @@ public class RealTimeCompletionProvider : IRealTimeCompletion
|
|||
return fn;
|
||||
}).ToArray();
|
||||
|
||||
var words = new List<string>();
|
||||
HookEmitter.Emit<IRealtimeHook>(_services, hook => words.AddRange(hook.OnModelTranscriptPrompt(agent)));
|
||||
|
||||
var realtimeModelSettings = _services.GetRequiredService<RealtimeModelSettings>();
|
||||
|
||||
var sessionUpdate = new
|
||||
|
|
@ -302,12 +300,6 @@ public class RealTimeCompletionProvider : IRealTimeCompletion
|
|||
{
|
||||
InputAudioFormat = realtimeModelSettings.InputAudioFormat,
|
||||
OutputAudioFormat = realtimeModelSettings.OutputAudioFormat,
|
||||
/*InputAudioTranscription = new InputAudioTranscription
|
||||
{
|
||||
Model = realtimeModelSettings.InputAudioTranscription.Model,
|
||||
Language = realtimeModelSettings.InputAudioTranscription.Language,
|
||||
Prompt = string.Join(", ", words.Select(x => x.ToLower().Trim()).Distinct()).SubstringMax(1024)
|
||||
},*/
|
||||
Voice = realtimeModelSettings.Voice,
|
||||
Instructions = instruction,
|
||||
ToolChoice = "auto",
|
||||
|
|
@ -329,6 +321,19 @@ public class RealTimeCompletionProvider : IRealTimeCompletion
|
|||
}
|
||||
};
|
||||
|
||||
if (realtimeModelSettings.InputAudioTranscribe)
|
||||
{
|
||||
var words = new List<string>();
|
||||
HookEmitter.Emit<IRealtimeHook>(_services, hook => words.AddRange(hook.OnModelTranscriptPrompt(agent)));
|
||||
|
||||
sessionUpdate.session.InputAudioTranscription = new InputAudioTranscription
|
||||
{
|
||||
Model = realtimeModelSettings.InputAudioTranscription.Model,
|
||||
Language = realtimeModelSettings.InputAudioTranscription.Language,
|
||||
Prompt = string.Join(", ", words.Select(x => x.ToLower().Trim()).Distinct()).SubstringMax(1024)
|
||||
};
|
||||
}
|
||||
|
||||
await HookEmitter.Emit<IContentGeneratingHook>(_services, async hook =>
|
||||
{
|
||||
await hook.OnSessionUpdated(agent, instruction, functions);
|
||||
|
|
|
|||
|
|
@ -357,6 +357,14 @@ public class TwilioVoiceController : TwilioController
|
|||
{
|
||||
await HookEmitter.Emit<ITwilioCallStatusHook>(_services, x => x.OnCallNoAnswerStatus(request));
|
||||
}
|
||||
else if (request.CallStatus == "canceled")
|
||||
{
|
||||
await HookEmitter.Emit<ITwilioCallStatusHook>(_services, x => x.OnCallCanceledStatus(request));
|
||||
}
|
||||
else if (request.CallStatus == "failed")
|
||||
{
|
||||
await HookEmitter.Emit<ITwilioCallStatusHook>(_services, x => x.OnCallFailedStatus(request));
|
||||
}
|
||||
|
||||
return Ok();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,4 +20,8 @@ public interface ITwilioCallStatusHook
|
|||
Task OnCallBusyStatus(ConversationalVoiceRequest request);
|
||||
|
||||
Task OnCallNoAnswerStatus(ConversationalVoiceRequest request);
|
||||
|
||||
Task OnCallCanceledStatus(ConversationalVoiceRequest request);
|
||||
|
||||
Task OnCallFailedStatus(ConversationalVoiceRequest request);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue