TableStore-based external memory provider for Hermes Agent.
This plugin uses the official tablestore Python SDK and Hermes' memory
provider interface to add:
- semantic long-term memory backed by TableStore memory APIs
- automatic turn sync after each completed conversation turn
- prefetch of relevant memories before the next turn
- explicit memory tools for inspect/search/store/delete operations
The built-in MEMORY.md and USER.md stores remain active. This plugin adds
one external memory backend alongside them.
tablestore_profileLists memories in the current scope.tablestore_searchRuns semantic search over stored memories.tablestore_rememberPersists a fact or short note to long-term memory.tablestore_forgetDeletes a memory by id.- Automatic
sync_turn()Sends completed user/assistant turns to TableStore memory ingestion. - Automatic
queue_prefetch()Retrieves likely relevant memories for the next turn. - Mirrors Hermes built-in memory writes into TableStore.
- Hermes Agent
v0.10.0or newer (2026-04-16or later) - Python environment used by Hermes can install:
tablestore==6.4.5alibabacloud-tablestore20201209alibabacloud-credentials
- A TableStore access key pair with permission to create or access the target instance
- Permission to create the memory store if it does not already exist
v0.9.0 may install the repository under ~/.hermes/plugins/ but still fail
to detect it as an external memory provider. Upgrade Hermes first if
hermes memory status shows Plugin: NOT installed.
hermes plugins install yourname/hermes-tablestore-memoryOr:
hermes plugins install https://github.com/yourname/hermes-tablestore-memory.gitHermes installs the plugin into:
~/.hermes/plugins/tablestore-mem/
Important: hermes plugins install ... installs the plugin files, but does
not reliably install Python runtime dependencies for memory providers. After
installation, either:
- run
hermes memory setupand selecttablestore-memso Hermes can installpip_dependenciesfromplugin.yaml, or - install the SDK manually into the exact Python environment used by
hermes
Manual install example:
uv pip install --python "$(head -n 1 "$(which hermes)" | sed 's/^#!//')" \
tablestore==6.4.5 \
alibabacloud-tablestore20201209 \
alibabacloud-credentialsCopy this repository into:
~/.hermes/plugins/tablestore-mem/
Then install the SDK dependency into the Python environment used by Hermes:
uv pip install --python "$(which python)" \
tablestore==6.4.5 \
alibabacloud-tablestore20201209 \
alibabacloud-credentialsIf Hermes runs from a venv, use that interpreter explicitly instead.
Interactive setup:
hermes memory setupSelect tablestore-mem from the provider list.
This step also installs any missing Python dependencies declared by the plugin,
including tablestore==6.4.5, alibabacloud-tablestore20201209, and
alibabacloud-credentials.
Or activate manually:
hermes config set memory.provider tablestore-memSecrets should go into:
~/.hermes/.env
All non-secret provider settings should go into:
$HERMES_HOME/tablestore_memory.json
TABLESTORE_MEMORY_AK=your_access_key_id
TABLESTORE_MEMORY_SK=your_access_key_secretOnly these two secret fields belong in .env.
{
"memory_store_name": "hermes_mem",
"description": "",
"app_id": "hermes",
"tenant_id": "",
"enable_rerank": true,
"auto_create_store": true,
"timeout": 30.0
}On first initialization, if instance_name is missing, the plugin will:
- create a TableStore VCU instance through the Alibaba Cloud control-plane API
- update the new instance network ACL to allow
INTERNET,VPC, andCLASSICand setNetworkSourceACLtoTRUST_PROXY - derive the data-plane endpoint as
https://{instance_name}.cn-beijing.ots.aliyuncs.com - persist both
instance_nameandendpointback intotablestore_memory.json
After that, Hermes reuses the same persisted instance for all later runs.
Real bootstrap behavior and limits:
- Both control-plane bootstrap and data-plane access use
TABLESTORE_MEMORY_AKandTABLESTORE_MEMORY_SK. - Newly created instances can take time to publish a usable public endpoint. During first initialization, Hermes now waits for endpoint DNS resolution and retries transient data-plane endpoint errors before surfacing a failure.
- As a result, the first
hermes tablestore-mem doctoron a brand-new Hermes home may take noticeably longer than normal. This is expected while the new instance becomes reachable.
If the user does not specify a memory store name, the plugin defaults to
hermes_mem and automatically creates it when missing.
Current built-in defaults:
endpoint: auto-derived after first instance bootstrap if not already savedinstance_name: auto-created after first instance bootstrap if not already savedmemory_store_name:hermes_memapp_id:hermestenant_id: empty string, then resolved from config, session fallback, or__default__description: empty stringenable_rerank:trueauto_create_store:truetimeout:30
The provider stores and retrieves memories under a TableStore memory scope:
appId / tenantId / agentId / runId
Current field resolution:
appIdSource:app_idintablestore_memory.json. Default:hermes.tenantIdSource:tenant_idintablestore_memory.jsonfirst. Fallback: Hermes sessionuser_id. Default:__default__.agentIdSource: Hermes session identity, currentlyagent_identity. Default:hermes.runIdSource priority:gateway_session_keysession_title- current
session_idDefault:__default__only if all of the above are empty.
This means only appId and tenantId are user-facing configuration inputs.
agentId and runId are intentionally session-derived so users do not need
to manage them manually.
Configuration source summary:
.env: onlyTABLESTORE_MEMORY_AKandTABLESTORE_MEMORY_SKtablestore_memory.json: endpoint, instance, store, scope defaults, rerank, auto-create, timeout, and description- session context: fallback
tenantIdviauser_id, plusagentIdandrunId
Write scope and search scope are intentionally different:
- writes use the current session scope exactly
- searches use the current
tenantIdwithagentId=*andrunId=*
This lets Hermes search across all agents and sessions for the same tenant while still writing memories with precise session attribution.
Check that Hermes sees the provider:
hermes memory statusYou should see:
Provider: tablestore-mem
Plugin: installed
Status: available
Then start a Hermes session and use the memory tools, or run a quick manual flow from a prompt:
- Ask Hermes to remember a fact.
- Ask Hermes to search for that fact.
- Optionally delete the stored memory by id.
If the plugin is installed but the required SDKs are not yet available in the Python environment Hermes is using, install the declared dependencies first:
uv pip install --python "$(head -n 1 "$(which hermes)" | sed 's/^#!//')" \
tablestore==6.4.5 \
alibabacloud-tablestore20201209 \
alibabacloud-credentialsWhen memory.provider is set to tablestore-mem, Hermes exposes:
hermes tablestore-mem add "User prefers concise answers"
hermes tablestore-mem add "User likes Rust" --metadata source=manual --metadata topic=preferences
hermes tablestore-mem add "Write this synchronously" --sync
hermes tablestore-mem search "concise answers"
hermes tablestore-mem search "Rust" --top-k 10
hermes tablestore-mem doctorNotes:
hermes tablestore-mem addwrites one memory payload through the provider.hermes tablestore-mem addis asynchronous by default; pass--syncto wait.hermes tablestore-mem searchreturns JSON search results.- Search is semantic and ranked. Immediately after a write, especially an asynchronous write, exact phrasing may not appear at the top of results yet. Treat search visibility as eventually consistent rather than strictly synchronous.
hermes tablestore-mem doctorruns read-only diagnostics.--metadata KEY=VALUEcan be repeated.- These CLI commands are only registered when
tablestore-memis the active external memory provider.
The doctor command performs read-only diagnostics by:
- initializing the provider
- calling
DescribeMemoryStorethroughget_memory_store - calling
ListMemories - returning structured JSON suitable for debugging support requests
When instance_name is missing, a successful doctor run also confirms that
bootstrap completed, the generated endpoint is reachable, and the new instance
can now serve data-plane memory requests.
- The plugin uses
tablestore.OTSClientmemory methods directly. - The plugin uses Alibaba Cloud control-plane OpenAPI once for first-run
instance bootstrap when
instance_nameis missing. - During first-run bootstrap, the plugin also enables public access on the new
instance by setting
network_type_acltoINTERNET,VPC, andCLASSIC, andNetworkSourceACLtoTRUST_PROXY. - Request signing and authentication are handled by the OTS SDK.
is_available()only checks local config presence and does not do network calls. It now only requiresAK/SK; missinginstance_nameis handled by bootstrap during initialization.sync_turn()runs asynchronously in a daemon thread to avoid blocking the agent loop.- explicit
tablestore_rememberwrites are asynchronous by default unlesssync=trueis provided. - search and prefetch use rerank by default unless disabled in config or at call time.
tablestore_remembermay create multiple memory units from a single input if the backend extracts structured memories.
Usually one of these values is missing:
TABLESTORE_MEMORY_AKTABLESTORE_MEMORY_SK- or the required Python SDK dependencies are not installed yet
Run:
hermes memory statusCheck:
- the endpoint is an OTS endpoint, not a separate application gateway
- the persisted instance endpoint matches the auto-derived format
https://{instance_name}.cn-beijing.ots.aliyuncs.com - the AK/SK pair has permission for the target instance
- the SDK versions are installed:
tablestore==6.4.5alibabacloud-tablestore20201209alibabacloud-credentials
This is expected in some deployments. AddMemories can extract and normalize
the input into multiple memory units, so search results may contain structured
facts rather than the exact original sentence.
The first write may take longer than a normal request when Hermes has to do one or both of the following before writing memory data:
- bootstrap a new TableStore instance and enable
INTERNET/VPC/CLASSICnetwork access plusTRUST_PROXYsource ACL on that instance - create the
hermes_memmemory store when it does not exist yet
Immediately after a brand-new instance is created, the public endpoint may still be propagating. Hermes now waits through that window during first initialization, so the first successful command can take noticeably longer than normal.
The default timeout is 30 seconds.
This repository is intentionally structured so Hermes can install it directly:
.
├── __init__.py
├── cli.py
├── CHANGELOG.md
├── plugin.yaml
├── README.md
├── README.zh-CN.md
├── after-install.md
└── LICENSE
The repository root is the plugin root.
This project is released under the MIT License. See LICENSE.