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-sdkor
yarn add @inworld/nodejs-sdkUsage
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.generateSessionToken(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 chuck 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.chuck
// 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 |