unit VaxServerExCOM;

interface

uses
  System.SysUtils,
  System.Classes,
  VaxServerCOM, MainFormDlg;

type

  TVaxServerExCOM = class(TVaxServerCOM)

  public

    constructor Create(); reintroduce; overload;
    constructor Create(hMainForm: TMainForm); reintroduce; overload;
    destructor Destroy; override;

  private

     m_RefMainForm: TMainForm;

  public

    function StartServer(nListenPort: Integer): Boolean;
    procedure StopServer;

  protected

    procedure OnRegisterUser(sUserName: String; sDomain: String; sUserAgent: String; sFromIP: String; nFromPort: Integer; nRegId: UInt64); override;
    procedure OnRegisterUserSuccess(sUserName: String; sFromIP: String; nFromPort: Integer; nRegId: UInt64); override;
    procedure OnRegisterUserFailed(sUserName: String; sFromIP: String; nFromPort: Integer; nRegId: UInt64); override;

    procedure OnIncomingCall(nSessionId: UInt64; sCallerName: String; sCallerId: String; sDialNo: String; nFromPeerType: Integer; sFromPeerName: String; sUserAgent: String; sFromIP: String; nFromPort: Integer); override;

    procedure OnVaxFunctionCallOpenAI(nSessionId: UInt64; sFuncName: String; sCallId: String; aParamNames: TArray<String>; aParamValues: TArray<String>); override;

    procedure OnCallSessionConnected(nSessionId: UInt64); override;

    procedure OnVaxAudioOutputTranscriptOpenAI(nSessionId: UInt64; sTranscript: String); override;
    procedure OnVaxAudioInputTranscriptOpenAI(nSessionId: UInt64; sTranscript: String); override;

    procedure OnLineRegisterTrying(sLineName: String); override;
    procedure OnLineRegisterFailed(sLineName: String; nStatusCode: Integer; sReasonPhrase: String); override;
    procedure OnLineRegisterSuccess(sLineName: String); override;

    procedure OnCallSessionConnecting(nSessionId: UInt64; nStatusCode: Integer; sReasonPhrase: String); override;
    procedure OnCallSessionFailed(nSessionId: UInt64; nStatusCode: Integer; sReasonPhrase: String; sContact: String); override;
    procedure OnCallSessionHangup(nSessionId: UInt64); override;
    procedure OnCallSessionTimeout(nSessionId: UInt64); override;

    procedure OnCallSessionErrorLog(nSessionId: UInt64; nErrorCode: Integer; sErrorMsg: String); override;
    procedure OnVaxErrorLog(sFuncName: String; nErrorCode: Integer; sErrorMsg: String); override;
    procedure OnVaxErrorOpenAI(nSessionId: UInt64; sMsg: String); override;

  private
    procedure AdjustFunctionOpenAI(nSessionId: UInt64);

  end;

implementation

constructor TVaxServerExCOM.Create();
begin
  inherited Create;
  m_RefMainForm := nil;
end;


constructor TVaxServerExCOM.Create(hMainForm: TMainForm);
begin
  inherited Create;
  m_RefMainForm := hMainForm;
end;


destructor TVaxServerExCOM.Destroy;
begin
  inherited Destroy;
end;


function TVaxServerExCOM.StartServer(nListenPort: Integer): Boolean;
begin

  StopServer;

  inherited SetLicenseKey('TRIAL-LICENSE-KEY');

  if not inherited Initialize('') then
  begin
    Result := False;
    Exit;
  end;

  if not inherited OpenNetworkUDP('', nListenPort) then
  begin
    UnInitialize;
    Result := False;
    Exit;
  end;

  inherited SetListenPortRangeRTP(20000, 30000);

  inherited AudioSessionLost(True, 30);
  inherited AddLine('AnonymousUDP', VAX_LINE_TYPE_UDP, '', '', '', '', '', '255.255.255.255', -1, '32');

  Result := True;
end;


procedure TVaxServerExCOM.StopServer;
begin
  inherited UnInitialize;
end;


  //////////////////////////////////////////////////////////////////////////////
  //////////////////////////////////////////////////////////////////////////////

procedure TVaxServerExCOM.OnRegisterUser(sUserName: String; sDomain: String; sUserAgent: String; sFromIP: String; nFromPort: Integer; nRegId: UInt64);
begin

  inherited RemoveUser(sUserName);
  inherited AddUser(sUserName, sUserName, '32');

  m_RefMainForm.SetStatus('OnRegisterUser(' + string(sUserName) + ')');

  AuthRegister(nRegId);

end;


procedure TVaxServerExCOM.OnRegisterUserSuccess(sUserName: String; sFromIP: String; nFromPort: Integer; nRegId: UInt64);
begin
  m_RefMainForm.SetStatus('OnRegisterUserSuccess(' + string(sUserName) + ')');
end;


procedure TVaxServerExCOM.OnRegisterUserFailed(sUserName: String; sFromIP: String; nFromPort: Integer; nRegId: UInt64);
begin
  m_RefMainForm.SetStatus('OnRegisterUserFailed(' + string(sUserName) + ')');
end;

  //////////////////////////////////////////////////////////////////////////////
  //////////////////////////////////////////////////////////////////////////////

procedure TVaxServerExCOM.OnIncomingCall(nSessionId: UInt64; sCallerName: String; sCallerId: String; sDialNo: String; nFromPeerType: Integer; sFromPeerName: String; sUserAgent: String; sFromIP: String; nFromPort: Integer);
var
  sModelPrompt: WideString;
  sKeyOpenAI: WideString;
  sModel: WideString;
begin

  AdjustFunctionOpenAI(nSessionId);    // Function Tools

  // inherited InputTranscriptOpenAI(nSessionId, true, '', '');   // Activate with default model = "gpt-4o-transcribe" and noise_reduction = "near_field"
                                                          // triggers event: OnVaxAudioInputTranscriptOpenAI()

  sModelPrompt := 'You are a FEMALE agent and must speak as a female. By default, respond in English. If the user speaks in another language, ' +
                  'automatically switch and respond in that same language. Use the provided tools when appropriate.';

  // https://platform.openai.com/audio/realtime


  sKeyOpenAI := 'YOUR-OPEN-AI-KEY';


  sModel := 'gpt-realtime';
  //sModel := 'gpt-realtime-mini';

  // inherited.ActivateSemanticVAD(nSessionId, ""); // Semantic VAD is activated by default
  // https://platform.openai.com/docs/guides/realtime-vad#server-vad

  //shimmer, coral, marin, alloy

  inherited AcceptCallSession(nSessionId, 30, sKeyOpenAI, sModelPrompt, sModel, 'coral', 1.0);

end;

  //////////////////////////////////////////////////////////////////////////////
  //////////////////////////////////////////////////////////////////////////////

procedure TVaxServerExCOM.OnVaxFunctionCallOpenAI(nSessionId: UInt64; sFuncName: String; sCallId: String; aParamNames: TArray<String>; aParamValues: TArray<String>);
var
  nValueA, nValueB: Integer;
  nValueTotal: Integer;
  sDeptName, sResult: String;
begin

  if SameText(sFuncName, 'add_two_numbers') then
  begin

      nValueA := StrToIntDef(aParamValues[0], 0);
      nValueB := StrToIntDef(aParamValues[1], 0);

      nValueTotal := nValueA + nValueB;
      sResult := IntToStr(nValueTotal);

      inherited SendFunctionResultOpenAI(nSessionId, sCallId, sResult);
      Exit;

  end;

  if SameText(sFuncName, 'DepartmentTalk') then
  begin

    sDeptName := aParamValues[0];

    inherited SendFunctionResultOpenAI(nSessionId, sCallId, 'Please wait Transfering');
    inherited SendReqTransferCallBlind(nSessionId, '7878');

    Exit;

  end;
end;

  //////////////////////////////////////////////////////////////////////////////
  //////////////////////////////////////////////////////////////////////////////

procedure TVaxServerExCOM.AdjustFunctionOpenAI(nSessionId: UInt64);
begin

  inherited AddFunctionOpenAI(nSessionId, 'add_two_numbers', 'Add two numbers and return the result.');
  inherited AddFunctionParamOpenAI(nSessionId, 'add_two_numbers', 'a', 'First number to add');
  inherited AddFunctionParamOpenAI(nSessionId, 'add_two_numbers', 'b', 'Second number to add');

  inherited AddFunctionOpenAI(nSessionId, 'DepartmentTalk', 'The department the user wants to talk to. Expected values: ''sales'' or ''technical support''');
  inherited AddFunctionParamOpenAI(nSessionId, 'DepartmentTalk', 'Department', 'Department Name');

end;

  //////////////////////////////////////////////////////////////////////////////
  //////////////////////////////////////////////////////////////////////////////

procedure TVaxServerExCOM.OnCallSessionConnected(nSessionId: UInt64);
begin

  inherited SendInputOpenAI(nSessionId, 'Hello');
   m_RefMainForm.SetStatus('OnCallSessionConnected()');

end;


procedure TVaxServerExCOM.OnVaxAudioOutputTranscriptOpenAI(nSessionId: UInt64; sTranscript: String);
begin
  m_RefMainForm.SetStatus('OnVaxAudioOutputTranscriptOpenAI(' + string(sTranscript) + ')');
end;

procedure TVaxServerExCOM.OnVaxAudioInputTranscriptOpenAI(nSessionId: UInt64; sTranscript: String);
begin
  m_RefMainForm.SetStatus('OnVaxAudioInputTranscriptOpenAI(' + string(sTranscript) + ')');
end;

 //////////////////////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////////////////////

procedure TVaxServerExCOM.OnLineRegisterTrying(sLineName: String);
begin
  m_RefMainForm.SetStatus('OnLineRegisterTrying(' + string(sLineName) + ')');
end;


procedure TVaxServerExCOM.OnLineRegisterFailed(sLineName: String; nStatusCode: Integer; sReasonPhrase: String);
begin
  m_RefMainForm.SetStatus('OnLineRegisterFailed(' + string(sLineName) + ')');
end;


procedure TVaxServerExCOM.OnLineRegisterSuccess(sLineName: String);
begin
  m_RefMainForm.SetStatus('OnLineRegisterSuccess(' + string(sLineName) + ')');
end;

  //////////////////////////////////////////////////////////////////////////////
  //////////////////////////////////////////////////////////////////////////////

procedure TVaxServerExCOM.OnCallSessionConnecting(nSessionId: UInt64; nStatusCode: Integer; sReasonPhrase: String);
begin
  m_RefMainForm.SetStatus('OnCallSessionConnecting(' + string(sReasonPhrase) + ')');
end;


procedure TVaxServerExCOM.OnCallSessionFailed(nSessionId: UInt64; nStatusCode: Integer; sReasonPhrase: String; sContact: String);
begin
  m_RefMainForm.SetStatus('OnCallSessionFailed(' + string(sReasonPhrase) + ')');
end;


procedure TVaxServerExCOM.OnCallSessionHangup(nSessionId: UInt64);
begin
  m_RefMainForm.SetStatus('OnCallSessionHangup()');
end;


procedure TVaxServerExCOM.OnCallSessionTimeout(nSessionId: UInt64);
begin
  m_RefMainForm.SetStatus('OnCallSessionTimeout()');
end;

  //////////////////////////////////////////////////////////////////////////////
  //////////////////////////////////////////////////////////////////////////////

procedure TVaxServerExCOM.OnCallSessionErrorLog(nSessionId: UInt64; nErrorCode: Integer; sErrorMsg: String);
begin
  m_RefMainForm.SetStatus('OnCallSessionErrorLog(' + string(sErrorMsg) + ')');
end;


procedure TVaxServerExCOM.OnVaxErrorLog(sFuncName: String; nErrorCode: Integer; sErrorMsg: String);
begin
  m_RefMainForm.SetStatus('OnVaxErrorLog(' + string(sFuncName) + ', ' + string(sErrorMsg) + ')');
end;


procedure TVaxServerExCOM.OnVaxErrorOpenAI(nSessionId: UInt64; sMsg: String);
begin
  m_RefMainForm.SetStatus('OnVaxErrorOpenAI(' + string(sMsg) + ')');
end;

end.

