Skip to main content

Configuring Memories

The Memory feature of the Skills Platform allows a Skill to store key-value pairs for the duration of a session, and retrieve those values on any subsequent Skill execution. These values may be PRIVATE only to the Skill that created them, or PUBLIC so that other Skills may also access these values.

When to use Memory

Skills are often implemented in a stateless way, so that they do not have the capacity to store or persist data across multiple calls to the Skill. This is most common when the Skill is implemented as a Cloud Function which is executed on-demand and does not have any storage associated.

The Memory feature of the Skills API allows a Skill developer to use the Skills Platform itself as a storage location for data that needs to be accessed repeatedly during a session.

A Skill may also use the Memory feature to expose valuable data for other Skills to consume. For example, if a Skill is designed to capture the user's name or email address, it may make those values PUBLIC so that other Skills do not need to request the same data again.

Memories are only persisted for the duration of the session. All Memory values are cleared when the session ends.

The Memory feature of the Skills API is always available to any programmatic Skill created using the Skill API.

Structure of a Memory

A memory is a simple object containing a key (name) and a value. The memory has a session_id associated with it, and has a scope which determines if the memory is PUBLIC and available to all Skills , or PRIVATE and only available to the Skill that created it.

type Memory {
name: string;
value: any;
session_id?: string;
scope?: 'PUBLIC' | 'PRIVATE';
}

Example memory:

const colorMemory = {
name: 'favorite-color',
value: 'blue',
session_id: 'xxx-xxx-xxx',
scope: 'PUBLIC',
};

Reading a Memory

Memory values can be accessed from the ExecuteRequest object under the req.memory property.

The memory values will include any PRIVATE memories created by this Skill, plus any PUBLIC memories created by this Skill or any other Skill used during the current session.

The SkillSDK libraries offer helper functions for working with memory.

Using the Python SkillSDK:

from smskillsdk.utils.memory import get_memory_value

def execute_handler(req: ExecuteRequest) -> ExecuteResponse:

favorite_color = get_memory_value(req.memory, "favorite_color", req.sessionId)
spoken_response = "Your favorite color is " + favorite_color + "."

return ExecuteResponse(
output=Output(text=spoken_response),
memory=req.memory,
endConversation=True
)

Using the Node SkillSDK:

import { getMemoryValue } from '@soulmachines/smskillsdk/utils/memory';

public executeHandler(req: ExecuteRequest): ExecuteResponse {

const [hasColorMemory, colorValue] = getMemoryValue(req.memory, 'favorite_color');
const spokenResponse = `Your favorite color is ${colorValue}.`;

console.log('all memory values:', req.memory);
console.log('favorite_color memory exists:', hasColorMemory);
console.log('favorite_color value:', colorValue);

const response: ExecuteResponse = {
output: {
text: spokenResponse
},
memory: req.memory,
endConversation: true,
};

return response;
}

Creating a Memory

A Skill's set of PRIVATE memories must be intentionally persisted by the Skill during each execute request. This can be achieved by capturing any memory values from the request, modifying those memory values as needed, and then including the same full set of values in the response.

Only memory values returned with each request will be persisted to the next request.

The SkillSDK libraries provide helper functions for working with memory.

from smskillsdk.utils.memory import set_memory_value

def execute_handler(req: ExecuteRequest) -> ExecuteResponse:

set_memory_value(req.memory, 'favorite_color', req.text, req.sessionId)

return ExecuteResponse(output=Output(text=req.text), memory=req.memory, endConversation=True)
import { setMemoryValue } from '@soulmachines/smskillsdk/utils/memory';

function execute_handler(req: ExecuteRequest): ExecuteResponse {
setMemoryValue(req.memory, 'favorite_color', req.text, req.sessionId);

return ExecuteResponse(
(output = Output((text = req.text))),
(memory = req.memory),
(endConversation = True)
);
}

Simple Memories

Only the 'name' and 'value' are required:

memory: [
{
name: 'favorite-color',
value: 'blue',
},
];

Public (Shared) Memories

Memories are private by default, but can be optionally set to public:

memory: [
{
name: 'favorite-color',
value: 'blue',
scope: 'PUBLIC',
},
];

Complex Memories

Memories can be objects, so long as they are JSON-serializable:

memory: [
{
name: 'favorite-color',
value: {
id: 123,
label: 'blue',
hex: '#0000FF',
},
},
];

Multiple Memories

More than one memory can be set at a time:

memory: [
{
name: 'favorite-color',
value: 'blue',
},
{
name: 'favorite-animal',
value: 'rabbit',
},
];

Deleting a Memory

Memories may only be modified by the Skill that created them, even if the memory value is in PUBLIC scope. Memories in PRIVATE scope may be deleted, but memories in PUBLIC scope can only be set to a falsy value - they cannot be deleted entirely.

Deleting Private Memories

Private memories may be deleted by simply leaving the Memory out of the ExecuteResponse:

public executeHandler(req: ExecuteRequest): ExecuteResponse {
// request contains two memory values from a previous execution
const colorMemory = req.memory.find((m) => m.name === 'favorite-color');
const animalMemory = req.memory.find((m) => m.name === 'favorite-animal');

// only keep the animal memory,
// forget the color memory
const newMemorySet = [animalMemory];

// use the edited memories in the response
const res: ExecuteResponse = {
output: {
text: 'A sample response',
variables: {
public: { }
}
},
intent: {
name: 'Sample_Intent',
confidence: 0.5
},
memory: newMemorySet, // <-- return the new memory set
endConversation: true
}

return res;

}

Deleting Public Memories

Public memories can not be deleted, but their values can be unset to signify that the memory has been cleared:

public executeHandler(req: ExecuteRequest): ExecuteResponse {
// request includes a PUBLIC memory created by this skill
// in a previous execution:
// {
// name: 'favorite-color',
// value: 'blue',
// scope: 'PUBLIC',
// }
const colorMemory = req.memory.find((m) => m.name === 'favorite-color');

// edit the memory to clear the value
colorMemory.value = false;

// return the edited memory in the response
const res: ExecuteResponse = {
output: {
text: 'A sample response',
variables: {
public: { }
}
},
intent: {
name: 'Sample_Intent',
confidence: 0.5
},
memory: [
colorMemory // <-- return the edited memory
],
endConversation: true
}

return res;

}

Supported Skill Providers

ProviderSupported
SM Skills API
Azure Bot⛔️
Dialogflow ES⛔️
Dialogflow CX⛔️
Watson Assistant V1⛔️