@tablestore/openclaw-tablestore-memory
v0.1.5
Published
OpenClaw memory plugin backed by Alibaba Cloud TableStore memory APIs
Readme
tablestore-mem
tablestore-mem is an OpenClaw memory plugin backed by Alibaba Cloud TableStore memory APIs via [email protected].
It provides:
- Automatic retrieval before each turn through
before_prompt_buildwith hidden system-context injection - Automatic writeback after each successful run through
agent_end - Slash commands:
/tablestore-mem-search/tablestore-mem-add
- CLI commands:
openclaw tablestore-mem searchopenclaw tablestore-mem addopenclaw tablestore-mem doctor
Features
- Native OpenClaw memory slot plugin
- Minimal required configuration
- Automatic Beijing instance provisioning and reuse when instance config is omitted
- Shared
instance.jsonreuse across CLI and conversation hooks - Automatic memory store creation
- Hermes-style scope mapping adapted for OpenClaw
- Cross-agent and cross-run retrieval under the same tenant
- CLI for direct add/search verification
- CLI doctor command for diagnosing connection, memory store, and scoped memory listing
Requirements
- Node.js
>=20 - OpenClaw
>=2026.3.23 - Valid TableStore access key pair
Installation
Install from a local directory:
cd /root/openclaw/tablestore-mem
npm install
openclaw plugins install /root/openclaw/tablestore-mem
openclaw plugins enable tablestore-memFor OpenClaw 2026.4.26+, if you want automatic writeback through agent_end, you must explicitly trust this non-bundled plugin to read conversation content:
{
"plugins": {
"entries": {
"tablestore-mem": {
"hooks": {
"allowConversationAccess": true
}
}
}
}
}This is an OpenClaw security policy flag, not a TableStore plugin business setting.
After publish, install from npm:
npm install -g @tablestore/openclaw-tablestore-memoryOr use it as a package source for your OpenClaw plugin deployment workflow.
Required Configuration
Only these two fields are required:
{
"accessKeyId": "<your-ak>",
"accessKeySecret": "<your-sk>"
}Example OpenClaw config:
{
"plugins": {
"slots": {
"memory": "tablestore-mem"
},
"entries": {
"tablestore-mem": {
"enabled": true,
"hooks": {
"allowConversationAccess": true
},
"config": {
"accessKeyId": "<your-ak>",
"accessKeySecret": "<your-sk>"
}
}
}
}
}Important:
accessKeyIdandaccessKeySecretare still the only required plugin business configuration values.plugins.entries.tablestore-mem.hooks.allowConversationAccess=trueis a separate OpenClaw trust flag required by OpenClaw2026.4.26+if you want the plugin'sagent_endwriteback hook to run.- If you omit that flag, CLI commands and automatic retrieval through
before_prompt_buildstill work, but automatic writeback after a conversation turn is blocked by OpenClaw.
Optional Configuration
These fields are optional:
otsInstanceName: optional instance name override; if unset, the plugin auto-creates one managed instance incn-beijingand reuses it laterendpoint: optional endpoint override; if unset, the plugin deriveshttps://<instance>.cn-beijing.ots.aliyuncs.comappId: optional override, defaults toopenclawtenantId: optional tenant override; if configured, it takes precedence over runtime session user identitymemoryStoreName: defaults toopenclaw_memautoCreateMemoryStore: defaults totruewritebackEnabled: defaults totrueincludeScores: defaults totruesearchTopK: defaults to5minQueryLength: defaults to6enableRerank: defaults totrue
If openclaw_mem does not exist, the plugin creates it automatically on first use.
If both otsInstanceName and endpoint are omitted, the plugin:
- creates a TableStore VCU instance in
cn-beijingon first use through the control-planeCreateVCUInstanceAPI - waits for the instance status to become ready
- updates the instance ACL through
UpdateInstanceto enable public data-plane access - waits for the data endpoint DNS to become resolvable before first data-plane use
- persists the created
instanceNameand derived endpoint under the local OpenClaw home - reuses that same instance on later runs
Connection resolution priority:
- If
otsInstanceNameis configured, use it. - If
endpointis also configured, use that endpoint. - If
otsInstanceNameis configured butendpointis omitted, derivehttps://<otsInstanceName>.cn-beijing.ots.aliyuncs.com. - If only
endpointis configured and it matcheshttps://<instance>.cn-beijing.ots.aliyuncs.com, parse the instance name from the endpoint and use it. - If
otsInstanceNameis omitted and no usable configured endpoint is available, read the persisted auto-created instance from$OPENCLAW_HOME/plugins/tablestore-mem/instance.jsonand wait for its endpoint to become usable. - If no persisted instance exists, create one in
cn-beijing, persist it, wait for readiness, and use it.
When OPENCLAW_HOME is not set, OpenClaw home defaults to ~/.openclaw, so the auto-created instance state is stored at:
~/.openclaw/plugins/tablestore-mem/instance.jsonEnvironment variable overrides:
TABLESTORE_MEMORY_APP_IDTABLESTORE_MEMORY_TENANT_ID
Scope Design
The plugin follows the Hermes-style scope design, adapted for OpenClaw.
appId
- Source priority:
- plugin config
appIdorapp_id TABLESTORE_MEMORY_APP_ID
- plugin config
- Default:
openclaw
tenantId
- Source priority:
- plugin config
tenantIdortenant_id TABLESTORE_MEMORY_TENANT_ID- current OpenClaw session
user_id,userId, or OpenAI-compatibleuser
- plugin config
- Default:
__default__
agentId
- Source: OpenClaw runtime context
agent_identityagentIdentityagentId- derived from
sessionKeyif needed
- Default:
openclaw
runId
- Source priority:
gateway_session_keyorgatewaySessionKeysession_titleorsessionTitle- current
sessionId
- Default:
__default__
Read vs Write Scope
Writes preserve runtime agent/run identity. tenantId uses the configured tenant when set; otherwise it falls back to the current session user identity:
{
"appId": "<configured-app-or-openclaw>",
"tenantId": "<configured-tenant-or-current-user>",
"agentId": "<runtime-agent>",
"runId": "<runtime-session-identity>"
}Reads intentionally search across all agents and runs under the same effective tenant:
{
"appId": "<configured-app-or-openclaw>",
"tenantId": "<configured-tenant-or-current-user>",
"agentId": "*",
"runId": "*"
}This allows a memory written by one OpenClaw agent to be recalled by another agent under the same user scope.
CLI Usage
Add one memory:
openclaw tablestore-mem add "Alice likes jasmine tea" --uid aliceSearch memory:
openclaw tablestore-mem search "what does Alice like" --uid aliceShow help:
openclaw tablestore-mem --help
openclaw tablestore-mem add --help
openclaw tablestore-mem doctor --help
openclaw tablestore-mem search --helpWithout --uid, the CLI uses the default/global tenant scope and is mainly useful for maintenance or debugging.
The CLI uses the same connection resolution and instance.json reuse flow as the automatic OpenClaw hooks.
Doctor:
openclaw tablestore-mem doctor --uid aliceDoctor checks:
- resolved endpoint and
otsInstanceName - memory store existence and metadata through
GetMemoryStore - scoped memory listing through
ListMemories - a small sample of returned memories for quick inspection
On the first AK/SK-only run, doctor may take longer because it can create a new instance and wait for the endpoint DNS to become ready.
Doctor returns structured JSON so users can share the output for troubleshooting.
Slash Commands
Inside an OpenClaw session:
/tablestore-mem-add Alice likes jasmine tea
/tablestore-mem-search jasmine teaSlash command search intentionally returns visible text because it is an explicit user command. Automatic retrieval uses hidden system context and is not printed into the visible session transcript.
OpenClaw Hook Trust
OpenClaw 2026.4.26+ treats some typed hooks as conversation-sensitive for non-bundled plugins.
For this plugin:
before_prompt_builddoes not requireallowConversationAccessagent_enddoes requireallowConversationAccess
That means:
- retrieval can still work without the flag
- writeback will be blocked without the flag
Recommended config:
{
"plugins": {
"entries": {
"tablestore-mem": {
"enabled": true,
"hooks": {
"allowConversationAccess": true
},
"config": {
"accessKeyId": "<your-ak>",
"accessKeySecret": "<your-sk>"
}
}
}
}
}How to verify:
openclaw plugins inspect tablestore-mem --jsonExpected result when writeback is enabled:
typedHookscontains bothbefore_prompt_buildandagent_endpolicy.allowConversationAccessistruediagnosticsdoes not contain a warning aboutagent_endbeing blocked
Expected result when the trust flag is missing:
before_prompt_buildis still presentagent_endis missingdiagnosticscontains a warning like:typed hook "agent_end" blocked because non-bundled plugins must set plugins.entries.tablestore-mem.hooks.allowConversationAccess=true
Runtime Behavior
Before prompt build:
- extracts the latest user prompt
- ensures the TableStore instance is resolved or auto-created
- waits for a newly auto-created instance to become ready before the first data-plane call
- ensures the memory store exists, creating
openclaw_memby default when missing - searches TableStore memory using tenant-wide read scope
- calls
SearchMemorieswithenableRerank=trueby default - injects matched memories into hidden system context
- does not print retrieved memories into the visible session transcript
- logs retrieval count and scope at debug level
After agent end:
- ensures the TableStore instance is resolved or auto-created
- reuses the same persisted
instance.jsonstate as CLI and retrieval hooks - ensures the memory store exists, creating
openclaw_memby default when missing - collects user/assistant messages from the completed turn
- writes them into TableStore using runtime write scope
- calls
AddMemorieswithsync=falseby default
OpenClaw 2026.4.26+ note:
- this
agent_endpath only runs whenplugins.entries.tablestore-mem.hooks.allowConversationAccess=true - if that trust flag is missing, OpenClaw blocks
agent_endbefore the plugin can see conversation messages
The plugin does not call ListMemories as a fallback. Search results are exactly the results returned by SearchMemories; server-side scope filtering is trusted.
Verification
Plugin inspection:
openclaw plugins inspect tablestore-memExpected shape:
- Typed hooks:
before_prompt_build,agent_end - Commands:
tablestore-mem-search,tablestore-mem-add - CLI doctor:
tablestore-mem doctor - CLI commands:
tablestore-mem
Syntax check:
npm run checkPackage dry run:
npm run pack:checkPackaged-plugin cold-start smoke test:
npm run smoke:packThis check is the new release gate for “fresh install but unusable” failures. It:
- runs
npm pack - installs the packed tarball into a brand new OpenClaw profile
- verifies the plugin loads from the packed artifact
- writes the minimal AK/SK config directly into that fresh profile
- verifies hooks, slash commands, and
openclaw tablestore-memCLI registration - verifies
doctor,add, andsearchsubcommand help can start successfully
Optional live OpenClaw smoke test against a real TableStore environment:
TABLESTORE_MEM_LIVE_ACCESS_KEY_ID="<ak>" \
TABLESTORE_MEM_LIVE_ACCESS_KEY_SECRET="<sk>" \
npm run smoke:liveOptional live overrides:
TABLESTORE_MEM_LIVE_ENDPOINTTABLESTORE_MEM_LIVE_OTS_INSTANCE_NAMETABLESTORE_MEM_LIVE_TENANT_ID
When TABLESTORE_MEM_LIVE_ENDPOINT and TABLESTORE_MEM_LIVE_OTS_INSTANCE_NAME are both omitted, npm run smoke:live exercises the AK/SK-only managed-instance path and verifies that a newly created instance.json is persisted and reused on the second doctor run.
Publishing
Pre-publish checklist:
- Update
versioninpackage.json - Run
npm install - Run
npm run release:check - If you rely on the managed AK/SK-only path, run one live smoke:
TABLESTORE_MEM_LIVE_ACCESS_KEY_ID=... TABLESTORE_MEM_LIVE_ACCESS_KEY_SECRET=... npm run smoke:live - If you want additional business validation, verify one real
doctor, one realadd, one realsearch
npm run release:check runs:
npm run checknpm run testnpm run pack:checknpm run smoke:pack
This means npm publish now fails before publish if the packed tarball cannot be installed into a clean OpenClaw profile or if the plugin fails to register its hooks and CLI after minimal configuration.
Publish:
npm publishThe package is configured for public publish under:
@tablestore/openclaw-tablestore-memoryNote:
- npm package names cannot use
tablestore/openclaw-tablestore-memorydirectly - the valid npm scoped package name is
@tablestore/openclaw-tablestore-memory
Notes
- The plugin uses the TableStore Node SDK directly.
- It does not depend on
message:preprocessed. - It does not register model-callable memory tools.
- Retrieval uses
SearchMemoriesresults directly and does not performListMemoriesfallback.
