Skip to content

Commit 5cc8a2e

Browse files
committed
Merge branch 'dev' into feat/mcp-dev
2 parents 0e1002d + a3dfeae commit 5cc8a2e

File tree

39 files changed

+2439
-1184
lines changed

39 files changed

+2439
-1184
lines changed

.github/PULL_REQUEST_TEMPLATE.md

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,26 +3,30 @@
33
<!--
44
Please include a summary of the changes below;
55
Fill in the issue number that this PR addresses (if applicable);
6+
Fill in the related MemOS-Docs repository issue or PR link (if applicable);
67
Mention the person who will review this PR (if you know who it is);
7-
Replace (summary), (issue), and (reviewer) with the appropriate information.
8+
Replace (summary), (issue), (docs-issue-or-pr-link), and (reviewer) with the appropriate information.
89
910
请在下方填写更改的摘要;
1011
填写此 PR 解决的问题编号(如果适用);
12+
填写相关的 MemOS-Docs 仓库 issue 或 PR 链接(如果适用);
1113
提及将审查此 PR 的人(如果您知道是谁);
12-
替换 (summary)、(issue) 和 (reviewer) 为适当的信息。
14+
替换 (summary)、(issue)、(docs-issue-or-pr-link) 和 (reviewer) 为适当的信息。
1315
-->
1416

1517
Summary: (summary)
1618

1719
Fix: #(issue)
1820

21+
Docs Issue/PR: (docs-issue-or-pr-link)
22+
1923
Reviewer: @(reviewer)
2024

2125
## Checklist:
2226

2327
- [ ] I have performed a self-review of my own code | 我已自行检查了自己的代码
2428
- [ ] I have commented my code in hard-to-understand areas | 我已在难以理解的地方对代码进行了注释
2529
- [ ] I have added tests that prove my fix is effective or that my feature works | 我已添加测试以证明我的修复有效或功能正常
26-
- [ ] I have added necessary documentation (if applicable) | 我已添加必要的文档(如果适用)
30+
- [ ] I have created related documentation issue/PR in [MemOS-Docs](https://github.com/MemTensor/MemOS-Docs) (if applicable) | 我已在 [MemOS-Docs](https://github.com/MemTensor/MemOS-Docs) 中创建了相关的文档 issue/PR(如果适用)
2731
- [ ] I have linked the issue to this PR (if applicable) | 我已将 issue 链接到此 PR(如果适用)
2832
- [ ] I have mentioned the person who will review this PR | 我已提及将审查此 PR 的人

.github/workflows/python-tests.yml

Lines changed: 47 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ jobs:
2626
os:
2727
- "ubuntu-latest"
2828
- "windows-latest"
29+
- "macos-13"
2930
- "macos-14"
3031
- "macos-15"
3132
# Ref: https://docs.github.com/en/actions/how-tos/writing-workflows/choosing-where-your-workflow-runs/choosing-the-runner-for-a-job
@@ -46,13 +47,54 @@ jobs:
4647
with:
4748
python-version: ${{ matrix.python-version }}
4849
cache: 'poetry'
49-
- name: Install dependencies
50+
51+
# Dependency and building tests
52+
- name: Install main dependencies
53+
run: |
54+
poetry install --no-root --no-interaction
55+
- name: Check no top-level optional dependencies
56+
run: |
57+
poetry run python scripts/check_dependencies.py
58+
- name: Build sdist and wheel
59+
run: poetry build
60+
- name: Test wheel installation on Windows
61+
if: startsWith(matrix.os, 'windows')
62+
run: |
63+
Get-ChildItem dist/*.whl | ForEach-Object { pip install $_.FullName }
64+
pip uninstall -y memoryos
65+
- name: Test wheel installation on Linux / Mac
66+
if: ${{ !startsWith(matrix.os, 'windows') }}
67+
run: |
68+
pip install dist/*.whl
69+
pip uninstall -y memoryos
70+
- name: Test sdist installation on Windows
71+
if: startsWith(matrix.os, 'windows')
5072
run: |
51-
poetry install --no-interaction --with dev --with test
52-
- name: Test with ruff
73+
Get-ChildItem dist/*.tar.gz | ForEach-Object { pip install $_.FullName }
74+
pip uninstall -y memoryos
75+
- name: Test sdist installation on Linux / Mac
76+
if: ${{ !startsWith(matrix.os, 'windows') }}
77+
run: |
78+
pip install dist/*.tar.gz
79+
pip uninstall -y memoryos
80+
81+
# Ruff checks
82+
- name: Install test group dependencies
83+
run: |
84+
poetry install --no-interaction --with test
85+
- name: Ruff checks
5386
run: |
5487
poetry run ruff check
5588
poetry run ruff format --check
56-
- name: Test with pytest
89+
90+
# PyTest checks
91+
- name: Install all extra dependencies
92+
# macos-13 doesn't support torch==2.7.1
93+
# So, pytest won't work
94+
if: ${{ !startsWith(matrix.os, 'macos-13') }}
95+
run: |
96+
poetry install --no-interaction --extras all
97+
- name: PyTest unit tests
98+
if: ${{ !startsWith(matrix.os, 'macos-13') }}
5799
run: |
58-
poetry run pytest tests -vv
100+
poetry run pytest tests -vv --durations=10

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
.PHONY: test
22

33
install:
4-
poetry install --with dev --with test
4+
poetry install --extras all --with dev --with test
55
poetry run pre-commit install --install-hooks
66

77
clean:

README.md

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@
1717
<a href="https://pypi.org/project/MemoryOS">
1818
<img src="https://img.shields.io/pypi/pyversions/MemoryOS.svg" alt="Supported Python versions">
1919
</a>
20+
<a href="https://pypi.org/project/MemoryOS">
21+
<img src="https://img.shields.io/badge/Platform-Linux%20%7C%20macOS%20%7C%20Windows-lightgrey" alt="Supported Platforms">
22+
</a>
2023
<a href="https://memos-docs.openmem.net/home/overview/">
2124
<img src="https://img.shields.io/badge/Documentation-view-blue.svg" alt="Documentation">
2225
</a>
@@ -138,34 +141,37 @@ For more detailed examples, please check out the [`examples`](./examples) direct
138141

139142
## 📦 Installation
140143

141-
> [!WARNING]
142-
> MemOS is compatible with Linux, Windows, and macOS.
143-
>
144-
> However, if you're using macOS, please note that there may be dependency issues that are difficult to resolve.
145-
>
146-
> For example, compatibility with macOS 13 Ventura is currently challenging.
147-
148144
### Install via pip
149145

150146
```bash
151147
pip install MemoryOS
152148
```
153149

154-
### Development Install
150+
### Optional Dependencies
151+
152+
MemOS provides several optional dependency groups for different features. You can install them based on your needs.
153+
154+
| Feature | Package Name |
155+
| --------------------- | ------------------------- |
156+
| Tree Memory | `MemoryOS[tree-mem]` |
157+
| Memory Reader | `MemoryOS[mem-reader]` |
158+
| Memory Scheduler | `MemoryOS[mem-scheduler]` |
155159

156-
To contribute to MemOS, clone the repository and install it in editable mode:
160+
Example installation commands:
157161

158162
```bash
159-
git clone https://github.com/MemTensor/MemOS.git
160-
cd MemOS
161-
make install
163+
pip install MemoryOS[tree-mem]
164+
pip install MemoryOS[tree-mem,mem-reader]
165+
pip install MemoryOS[mem-scheduler]
166+
pip install MemoryOS[tree-mem,mem-reader,mem-scheduler]
162167
```
163168

164-
### Optional Dependencies
169+
### External Dependencies
165170

166171
#### Ollama Support
167172

168173
To use MemOS with [Ollama](https://ollama.com/), first install the Ollama CLI:
174+
169175
```bash
170176
curl -fsSL https://ollama.com/install.sh | sh
171177
```

evaluation/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ This repository provides tools and scripts for evaluating the LoCoMo dataset usi
1212

1313
2. Install the required dependencies:
1414
```bash
15-
poetry install --with eval
15+
poetry install --extras all --with eval
1616
```
1717

1818
## Configuration

examples/basic_modules/llm.py

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,11 @@
6969
print("Scenario 3:", response)
7070
print("==" * 20)
7171

72+
print("Scenario 3:\n")
73+
for chunk in llm.generate_stream(messages):
74+
print(chunk, end="")
75+
print("==" * 20)
76+
7277

7378
# Scenario 4: Using LLMFactory with Huggingface Models
7479

@@ -91,3 +96,89 @@
9196
response = llm.generate(messages)
9297
print("Scenario 4:", response)
9398
print("==" * 20)
99+
100+
101+
# Scenario 5: Using LLMFactory with Qwen (DashScope Compatible API)
102+
# Note:
103+
# This example works for any model that supports the OpenAI-compatible Chat Completion API,
104+
# including but not limited to:
105+
# - Qwen models: qwen-plus, qwen-max-2025-01-25
106+
# - DeepSeek models: deepseek-chat, deepseek-coder, deepseek-v3
107+
# - Other compatible providers: MiniMax, Fireworks, Groq, OpenRouter, etc.
108+
#
109+
# Just set the correct `api_key`, `api_base`, and `model_name_or_path`.
110+
111+
config = LLMConfigFactory.model_validate(
112+
{
113+
"backend": "qwen",
114+
"config": {
115+
"model_name_or_path": "qwen-plus", # or qwen-max-2025-01-25
116+
"temperature": 0.7,
117+
"max_tokens": 1024,
118+
"top_p": 0.9,
119+
"top_k": 50,
120+
"api_key": "sk-xxx",
121+
"api_base": "https://dashscope.aliyuncs.com/compatible-mode/v1",
122+
},
123+
}
124+
)
125+
llm = LLMFactory.from_config(config)
126+
messages = [
127+
{"role": "user", "content": "Hello, who are you"},
128+
]
129+
response = llm.generate(messages)
130+
print("Scenario 5:", response)
131+
print("==" * 20)
132+
133+
print("Scenario 5:\n")
134+
for chunk in llm.generate_stream(messages):
135+
print(chunk, end="")
136+
print("==" * 20)
137+
138+
# Scenario 6: Using LLMFactory with Deepseek-chat
139+
140+
cfg = LLMConfigFactory.model_validate(
141+
{
142+
"backend": "deepseek",
143+
"config": {
144+
"model_name_or_path": "deepseek-chat",
145+
"api_key": "sk-xxx",
146+
"api_base": "https://api.deepseek.com",
147+
"temperature": 0.6,
148+
"max_tokens": 512,
149+
"remove_think_prefix": False,
150+
},
151+
}
152+
)
153+
llm = LLMFactory.from_config(cfg)
154+
messages = [{"role": "user", "content": "Hello, who are you"}]
155+
resp = llm.generate(messages)
156+
print("Scenario 6:", resp)
157+
158+
159+
# Scenario 7: Using LLMFactory with Deepseek-chat + reasoning + CoT + streaming
160+
161+
cfg2 = LLMConfigFactory.model_validate(
162+
{
163+
"backend": "deepseek",
164+
"config": {
165+
"model_name_or_path": "deepseek-reasoner",
166+
"api_key": "sk-xxx",
167+
"api_base": "https://api.deepseek.com",
168+
"temperature": 0.2,
169+
"max_tokens": 1024,
170+
"remove_think_prefix": False,
171+
},
172+
}
173+
)
174+
llm = LLMFactory.from_config(cfg2)
175+
messages = [
176+
{
177+
"role": "user",
178+
"content": "Explain how to solve this problem step-by-step. Be explicit in your thinking process. Question: If a train travels from city A to city B at 60 mph and returns at 40 mph, what is its average speed for the entire trip? Let's think step by step.",
179+
},
180+
]
181+
print("Scenario 7:\n")
182+
for chunk in llm.generate_stream(messages):
183+
print(chunk, end="")
184+
print("==" * 20)

0 commit comments

Comments
 (0)