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
Provider | Supported |
---|---|
SM Skills API | ✅ |
Azure Bot | ⛔️ |
Dialogflow ES | ⛔️ |
Dialogflow CX | ⛔️ |
Watson Assistant V1 | ⛔️ |