Overview

The @tixae-labs/react-voice-orb package provides a React component that renders a voice orb widget. This component uses WebRTC for voice calls and WebGL for rendering the animated orb. It is designed for use in React applications and provides an easy-to-integrate solution.

Installation

Install the package using pnpm or npm:

pnpm install @tixae-labs/react-voice-orb@latest

Or

npm install @tixae-labs/react-voice-orb@latest

Usage

Prerequisites

  • Navigate to the TIXAE Dashboard and create an agent.
  • Use the agent id and region parameters to start a voice call from the URL:
    1. agentId - The agent id is a unique identifier for the agent you want to call.
    2. region - The region is the region of the agent you want to call.

For example this URL:

  • The agentId is enit5lczmqbz1s7d and the region is eu.
https://www.tixaeagents.ai/app/eu/agents/enit5lczmqbz1s7d/overview?showDebugger=true&thin=true

Example usage with NextJS 13+ (App Router + TypeScript).

  1. Wrap the page/component with the VoiceProvider and OrbThemeProvider components.
// layout.tsx
"use client";
import React from "react";
import { VoiceProvider, OrbThemeProvider } from "@tixae-labs/react-voice-orb";

const layout = (props: { children: React.ReactNode }) => {
  return (
    <VoiceProvider
      agentId="ox0uepumt3qokr98"
      region="eu"
    >
      <OrbThemeProvider isDark={true} primaryColor="#CBC3E3">
        {props.children}
      </OrbThemeProvider>
    </VoiceProvider>
  );
};

export default layout;
Replace β€œagentId” and β€œregion” with values from your TIXAE Dashboard.
  1. Use the useAIVoice hook and the AudioAnimationOrb component to control the call and display the orb.
// page.tsx
"use client";
import { AudioAnimationOrb, useAIVoice, Spinner } from "@tixae-labs/react-voice-orb";
import React, { useState } from "react";
import { FaCircleStop, FaMicrophone, FaMicrophoneSlash } from "react-icons/fa6";


const page = () => {

  const { webCall, callState, isMuted } = useAIVoice();
  const [showOrb, setShowOrb] = useState(false);

  return (
      <AudioAnimationOrb
        orbPlaceholder={
          <div
            style={{
              width: "100%",
              height: "100%",
              backgroundColor: "#e1e1e1",
              borderRadius: "50%",
            }}
          ></div>
        }
        showOrb={showOrb}
        width={500}
        height={500}
      >
        <div
          style={{
            width: 500,
            height: 500,
            backgroundColor: "rgba(0, 0, 0, 0.1)",
            borderRadius: "100%",
            display: "flex",
            justifyContent: "center",
            alignItems: "center",
          }}
        >
           <div
          className="ta-orb-controls"
          style={{
            display: "flex",
            flexDirection: "column",
            alignItems: "center",
            justifyContent: "center",
            height: "100%",
            width: "100%",
            backgroundColor: "transparent",
            color: "#fff",
            padding: "10px 20px",
            borderRadius: "5px",
          }}
        >
          <button
            className="ta-button"
            style={{
              backgroundColor: callState === "connected" ? "rgba(250, 0, 0, 0.5)" : "rgba(0, 0, 0, 0.5)",
              color: "#fff",
              padding: "10px 20px",
              borderRadius: "100%",
              width: "100px",
              height: "100px",
              display: "flex",
              justifyContent: "center",
              alignItems: "center",
            }}
            onClick={() => {
              if (!showOrb) {
                setShowOrb(true);
                return;
              }
              if (callState === "idle") {
                webCall.startCall();
              } else {
                // tixaeVoice?.endCall();
                webCall.toggleMute();
              }
            }}
          >
            {callState === "idle" ? (
              <FaMicrophone style={{ width: "50px", height: "50px" }} />
            ) : null}
            {callState === "connecting" ? <Spinner /> : null}
            {callState === "connected" ? (
              <>
                {isMuted ? (
                  <FaMicrophoneSlash
                    style={{ width: "50px", height: "50px" }}
                  />
                ) : (
                  <FaMicrophone style={{ width: "50px", height: "50px" }} />
                )}
              </>
            ) : null}
          </button>
          {callState === "connected" ? (
            <>
              <button
                style={{
                  marginTop: `10px`,
                  display: `flex`,
                  alignItems: `center`,
                  justifyContent: `center`,
                  gap: `10px`,
                  padding: `10px 20px`,
                  backgroundColor: `rgba(0, 0, 0, 0.5)`,
                  borderRadius: `10px`,
                }}
                className="ta-button-end"
                onClick={() => {
                  webCall.endCall();
                }}
              >
                End Call
                <FaCircleStop style={{ width: "20px", height: "20px" }} />
              </button>
            </>
          ) : null}
        </div>
        </div>
      </AudioAnimationOrb>
  );
};

export default page;

Sending Extra Messages to the Agent

You can append messages to the conversation by passing options parameters to .init() method, in addition to overriding tools or variables for the agent.

// page.tsx
await voice.init({
  agentId: "LPTp73I6VFsI0jFVFAPr",
  region: "eu",
  options: {
    messagesHistory: [
      {
        role: "assistant",
        content: "Hi there, how can I help you today?",
      },
      {
        role: "user",
        content: "I'm good my name is Moe btw.",
      },
    ],
  },
});

Notes:

  • This packages uses WebRTC to make the voice call, any browser that doesn’t support that might not be compatible with this package.
  • We use WebGL to render the orb, so it might not work on all devices/browsers.
If you have a bug report please open an issue on the GitHub Repository.