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

@soulmachines/smskillsdk

v1.4.0-rc.0

Published

NodeJS package for the Soul Machines Skill API

Downloads

75

Readme

smskillsdk (NodeJS)

The Skills NodeJS SDK package contains data types for the session and execute endpoints specified within the Skills REST API, along with a range of utility functions for working with the memory data structure.

Installation

This package is intended for use with NodeJS 14 and above.

npm install @soulmachines/smskillsdk

Usage

Accessing request/response models

import {
  SessionRequest,
  SessionResponse,
  ExecuteRequest,
  ExecuteResponse,
} from "@soulmachines/smskillsdk";

Sub-models used within these request and response models can also be imported using

import { Output, Intent, Variables } from "@soulmachines/smskillsdk";

In general, a developer should implement separate handler functions for the session and execute endpoints which takes a SessionRequest or ExecuteRequest as an argument and returns a SessionResponse or ExecuteResponse respectively. These objects can be serialized to JSON and returned within the HTTP response body. An example implementation of a handler function for generating an ExecuteResponse and a route method is shown below.

// execute endpoint handler containing response generation logic
function executeHandler(request: ExecuteRequest): ExecuteResponse {

    // response generation logic here

    const variables = {
        "public": {
            "card": { ... }
        }
    } as Variables;

    const output = {
        "text": "Text for the digital person to speak",
        variables
    } as Output;

    const response = {
        output,
        "memory": [],
        "endConversation": true
    } as ExecuteResponse;
    return response;
}

// route method
app.post("/", (req, res) => {
    const executeRequest = request.body as ExecuteRequest;
    const executeResponse = executeHandler(executeRequest);
    response.json(executeResponse);
})

Working with memory

The memory field within the request and response models of the session/execute endpoints can be used to persist state between conversation turns and share information between skills within a single session.

The data structure is comprised of an array of Memory objects

class Memory {
    name: string;
    value: any | null;
    sessionId?: string;
    scope?: MemoryScope;
}

where the name field acts as a key. The optional sessionId field can be used to differentiate between objects having the same name value, while the optional scope field can be used to control whether objects are shared between skills or remain private to a single skill (the default scope is MemoryScope.Private). Setting scope: MemoryScope.Public will mean that this particular memory object will be viewable and editable by all skills within a particular session.

Note that memory objects with the same name but different session ID/scope will be treated as unique.

We offer a range of utility functions to work with the memory data structure:

serializeMemory(data: Record<string, unknown>, sessionId?: string, scope?: MemoryScope): Array<Memory>

Converts an object into an array of memory objects with an optional session ID and scope.

Arguments:

  • data: Record<string, unknown>: An object to be converted; keys should be strings
  • sessionId: string: An optional session ID to be assigned to each memory object
  • scope: MemoryScope: An optional scope to determine if the memory objects should be able to be shared with other skills within the session (default: MemoryScope.Private)

Returns:

  • Array<Memory>: An array of memory objects

deserializeMemory(memories: Array<Memory>, sessionId?: string, scope?: MemoryScope): Record<string, unknown>

Converts an array of memory objects into an object, filtered using an optional session ID or scope value. If there are multiple valid memory objects with the same name, the value closest to the end of the memories array will be returned.

Arguments:

  • memories: Array<Memory>: An array of memory objects to be converted
  • sessionId?: string: If provided, will only deserialize memory objects with a matching session ID
  • scope: MemoryScope: If provided, will only deserialize memory objects with a matching scope (otherwise all memory objects will be treated as valid)

Returns:

  • Record<string, unknown>

setMemoryValue(memories: Array<Memory>, name: string, value: unknown, sessionId?: string, scope?: MemoryScope)

Sets a value in an array of Memory objects corresponding to a Memory name and optional session ID or scope. If an object with a matching name/session ID/scope exists, its value will be overwritten.

Arguments:

  • memories: Array<Memory>: The array of Memory objects which will be operated on
  • name: string: The name of Memory to search for
  • value: unknown: The value to set
  • sessionId: string: If provided, only Memory objects with a matching session ID will be considered; if none are found, a new memory object with a session ID will be created
  • scope: MemoryScope: If provided, only Memory objects with a matching scope will be considered (defaults to MemoryScope.Private)

Returns:

  • No return value, the array of memory objects is modified in-place

getMemoryValue(memories: Array<Memory>, name: string, sessionId?: string, scope?: MemoryScope): [boolean, unknown]

Retrieves the first valid value from an array of memory objects corresponding to a Memory name and optional session ID or scope value.

Arguments:

  • memories: Array<Memory>: The array of Memory objects to be searched
  • name: string: The name of Memory to search for
  • sessionId: string: If provided, only Memory objects with a matching session ID will be considered
  • scope: MemoryScope: If provided, only Memory objects with a matching scope will be considered (otherwise all Memory objects will be considered)

Returns:

  • [boolean, unknown]: A flag indicating whether the Memory was found and its corresponding value; this can be unpacked as shown below
let found, value;
[found, value] = getMemoryValue(memories, "name", "sessionId");

Common session memory values

We have defined two memory objects which can be used to share information in a common format between skills:

interface UserIdentity {
  firstName?: string;
  lastName?: string;
  preferredName?: string;
  id?: string;
}

interface UserLocation {
  city?: string;
  country?: string;
}

Users may define their own objects to work across their skills, or to expose information to other skills. These values can be set and retrieved from a memory array using the following helper functions:

  • setUserIdentity(memories: Array<Memory>, firstName?: string, lastName?: string, preferredName?: string, id?: string): void
  • getUserIdentity(memories: Array<Memory>): UserIdentity | null
  • setUserLocation(memories: Array<Memory>, city?: string, country?: string): void
  • getUserLocation(memories: Array<Memory>): UserLocation | null