Session State Management
Overview
There are two ways that a Skill can choose to manage session state:
Since Skills are designed to be implemented as webhooks, they are often implemented as a serverless function and hosted over a cloud platform, like an Azure Function or an AWS Lambda.
A Skill can manage session states in a Stateless
way, where it does not need the capacity to store nor persist data across multiple calls to the same Skill. Therefore, it is more common for a Skill to be Stateless
, especially when implemented as a cloud function that is executed on-demand and without any storage associated.
Alternatively, session states can be managed in a Stateful
way by Skills that can both contain and maintain data across multiple calls. This is supported by having additional resources, which the Skill can preload and initialize before each session, to help with data persistence.
Stateless
This allows the Skill to be lightweight and set up easily. However, the Skill will lack the ability to keep track of significant events or actions during the same session.
Should your Skill require data storage and persistency but does not have the resources to be configured in a Stateful
way, you may choose to use Memory to maintain the 'state' manually.
A Skill's Memory is only retained for the duration of each session and cleared upon each session ends.
Refer to working with Memory for more details.
Since being Stateless
does not require the configuration of endpointSession
, calls to its endpointExecute
within the same session will always contain the config
property where it persists pre-configured config values of the Skill.
Stateful
When session states are managed via the Stateful
way, Soul Machines provides the session
endpoint that can be configured in your Skill Definition file under endpointSession
. This allows your Skill to preload and initialize additional resources required for session state management.
{
"name": "My Skill",
"summary": "skill summary here",
"description": "",
"endpointExecute": "https://yourname.loca.lt/execute",
// ... other skill properties
"endpointSession": "https://yourname.loca.lt/session",
"config": {
// skill config here
}
}
This endpoint will subsequently be called once during the start of each session.
Depending on your Skill's Service Provider, this endpoint should allow for the Skill's State to be set up accordingly.
NLP Adapter Skill
When building an NLP Adapter Skill, it uses SKILL_API
as the Service Provider. As such, the requests sent to endpointExecute
will no longer contain the config
property anymore for this skill, for as long as the endpointSession
is configured.
The requests received by endpointInit
and endpointSession
will still contain the config
property, as highlighted in Lifecycle Hooks.
You will need to account for this if your Skill requires this config
property to perform specific actions.
Stateful
management also gets access to Memory, similar to Stateless
.
Example of the Session
endpoint
- ExpressJS
- Python
app.post('/session', async (req: Request, res: Response) => {
// Get the Soul Machines request object
const smRequest = req.body as ExecuteRequest;
// Extract relevant data such as config, memory and sessionId as required
const { memory: smMemory, config: smConfig, sessionId } = smRequest;
// @TODO: Preload your Skill's required resources before each session starts, as required
const fakeNLPService = new FakeNLPService();
fakeNLPService.initSessionResources(sessionId, smConfig, smMemory);
// @TODO: Persist data in Memory as required
const dataToPersist = fakeNLPService.persistData(sessionId) as Memory[];
const memory: Memory[] = [
...smMemory,
...dataToPersist,
];
// Construct SM-formatted response body
const smResponse: SessionResponse = {
memory,
// other response properties here
};
res.send(smResponse);
});
@router.post("/session", status_code=200, response_model=SessionResponse, response_model_exclude_unset=True)
async def session(request: SessionRequest) -> SessionResponse:
# Extract relevant data such as config, memory and sessionId as required
skill_config, skill_memory, session_id = attrgetter("config", "memory", "sessionId")(request)
# TODO: Preload your Skill's required resources before each session starts, as required
fake_nlp_service = FakeNLPService()
fake_nlp_service.init_session_resources(session_id, skill_config, skill_memory)
# TODO: Persist data in Memory as required
data_to_persist = fake_nlp_service.persist_data()
set_memory_value(memories=skill_memory, data_to_persist)
# Construct SM-formatted response body
response = SessionResponse(
memory=skill_memory,
# ... add your other required kwargs here
)
return response
For more information about this endpoint, refer to the API reference - Session.