Skip to content

Commit 48a3f43

Browse files
committed
Merge commit 'd78278077cce484ee161f6ccf5dcf847975f9c33' as 'apps/MemOS-Cloud-OpenClaw-Plugin'
2 parents eadeb95 + d782780 commit 48a3f43

File tree

12 files changed

+2426
-0
lines changed

12 files changed

+2426
-0
lines changed
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# Dependencies
2+
node_modules
3+
4+
# Environment variables
5+
.env
6+
.env.*
7+
8+
# NPM
9+
.npmrc
10+
11+
# System
12+
.DS_Store
13+
Thumbs.db
14+
15+
# Logs
16+
npm-debug.log*
17+
yarn-debug.log*
18+
yarn-error.log*
Lines changed: 201 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,201 @@
1+
Apache License
2+
Version 2.0, January 2004
3+
http://www.apache.org/licenses/
4+
5+
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6+
7+
1. Definitions.
8+
9+
"License" shall mean the terms and conditions for use, reproduction,
10+
and distribution as defined by Sections 1 through 9 of this document.
11+
12+
"Licensor" shall mean the copyright owner or entity authorized by
13+
the copyright owner that is granting the License.
14+
15+
"Legal Entity" shall mean the union of the acting entity and all
16+
other entities that control, are controlled by, or are under common
17+
control with that entity. For the purposes of this definition,
18+
"control" means (i) the power, direct or indirect, to cause the
19+
direction or management of such entity, whether by contract or
20+
otherwise, or (ii) ownership of fifty percent (50%) or more of the
21+
outstanding shares, or (iii) beneficial ownership of such entity.
22+
23+
"You" (or "Your") shall mean an individual or Legal Entity
24+
exercising permissions granted by this License.
25+
26+
"Source" form shall mean the preferred form for making modifications,
27+
including but not limited to software source code, documentation
28+
source, and configuration files.
29+
30+
"Object" form shall mean any form resulting from mechanical
31+
transformation or translation of a Source form, including but
32+
not limited to compiled object code, generated documentation,
33+
and conversions to other media types.
34+
35+
"Work" shall mean the work of authorship, whether in Source or
36+
Object form, made available under the License, as indicated by a
37+
copyright notice that is included in or attached to the work
38+
(an example is provided in the Appendix below).
39+
40+
"Derivative Works" shall mean any work, whether in Source or Object
41+
form, that is based on (or derived from) the Work and for which the
42+
editorial revisions, annotations, elaborations, or other modifications
43+
represent, as a whole, an original work of authorship. For the purposes
44+
of this License, Derivative Works shall not include works that remain
45+
separable from, or merely link (or bind by name) to the interfaces of,
46+
the Work and Derivative Works thereof.
47+
48+
"Contribution" shall mean any work of authorship, including
49+
the original version of the Work and any modifications or additions
50+
to that Work or Derivative Works thereof, that is intentionally
51+
submitted to Licensor for inclusion in the Work by the copyright owner
52+
or by an individual or Legal Entity authorized to submit on behalf of
53+
the copyright owner. For the purposes of this definition, "submitted"
54+
means any form of electronic, verbal, or written communication sent
55+
to the Licensor or its representatives, including but not limited to
56+
communication on electronic mailing lists, source code control systems,
57+
and issue tracking systems that are managed by, or on behalf of, the
58+
Licensor for the purpose of discussing and improving the Work, but
59+
excluding communication that is conspicuously marked or otherwise
60+
designated in writing by the copyright owner as "Not a Contribution."
61+
62+
"Contributor" shall mean Licensor and any individual or Legal Entity
63+
on behalf of whom a Contribution has been received by Licensor and
64+
subsequently incorporated within the Work.
65+
66+
2. Grant of Copyright License. Subject to the terms and conditions of
67+
this License, each Contributor hereby grants to You a perpetual,
68+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69+
copyright license to reproduce, prepare Derivative Works of,
70+
publicly display, publicly perform, sublicense, and distribute the
71+
Work and such Derivative Works in Source or Object form.
72+
73+
3. Grant of Patent License. Subject to the terms and conditions of
74+
this License, each Contributor hereby grants to You a perpetual,
75+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76+
(except as stated in this section) patent license to make, have made,
77+
use, offer to sell, sell, import, and otherwise transfer the Work,
78+
where such license applies only to those patent claims licensable
79+
by such Contributor that are necessarily infringed by their
80+
Contribution(s) alone or by combination of their Contribution(s)
81+
with the Work to which such Contribution(s) was submitted. If You
82+
institute patent litigation against any entity (including a
83+
cross-claim or counterclaim in a lawsuit) alleging that the Work
84+
or a Contribution incorporated within the Work constitutes direct
85+
or contributory patent infringement, then any patent licenses
86+
granted to You under this License for that Work shall terminate
87+
as of the date such litigation is filed.
88+
89+
4. Redistribution. You may reproduce and distribute copies of the
90+
Work or Derivative Works thereof in any medium, with or without
91+
modifications, and in Source or Object form, provided that You
92+
meet the following conditions:
93+
94+
(a) You must give any other recipients of the Work or
95+
Derivative Works a copy of this License; and
96+
97+
(b) You must cause any modified files to carry prominent notices
98+
stating that You changed the files; and
99+
100+
(c) You must retain, in the Source form of any Derivative Works
101+
that You distribute, all copyright, patent, trademark, and
102+
attribution notices from the Source form of the Work,
103+
excluding those notices that do not pertain to any part of
104+
the Derivative Works; and
105+
106+
(d) If the Work includes a "NOTICE" text file as part of its
107+
distribution, then any Derivative Works that You distribute must
108+
include a readable copy of the attribution notices contained
109+
within such NOTICE file, excluding those notices that do not
110+
pertain to any part of the Derivative Works, in at least one
111+
of the following places: within a NOTICE text file distributed
112+
as part of the Derivative Works; within the Source form or
113+
documentation, if provided along with the Derivative Works; or,
114+
within a display generated by the Derivative Works, if and
115+
wherever such third-party notices normally appear. The contents
116+
of the NOTICE file are for informational purposes only and
117+
do not modify the License. You may add Your own attribution
118+
notices within Derivative Works that You distribute, alongside
119+
or as an addendum to the NOTICE text from the Work, provided
120+
that such additional attribution notices cannot be construed
121+
as modifying the License.
122+
123+
You may add Your own copyright statement to Your modifications and
124+
may provide additional or different license terms and conditions
125+
for use, reproduction, or distribution of Your modifications, or
126+
for any such Derivative Works as a whole, provided Your use,
127+
reproduction, and distribution of the Work otherwise complies with
128+
the conditions stated in this License.
129+
130+
5. Submission of Contributions. Unless You explicitly state otherwise,
131+
any Contribution intentionally submitted for inclusion in the Work
132+
by You to the Licensor shall be under the terms and conditions of
133+
this License, without any additional terms or conditions.
134+
Notwithstanding the above, nothing herein shall supersede or modify
135+
the terms of any separate license agreement you may have executed
136+
with Licensor regarding such Contributions.
137+
138+
6. Trademarks. This License does not grant permission to use the trade
139+
names, trademarks, service marks, or product names of the Licensor,
140+
except as required for reasonable and customary use in describing the
141+
origin of the Work and reproducing the content of the NOTICE file.
142+
143+
7. Disclaimer of Warranty. Unless required by applicable law or
144+
agreed to in writing, Licensor provides the Work (and each
145+
Contributor provides its Contributions) on an "AS IS" BASIS,
146+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147+
implied, including, without limitation, any warranties or conditions
148+
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149+
PARTICULAR PURPOSE. You are solely responsible for determining the
150+
appropriateness of using or redistributing the Work and assume any
151+
risks associated with Your exercise of permissions under this License.
152+
153+
8. Limitation of Liability. In no event and under no legal theory,
154+
whether in tort (including negligence), contract, or otherwise,
155+
unless required by applicable law (such as deliberate and grossly
156+
negligent acts) or agreed to in writing, shall any Contributor be
157+
liable to You for damages, including any direct, indirect, special,
158+
incidental, or consequential damages of any character arising as a
159+
result of this License or out of the use or inability to use the
160+
Work (including but not limited to damages for loss of goodwill,
161+
work stoppage, computer failure or malfunction, or any and all
162+
other commercial damages or losses), even if such Contributor
163+
has been advised of the possibility of such damages.
164+
165+
9. Accepting Warranty or Additional Liability. While redistributing
166+
the Work or Derivative Works thereof, You may choose to offer,
167+
and charge a fee for, acceptance of support, warranty, indemnity,
168+
or other liability obligations and/or rights consistent with this
169+
License. However, in accepting such obligations, You may act only
170+
on Your own behalf and on Your sole responsibility, not on behalf
171+
of any other Contributor, and only if You agree to indemnify,
172+
defend, and hold each Contributor harmless for any liability
173+
incurred by, or claims asserted against, such Contributor by reason
174+
of your accepting any such warranty or additional liability.
175+
176+
END OF TERMS AND CONDITIONS
177+
178+
APPENDIX: How to apply the Apache License to your work.
179+
180+
To apply the Apache License to your work, attach the following
181+
boilerplate notice, with the fields enclosed by brackets "[]"
182+
replaced with your own identifying information. (Don't include
183+
the brackets!) The text should be enclosed in the appropriate
184+
comment syntax for the file format. We also recommend that a
185+
file or class name and description of purpose be included on the
186+
same "printed page" as the copyright notice for easier
187+
identification within third-party archives.
188+
189+
Copyright [yyyy] [name of copyright owner]
190+
191+
Licensed under the Apache License, Version 2.0 (the "License");
192+
you may not use this file except in compliance with the License.
193+
You may obtain a copy of the License at
194+
195+
http://www.apache.org/licenses/LICENSE-2.0
196+
197+
Unless required by applicable law or agreed to in writing, software
198+
distributed under the License is distributed on an "AS IS" BASIS,
199+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200+
See the License for the specific language governing permissions and
201+
limitations under the License.
Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
1+
# MemOS Cloud OpenClaw Plugin (Lifecycle)
2+
3+
Official plugin maintained by MemTensor.
4+
5+
A minimal OpenClaw lifecycle plugin that **recalls** memories from MemOS Cloud before each run and **adds** new messages to MemOS Cloud after each run.
6+
7+
## Features
8+
- **Recall**: `before_agent_start``/search/memory`
9+
- **Add**: `agent_end``/add/message`
10+
- Uses **Token** auth (`Authorization: Token <MEMOS_API_KEY>`)
11+
12+
## Install
13+
14+
### Option A — NPM (Recommended)
15+
```bash
16+
openclaw plugins install @memtensor/memos-cloud-openclaw-plugin@latest
17+
openclaw gateway restart
18+
```
19+
20+
> **Note for Windows Users**:
21+
> If you encounter `Error: spawn EINVAL`, this is a known issue with OpenClaw's plugin installer on Windows. Please use **Option B** (Manual Install) below.
22+
23+
Make sure it’s enabled in `~/.openclaw/openclaw.json`:
24+
```json
25+
{
26+
"plugins": {
27+
"entries": {
28+
"memos-cloud-openclaw-plugin": { "enabled": true }
29+
}
30+
}
31+
}
32+
```
33+
34+
### Option B — Manual Install (Workaround for Windows)
35+
1. Download the latest `.tgz` from [NPM](https://www.npmjs.com/package/@memtensor/memos-cloud-openclaw-plugin).
36+
2. Extract it to a local folder (e.g., `C:\Users\YourName\.openclaw\extensions\memos-cloud-openclaw-plugin`).
37+
3. Configure `~/.openclaw/openclaw.json` (or `%USERPROFILE%\.openclaw\openclaw.json`):
38+
39+
```json
40+
{
41+
"plugins": {
42+
"entries": {
43+
"memos-cloud-openclaw-plugin": { "enabled": true }
44+
},
45+
"load": {
46+
"paths": [
47+
"C:\\Users\\YourName\\.openclaw\\extensions\\memos-cloud-openclaw-plugin\\package"
48+
]
49+
}
50+
}
51+
}
52+
```
53+
*Note: The extracted folder usually contains a `package` subfolder. Point to the folder containing `package.json`.*
54+
55+
Restart the gateway after config changes.
56+
57+
## Environment Variables
58+
The plugin tries env files in order (**openclaw → moltbot → clawdbot**). For each key, the first file with a value wins.
59+
If none of these files exist (or the key is missing), it falls back to the process environment.
60+
61+
**Where to configure**
62+
- Files (priority order):
63+
- `~/.openclaw/.env`
64+
- `~/.moltbot/.env`
65+
- `~/.clawdbot/.env`
66+
- Each line is `KEY=value`
67+
68+
**Quick setup (shell)**
69+
```bash
70+
echo 'export MEMOS_API_KEY="mpg-..."' >> ~/.zshrc
71+
source ~/.zshrc
72+
# or
73+
74+
echo 'export MEMOS_API_KEY="mpg-..."' >> ~/.bashrc
75+
source ~/.bashrc
76+
```
77+
78+
**Quick setup (Windows PowerShell)**
79+
```powershell
80+
[System.Environment]::SetEnvironmentVariable("MEMOS_API_KEY", "mpg-...", "User")
81+
```
82+
83+
If `MEMOS_API_KEY` is missing, the plugin will warn with setup instructions and the API key URL.
84+
85+
**Minimal config**
86+
```env
87+
MEMOS_API_KEY=YOUR_TOKEN
88+
```
89+
90+
**Optional config**
91+
- `MEMOS_BASE_URL` (default: `https://memos.memtensor.cn/api/openmem/v1`)
92+
- `MEMOS_API_KEY` (required; Token auth) — get it at https://memos-dashboard.openmem.net/cn/apikeys/
93+
- `MEMOS_USER_ID` (optional; default: `openclaw-user`)
94+
- `MEMOS_CONVERSATION_ID` (optional override)
95+
- `MEMOS_RECALL_GLOBAL` (default: `true`; when true, search does **not** pass conversation_id)
96+
- `MEMOS_MULTI_AGENT_MODE` (default: `false`; enable multi-agent data isolation)
97+
- `MEMOS_CONVERSATION_PREFIX` / `MEMOS_CONVERSATION_SUFFIX` (optional)
98+
- `MEMOS_CONVERSATION_SUFFIX_MODE` (`none` | `counter`, default: `none`)
99+
- `MEMOS_CONVERSATION_RESET_ON_NEW` (default: `true`, requires hooks.internal.enabled)
100+
- `MEMOS_RECALL_FILTER_ENABLED` (default: `false`; run model-based memory filtering before injection)
101+
- `MEMOS_RECALL_FILTER_BASE_URL` (OpenAI-compatible base URL, e.g. `http://127.0.0.1:11434/v1`)
102+
- `MEMOS_RECALL_FILTER_API_KEY` (optional; required if your endpoint needs auth)
103+
- `MEMOS_RECALL_FILTER_MODEL` (model name used to filter recall candidates)
104+
- `MEMOS_RECALL_FILTER_TIMEOUT_MS` (default: `6000`)
105+
- `MEMOS_RECALL_FILTER_RETRIES` (default: `0`)
106+
- `MEMOS_RECALL_FILTER_CANDIDATE_LIMIT` (default: `30` per category)
107+
- `MEMOS_RECALL_FILTER_MAX_ITEM_CHARS` (default: `500`)
108+
- `MEMOS_RECALL_FILTER_FAIL_OPEN` (default: `true`; fallback to unfiltered recall on failure)
109+
110+
## Optional Plugin Config
111+
In `plugins.entries.memos-cloud-openclaw-plugin.config`:
112+
```json
113+
{
114+
"baseUrl": "https://memos.memtensor.cn/api/openmem/v1",
115+
"apiKey": "YOUR_API_KEY",
116+
"userId": "memos_user_123",
117+
"conversationId": "openclaw-main",
118+
"queryPrefix": "important user context preferences decisions ",
119+
"recallEnabled": true,
120+
"recallGlobal": true,
121+
"addEnabled": true,
122+
"captureStrategy": "last_turn",
123+
"maxItemChars": 8000,
124+
"includeAssistant": true,
125+
"conversationIdPrefix": "",
126+
"conversationIdSuffix": "",
127+
"conversationSuffixMode": "none",
128+
"resetOnNew": true,
129+
"knowledgebaseIds": [],
130+
"memoryLimitNumber": 6,
131+
"preferenceLimitNumber": 6,
132+
"includePreference": true,
133+
"includeToolMemory": false,
134+
"toolMemoryLimitNumber": 6,
135+
"relativity": 0.45,
136+
"tags": ["openclaw"],
137+
"agentId": "",
138+
"multiAgentMode": false,
139+
"asyncMode": true,
140+
"recallFilterEnabled": false,
141+
"recallFilterBaseUrl": "http://127.0.0.1:11434/v1",
142+
"recallFilterApiKey": "",
143+
"recallFilterModel": "qwen2.5:7b",
144+
"recallFilterTimeoutMs": 6000,
145+
"recallFilterRetries": 0,
146+
"recallFilterCandidateLimit": 30,
147+
"recallFilterMaxItemChars": 500,
148+
"recallFilterFailOpen": true
149+
}
150+
```
151+
152+
## How it Works
153+
- **Recall** (`before_agent_start`)
154+
- Builds a `/search/memory` request using `user_id`, `query` (= prompt + optional prefix), and optional filters.
155+
- Default **global recall**: when `recallGlobal=true`, it does **not** pass `conversation_id`.
156+
- Optional second-pass filtering: if `recallFilterEnabled=true`, candidates are sent to your configured model and only returned `keep` items are injected.
157+
- Injects a stable MemOS recall protocol via `appendSystemContext`, while the retrieved `<memories>` block remains in `prependContext`.
158+
159+
- **Add** (`agent_end`)
160+
- Builds a `/add/message` request with the **last turn** by default (user + assistant).
161+
- Sends `messages` with `user_id`, `conversation_id`, and optional `tags/info/agent_id/app_id`.
162+
163+
## Multi-Agent Support
164+
The plugin provides native support for multi-agent architectures (via the `agent_id` parameter):
165+
- **Enable Mode**: Set `"multiAgentMode": true` in config or `MEMOS_MULTI_AGENT_MODE=true` in env variables (default is `false`).
166+
- **Dynamic Context**: When enabled, it automatically captures `ctx.agentId` during OpenClaw lifecycle hooks. (Note: the default OpenClaw agent `"main"` is ignored to preserve backwards compatibility for single-agent users).
167+
- **Data Isolation**: The `agent_id` is automatically injected into both `/search/memory` and `/add/message` requests. This ensures completely isolated memory and message histories for different agents, even under the same user or session.
168+
- **Static Override**: You can also force a specific agent ID by setting `"agentId": "your_agent_id"` in the plugin's `config`.
169+
170+
## Notes
171+
- `conversation_id` defaults to OpenClaw `sessionKey` (unless `conversationId` is provided). **TODO**: consider binding to OpenClaw `sessionId` directly.
172+
- Optional **prefix/suffix** via env or config; `conversationSuffixMode=counter` increments on `/new` (requires `hooks.internal.enabled`).
173+
174+
## Acknowledgements
175+
- Thanks to @anatolykoptev (Contributor) — LinkedIn: https://www.linkedin.com/in/koptev?utm_source=share&utm_campaign=share_via&utm_content=profile&utm_medium=ios_app

0 commit comments

Comments
 (0)