Home/Documentation
Voice Memory · Concepts

Voice Memory concepts

MemoAir Voice has two model surfaces every integrator needs to internalise: the identity model (account → project → agent → end-user) and the four memory lanes (profile, working, permanent, org). Identity decides whose memory is in scope; lanes decide what kind of memory it is.

Identity model — account, project, agent, end-user

MemoAir Voice runs four nested levels of identity. Each layer narrows scope; together they answer which voice bot, in which workspace, owned by which company, is talking to which caller right now.

account              "Fundamento" — your company, one MemoAir org
└── project          "Acme support bot project" — proj_acme
    └── agent        "Acme returns concierge" — agent_returns
        └── end-user "caller hash 0xab12…" — varies per call
  • Account. One MemoAir org per company. Holds billing, the account API key, the team roster. There is exactly one memoair_pk_… key per account; it works against every project and agent in the org.
  • Project. A workspace inside the account — usually one per customer or one per product surface. Owns its own org index, profiles, permanent memory, and agents. Identified by a stable proj_… ID.
  • Agent. A voice bot identity inside a project — usually one per use-case ("returns concierge", "triage IVR", "onboarding tutor"). Owns its prompt version, eval suite, dashboard analytics. Identified by agent_….
  • End-user. The caller on the other end of the audio link — a phone-number hash, a logged-in user_id, a session token. Per call, not per process. Owns the profile and permanent lanes; routed via per-call user={id,name,metadata} through the SDK runtime pool.

Wire format on every cloud call

The SDK attaches all four identity layers as headers when it talks to MemoAir cloud. The runtime pool fills these in for you; you only need to construct MemoAirVoiceClient with the first three and pass user per call.

Authorization: Bearer memoair_pk_<...>
X-Project-Id:  proj_<...>
X-Agent-Id:    agent_<...>
X-User-Id:     <your end-user id>
Profile

Stable identity, preferences, constraints.

A compact, versioned snapshot of who the user is. Always rendered first when non-empty. Beats any conflicting permanent statement on the same canonical attribute.

Working brief

What was just said this call.

The current call's running summary. Maintained on disk per session and surfaced before permanent and org hits so the model always has tight short-term context.

Permanent

User-scoped facts that survive across sessions.

Extracted from prior calls and synced down to the runtime as a per-user .mv2 projection. Recalled by vector similarity against the live query.

Org

Shared knowledge across the workspace.

Documents, FAQs, policies, runbooks — anything ingested at the workspace level. The same projection format as permanent, but scoped to the whole workspace rather than one user.

Trust hierarchy

When the same statement appears across lanes the composer keeps the highest-trust version and discards duplicates:

profile  >  working  >  permanent  >  org

That means a freshly captured profile attribute will override a stale permanent fact about the same attribute, and the working brief will always rank above static facts inside the same call.

Where the writes happen

  • Per turn: the SDK calls after_turn(...); the runtime appends to a session JSONL and to an outbox that streams back to MemoAir cloud.
  • Per session end: the runtime flushes the working brief and pushes the outbox before returning from end_session.
  • Cloud-side, asynchronously: a consolidation job distills the session JSONL into permanent facts and rebuilds the user’s .mv2 projection.
  • Next call start: bootstrap pulls the new manifest version and applies the delta (or downloads a fresh snapshot) before start_session returns.

Identity binding (runtime layer)

A voice-runtime process is single-tenant by design — each process pins one (project_id, user.id) at boot and refuses mismatched calls with runtime.identity_mismatch. That isolation guarantee is enforced at the runtime, not the SDK.

The SDK delivers concurrent users on top of that single-tenant contract by managing a pool of runtimes inside MemoAirVoiceClient: one runtime per (project_id, user.id), bounded LRU, per-call routing through user={...}. See the RuntimePool section in the SDK reference for capacity tuning.