Skip to content
RasaGet a free licence
Menu

tutorial

Chapter 4 of 6

Rasa project memory: stop callers re-authenticating

by Rod Rivera Published

The layer that stops the caller re-authenticating: facts about the session that every skill can read.

Back to the bank transfer that makes you identify yourself twice. In Mantle the fix is project memory — declared once at the root, readable and writable by every skill.

# memory.yml
authenticated:
  type: bool
  description: Whether the caller has proven their identity this session.
customer_id:
  type: text
  description: Meridian customer id, set once identity is proven.
preferred_language:
  type: text
  description: Language the customer asked to be served in.
  initial_value: en

These are facts about the session and the end user, not about one skill’s workflow. Is the caller verified. Who are they. What language do they want.

Writing it

The authentication tool writes with a bare name:

context.memory.set("customer_id", customer["customer_id"])
context.memory.set("authenticated", True)

The slice resolves a bare name against the active skill first, then the project. Reads may also use a qualified name:

customer_id = context.memory.get("project.customer_id")

The companion reads project.customer_id and writes the bare name customer_id. Use those same forms when tracing the example’s tools. Write bare, read either way.

Reading it

Both of the other skills’ tools open the same way:

customer_id = context.memory.get("project.customer_id")
if not customer_id:
    return ToolResult(llm_response={"ok": False, "error": "not_authenticated"})

That is the whole trick. authenticate ran, wrote the id, and every later skill picks it up. The caller is asked once.

Put the guardrail in the tool, not the prose

It is tempting to write the check into the instructions:

If the caller is not verified, ask them to sign in first.

Resist it. The tool already knows, deterministically, and a tool cannot be talked out of its answer. So the instruction branches on the tool’s result instead:

`fetch_balance` reads the signed-in customer from project memory, so it is the
authority on whether the caller is verified. If it returns `not_authenticated`,
tell the caller you need to verify them first and let the Authenticate skill
run. Never state a balance in that case.

The model is deciding what to say. The tool is deciding what is true.

Check whether the shared value can change

In the pinned 3.21.0.dev5 runtime, the memory manager rejects a project-slot write when that slot already holds a value other than None. Its field declaration has no immutable member. Do not copy an older immutable setting into this example and assume it supplies the same behaviour.

For a customer ID, trace both the first write and an attempted later change. Establishing the ID does not replace the sign-in check, and sharing it across skills does not authorise every banking action. The transfer tool still needs its own task-specific checks.

You can inspect the rule in your installed version without calling a model:

import inspect
from rasa.mantle.memory.manager import MemoryManager
print(inspect.getsource(MemoryManager._reject_if_project_already_set))

That is a source-inspection step for the tutorial’s pinned release, not an additional configuration option. Recheck it when changing the runtime version.