feat(mem0-plugin): v0.2.5 — fix identity scoping, skill param bugs, add checklists (#5247)
This commit is contained in:
@@ -22,12 +22,10 @@ Pre-fetches relevant memories to prime context before working on a task.
|
||||
|
||||
| Query angle | Filter | Purpose |
|
||||
|---|---|---|
|
||||
| Feature/module name | `{"metadata": {"type": "decision"}}` | Architecture decisions |
|
||||
| File paths mentioned | `{"metadata": {"type": "convention"}}` | Coding patterns |
|
||||
| Error keywords (if any) | `{"metadata": {"type": "anti_pattern"}}` | Known pitfalls |
|
||||
| Broad project context | no metadata filter | Catch-all |
|
||||
|
||||
All calls must include `user_id` and `app_id` filters.
|
||||
| Feature/module name | `{"AND": [{"user_id": "<id>"}, {"app_id": "<pid>"}, {"metadata": {"type": "decision"}}]}` | Architecture decisions |
|
||||
| File paths mentioned | `{"AND": [{"user_id": "<id>"}, {"app_id": "<pid>"}, {"metadata": {"type": "convention"}}]}` | Coding patterns |
|
||||
| Error keywords (if any) | `{"AND": [{"user_id": "<id>"}, {"app_id": "<pid>"}, {"metadata": {"type": "anti_pattern"}}]}` | Known pitfalls |
|
||||
| Broad project context | `{"AND": [{"user_id": "<id>"}, {"app_id": "<pid>"}]}` | Catch-all |
|
||||
|
||||
3. **Deduplicate** results by memory ID across all search responses.
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ identifies near-duplicates, flags contradictions, and prunes stale entries based
|
||||
configured retention policies. All proposed changes are shown as a diff for user
|
||||
approval before anything is modified.
|
||||
|
||||
---
|
||||
**IMPORTANT: Execute steps strictly in order (1 → 2 → 3 → 4 → 5 → 6). Each step depends on the previous one. Do NOT run steps in parallel or skip ahead.**
|
||||
|
||||
## Step 1: Load Retention Policies
|
||||
|
||||
@@ -99,7 +99,7 @@ confidence.
|
||||
|
||||
---
|
||||
|
||||
## Step 4: Print Diff Report (item 15)
|
||||
## Step 4: Print Diff Report
|
||||
|
||||
Print a structured diff to the terminal before making any changes. Use exactly
|
||||
this format:
|
||||
@@ -159,7 +159,7 @@ For each approved merge pair:
|
||||
1. `delete_memory(<id1>)`
|
||||
2. `delete_memory(<id2>)`
|
||||
3. `add_memory` with:
|
||||
- `messages=[{"role": "user", "content": "<merged content>"}]`
|
||||
- `text="<merged content>"`
|
||||
- `user_id=<active_user_id>`
|
||||
- `app_id=<active_project_id>` (top-level, not in metadata)
|
||||
- `metadata={"type": "<original type>", "branch": "<active_branch>", "confidence": <higher of the two original scores>, "source": "mem0-dream"}`
|
||||
@@ -168,10 +168,7 @@ For each approved merge pair:
|
||||
#### Contradictions (resolved)
|
||||
|
||||
For each resolved conflict where the user chose A or B:
|
||||
- Identify the loser (the non-chosen memory).
|
||||
- First call `get_memory(<loser_id>)` to read its current text content.
|
||||
- Then call `update_memory(<loser_id>, text=<original_text_content>)` to preserve the text while updating it.
|
||||
- **Important:** `update_memory` requires the `text` parameter. A metadata-only call may error or wipe the content. Always read first, then update with the original text.
|
||||
- Delete the loser (the non-chosen memory): `delete_memory(memory_id=<loser_id>)`
|
||||
|
||||
Contradictions where the user chose `skip` are left untouched.
|
||||
|
||||
@@ -200,6 +197,14 @@ When invoked with `--auto` (e.g., `/mem0:dream --auto`), run non-interactively:
|
||||
- **Prunes**: applied automatically (age/confidence-based, no ambiguity).
|
||||
- **Contradictions**: skipped — they require human judgment.
|
||||
|
||||
### Concurrency guard
|
||||
|
||||
Before doing any work, check for a lock file at `/tmp/mem0_dream_auto.lock`:
|
||||
- If the lock file exists and is less than 10 minutes old, print `[mem0-dream --auto] Another run in progress — skipping.` and stop.
|
||||
- Otherwise, create the lock file (write the current timestamp). Delete it when done (in all exit paths).
|
||||
|
||||
### Execution
|
||||
|
||||
In auto mode:
|
||||
1. Load policies and fetch memories (Steps 1–3) as normal.
|
||||
2. Apply merges and prunes silently without printing the diff or prompting.
|
||||
@@ -207,10 +212,13 @@ In auto mode:
|
||||
```
|
||||
[mem0-dream --auto] project=<id> merged=<N> pruned=<N> conflicts_skipped=<N>
|
||||
```
|
||||
4. If contradictions were detected but skipped, store a reminder memory:
|
||||
4. If contradictions were detected but skipped, check if a `mem0-dream-auto` reminder already exists before storing one:
|
||||
- Search for existing reminders: `search_memories(query="mem0-dream contradictions manual review", filters={"AND": [{"user_id": "<active_user_id>"}, {"app_id": "<active_project_id>"}, {"metadata": {"source": "mem0-dream-auto"}}]}, top_k=1)`
|
||||
- If a result exists with similarity > 0.9, skip storing the reminder (one already exists).
|
||||
- If no match, store the reminder:
|
||||
```python
|
||||
add_memory(
|
||||
messages=[{"role": "user", "content": "mem0-dream detected <N> contradiction(s) requiring manual review. Run /mem0:dream to resolve them interactively."}],
|
||||
text="mem0-dream detected <N> contradiction(s) requiring manual review. Run /mem0:dream to resolve them interactively.",
|
||||
user_id="<active_user_id>",
|
||||
app_id="<active_project_id>",
|
||||
metadata={"type": "task_learning", "source": "mem0-dream-auto", "branch": "<active_branch>"},
|
||||
|
||||
@@ -18,8 +18,7 @@ Determine the active identity:
|
||||
### Step 2: Fetch all memories
|
||||
|
||||
Call `get_memories` with:
|
||||
- `user_id=<active_user_id>`
|
||||
- `app_id=<active_project_id>`
|
||||
- `filters={"AND": [{"user_id": "<active_user_id>"}, {"app_id": "<active_project_id>"}]}`
|
||||
- `page_size=200`
|
||||
|
||||
If the response is paginated (i.e. the result contains a `next` cursor or the count equals `page_size`), continue fetching pages until all memories are retrieved.
|
||||
|
||||
@@ -14,26 +14,38 @@ Run ALL checks, then display a single summary. Do not stop on the first failure.
|
||||
### Check 1: API key
|
||||
|
||||
```bash
|
||||
echo "${MEM0_API_KEY:-${CLAUDE_PLUGIN_OPTION_MEM0_API_KEY:-NOT_SET}}"
|
||||
_KEY="${MEM0_API_KEY:-${CLAUDE_PLUGIN_OPTION_MEM0_API_KEY:-}}"
|
||||
[ -n "$_KEY" ] && echo "${_KEY:0:6}..." || echo "NOT_SET"
|
||||
```
|
||||
|
||||
- If `NOT_SET`: FAIL — "No API key configured"
|
||||
- If set: PASS — show first 6 chars + `...` (never print the full key)
|
||||
- If set: PASS — the command already prints only the first 6 chars
|
||||
|
||||
### Check 2: Identity resolution
|
||||
|
||||
Read the active identity from the SessionStart banner or resolve manually:
|
||||
- `user_id`: from `MEM0_RESOLVED_USER_ID` or `$USER`
|
||||
- `project_id`: from `MEM0_PROJECT_ID` or current directory name
|
||||
- `branch`: from `MEM0_BRANCH` or `git rev-parse --abbrev-ref HEAD`
|
||||
Resolve identity using the plugin's own resolver scripts to match what hooks use:
|
||||
|
||||
```bash
|
||||
SCRIPT_DIR="${CLAUDE_PLUGIN_ROOT:-${CODEX_PLUGIN_ROOT:-${CURSOR_PLUGIN_ROOT:-}}}/scripts"
|
||||
source "$SCRIPT_DIR/_identity.sh" 2>/dev/null
|
||||
echo "user_id=${MEM0_RESOLVED_USER_ID:-}"
|
||||
echo "project_id=${MEM0_PROJECT_ID:-}"
|
||||
echo "branch=${MEM0_BRANCH:-}"
|
||||
```
|
||||
|
||||
If `CLAUDE_PLUGIN_ROOT` is not available, fall back to:
|
||||
- `user_id`: from `MEM0_USER_ID` or `$USER`
|
||||
- `project_id`: from `MEM0_PROJECT_ID` or check `~/.mem0/project_map.json` for `$PWD`
|
||||
- `branch`: from `git branch --show-current`
|
||||
|
||||
PASS if all three are non-empty. WARN if any falls back to defaults.
|
||||
|
||||
### Check 3: MCP server connectivity
|
||||
|
||||
Call `search_memories` with:
|
||||
- `query="health check"`, `user_id=<id>`, `limit=1`
|
||||
- `filters={"AND": [{"user_id": "<id>"}, {"app_id": "<project_id>"}]}`
|
||||
- `query="health check"`
|
||||
- `filters={"AND": [{"user_id": "<active_user_id>"}, {"app_id": "<active_project_id>"}]}`
|
||||
- `top_k=1`
|
||||
|
||||
- If returns successfully (even empty): PASS
|
||||
- If errors: FAIL — show the error message
|
||||
@@ -41,12 +53,17 @@ Call `search_memories` with:
|
||||
### Check 4: Memory write capability
|
||||
|
||||
Call `add_memory` with:
|
||||
- `messages=[{"role": "user", "content": "Health check probe — safe to delete."}]`
|
||||
- `user_id=<id>`, `app_id=<project_id>`
|
||||
- `text="Health check probe — safe to delete."`
|
||||
- `user_id=<active_user_id>`
|
||||
- `app_id=<active_project_id>`
|
||||
- `metadata={"type": "health_check", "probe": true}`
|
||||
- `infer=False`
|
||||
|
||||
If it returns a memory ID: PASS — then immediately call `delete_memory` with that ID to clean up.
|
||||
If it errors: FAIL — show the error.
|
||||
The response returns `event_id` (v3 writes are async). Call `get_event_status(event_id=<event_id>)` to check processing.
|
||||
|
||||
- If status is `SUCCEEDED`: PASS — extract the memory ID from the event result, then call `delete_memory` with that ID to clean up.
|
||||
- If status is `PENDING` after 5 seconds: PASS (write accepted, processing delayed)
|
||||
- If errors: FAIL — show the error.
|
||||
|
||||
### Check 5: Session stats tracker
|
||||
|
||||
@@ -85,7 +102,7 @@ When invoked with `--deep` (e.g., `/mem0:health --deep`), run the standard 5 che
|
||||
|
||||
### Quality Check 1: Duplicates
|
||||
|
||||
Call `get_memories` with `user_id`, `app_id`, `page_size=200`. Compare all pairs within the same `metadata.type` group for high textual overlap (shared nouns/keywords > 60%). Report:
|
||||
Call `get_memories` with `filters={"AND": [{"user_id": "<active_user_id>"}, {"app_id": "<active_project_id>"}]}`, `page_size=200`. Compare all pairs within the same `metadata.type` group for high textual overlap (shared nouns/keywords > 60%). Report:
|
||||
|
||||
```
|
||||
Potential duplicates: <N> pairs
|
||||
|
||||
@@ -63,7 +63,7 @@ Determine the active identity:
|
||||
|
||||
For each record in the parsed JSON array, call `add_memory` with:
|
||||
|
||||
- `messages=[{"role": "user", "content": "<record.content>"}]`
|
||||
- `text="<record.content>"`
|
||||
- `user_id=<active_user_id>`
|
||||
- `app_id=<active_project_id>`
|
||||
- `metadata={`
|
||||
@@ -156,7 +156,7 @@ detects native auto-memory and the user chooses to import:
|
||||
2. Split by non-empty lines. Each line becomes one memory.
|
||||
3. Skip lines shorter than 20 characters or lines that are just headers (`#`).
|
||||
4. For each line, call `add_memory` with:
|
||||
- `messages=[{"role": "user", "content": "<line>"}]`
|
||||
- `text="<line>"`
|
||||
- `user_id=<active_user_id>`
|
||||
- `app_id=<active_project_id>`
|
||||
- `metadata={"type": "task_learning", "source": "memory-md-import", "confidence": 0.8}`
|
||||
|
||||
@@ -16,7 +16,7 @@ Audits memory quality for the active project. Finds duplicates, contradictions,
|
||||
|
||||
## Steps
|
||||
|
||||
1. **Fetch all memories** for active project via `get_memories` with `user_id` and `app_id`. Paginate if needed — cap at 200 memories.
|
||||
1. **Fetch all memories** for active project via `get_memories` with `filters={"AND": [{"user_id": "<active_user_id>"}, {"app_id": "<active_project_id>"}]}`, `page_size=200`. Paginate if needed — cap at 200 memories.
|
||||
|
||||
2. **Group by `metadata.type`**. Common types: `decision`, `convention`, `anti_pattern`, `task_learning`, `project_profile`, `user_preference`, `session_state`.
|
||||
|
||||
|
||||
@@ -7,6 +7,8 @@ description: Sets up mem0 for a new project including API key configuration, MCP
|
||||
|
||||
Run this wizard to set up the mem0 plugin for the current project. Complete in ~60 seconds.
|
||||
|
||||
**IMPORTANT: Execute steps strictly in order (0 → 1 → 2 → 3 → 4 → 5 → 6). Each step depends on the previous one. Do NOT run steps in parallel or skip ahead. Complete one step fully before starting the next.**
|
||||
|
||||
## Step 0: Ensure mem0ai SDK is installed
|
||||
|
||||
The plugin installs the `mem0ai` Python SDK automatically on session start via a venv in `${CLAUDE_PLUGIN_DATA}/venv`. If Step 5 (categories) fails with an import error, run:
|
||||
@@ -22,10 +24,12 @@ This is silent and idempotent — safe to run anytime.
|
||||
Check if `MEM0_API_KEY` is already set by running:
|
||||
|
||||
```bash
|
||||
echo $MEM0_API_KEY
|
||||
[ -n "$MEM0_API_KEY" ] && echo "SET" || echo "NOT_SET"
|
||||
```
|
||||
|
||||
### If API key IS set (non-empty output)
|
||||
IMPORTANT: Never run `echo $MEM0_API_KEY` — that prints the secret in plaintext to the conversation log.
|
||||
|
||||
### If API key IS set (output is "SET")
|
||||
|
||||
Print: `- API key found.` and proceed to Step 2.
|
||||
|
||||
@@ -46,15 +50,18 @@ Step 1: Setting up API key.
|
||||
source ~/.zshrc
|
||||
|
||||
3. Verify:
|
||||
echo $MEM0_API_KEY
|
||||
# Should print your key
|
||||
[ -n "$MEM0_API_KEY" ] && echo "SET" || echo "NOT_SET"
|
||||
```
|
||||
|
||||
After the user confirms they've set the key, verify it by running `echo $MEM0_API_KEY`. If still empty, repeat the instructions. If set, proceed to Step 2.
|
||||
After the user confirms they've set the key, verify it by running `[ -n "$MEM0_API_KEY" ] && echo "SET" || echo "NOT_SET"`. If NOT_SET, repeat the instructions. If SET, proceed to Step 2.
|
||||
|
||||
## Step 2: MCP OAuth login
|
||||
## Step 2: MCP server connection
|
||||
|
||||
Now authenticate the MCP server connection. Tell the user:
|
||||
First, check if MCP tools are already available using ToolSearch with query `"mem0 search_memories"`. The exact tool name varies by install method (may be `mcp__mem0__search_memories` or `mcp__plugin_mem0_mem0__search_memories`).
|
||||
|
||||
**If MCP tools ARE found:** Print `- MCP already connected.` and proceed to Step 3.
|
||||
|
||||
**If MCP tools are NOT found:** Guide the user through OAuth:
|
||||
|
||||
```
|
||||
Step 2: MCP OAuth login.
|
||||
@@ -65,7 +72,7 @@ Step 2: MCP OAuth login.
|
||||
4. Return here after authenticating in your browser
|
||||
```
|
||||
|
||||
After the user completes OAuth, verify MCP tools are available using ToolSearch with query `"mem0 search_memories"`. The exact tool name varies by install method (may be `mcp__mem0__search_memories` or `mcp__plugin_mem0_mem0__search_memories`).
|
||||
After the user completes OAuth, verify MCP tools again using ToolSearch.
|
||||
|
||||
- If MCP tools found: Print `- MCP connected.` and proceed to Step 3.
|
||||
- If NOT found: Troubleshoot before giving up:
|
||||
@@ -77,7 +84,7 @@ After the user completes OAuth, verify MCP tools are available using ToolSearch
|
||||
|
||||
## Step 3: Verify connectivity and show identity
|
||||
|
||||
Call `search_memories` with `query="project setup"`, `user_id=<active_user_id>`, `filters={"AND": [{"user_id": "<active_user_id>"}, {"app_id": "<active_project_id>"}]}`, `limit=1` to verify connectivity.
|
||||
Call `search_memories` with `query="project setup"`, `filters={"AND": [{"user_id": "<active_user_id>"}, {"app_id": "<active_project_id>"}]}`, `top_k=1` to verify connectivity.
|
||||
|
||||
Print:
|
||||
```
|
||||
@@ -89,29 +96,54 @@ Print:
|
||||
|
||||
If the search fails, troubleshoot the API key and MCP connection.
|
||||
|
||||
## Step 4: Detect and import project files
|
||||
## Step 4: Import project files
|
||||
|
||||
Check for these files in the project root:
|
||||
1. `CLAUDE.md`
|
||||
2. `AGENTS.md`
|
||||
3. `.cursorrules`
|
||||
4. `.windsurfrules`
|
||||
5. `mem0.md`
|
||||
Project files (CLAUDE.md, AGENTS.md, etc.) are automatically imported into mem0 when a session starts. This step verifies import status and triggers a re-import if needed.
|
||||
|
||||
For each file found, ask the user: "Found `<filename>` (<size> bytes). Import into mem0? [Y/n]"
|
||||
### 4a: Detect project files
|
||||
|
||||
If user says yes (or default):
|
||||
- Read the file content
|
||||
- Call `add_memory` with:
|
||||
- `messages=[{"role": "user", "content": "## Project Profile: <filename>\n\nProject: <project_id>\n\n<file_content>"}]`
|
||||
- `user_id=<active_user_id>`
|
||||
- `app_id=<active_project_id>`
|
||||
- `metadata={"type": "project_profile", "file": "<filename>", "source": "onboard", "branch": "<active_branch>"}`
|
||||
- `infer=False`
|
||||
- The response contains `event_id` (writes are async). Do not block on each — continue importing. The summary reflects files submitted, not confirmed processed.
|
||||
```bash
|
||||
for f in CLAUDE.md AGENTS.md .cursorrules .windsurfrules mem0.md; do
|
||||
[ -f "$f" ] && echo "FOUND: $f ($(wc -c < "$f") bytes)"
|
||||
done || true
|
||||
```
|
||||
|
||||
If no files found, print `- No project files found. Skipping import.` and proceed to Step 5.
|
||||
|
||||
### 4b: Check and import
|
||||
|
||||
Run auto_import in foreground to check status and import if needed:
|
||||
|
||||
```bash
|
||||
MEM0_DEBUG=1 MEM0_CWD="$PWD" python3 "${CLAUDE_PLUGIN_ROOT}/scripts/auto_import.py"
|
||||
```
|
||||
|
||||
### 4c: Report to user
|
||||
|
||||
Parse the auto_import output and print a user-friendly summary:
|
||||
|
||||
- If output contains `Imported` lines:
|
||||
```
|
||||
- Importing project files into mem0... done.
|
||||
<N> file(s) imported (<M> chunks). These are stored verbatim for future context.
|
||||
```
|
||||
- If output contains only `skipping` lines:
|
||||
```
|
||||
- Project files already in mem0 (imported during session start). Verified server-side.
|
||||
```
|
||||
- If output contains `re-importing`:
|
||||
```
|
||||
- Project files were missing from mem0. Re-imported successfully.
|
||||
```
|
||||
- If output contains errors or no files were processed:
|
||||
```
|
||||
- Project file import failed. Check API key and retry with: /mem0:onboard
|
||||
```
|
||||
|
||||
## Step 5: Install coding categories
|
||||
|
||||
The setup script is idempotent — it compares existing categories against the proposed set and skips the API call if they already match (tolerates order differences and extra API fields). Safe to re-run.
|
||||
|
||||
Ask: "Install coding categories optimized for development workflows? [Y/n]"
|
||||
|
||||
If yes, run the setup script using the plugin's venv python:
|
||||
@@ -125,6 +157,11 @@ else
|
||||
fi
|
||||
```
|
||||
|
||||
Parse the output:
|
||||
- `"Categories already match -- skipping update."` → Print: `- Coding categories already installed. Skipped.`
|
||||
- `"Done."` → Print: `- Coding categories installed (<N> categories).`
|
||||
- Error → Print the error and suggest re-running `/mem0:onboard`.
|
||||
|
||||
If the script fails with "mem0ai SDK not found", run the dependency installer first:
|
||||
```bash
|
||||
"${CLAUDE_PLUGIN_ROOT}/scripts/ensure_deps.sh"
|
||||
@@ -138,8 +175,8 @@ Print a summary:
|
||||
- Onboarding complete.
|
||||
user_id: <user_id>
|
||||
project_id: <project_id> (app_id)
|
||||
imported: <N> files
|
||||
categories: <installed or skipped>
|
||||
files: <N> found, <M> imported
|
||||
categories: <N installed | already installed | skipped by user>
|
||||
|
||||
Memory is now active for this project. Start working — mem0 will
|
||||
automatically search relevant context and capture learnings.
|
||||
|
||||
@@ -29,20 +29,21 @@ Call `get_memory` with the selected memory ID. Store:
|
||||
|
||||
### Step 3: Pin it
|
||||
|
||||
Call `update_memory` with:
|
||||
- `memory_id=<selected_id>`
|
||||
- `text=<original_text>` (preserve existing content)
|
||||
- `metadata=` merge `original_metadata` with `{"pinned": true}`
|
||||
The MCP `update_memory` tool only accepts `memory_id`, `text`, and `source` — it
|
||||
does not accept a `metadata` parameter. To pin, append a pin marker to the text:
|
||||
|
||||
```python
|
||||
updated_meta = {**original_metadata, "pinned": True}
|
||||
update_memory(memory_id=<selected_id>, text=<original_text>, metadata=updated_meta)
|
||||
pinned_text = "[PINNED] " + original_text if not original_text.startswith("[PINNED]") else original_text
|
||||
update_memory(memory_id=<selected_id>, text=pinned_text)
|
||||
```
|
||||
|
||||
**Important:** `update_memory` requires the `text` parameter. Passing only metadata may error or wipe content.
|
||||
|
||||
**For new memories** (user wants to pin text that isn't stored yet):
|
||||
1. Call `add_memory` with the text + `metadata={"pinned": true, "type": "decision", "confidence": 1.0}`
|
||||
1. Call `add_memory` with:
|
||||
- `text="[PINNED] <the user's text>"`
|
||||
- `user_id=<active_user_id>`
|
||||
- `app_id=<active_project_id>`
|
||||
- `metadata={"pinned": true, "type": "decision", "confidence": 1.0}`
|
||||
- `infer=False`
|
||||
2. The response contains `event_id`. Call `get_event_status(event_id=<event_id>)` once to retrieve the memory ID, then confirm.
|
||||
|
||||
### Step 4: Confirm
|
||||
@@ -57,10 +58,10 @@ Append `...` only if content exceeds 80 characters.
|
||||
### Unpin
|
||||
|
||||
If the user says "unpin":
|
||||
1. Call `get_memory` to read current content and metadata.
|
||||
2. Set `metadata.pinned = false`:
|
||||
1. Call `get_memory` to read current content.
|
||||
2. Remove the pin marker from the text:
|
||||
```python
|
||||
updated_meta = {**original_metadata, "pinned": False}
|
||||
update_memory(memory_id=<id>, text=<original_text>, metadata=updated_meta)
|
||||
unpinned_text = original_text.removeprefix("[PINNED] ")
|
||||
update_memory(memory_id=<id>, text=unpinned_text)
|
||||
```
|
||||
3. Print: `Unpinned: "<content>..."`
|
||||
|
||||
@@ -32,7 +32,7 @@ Based on the content, pick the best `metadata.type`:
|
||||
### Step 3: Store
|
||||
|
||||
Call `add_memory` with:
|
||||
- `messages=[{"role": "user", "content": "<the user's text>"}]`
|
||||
- `text="<the user's text>"`
|
||||
- `user_id=<active_user_id>`
|
||||
- `app_id=<active_project_id>`
|
||||
- `metadata={"type": "<classified_type>", "branch": "<active_branch>", "confidence": 1.0, "source": "remember_command"}`
|
||||
|
||||
@@ -26,8 +26,7 @@ If the script returns empty or errors, note "No session data available" and cont
|
||||
|
||||
**Lifetime stats:**
|
||||
Call `get_memories` with:
|
||||
- `user_id=<active_user_id>`
|
||||
- `app_id=<active_project_id>`
|
||||
- `filters={"AND": [{"user_id": "<active_user_id>"}, {"app_id": "<active_project_id>"}]}`
|
||||
- `page_size=100`
|
||||
|
||||
Count the returned memories. Group them by:
|
||||
@@ -38,14 +37,14 @@ Count the returned memories. Group them by:
|
||||
**Session stats (API-backed):**
|
||||
Read the session ID file at `/tmp/mem0_session_id_$USER`. If it exists and contains
|
||||
a non-empty value, also call `get_memories` with:
|
||||
- `filters={"AND": [{"user_id": "<id>"}, {"app_id": "<pid>"}, {"run_id": "<session_id>"}]}`
|
||||
- `filters={"AND": [{"user_id": "<active_user_id>"}, {"app_id": "<active_project_id>"}, {"run_id": "<session_id>"}]}`
|
||||
- `page_size=100`
|
||||
|
||||
This returns only memories written in the current session. Use this count to
|
||||
cross-check the local stats file. If the API count is higher, use the API count
|
||||
(the local tracker may have missed operations).
|
||||
|
||||
Also run a `search_memories` call with `query="project"`, `top_k=1` to measure round-trip latency (time the call).
|
||||
Also run a `search_memories` MCP tool call with `query="project"`, `filters={"AND": [{"user_id": "<active_user_id>"}, {"app_id": "<active_project_id>"}]}`, `top_k=1` to measure round-trip latency. Note the time before and after the MCP call — do NOT attempt raw HTTP calls to the API.
|
||||
|
||||
### Step 3: Display
|
||||
|
||||
@@ -88,9 +87,9 @@ activity digest after the standard stats dashboard:
|
||||
### W1: Fetch recent memories
|
||||
|
||||
Call `search_memories` in parallel with time-scoped queries:
|
||||
1. `query="decisions made this week"`, `filters={"AND": [{"user_id": "<id>"}, {"app_id": "<pid>"}, {"created_at": {"gte": "<7 days ago YYYY-MM-DD>"}}]}`, `limit=20`
|
||||
2. `query="bugs errors fixes"`, same time filter, `limit=20`
|
||||
3. `query="patterns conventions learnings"`, same time filter, `limit=20`
|
||||
1. `query="decisions made this week"`, `filters={"AND": [{"user_id": "<id>"}, {"app_id": "<pid>"}, {"created_at": {"gte": "<7 days ago YYYY-MM-DD>"}}]}`, `top_k=20`
|
||||
2. `query="bugs errors fixes"`, same time filter, `top_k=20`
|
||||
3. `query="patterns conventions learnings"`, same time filter, `top_k=20`
|
||||
|
||||
### W2: Analyze
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ The user provides a project name as an argument: `/mem0:switch-project <project-
|
||||
(Replace `<PROJECT_NAME>` with the user's chosen project name.)
|
||||
|
||||
3. Verify by searching for existing memories:
|
||||
- Call `search_memories` with `query="project"`, `filters={"AND": [{"user_id": "<id>"}, {"app_id": "<PROJECT_NAME>"}]}`, `limit=1`
|
||||
- Call `search_memories` with `query="project"`, `filters={"AND": [{"user_id": "<active_user_id>"}, {"app_id": "<PROJECT_NAME>"}]}`, `top_k=1`
|
||||
|
||||
4. Print:
|
||||
```
|
||||
|
||||
@@ -12,9 +12,9 @@ Show the user what mem0 has stored for the current project.
|
||||
When invoked with `--all-projects` (e.g., `/mem0:tour --all-projects` or
|
||||
`/mem0:tour --all-projects auth middleware`), search across ALL projects:
|
||||
|
||||
1. Call `get_memories` with `user_id=<active_user_id>`, `page_size=200` — **no `app_id` filter**.
|
||||
1. Call `get_memories` with `filters={"AND": [{"user_id": "<active_user_id>"}]}`, `page_size=200` — **no `app_id` filter**.
|
||||
2. If a search query was also provided, run `search_memories` with `query=<query>`,
|
||||
`filters={"AND": [{"user_id": "<id>"}]}`, `limit=20` — again no `app_id`.
|
||||
`filters={"AND": [{"user_id": "<active_user_id>"}]}`, `top_k=20` — again no `app_id`.
|
||||
3. Group results by `app_id` first, then by category within each project.
|
||||
4. Display:
|
||||
```
|
||||
@@ -37,8 +37,8 @@ When `/mem0:tour` receives a search query argument (e.g., `/mem0:tour auth middl
|
||||
WITHOUT `--all-projects`, run in **peek mode** — compact one-liner results:
|
||||
|
||||
1. Run 2 parallel `search_memories` calls:
|
||||
- Broad: `query=<query>`, `filters={"AND": [{"user_id": "<id>"}, {"app_id": "<pid>"}]}`, `limit=10`, `rerank=true`
|
||||
- Targeted: `query=<query>`, `filters={"AND": [{"user_id": "<id>"}, {"app_id": "<pid>"}, {"metadata": {"type": "decision"}}]}`, `limit=5`, `rerank=true`
|
||||
- Broad: `query=<query>`, `filters={"AND": [{"user_id": "<id>"}, {"app_id": "<pid>"}]}`, `top_k=10`, `rerank=true`
|
||||
- Targeted: `query=<query>`, `filters={"AND": [{"user_id": "<id>"}, {"app_id": "<pid>"}, {"metadata": {"type": "decision"}}]}`, `top_k=5`, `rerank=true`
|
||||
2. Deduplicate by ID, display compact results:
|
||||
```
|
||||
## mem0 search: "<query>" (<N> results)
|
||||
@@ -57,23 +57,18 @@ If no query argument and no `--all-projects` flag, use the full tour flow below.
|
||||
### Step 1: Fetch ALL memories for this project
|
||||
|
||||
Call `get_memories` with:
|
||||
- `user_id=<active_user_id>`
|
||||
- `app_id=<active_project_id>`
|
||||
- `filters={"AND": [{"user_id": "<active_user_id>"}, {"app_id": "<active_project_id>"}]}`
|
||||
- `page_size=100`
|
||||
|
||||
This returns every memory scoped to the project — no semantic filtering, no missed results.
|
||||
|
||||
If `get_memories` doesn't support `app_id` as a direct parameter, use:
|
||||
- `filters={"AND": [{"user_id": "<id>"}, {"app_id": "<pid>"}]}`
|
||||
|
||||
Pass `page_size=100` (or the maximum allowed) to get a full picture.
|
||||
|
||||
### Step 2: Run supplementary semantic searches
|
||||
|
||||
In parallel, run these `search_memories` calls to get relevance-ranked results for key topics:
|
||||
|
||||
- `query="architecture decisions design choices"`, `filters={"AND": [{"user_id": "<id>"}, {"app_id": "<pid>"}]}`, `limit=10`, `rerank=true`
|
||||
- `query="bugs errors failures anti-patterns"`, `filters={"AND": [{"user_id": "<id>"}, {"app_id": "<pid>"}]}`, `limit=10`, `rerank=true`
|
||||
- `query="project setup tooling conventions preferences"`, `filters={"AND": [{"user_id": "<id>"}, {"app_id": "<pid>"}]}`, `limit=10`, `rerank=true`
|
||||
- `query="architecture decisions design choices"`, `filters={"AND": [{"user_id": "<id>"}, {"app_id": "<pid>"}]}`, `top_k=10`, `rerank=true`
|
||||
- `query="bugs errors failures anti-patterns"`, `filters={"AND": [{"user_id": "<id>"}, {"app_id": "<pid>"}]}`, `top_k=10`, `rerank=true`
|
||||
- `query="project setup tooling conventions preferences"`, `filters={"AND": [{"user_id": "<id>"}, {"app_id": "<pid>"}]}`, `top_k=10`, `rerank=true`
|
||||
|
||||
**Do NOT filter by `metadata.type` in these calls.** The platform auto-assigns `categories` — filtering on `metadata.type` misses memories that were auto-categorized but don't have an explicit `metadata.type`.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user