memsearch 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. memsearch-0.1.0/.github/workflows/docs.yml +27 -0
  2. memsearch-0.1.0/.github/workflows/release.yml +40 -0
  3. memsearch-0.1.0/.gitignore +11 -0
  4. memsearch-0.1.0/LICENSE +21 -0
  5. memsearch-0.1.0/PKG-INFO +466 -0
  6. memsearch-0.1.0/README.md +435 -0
  7. memsearch-0.1.0/assets/logo-banner-alt.jpg +0 -0
  8. memsearch-0.1.0/assets/logo-banner.jpg +0 -0
  9. memsearch-0.1.0/assets/logo-icon.jpg +0 -0
  10. memsearch-0.1.0/ccplugin/.claude-plugin/plugin.json +5 -0
  11. memsearch-0.1.0/ccplugin/README.md +257 -0
  12. memsearch-0.1.0/ccplugin/hooks/common.sh +85 -0
  13. memsearch-0.1.0/ccplugin/hooks/hooks.json +50 -0
  14. memsearch-0.1.0/ccplugin/hooks/parse-transcript.sh +111 -0
  15. memsearch-0.1.0/ccplugin/hooks/session-end.sh +9 -0
  16. memsearch-0.1.0/ccplugin/hooks/session-start.sh +68 -0
  17. memsearch-0.1.0/ccplugin/hooks/stop.sh +97 -0
  18. memsearch-0.1.0/ccplugin/hooks/user-prompt-submit.sh +48 -0
  19. memsearch-0.1.0/docs/architecture.md +374 -0
  20. memsearch-0.1.0/docs/assets/logo-icon.jpg +0 -0
  21. memsearch-0.1.0/docs/claude-plugin.md +390 -0
  22. memsearch-0.1.0/docs/cli.md +742 -0
  23. memsearch-0.1.0/docs/getting-started.md +530 -0
  24. memsearch-0.1.0/docs/index.md +172 -0
  25. memsearch-0.1.0/docs/stylesheets/terminal.css +189 -0
  26. memsearch-0.1.0/examples/sample-memory/MEMORY.md +35 -0
  27. memsearch-0.1.0/examples/sample-memory/memory/2026-02-05.md +27 -0
  28. memsearch-0.1.0/examples/sample-memory/memory/2026-02-06.md +37 -0
  29. memsearch-0.1.0/examples/sample-memory/memory/2026-02-07.md +31 -0
  30. memsearch-0.1.0/examples/sample-memory/memory/2026-02-08.md +4 -0
  31. memsearch-0.1.0/examples/test_e2e.py +26 -0
  32. memsearch-0.1.0/mkdocs.yml +54 -0
  33. memsearch-0.1.0/pyproject.toml +45 -0
  34. memsearch-0.1.0/src/memsearch/__init__.py +5 -0
  35. memsearch-0.1.0/src/memsearch/__main__.py +5 -0
  36. memsearch-0.1.0/src/memsearch/chunker.py +155 -0
  37. memsearch-0.1.0/src/memsearch/cli.py +628 -0
  38. memsearch-0.1.0/src/memsearch/config.py +230 -0
  39. memsearch-0.1.0/src/memsearch/core.py +339 -0
  40. memsearch-0.1.0/src/memsearch/embeddings/__init__.py +78 -0
  41. memsearch-0.1.0/src/memsearch/embeddings/google.py +37 -0
  42. memsearch-0.1.0/src/memsearch/embeddings/local.py +37 -0
  43. memsearch-0.1.0/src/memsearch/embeddings/ollama.py +31 -0
  44. memsearch-0.1.0/src/memsearch/embeddings/openai.py +48 -0
  45. memsearch-0.1.0/src/memsearch/embeddings/voyage.py +40 -0
  46. memsearch-0.1.0/src/memsearch/flush.py +107 -0
  47. memsearch-0.1.0/src/memsearch/scanner.py +65 -0
  48. memsearch-0.1.0/src/memsearch/store.py +212 -0
  49. memsearch-0.1.0/src/memsearch/transcript.py +224 -0
  50. memsearch-0.1.0/src/memsearch/watcher.py +120 -0
  51. memsearch-0.1.0/tests/__init__.py +0 -0
  52. memsearch-0.1.0/tests/test_chunker.py +63 -0
  53. memsearch-0.1.0/tests/test_config.py +172 -0
  54. memsearch-0.1.0/tests/test_core.py +68 -0
  55. memsearch-0.1.0/tests/test_embeddings_openai.py +54 -0
  56. memsearch-0.1.0/tests/test_scanner.py +52 -0
  57. memsearch-0.1.0/tests/test_store.py +150 -0
  58. memsearch-0.1.0/uv.lock +3330 -0
@@ -0,0 +1,27 @@
1
+ name: Deploy docs
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ paths:
7
+ - 'docs/**'
8
+ - 'mkdocs.yml'
9
+ - '.github/workflows/docs.yml'
10
+ workflow_dispatch:
11
+
12
+ permissions:
13
+ contents: write
14
+
15
+ jobs:
16
+ deploy:
17
+ runs-on: ubuntu-latest
18
+ steps:
19
+ - uses: actions/checkout@v4
20
+
21
+ - uses: actions/setup-python@v5
22
+ with:
23
+ python-version: '3.12'
24
+
25
+ - run: pip install mkdocs-material mkdocs-terminal pymdown-extensions
26
+
27
+ - run: mkdocs gh-deploy --force
@@ -0,0 +1,40 @@
1
+ # Publish to PyPI when a version tag is pushed
2
+ #
3
+ # Usage:
4
+ # git tag v0.1.0 # Must match the version in pyproject.toml
5
+ # git push --tags
6
+
7
+ name: Publish Python Package to PyPI
8
+
9
+ on:
10
+ push:
11
+ tags:
12
+ - "v*"
13
+
14
+ jobs:
15
+ publish:
16
+ name: Publish to PyPI
17
+ runs-on: ubuntu-latest
18
+ environment: pypi
19
+
20
+ permissions:
21
+ id-token: write
22
+ contents: read
23
+
24
+ steps:
25
+ - name: Checkout code
26
+ uses: actions/checkout@v4
27
+
28
+ - name: Set up Python
29
+ uses: actions/setup-python@v5
30
+ with:
31
+ python-version: "3.10"
32
+
33
+ - name: Install build tools
34
+ run: python -m pip install build
35
+
36
+ - name: Build package
37
+ run: python -m build
38
+
39
+ - name: Publish to PyPI
40
+ uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,11 @@
1
+ __pycache__/
2
+ *.py[cod]
3
+ *.egg-info/
4
+ dist/
5
+ build/
6
+ .venv/
7
+ *.db
8
+ .pytest_cache/
9
+ .ruff_cache/
10
+ .memsearch/
11
+ CONTEXT.md
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 zhangchen
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,466 @@
1
+ Metadata-Version: 2.4
2
+ Name: memsearch
3
+ Version: 0.1.0
4
+ Summary: Semantic memory search for markdown knowledge bases
5
+ License-Expression: MIT
6
+ License-File: LICENSE
7
+ Requires-Python: >=3.11
8
+ Requires-Dist: click>=8.1
9
+ Requires-Dist: openai>=1.0
10
+ Requires-Dist: pymilvus[milvus-lite]>=2.5.0
11
+ Requires-Dist: setuptools<75
12
+ Requires-Dist: tomli-w>=1.0
13
+ Requires-Dist: watchdog>=4.0
14
+ Provides-Extra: all
15
+ Requires-Dist: anthropic>=0.40; extra == 'all'
16
+ Requires-Dist: google-genai>=1.0; extra == 'all'
17
+ Requires-Dist: ollama>=0.4; extra == 'all'
18
+ Requires-Dist: sentence-transformers>=3.0; extra == 'all'
19
+ Requires-Dist: voyageai>=0.3; extra == 'all'
20
+ Provides-Extra: anthropic
21
+ Requires-Dist: anthropic>=0.40; extra == 'anthropic'
22
+ Provides-Extra: google
23
+ Requires-Dist: google-genai>=1.0; extra == 'google'
24
+ Provides-Extra: local
25
+ Requires-Dist: sentence-transformers>=3.0; extra == 'local'
26
+ Provides-Extra: ollama
27
+ Requires-Dist: ollama>=0.4; extra == 'ollama'
28
+ Provides-Extra: voyage
29
+ Requires-Dist: voyageai>=0.3; extra == 'voyage'
30
+ Description-Content-Type: text/markdown
31
+
32
+ <p align="center">
33
+ <img src="assets/logo-icon.jpg" alt="memsearch" width="120">
34
+ </p>
35
+
36
+ <h1 align="center">memsearch</h1>
37
+
38
+ <p align="center">
39
+ <strong><a href="https://github.com/openclaw/openclaw">OpenClaw</a>'s memory, everywhere.</strong>
40
+ </p>
41
+
42
+ > 💡 **memsearch extracts [OpenClaw](https://github.com/openclaw/openclaw)'s memory system into a standalone library** — same markdown-first architecture, same chunking, same chunk ID format. Pluggable into *any* agent framework, backed by [Milvus](https://milvus.io/) (local Milvus Lite → Milvus Server → Zilliz Cloud). See it in action with the included **[Claude Code plugin](ccplugin/README.md)**.
43
+
44
+ ### ✨ Why memsearch?
45
+
46
+ - 🦞 **OpenClaw's memory, everywhere** — OpenClaw has one of the best memory designs in open-source AI: **markdown as the single source of truth** — simple, human-readable, `git`-friendly, zero vendor lock-in
47
+ - ⚡ **Smart dedup** — SHA-256 content hashing means unchanged content is never re-embedded
48
+ - 🔄 **Live sync** — File watcher auto-indexes on changes, deletes stale chunks when files are removed
49
+ - 🧹 **Memory flush** — LLM-powered summarization compresses old memories, just like OpenClaw's flush cycle
50
+ - 🧩 **Claude Code plugin included** — A real-world example: **[ccplugin/](ccplugin/README.md)** gives Claude persistent memory across sessions with zero config
51
+
52
+ ## 🔍 How It Works
53
+
54
+ **Markdown is the source of truth** — the vector store is just a derived index, rebuildable anytime.
55
+
56
+ ```
57
+ ┌─── Search ─────────────────────────────────────────────────────────┐
58
+ │ │
59
+ │ "how to configure Redis?" │
60
+ │ │ │
61
+ │ ▼ │
62
+ │ ┌──────────┐ ┌─────────────────┐ ┌──────────────────┐ │
63
+ │ │ Embed │────▶│ Cosine similarity│────▶│ Top-K results │ │
64
+ │ │ query │ │ (Milvus) │ │ with source info │ │
65
+ │ └──────────┘ └─────────────────┘ └──────────────────┘ │
66
+ │ │
67
+ └────────────────────────────────────────────────────────────────────┘
68
+
69
+ ┌─── Ingest ─────────────────────────────────────────────────────────┐
70
+ │ │
71
+ │ MEMORY.md │
72
+ │ memory/2026-02-09.md ┌──────────┐ ┌────────────────┐ │
73
+ │ memory/2026-02-08.md ───▶│ Chunker │────▶│ Dedup │ │
74
+ │ │(heading, │ │(chunk_hash PK) │ │
75
+ │ │paragraph)│ └───────┬────────┘ │
76
+ │ └──────────┘ │ │
77
+ │ new chunks only │
78
+ │ ▼ │
79
+ │ ┌──────────────┐ │
80
+ │ │ Embed & │ │
81
+ │ │ Milvus upsert│ │
82
+ │ └──────────────┘ │
83
+ │ │
84
+ └────────────────────────────────────────────────────────────────────┘
85
+
86
+ ┌─── Watch ──────────────────────────────────────────────────────────┐
87
+ │ File watcher (1500ms debounce) ──▶ auto re-index / delete stale │
88
+ └────────────────────────────────────────────────────────────────────┘
89
+
90
+ ┌─── Flush ──────────────────────────────────────────────────────────┐
91
+ │ Retrieve chunks ──▶ LLM summarize ──▶ write memory/YYYY-MM-DD.md │
92
+ └────────────────────────────────────────────────────────────────────┘
93
+ ```
94
+
95
+ 🔒 The entire pipeline runs locally by default — your data never leaves your machine unless you choose a remote Milvus backend or a cloud embedding provider.
96
+
97
+ ## 🧩 Claude Code Plugin
98
+
99
+ memsearch ships with a **[Claude Code plugin](ccplugin/README.md)** — a real-world example of OpenClaw's memory running outside OpenClaw. It gives Claude **automatic persistent memory** across sessions: every session is summarized to markdown, every prompt triggers a semantic search, and a background watcher keeps the index in sync. No commands to learn, no manual saving — just install and go.
100
+
101
+ ```bash
102
+ # Install memsearch, then launch Claude with the plugin
103
+ pip install memsearch
104
+ claude --plugin-dir ./ccplugin
105
+ ```
106
+
107
+ ```
108
+ Session start ──▶ start memsearch watch (singleton) ──▶ inject recent memories
109
+
110
+ User prompt ──▶ memsearch search ──▶ inject relevant memories
111
+
112
+ Claude stops ──▶ haiku summary ──▶ write .memsearch/memory/YYYY-MM-DD.md
113
+ │ │
114
+ Session end ──▶ stop watch watch auto-indexes ◀┘
115
+ ```
116
+
117
+ Under the hood: 4 shell hooks + 1 watch process, all calling the `memsearch` CLI. Memories are transparent `.md` files — human-readable, git-friendly, rebuildable. See **[ccplugin/README.md](ccplugin/README.md)** for the full architecture, hook details, progressive disclosure model, and comparison with claude-mem.
118
+
119
+ ## 📦 Installation
120
+
121
+ ```bash
122
+ pip install memsearch
123
+ ```
124
+
125
+ ### Additional embedding providers
126
+
127
+ ```bash
128
+ pip install "memsearch[google]" # Google Gemini
129
+ pip install "memsearch[voyage]" # Voyage AI
130
+ pip install "memsearch[ollama]" # Ollama (local)
131
+ pip install "memsearch[local]" # sentence-transformers (local, no API key)
132
+ pip install "memsearch[all]" # Everything
133
+ ```
134
+
135
+ ## 🐍 Python API — Build an Agent with Memory
136
+
137
+ The example below shows a complete agent loop with memory: save knowledge to markdown, index it, and recall it later via semantic search.
138
+
139
+ ```python
140
+ import asyncio
141
+ from datetime import date
142
+ from pathlib import Path
143
+ from openai import OpenAI
144
+ from memsearch import MemSearch
145
+
146
+ MEMORY_DIR = "./memory"
147
+ llm = OpenAI() # your LLM client
148
+ ms = MemSearch(paths=[MEMORY_DIR]) # memsearch handles the rest
149
+
150
+ def save_memory(content: str):
151
+ """Append a note to today's memory log (OpenClaw-style daily markdown)."""
152
+ p = Path(MEMORY_DIR) / f"{date.today()}.md"
153
+ p.parent.mkdir(parents=True, exist_ok=True)
154
+ with open(p, "a") as f:
155
+ f.write(f"\n{content}\n")
156
+
157
+ async def agent_chat(user_input: str) -> str:
158
+ # 1. Recall — search past memories for relevant context
159
+ memories = await ms.search(user_input, top_k=3)
160
+ context = "\n".join(f"- {m['content'][:200]}" for m in memories)
161
+
162
+ # 2. Think — call LLM with memory context
163
+ resp = llm.chat.completions.create(
164
+ model="gpt-4o-mini",
165
+ messages=[
166
+ {"role": "system", "content": f"You have these memories:\n{context}"},
167
+ {"role": "user", "content": user_input},
168
+ ],
169
+ )
170
+ answer = resp.choices[0].message.content
171
+
172
+ # 3. Remember — save this exchange and index it
173
+ save_memory(f"## {user_input}\n{answer}")
174
+ await ms.index()
175
+
176
+ return answer
177
+
178
+ async def main():
179
+ # Seed some knowledge
180
+ save_memory("## Team\n- Alice: frontend lead\n- Bob: backend lead")
181
+ save_memory("## Decision\nWe chose Redis for caching over Memcached.")
182
+ await ms.index()
183
+
184
+ # Agent can now recall those memories
185
+ print(await agent_chat("Who is our frontend lead?"))
186
+ print(await agent_chat("What caching solution did we pick?"))
187
+
188
+ asyncio.run(main())
189
+ ```
190
+
191
+ <details>
192
+ <summary>💜 <b>Anthropic Claude example</b> — click to expand</summary>
193
+
194
+ ```bash
195
+ pip install memsearch anthropic
196
+ ```
197
+
198
+ ```python
199
+ import asyncio
200
+ from datetime import date
201
+ from pathlib import Path
202
+ from anthropic import Anthropic
203
+ from memsearch import MemSearch
204
+
205
+ MEMORY_DIR = "./memory"
206
+ llm = Anthropic()
207
+ ms = MemSearch(paths=[MEMORY_DIR])
208
+
209
+ def save_memory(content: str):
210
+ p = Path(MEMORY_DIR) / f"{date.today()}.md"
211
+ p.parent.mkdir(parents=True, exist_ok=True)
212
+ with open(p, "a") as f:
213
+ f.write(f"\n{content}\n")
214
+
215
+ async def agent_chat(user_input: str) -> str:
216
+ # 1. Recall
217
+ memories = await ms.search(user_input, top_k=3)
218
+ context = "\n".join(f"- {m['content'][:200]}" for m in memories)
219
+
220
+ # 2. Think — call Claude with memory context
221
+ resp = llm.messages.create(
222
+ model="claude-sonnet-4-5-20250929",
223
+ max_tokens=1024,
224
+ system=f"You have these memories:\n{context}",
225
+ messages=[{"role": "user", "content": user_input}],
226
+ )
227
+ answer = resp.content[0].text
228
+
229
+ # 3. Remember
230
+ save_memory(f"## {user_input}\n{answer}")
231
+ await ms.index()
232
+ return answer
233
+
234
+ async def main():
235
+ save_memory("## Team\n- Alice: frontend lead\n- Bob: backend lead")
236
+ await ms.index()
237
+ print(await agent_chat("Who is our frontend lead?"))
238
+
239
+ asyncio.run(main())
240
+ ```
241
+
242
+ </details>
243
+
244
+ <details>
245
+ <summary>🦙 <b>Ollama (fully local, no API key)</b> — click to expand</summary>
246
+
247
+ ```bash
248
+ pip install "memsearch[ollama]"
249
+ ollama pull nomic-embed-text # embedding model
250
+ ollama pull llama3.2 # chat model
251
+ ```
252
+
253
+ ```python
254
+ import asyncio
255
+ from datetime import date
256
+ from pathlib import Path
257
+ from ollama import chat
258
+ from memsearch import MemSearch
259
+
260
+ MEMORY_DIR = "./memory"
261
+ ms = MemSearch(paths=[MEMORY_DIR], embedding_provider="ollama")
262
+
263
+ def save_memory(content: str):
264
+ p = Path(MEMORY_DIR) / f"{date.today()}.md"
265
+ p.parent.mkdir(parents=True, exist_ok=True)
266
+ with open(p, "a") as f:
267
+ f.write(f"\n{content}\n")
268
+
269
+ async def agent_chat(user_input: str) -> str:
270
+ # 1. Recall
271
+ memories = await ms.search(user_input, top_k=3)
272
+ context = "\n".join(f"- {m['content'][:200]}" for m in memories)
273
+
274
+ # 2. Think — call Ollama locally
275
+ resp = chat(
276
+ model="llama3.2",
277
+ messages=[
278
+ {"role": "system", "content": f"You have these memories:\n{context}"},
279
+ {"role": "user", "content": user_input},
280
+ ],
281
+ )
282
+ answer = resp.message.content
283
+
284
+ # 3. Remember
285
+ save_memory(f"## {user_input}\n{answer}")
286
+ await ms.index()
287
+ return answer
288
+
289
+ async def main():
290
+ save_memory("## Team\n- Alice: frontend lead\n- Bob: backend lead")
291
+ await ms.index()
292
+ print(await agent_chat("Who is our frontend lead?"))
293
+
294
+ asyncio.run(main())
295
+ ```
296
+
297
+ </details>
298
+
299
+ ### 🗄️ Milvus Backend Configuration
300
+
301
+ memsearch supports three Milvus deployment modes — just change `milvus_uri` and `milvus_token`:
302
+
303
+ #### 1. Milvus Lite (default — zero config, local file)
304
+
305
+ ```python
306
+ ms = MemSearch(
307
+ paths=["./docs/"],
308
+ milvus_uri="~/.memsearch/milvus.db", # local file, no server needed
309
+ )
310
+ ```
311
+
312
+ No server to install. Data is stored in a single `.db` file. Perfect for personal use, single-agent setups, and development.
313
+
314
+ #### 2. Milvus Server (self-hosted)
315
+
316
+ ```python
317
+ ms = MemSearch(
318
+ paths=["./docs/"],
319
+ milvus_uri="http://localhost:19530", # your Milvus server
320
+ milvus_token="root:Milvus", # default credentials, change in production
321
+ )
322
+ ```
323
+
324
+ Deploy via Docker (`docker compose`) or Kubernetes. Ideal for multi-agent workloads and team environments where you need a shared, always-on vector store.
325
+
326
+ #### 3. Zilliz Cloud (fully managed)
327
+
328
+ ```python
329
+ ms = MemSearch(
330
+ paths=["./docs/"],
331
+ milvus_uri="https://in03-xxx.api.gcp-us-west1.zillizcloud.com",
332
+ milvus_token="your-api-key",
333
+ )
334
+ ```
335
+
336
+ Zero-ops, auto-scaling managed service. Get your free cluster at [cloud.zilliz.com](https://cloud.zilliz.com). Great for production deployments and when you don't want to manage infrastructure.
337
+
338
+ ## 🖥️ CLI Usage
339
+
340
+ ### Index markdown files
341
+
342
+ ```bash
343
+ # Index one or more directories / files
344
+ memsearch index ./docs/ ./notes/
345
+
346
+ # Use a different embedding provider
347
+ memsearch index ./docs/ --provider google
348
+
349
+ # Force re-index everything
350
+ memsearch index ./docs/ --force
351
+
352
+ # Use a remote Milvus server
353
+ memsearch index ./docs/ --milvus-uri http://localhost:19530 --milvus-token root:Milvus
354
+ ```
355
+
356
+ ### Search
357
+
358
+ ```bash
359
+ memsearch search "how to configure Redis caching"
360
+
361
+ # Return more results
362
+ memsearch search "authentication flow" --top-k 10
363
+
364
+ # JSON output (for piping to other tools)
365
+ memsearch search "error handling" --json-output
366
+ ```
367
+
368
+ ### Watch for changes
369
+
370
+ ```bash
371
+ # Auto-index on file changes (Ctrl+C to stop)
372
+ memsearch watch ./docs/ ./notes/
373
+
374
+ # Custom debounce interval
375
+ memsearch watch ./docs/ --debounce-ms 3000
376
+ ```
377
+
378
+ ### Flush (compress memories)
379
+
380
+ Summarize indexed chunks into a condensed memory using an LLM:
381
+
382
+ ```bash
383
+ memsearch flush
384
+
385
+ # Use a specific LLM
386
+ memsearch flush --llm-provider anthropic
387
+ memsearch flush --llm-provider gemini
388
+
389
+ # Only flush chunks from a specific source
390
+ memsearch flush --source ./docs/old-notes.md
391
+ ```
392
+
393
+ ### Configuration management
394
+
395
+ ```bash
396
+ memsearch config init # Interactive wizard
397
+ memsearch config set milvus.uri http://localhost:19530
398
+ memsearch config get milvus.uri
399
+ memsearch config list --resolved # Show merged config from all sources
400
+ memsearch config list --global # Show ~/.memsearch/config.toml only
401
+ memsearch config list --project # Show .memsearch.toml only
402
+ ```
403
+
404
+ ### Manage
405
+
406
+ ```bash
407
+ memsearch stats # Show index statistics
408
+ memsearch reset # Drop all indexed data (with confirmation)
409
+ ```
410
+
411
+ ## ⚙️ Configuration
412
+
413
+ memsearch uses a layered configuration system. Settings are resolved in priority order (lowest → highest):
414
+
415
+ 1. **Built-in defaults**
416
+ 2. **Global config** — `~/.memsearch/config.toml`
417
+ 3. **Project config** — `.memsearch.toml` (in your working directory)
418
+ 4. **Environment variables** — `MEMSEARCH_SECTION_FIELD` (e.g. `MEMSEARCH_MILVUS_URI`)
419
+ 5. **CLI flags** — `--milvus-uri`, `--provider`, etc.
420
+
421
+ ### API keys
422
+
423
+ API keys for embedding and LLM providers are read from standard environment variables:
424
+
425
+ ```bash
426
+ # Embedding providers (set the one you use)
427
+ export OPENAI_API_KEY="sk-..."
428
+ export OPENAI_BASE_URL="https://..." # optional, for proxies / Azure
429
+ export GOOGLE_API_KEY="..."
430
+ export VOYAGE_API_KEY="..."
431
+
432
+ # LLM for flush/summarization (set the one you use)
433
+ export ANTHROPIC_API_KEY="..." # for flush with Anthropic
434
+ ```
435
+
436
+ ## 🔌 Embedding Providers
437
+
438
+ | Provider | Install | Env Var | Default Model |
439
+ |----------|---------|---------|---------------|
440
+ | OpenAI | `memsearch` (included) | `OPENAI_API_KEY` | `text-embedding-3-small` |
441
+ | Google | `memsearch[google]` | `GOOGLE_API_KEY` | `text-embedding-004` |
442
+ | Voyage | `memsearch[voyage]` | `VOYAGE_API_KEY` | `voyage-3-lite` |
443
+ | Ollama | `memsearch[ollama]` | `OLLAMA_HOST` (optional) | `nomic-embed-text` |
444
+ | Local | `memsearch[local]` | — | `all-MiniLM-L6-v2` |
445
+
446
+ ## 🐾 OpenClaw Compatibility
447
+
448
+ memsearch is designed to be a drop-in memory backend for projects following [OpenClaw's memory architecture](https://github.com/openclaw/openclaw):
449
+
450
+ | Feature | OpenClaw | memsearch |
451
+ |---------|----------|-----------|
452
+ | Memory layout | `MEMORY.md` + `memory/YYYY-MM-DD.md` | ✅ Same |
453
+ | Chunk ID format | `hash(source:startLine:endLine:contentHash:model)` | ✅ Same |
454
+ | Dedup strategy | Content-hash primary key | ✅ Same |
455
+ | Flush target | Append to daily markdown log | ✅ Same |
456
+ | Source of truth | Markdown files (vector DB is derived) | ✅ Same |
457
+ | File watch debounce | 1500ms | ✅ Same default |
458
+ | Vector backend | Built-in | Milvus (Lite / Server / Zilliz Cloud) |
459
+ | Embedding providers | Built-in | Pluggable (OpenAI, Google, Voyage, Ollama, local) |
460
+ | Packaging | Part of OpenClaw monorepo | Standalone `pip install` |
461
+
462
+ If you're already using OpenClaw's memory directory layout, just point memsearch at it — no migration needed.
463
+
464
+ ## 📄 License
465
+
466
+ MIT