Advanced: Cross-Session Working Memory Handoff

Updated at:

Hand work off across sessions with a memory store — API creation and writes, file-tool reads/writes in-session, read-only handoff, version history and conditional-update conflicts, and the mounting-time boundary.

Overview

This page covers using a memory store (Memory Store) for cross-session handoff: one session writes verified facts and progress into working notes, and the next session reads those notes and continues without a re-briefing. The mechanism: a resource tree independent of sessions → mounted at session creation → read and written with file tools in-session → read back and versioned over the API.

Scenario: the next session picks up where the last one stopped

Every new session on a long-running project needs the same briefing again — project code, verified numbers, unfinished work. Writing the handoff into a place that persists across sessions, and having the new session read those notes first, is the closest thing to a human shift handover.

The full chain with a memory store: create the store → write an initial note → mount it read-write in a session that completes the work → write back verified conclusions → mount it read-only in the next session to pick up the conclusions.

Pick the right memory product first

NeedProduct and isolation model
Project notes, work progress, cross-session handoffMA memory store: mount an independent file tree via the session's resources
Per-UserId personal preferences and personalized memoryBailian Memory: a separate product with its own API

metadata.user_id does not isolate memory store content automatically: sessions sharing one store share its content. When isolation is required, allocate a separate store per business subject and validate access ownership on the business side.

Request sequence

1. Create the memory store

curl -s -X POST "$AGENTSTUDIO_URL/memory_stores" \
  -H "Authorization: Bearer $DASHSCOPE_API_KEY" -H "Content-Type: application/json" \
  -d '{"name": "project-notes", "description": "Work handoff"}'

Returns a memory store ID with the memstore_ prefix. Full parameters: Create Memory Store API.

2. Write the initial note

curl -s -X POST "$AGENTSTUDIO_URL/memory_stores/$STORE_ID/memories" \
  -H "Authorization: Bearer $DASHSCOPE_API_KEY" -H "Content-Type: application/json" \
  -d '{"path": "/notes/handoff.md", "content": "Project code is ORCHID-73."}'

Returns a memory ID with the mem_ prefix — keep it for the read-back later.

3. Mount at session creation (read_write)

Mount the store as a session resource, with instructions stating the handoff requirements:

curl -s -X POST "$AGENTSTUDIO_URL/sessions" \
  -H "Authorization: Bearer $DASHSCOPE_API_KEY" -H "Content-Type: application/json" \
  -d '{
    "agent": {"id": "<agent_id>"},
    "environment_id": "<environment_id>",
    "resources": [{
      "type": "memory_store",
      "memory_store_id": "<memory_store_id>",
      "access": "read_write",
      "instructions": "Read the working notes first; after finishing the task, write verified facts back to the notes. Use file tools, not bash."
    }]
  }'

4. Read and write the notes in-session

The server-side mount path is /mnt/memory/<name>/…. Use the platform-provided path; do not construct an ordinary local directory:

Read /mnt/memory/project-notes/notes/handoff.md.
Keep the existing content, then append one line: Verified total is 350.
Use file tools, not bash.

Warningbash cannot reach this memory file tree. Read and write memories with the write / read / edit file tools; state "use file tools, not bash" in instructions as well.

5. Read back over the API

After the session ends, read back to confirm the write persisted:

curl -s "$AGENTSTUDIO_URL/memory_stores/$STORE_ID/memories/$MEMORY_ID" \
  -H "Authorization: Bearer $DASHSCOPE_API_KEY"

In testing, this response's content contained both the original line Project code is ORCHID-73. and the appended Verified total is 350.

6. Hand off in a second session, read-only

The new session mounts the same store with access set to read_only, so the receiving side reads the updated notes:

curl -s -X POST "$AGENTSTUDIO_URL/sessions" \
  -H "Authorization: Bearer $DASHSCOPE_API_KEY" -H "Content-Type: application/json" \
  -d '{
    "agent": {"id": "<agent_id>"},
    "environment_id": "<environment_id>",
    "resources": [{
      "type": "memory_store",
      "memory_store_id": "<memory_store_id>",
      "access": "read_only"
    }]
  }'

In testing, the read-only session correctly read both ORCHID-73 and 350; asked to append a line, it refused before ever issuing a write call, and the API read-back confirmed the content was unchanged. Even if the receiving agent is configured with write tools, mount its memory store as read_only — a second line of defense.

7. Version history and conditional updates

GET /memory_stores/{store_id}/memory_versions returns the version history (in testing: create and modify operations). When multiple writers modify the same memory concurrently, use a conditional update to avoid clobbering: include the content_sha256 returned by the previous read in the update body:

curl -s -X POST "$AGENTSTUDIO_URL/memory_stores/$STORE_ID/memories/$MEMORY_ID" \
  -H "Authorization: Bearer $DASHSCOPE_API_KEY" -H "Content-Type: application/json" \
  -d '{
    "content": "<updated full body>",
    "precondition": {
      "type": "content_sha256",
      "content_sha256": "<hash from the previous read>"
    }
  }'

type is the required condition type field. In testing: the current hash updated successfully; a stale hash returned HTTP 409 with error code memory_precondition_failed_error, and the newer content stayed intact. On conflict, re-read, merge, and resubmit.

Configure file tools for the working notes

Memory reads and writes go through file tools — enable them explicitly in one builtin_toolkit:

{
  "type": "builtin_toolkit",
  "default_config": {"enabled": false},
  "configs": [
    {"name": "read", "enabled": true},
    {"name": "write", "enabled": true},
    {"name": "edit", "enabled": true},
    {"name": "glob", "enabled": true}
  ]
}

Spell out the handoff requirements: read the existing notes first; after the task, record verified facts and unfinished work; have the next session read the same store.

Two boundaries

  • Mount timing: memory stores mount only at session creation. POSTing type: memory_store to /sessions/{id}/resources on an existing session returns 400 (runtime resource appends support files only, see building a chat client); to change mounts, create a new session.
  • The resource list does not show memory mounts: GET /sessions/{id}/resources does not list memory stores even when the mount is active — the list stays empty. Verify mounts across three places: the creation config, in-session file-tool output, and the Memory API read-back; an empty resource list alone does not prove the mount failed.

NoteMemory store archiving is irreversible: once archived, it accepts no writes and cannot be mounted into new sessions. Confirm no session still depends on it first — see Memory Store.

Summary

  • The handoff is one persistent chain: POST /memory_stores to create → write the initial note → mount read-write and do the work → write back verified facts → mount read-only in the next session;
  • Reads and writes use file tools, fixed at /mnt/memory/<name>/…; bash cannot reach it;
  • Read-only provides a second safeguard: platform-side read-only blocks writes regardless of agent tooling; setting both is more robust;
  • Concurrent writes use conditional updates: the content_sha256 optimistic lock returns 409 on conflict; re-read, merge, resubmit;
  • Mounting happens only at session creation, the resource list does not reflect memory mounts, and verification needs file-tool output plus API read-back.

Next steps