npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@sindarin/persona

v0.0.23

Published

Sindarin Persona SDK

Downloads

128

Readme

Sindarin Persona SDK for Web Browsers

Version

Sindarin Persona enables you to add lifelike conversational speech AI agents to your webapp. It features ultra low latency, industry-leading turn-taking and transcription, and high-fidelity speech synthesis.

Demo: https://sindarin.tech

Installation

Install the package with:

npm install @sindarin/persona
# or
yarn add @sindarin/persona

or

var script = document.createElement("script");
script.src = "https://api.prod.centralus.az.sindarin.tech/PersonaClientPublicV2?apikey=<YOUR_CLIENT_KEY>";
script.onload = () => {
  var personaClient = new window.PersonaClient.default("<YOUR_CLIENT_KEY>");
  // ... initialize, etc
};
document.head.appendChild(script);

Usage

The package needs to be configured with your account's secret key, which is available in the Persona Web App / Settings.

import PersonaClient from "@sindarin/persona";

const personaClient = new PersonaClient("<YOUR_CLIENT_KEY>");

const handleStartChatButtonClick = async () => {
  // Example config using a persona defined in the Playground; there are many ways to do things!
  const config = {
    userId: "admin",
    personaName: "John",
    options: {
      debugMode: true,
      streamTranscripts: true,
      shouldNotSaveConversation: true,
    },
  };

  try {
    await personaClient.init(config);
    configurePersonaEvents();
  } catch (error) {
    console.log(error);
  }
};

const handlePauseChatButtonClick = async () => {
  try {
    await personaClient.pause();
  } catch (error) {
    console.log(error);
  }
};

const handleResumeChatButtonClick = async () => {
  try {
    await personaClient.resume();
  } catch (error) {
    console.log(error);
  }
};

const handleStopChatButtonClick = async () => {
  try {
    await personaClient.end();
  } catch (error) {
    console.log(error);
  }
};

const handleUpdateState = async (newState) => {
  try {
    personaClient.updateState(newState);
  } catch (error) {
    console.log(error);
  }
};

const handleReactTo = async (thought) => {
  try {
    personaClient.reactTo(thought);
  } catch (error) {
    console.log(error);
  }
};

const configurePersonaEvents = () => {
  personaClient.on("messages_update", (messages) => {
    console.log(messages);
  });

  personaClient.on("state_updated", (newState) => {
    console.log(newState);
  })

  personaClient.on("action", (action) => {
    console.log(action);
  })
};

Configuration

Initialize with config object

You can initialize a conversation with the following config fields:

const config = {
  userId: "admin", // optional
  personaName: "John", // optional
  personaId: "example_id", // optional; this is found in the Persona Playground
  details: { firstName: "John" }, // optional; arbitrary data you can inject into your prompt with {{details.x}}
  metadata: { orderId: "1" }, // optional; arbitrary data used for conversation retrieval / filtering later
  personaConfig: {
    initialMessage: "Hello {{details.firstName}}!",
    prompt: "You are a fun and helpful persona.",
    actions: { properties: {} },
    ttsConfig: {
      voiceId: "example_id", // voice IDs can be found and tested in the Playground
    },
    llmConfig: {
      llm: "example_llm_name", // e.g. llama-3-70b, llama-3-8b, gpt-4o, hermes-2-mixtral-8x7B-dpo
      temperature: 0.8, // 0 to 1
      repetitionPenalty: 1 // -3.5 to 3.5 for non-openai models; -2 to 2 for openai models
    },
    interjections: { // the ability for the persona to speak spontaneously
      enabled: true,
      minWait: 7500,
      maxWait: 10000,
      thought: "Nobody has said anything in a while. I should nudge the conversation along."
    },
    chargeLimitEnabled: true, // optional; should the conversation be cut off after a certain amount of charges incurred?
    chargeLimit: 2, // optional; the charge limit
    lifecycleEvents: { // optional; if the webhook endpoint returns { state } or { details } in the response body, they will be injected
      onInit: {
        webhook: {
          url: "http://your-webhook-url/init",
          method: "POST",
          body: {},
          headers: "Bearer xyz"
        }
      },
      onStateChange: { /* ... */ },
      onEnd: { /* ... */ }
    }
  },
  options: {
    debugMode: true, // emit debug events in messages
    streamTranscripts: true, // stream transcripts in realtime
    shouldNotSaveConversation: true, // do not save transcripts
  },
};

try {
  await personaClient.init(config);
} catch (error) {
  console.log(error);
}

| Option | Default | Description | | ----------------------------------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------ | | userId | null | [Optional] Your unique ID for the current user. | | personaName | null | [Optional; this or personaId or personaConfig required] The persona name in the Playground specifying a particular persona config. | | personaId | null | [Optional; this or personaName or personaConfig required] The persona ID in the Playground specifying a particular persona config. This takes priority over personaName if both are provided. | | details | null | [Optional] An object containing arbitrary information that you can inject into your prompt before the conversation starts using {{details.x}}. | | metadata | null | [Optional] An object containing arbitrary information for the developer to retrieve the conversation by. | | personaConfig | null | [Optional; this or personaName or personaId required] An ad hoc persona configuration specified entirely in your code. | | options | - | [Optional] Additional options (below). | | options.debugMode | false | Messages array will contain additional debug events (info, warn, error) for debugging purposes during a conversation. | | options.streamTranscripts | false | Temporary transcripts will be rendered in the messages array. | options.shouldNotSaveConversation | false | If true, the transcript will not be saved after the conversation ends. |

Error Handling Options

try {
  await personaClient.init(config);
} catch (error) {
  console.log(error);
}

personaClient.on("error", (error) => {
  console.log(error);
});

personaClient.on("connect_error", (error) => {
  console.log(error);
});