JSPM

  • Created
  • Published
  • Downloads 591
  • Score
    100M100P100Q98870F
  • License SEE LICENSE IN LICENSE.md

Package Exports

  • @inworld/nodejs-sdk
  • @inworld/nodejs-sdk/build/src/index.js

This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (@inworld/nodejs-sdk) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.

Readme

Inworld Node.js SDK

Below we will describe how to set up our virtual character integration package for Node.js. Note that this package has TypeScript support.

Installation

Node 16 is recommended. The exact set of compatible Node versions can be found in the engines field of the package.json file.

npm install @inworld/nodejs-sdk

or

yarn add @inworld/nodejs-sdk

Usage

Say hello

Use the following code to say "Hello" to your character.

import {
  InworldClient,
  InworldPacket,
} from '@inworld/nodejs-sdk';

async function sayHello() {
  const client = new InworldClient()
    // Get key and secret from the integrations page.
    .setApiKey({
      key: process.env.INWORLD_KEY!,
      secret: process.env.INWORLD_SECRET!,
    })
    // Setup a user name.
    // It allows character to call you by name.
    .setUser({ fullName: 'Your name' })
    // Setup required capabilities.
    // In this case you can receive character emotions.
    .setConfiguration({
      capabilities: { audio: true, emotions: true },
    })
    // Use a full character name.
    // It should be like workspaces/{WORKSPACE_NAME}/characters/{CHARACTER_NAME}.
    // Or like workspaces/{WORKSPACE_NAME}/scenes/{SCENE_NAME}.
    .setScene(process.env.INWORLD_SCENE!)
    // Attach handlers
    .setOnError((err: Error) => console.error(err))
    .setOnMessage((msg: InworldPacket) => {
      console.log(msg);

      // Close connection.
      connection.close();
    });

  // Finish connection configuration.
  const connection = client.build();

  // Send your message to a character.
  await connection.sendText('Hello');
}

sayHello();

Generate token only

import { InworldClient } from '@inworld/nodejs-sdk';

const run = async function () {
  const token = await getToken();

  // Use token here...
};

const getToken = async function() {
  // Get key and secret from the integrations page.
  const client = new InworldClient()
    .setApiKey({
      key: process.env.INWORLD_KEY,
      secret: process.env.INWORLD_SECRET,
    });

  return client.generateSessionToken();
}

run();

More examples can be found in the examples folder.

API

Capabilities configuration

const capabilities = new Capabilities({ emotions: true });
Name Description Default value
audio If *false, then the client will not receive spoken audio from the characters (text only mode). true
emotions You will receive character emotions. false

Connection configuration

const connection = {
  disconnectTimeout: 10 * 1000, // time in milliseconds
  autoReconnect: false, // true by default
}
Name Description Default value
disconnectTimeout Close connection due to inactivity 60000
autoReconnect Connection will be opened automatically on send if it is closed. Otherwise an existing open connection will be used. Our server closes the connection automatically after 1 minute of inactivity. true

SessionToken

const token = client.generateSessionToken();

// Get a token.
token.getToken();

// Get type (Bearer).
token.getType();

// Get expiration time.
// Token should be regenerated after expiration time.
token.getExpirationTime();

// Get session id.
token.getSessionId();

InworldClient with API KEY

If you prefer to use automatic session management set client key/secret.

const client = new InworldClient();

// ApiKey is required.
client.setApiKey({ key, secret });

// User is not required.
client.setUser(user);

// Configuration is not required.
client.setConfiguration({
  capabilities,
  connection: {
    disconnectTimeout: 10 * 1000, // time in milliseconds
    autoReconnect: false,
  }
});

// Scene is not required for token generation.
// But if you would like to speak with scene characters you need to provide scene full name.
// It should be like workspaces/{WORKSPACE_NAME}/characters/{CHARACTER_NAME}.
// Or like workspaces/{WORKSPACE_NAME}/scenes/{SCENE_NAME}.
client.setScene(scene);

// Event handlers
client.setOnDisconnect(fn);
client.setOnError(fn);
client.setOnMessage(fn);

// Generate SessionAccessToken.
client.generateSessionToken();

// Finish connection configuration.
// Return instance of EventService.
// Сonnection is not open. It's just ready to open on message send.
const connection = client.build();

InworldClient with token

If you prefer to manage session manually you should provide generateSessionToken function instead of client key/secret. It allows you to keep session_id in some storage (for example, redis) and reuse session on application restart. See discord_bot example for more details.

const key = 'character_key';

async function generateSessionToken() {
  const client = new InworldClient()
    .setApiKey({
      key: process.env.INWORLD_KEY,
      secret: process.env.INWORLD_SECRET,
    });
  const token = await client.generateSessionToken();

  const sessionId = await redisClient.get(key);
  const actualToken = new SessionToken({
    expirationTime: token.getExpirationTime(),
    token: token.getToken(),
    type: token.getType(),
    sessionId: sessionId ?? token.getSessionId(),
  });

  if (!sessionId) {
    redisClient.set(key, actualToken.getSessionId());
  }

  return actualToken;
}

const client = new InworldClient();

// User is not required.
client.setUser(user);

// Configuration is not required.
client.setConfiguration({
  capabilities,
  connection: {
    disconnectTimeout: 10 * 1000, // time in milliseconds
    autoReconnect: false,
  }
});

// Scene is not required for token generation.
// But if you would like to speak with scene characters you need to provide scene full name.
// It should be like workspaces/{WORKSPACE_NAME}/characters/{CHARACTER_NAME}.
// Or like workspaces/{WORKSPACE_NAME}/scenes/{SCENE_NAME}.
client.setScene(scene);

// Event handlers
client.setOnDisconnect(fn);
client.setOnError(fn);
client.setOnMessage(fn);

// Generate SessionAccessToken.
// It will be called only if currect token is empty or expired.
client.setGenerateSessionToken(generateSessionToken);

// Finish connection configuration.
// Return instance of EventService.
// Сonnection is not open. It's just ready to open on message send.
const connection = client.build();

InworldConnectionService

const connection = client.build();

// Open connection manually. Available only if configuration.connection.autoReconnect = false.
// Otherwise connection will be managed automatically by SDK.
connection.open();

// You can check if the connection is open or not in case of configuration.connection.autoReconnect = false.
connection.isActive();

// Send text message.
const sentPacket = connection.sendText(message);

// Send trigger. Pass trigger name as parameter.
const sentPacket = connection.sendTrigger(name);

// Send audio start event before call sendAudio.
const sentPacket = connection.sendAudioSessionStart();

// Send audio end event after all audio chunks you would like to send.
const sentPacket = connection.sendAudioSessionEnd();

// Send audio. Pass string chunk as parameter.
const sentPacket = connection.sendAudio(chunk);

// Send a cancel response.
const sentPacket = connection.sendCancelResponse();

// Close connection.
connection.close();

// Get a character list.
connection.getCharacters();

// Get the current character.
connection.getCurrentCharacter();

// Change character in the scene.
connection.setCurrentCharacter(character);

Character

const character = connection.getCurrentCharacter();

// Character id.
character.getId();

// Character resource name.
character.getResourceName();

// Character display name.
character.getDisplayName();

InworldPacket

client.setOnMessage((packet: InworldPacket) => {...});

// ISO string.
packet.date

// It's a text event.
packet.isText()

// Get message of text event.
packet.text.text
packet.text.final

// Get emotions.
packet.emotion.joy
packet.emotion.fear
packet.emotion.trust
packet.emotion.surprise

// Get behavior affected by emotions.
packet.emotion.behavior.isNeutral()
packet.emotion.behavior.isDisgust()
packet.emotion.behavior.isContempt()
packet.emotion.behavior.isBelligerence()
packet.emotion.behavior.isDomineering()
packet.emotion.behavior.isCriticism()
packet.emotion.behavior.isAnger()
packet.emotion.behavior.isAnger()
packet.emotion.behavior.isTension()
packet.emotion.behavior.isTenseHumor()
packet.emotion.behavior.isDefensiveness()
packet.emotion.behavior.isWhining()
packet.emotion.behavior.isSadness()
packet.emotion.behavior.isStonewalling()
packet.emotion.behavior.isInterest()
packet.emotion.behavior.isValidation()
packet.emotion.behavior.isAffection()
packet.emotion.behavior.isHumor()
packet.emotion.behavior.isSurprise()
packet.emotion.behavior.isJoy()

// Get strength of the emotion.
packet.emotion.strength.isWeak()
packet.emotion.strength.isStrong()

// It's an audio event.
packet.isAudio()

// Get chunck of audio event.
packet.audio.chunk

// It's a trigger event.
packet.isTrigger()

// It's an emotion event.
packet.isEmotion()

// It's a control event.
packet.isControl()

// It's a special control event. It means that interaction ends.
packet.isInteractionEnd();

Error handling

import {
  status,
} from '@inworld/nodejs-sdk';

handleError(err: ServiceError) {
  switch (err.code) {
    // Cancelled by server due timeout inactivity.
    case status.ABORTED:
    // Cancelled by client.
    case status.CANCELLED:
      break;
    default:
      console.error(err);
      break;
  }

You can read more about states here.

ENVIRONMENT

Use these environment variables for local debugging of the package.

Name Description Deafult value
NODE_SDK_INWORLD_STUDIO_HOST Studio host api-studio.inworld.ai:443
NODE_SDK_INWORLD_STUDIO_SSL Define Studio connection will be secure or not true
NODE_SDK_INWORLD_ENGINE_HOST Engine host api-engine.inworld.ai:443
NODE_SDK_INWORLD_ENGINE_SSL Define Engine connection will be secure or not true

License

https://www.inworld.ai/sdk-license