All Products
Search
Document Center

Tablestore:File memory

Last Updated:Jul 28, 2026

File memory lets AI agents read and maintain long-term context as files. Applications can manage memory files directly or use read-only file views generated from structured memories.

File access options

Memory Store provides the following file access options.

Option

Input

File operations

Use case

Structured memories and file views

Write conversation messages or text for the service to extract long-term memories

List and read service-generated, read-only files

Use semantic search and file-based access for agents

File memory

Write Markdown or UTF-8 text files directly

Create, read, update, rename, delete, and manage versions

Use existing memory files or organize memories in custom directories

On Linux, agent-memory-fuse can mount file memory as a local directory. Agents and applications can then access memories with standard file operations.

Prerequisites

  • A Tablestore instance with its HTTPS endpoint and instance name

  • An API Key generated for the instance, or an AccessKey ID and AccessKey secret

  • An Agent Storage SDK version that supports file memory: Python SDK 1.0.10 or later, or TypeScript SDK 0.0.11 or later

Quick start

The following examples install the SDK, configure credentials, initialize a client, create a file memory store, and write a Markdown file. The examples then list and read the file.

For client initialization and common settings, see Agent Storage SDK.

Python

Install the Python SDK.

pip install "tablestore-agent-storage>=1.0.10"

In the following program, specify the API Key, HTTPS endpoint, and instance name.

Create and run the program to initialize the client and use file memory.

from tablestore_agent_storage import AgentStorageClient

client = AgentStorageClient(
    api_key="your-api-key",
    ots_endpoint="https://your-instance.cn-beijing.ots.aliyuncs.com",
    ots_instance_name="your-instance-name",
)

scope = {
    "appId": "app-001",
    "tenantId": "user-001",
    "agentId": "assistant",
    "runId": "session-001",
}

client.create_memory_store({
    "memoryStoreName": "agent_files",
    "storageMode": "filemem",
})

client.add_item({
    "memoryStoreName": "agent_files",
    "scope": scope,
    "path": "/profile/preferences.md",
    "content": "# User preferences\n\n- Likes Americano coffee\n- Prefers concise answers\n",
})

listed = client.list_items({
    "memoryStoreName": "agent_files",
    "scope": scope,
    "pathPrefix": "/profile/",
})
for entry in listed["items"]:
    print(entry["path"], entry["contentSizeBytes"])

item = client.get_item({
    "memoryStoreName": "agent_files",
    "scope": scope,
    "path": "/profile/preferences.md",
})
print(item["content"])

TypeScript

Install the TypeScript SDK.

npm install "@tablestore/agent-storage@^0.0.11"

In the following program, specify the API Key, HTTPS endpoint, and instance name.

Create and run the program to initialize the client and use file memory.

import { AgentStorageClient } from '@tablestore/agent-storage';

async function main() {
  const client = new AgentStorageClient({
    apiKey: 'your-api-key',
    endpoint: 'https://your-instance.cn-beijing.ots.aliyuncs.com',
    instanceName: 'your-instance-name',
  });

  const scope = {
    appId: 'app-001',
    tenantId: 'user-001',
    agentId: 'assistant',
    runId: 'session-001',
  };

  await client.createMemoryStore({
    memoryStoreName: 'agent_files',
    storageMode: 'filemem',
  });

  await client.addItem({
    memoryStoreName: 'agent_files',
    scope,
    path: '/profile/preferences.md',
    content: '# User preferences\n\n- Likes Americano coffee\n- Prefers concise answers\n',
  });

  const listed = await client.listItems({
    memoryStoreName: 'agent_files',
    scope,
    pathPrefix: '/profile/',
  });

  const item = await client.getItem({
    memoryStoreName: 'agent_files',
    scope,
    path: '/profile/preferences.md',
  });
  console.log(listed.items, item.content);
}

void main();

storageMode is required when you create a memory store and cannot be changed later. File operations do not require this parameter. Agent Storage SDK automatically adds the type field required by Item APIs.

Mount file memory as a local directory with FUSE

agent-memory-fuse maps one file memory store and one exact scope in a Tablestore instance to a local Linux directory. After mounting, agents and applications can read and write memories with ls, cat, editors, or file APIs without integrating Agent Storage SDK.

Each mount maps one (instance, memoryStoreName, scope) combination. The tool is designed for file memory and is not a general-purpose POSIX file system.

Prepare the environment

  • Download the agent-memory-fuse Linux executable that matches the runtime architecture, and make the file executable.

  • Enable FUSE in the Linux kernel, and grant the current user or container access to /dev/fuse.

  • Install fusermount3. On some systems, the command is named fusermount.

  • Create a file memory store with storageMode=filemem, and obtain the HTTPS endpoint, instance name, and all four scope fields.

  • Prepare an API Key, AccessKey, or Security Token Service (STS) temporary credential. API Key authentication requires an HTTPS endpoint.

Running the tool in a container typically requires mapping /dev/fuse and granting CAP_SYS_ADMIN or equivalent user-namespace mount permissions. Use the minimum permissions required by the runtime environment.

chmod +x ./agent-memory-fuse
mkdir -p /mnt/agent-memory

Mount file memory

Run the following command. The scope matches the scope object in Quick start. Enclose the complete scope in quotation marks to prevent the shell from interpreting special characters.

./agent-memory-fuse mount \
  --endpoint https://your-instance.cn-beijing.ots.aliyuncs.com \
  --instance your-instance-name \
  --credential apikey:your-api-key \
  --store agent_files \
  --scope 'app-001#user-001#assistant#session-001' \
  --session fuse-session-001 \
  /mnt/agent-memory

The mount command runs in the foreground and maintains the mount lifecycle. The following log indicates that the initial directory was loaded and mounted.

mounted /mnt/agent-memory: store=agent_files files=1 readOnly=false

Keep the process running and access the mounted directory from another terminal or application process. In production, use systemd or a container orchestrator to manage the process. Do not forcibly terminate the process while the mount is in use.

The following table describes the main parameters.

Parameter

Description

--endpoint

HTTPS endpoint of the Tablestore instance

--instance

Tablestore instance name

--credential

apikey:<key>, aksk:<id>:<secret>, or sts:<id>:<secret>:<token>

--store

Name of a memory store with storageMode=filemem

--scope

Exact appId#tenantId#agentId#runId scope separated by #. Wildcards are not supported.

--session

Session identifier for the mount, used to associate versions on the server. Use a different value for each write session.

--read-only

Optional. Mount the directory as read-only.

Final positional argument

Local mount directory

--credential contains sensitive information. The example shows only the parameter format. Do not store real credentials in source code, container images, logs, or shared scripts. Prefer short-lived credentials with restricted permissions.

Read and write files

After mounting, read, create, modify, rename, and delete files as you would in a regular directory.

# View files stored on the server
find /mnt/agent-memory -type f
cat /mnt/agent-memory/profile/preferences.md

# Create or update a file
mkdir -p /mnt/agent-memory/projects/alpha
printf '%s\n' '# Project decisions' '' '- Use an event-driven architecture' \
  > /mnt/agent-memory/projects/alpha/decisions.md
cat /mnt/agent-memory/projects/alpha/decisions.md

# Rename and delete a file
mv /mnt/agent-memory/projects/alpha/decisions.md \
  /mnt/agent-memory/projects/alpha/architecture.md
rm /mnt/agent-memory/projects/alpha/architecture.md

Files are synchronized to the server during flush, fsync, or close operations. Production applications must check the return values of fsync and close. Some shell redirections do not display errors raised during close. Read critical writes back to confirm that they succeeded.

Directories are derived from file path prefixes. Directories that contain files persist across processes and remounts. Empty directories exist only in the current mount process.

Use a read-only mount

If an agent only needs to read memories, add --read-only before the mount directory argument.

./agent-memory-fuse mount \
  --endpoint https://your-instance.cn-beijing.ots.aliyuncs.com \
  --instance your-instance-name \
  --credential apikey:your-api-key \
  --store agent_files \
  --scope 'app-001#user-001#assistant#session-001' \
  --session fuse-reader-001 \
  --read-only \
  /mnt/agent-memory

For a read-only file view generated from structured memories, the service automatically switches the mount to read-only. Write operations on a read-only mount return EROFS.

Rotate STS credentials

When a mount uses STS credentials, rotate the AccessKey ID, AccessKey secret, and STS token without unmounting the directory. The credential provider must write the following JSON to standard output and pipe it to the rotation command.

{"accessKeyId":"new-access-key-id","accessKeySecret":"new-access-key-secret","stsToken":"new-sts-token"}
your-credential-provider | \
  ./agent-memory-fuse rotate-credential --mountpoint /mnt/agent-memory

The rotation command reads credentials from standard input so that new credentials are not exposed in command-line arguments. A successful command installs the credentials in the local mount process. Subsequent file requests verify the credentials. Only trusted processes can access the mount point and rotate credentials.

Unmount file memory

After all file operations finish and all open files are closed, run the following command.

./agent-memory-fuse umount /mnt/agent-memory

After the directory is unmounted, the foreground mount process exits. If fusermount3 and fusermount are unavailable, the unmount command returns an error. Install the FUSE user-space tools before you retry.

Limitations and troubleshooting

  • Only valid UTF-8 text is supported, and each file can be up to 100 KiB. Content and size violations return EILSEQ and EFBIG, respectively.

  • Each scope stores up to 2,000 current files by default. Writes return ENOSPC when the quota is reached.

  • When multiple clients modify the same file concurrently, stale file handles might return ESTALE. Reopen the file, read the latest content, and then decide whether to retry.

  • Invalid credentials or an expired STS token return EACCES. Rotate the credentials or remount with valid credentials.

  • Throttling or temporary service unavailability might return EAGAIN. The tool first performs bounded retries. Applications must use backoff to handle the final error.

  • Symbolic links, hard links, access control lists (ACLs), application-defined extended attributes, sparse files, and cross-session file locks are not supported.

  • For an operation not permitted error or failure to open /dev/fuse, check device mapping, current-user permissions, and container mount capabilities.

  • For an initial directory load error, verify that the endpoint, instance name, credentials, memory store name, and scope match.

File identification

A memory store, a scope, and a path together identify a file.

  • memoryStoreName: The memory store name.

  • scope: The scope that owns the file. Specify appId, tenantId, agentId, and runId. The * wildcard is not supported.

  • path: The file path within the scope. Use a meaningful path with a leading /, such as /profile/preferences.md or /projects/alpha/decisions.md.

The same path can be used in different scopes because their file contents are isolated. The itemId returned by ListItems is the stable file identifier and is required to query version history.

Common file operations

The following examples use the Python client, scope, and agent_files memory store from Quick start.

Read file metadata only

Set includeContent to False to omit content from the response. Use this option to inspect the content digest and update time.

current = client.get_item({
    "memoryStoreName": "agent_files",
    "scope": scope,
    "path": "/profile/preferences.md",
    "includeContent": False,
})
print(current["contentSha256"], current["updatedAt"])

Update file content

For concurrent writes, pass the most recently read contentSha256 value as expectedSha256. If another request has modified the file, the service rejects the overwrite. Read the file again before deciding whether to retry.

updated = client.update_item({
    "memoryStoreName": "agent_files",
    "scope": scope,
    "path": "/profile/preferences.md",
    "content": "# User preferences\n\n- Likes latte\n- Prefers concise answers\n",
    "expectedSha256": current["contentSha256"],
})

Rename a file

UpdateItem updates content or renames a file. Each request must specify exactly one of content and newPath.

renamed = client.update_item({
    "memoryStoreName": "agent_files",
    "scope": scope,
    "path": "/profile/preferences.md",
    "newPath": "/profile/user-preferences.md",
    "expectedSha256": updated["contentSha256"],
})

If the destination path exists, the request returns a conflict by default. Set "overwrite": True only when replacing the destination file is acceptable.

List files by page

ListItems returns 100 files per page by default and up to 500 files per page. If the response contains nextToken, pass it unchanged in the next request.

next_token = None
while True:
    request = {
        "memoryStoreName": "agent_files",
        "scope": scope,
        "pathPrefix": "/profile/",
        "limit": 100,
    }
    if next_token:
        request["nextToken"] = next_token

    page = client.list_items(request)
    for entry in page["items"]:
        print(entry["path"])

    next_token = page.get("nextToken")
    if not next_token:
        break

Delete a file

client.delete_item({
    "memoryStoreName": "agent_files",
    "scope": scope,
    "path": "/profile/user-preferences.md",
    "expectedSha256": renamed["contentSha256"],
})

Deleting a file removes the current file. Historical versions remain available by file ID.

View version history

Each create, update, rename, or delete operation creates an immutable historical version. Get the itemId from the current file or a previously saved response, and then list the versions.

versions = client.list_item_versions({
    "memoryStoreName": "agent_files",
    "scope": scope,
    "itemId": renamed["itemId"],
    "limit": 20,
})

version = versions["versions"][0]
snapshot = client.get_item_version({
    "memoryStoreName": "agent_files",
    "scope": scope,
    "itemId": version["itemId"],
    "versionId": version["versionId"],
    "versionSeq": version["versionSeq"],
})
print(snapshot.get("content"))

Use operation to filter created, modified, or deleted versions. Version lists do not include content. Call GetItemVersion to read a specific snapshot.

Redact a historical version

Warning

Redaction is irreversible. Before you continue, verify that you selected the correct historical version.

RedactItemVersion removes the path, content, digest, and size from a historical snapshot. The operation type, version sequence, creation time, and redaction audit information remain. Repeated requests are idempotent. Redaction does not modify the current file or create a version.

redacted = client.redact_item_version({
    "memoryStoreName": "agent_files",
    "scope": scope,
    "itemId": version["itemId"],
    "versionId": version["versionId"],
    "versionSeq": version["versionSeq"],
    "sessionId": "privacy-job-001",
})
print(redacted["redacted"], redacted["redactedAt"])

After redaction, GetItemVersion still returns the version without the content field.

Read file views of structured memories

If an application writes conversations or text to the service and uses structured memory APIs for semantic search, agents can also browse the same memories as files.

  • Continue to write and maintain data with structured memory APIs such as AddMemories, UpdateMemory, and DeleteMemory.

  • Use Agent Storage SDK list_items and get_item to list and read generated files.

  • If a ListItems response contains readOnly: true, the file view is read-only. Create, update, rename, delete, and version operations are not supported.

    page = client.list_items({
        "memoryStoreName": "agent_memory",
        "scope": scope,
    })
    
    if page.get("readOnly"):
        for entry in page["items"]:
            item = client.get_item({
                "memoryStoreName": "agent_memory",
                "scope": scope,
                "path": entry["path"],
            })
            print(item["path"], item["content"])

File write operations against a read-only file view return READ_ONLY_STORE. Modify the source memories through structured memory APIs instead.

Common errors

Error code

Cause

Solution

VALIDATION_ERROR

The scope is incomplete, the path is invalid, or the update request contains both content and newPath.

Check all four scope fields, the path, and the update operation.

NOT_FOUND

The memory store, scope, path, or version does not exist.

Check the file identifiers. Do not reuse a file identifier across scopes.

PATH_EXISTS

The destination path for a create or rename operation already exists.

Use a different path, or enable overwrite only when replacing the destination is acceptable.

SHA_MISMATCH

Another request modified the file.

Read the latest content before deciding whether to retry.

LOCK_CONFLICT

A concurrent change is in progress in the same scope.

Retry with a short backoff, and then read the latest file.

READ_ONLY_STORE

A request attempted to modify a read-only file view.

Update the source memories through structured memory APIs.

Limitations

  • Only valid UTF-8 text is supported. Each file can be up to 100 KiB.

  • A normalized path can be up to 800 bytes. A path cannot point to the root directory or contain empty path segments, ., .., or NUL characters.

  • Each scope stores up to 2,000 current files by default.

  • All Item APIs require all four scope fields. Wildcards are not supported.

  • Historical version redaction cannot be undone.