feat(plugin): coding-focused custom-category setup script
mem0 auto-tags every memory with one or more `categories` from a
project-level list. The default list is consumer-oriented (food,
hobbies, music, ...), which produces meaningless tags for code
workflows.
Per-request `custom_categories` is not supported on the managed API,
so the fix has to be a one-time project-level configuration. New
script `setup_coding_categories.py` does this:
- Dry-run by default: prints current vs proposed taxonomy, exits.
- `--apply` flag actually calls `project.update(custom_categories=...)`.
- Falls back gracefully when mem0ai SDK isn't installed or
MEM0_API_KEY is missing/invalid (friendly error, no stack trace).
Recommended taxonomy:
architecture_decisions, anti_patterns, task_learnings,
tooling_setup, bug_fixes, coding_conventions, user_preferences
Skill clarification: `metadata.type` (agent-applied explicit tag,
used in filters) and `categories` (platform-applied auto-tag, used
in dashboards) are complementary; agent should keep using
`metadata.type` and not try to set `categories` per-request.
README: section under Step 2 explaining how to run the script.
This commit is contained in:
@@ -157,6 +157,20 @@ After installing, confirm the MCP server is connected:
|
|||||||
- **Mem0 SDK Skill** — Guides the AI on how to integrate the Mem0 SDK (Python & TypeScript) into your applications.
|
- **Mem0 SDK Skill** — Guides the AI on how to integrate the Mem0 SDK (Python & TypeScript) into your applications.
|
||||||
- **Memory Protocol Skill** — Codex-specific skill that instructs the agent to retrieve relevant memories at task start, store learnings on completion, and capture session state before context loss. Complements the lifecycle hooks on Codex.
|
- **Memory Protocol Skill** — Codex-specific skill that instructs the agent to retrieve relevant memories at task start, store learnings on completion, and capture session state before context loss. Complements the lifecycle hooks on Codex.
|
||||||
|
|
||||||
|
## Optional: tune categories for coding workflows
|
||||||
|
|
||||||
|
mem0 auto-tags every memory with one or more `categories` from a project-level list. The default list is consumer-oriented (`food`, `hobbies`, `music` …) — useful for chat assistants, less so for code. A one-shot script in this plugin replaces it with a coding-focused taxonomy:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Dry-run first -- prints current vs proposed, no changes:
|
||||||
|
python mem0-plugin/scripts/setup_coding_categories.py
|
||||||
|
|
||||||
|
# Actually write:
|
||||||
|
python mem0-plugin/scripts/setup_coding_categories.py --apply
|
||||||
|
```
|
||||||
|
|
||||||
|
Requires the `mem0ai` Python SDK (`pip install mem0ai`) and `MEM0_API_KEY` set. New memories will then auto-tag against `architecture_decisions`, `anti_patterns`, `task_learnings`, `tooling_setup`, `bug_fixes`, `coding_conventions`, `user_preferences`. Re-run with a different list any time; `project.update(custom_categories=[...])` always replaces.
|
||||||
|
|
||||||
## MCP Tools
|
## MCP Tools
|
||||||
|
|
||||||
Once installed, the following tools are available:
|
Once installed, the following tools are available:
|
||||||
|
|||||||
@@ -0,0 +1,142 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""Replace mem0's default category taxonomy with one tuned for coding workflows.
|
||||||
|
|
||||||
|
mem0 auto-tags every memory with one or more `categories`. By default the list
|
||||||
|
is consumer-oriented (food, hobbies, music, ...), which is meaningless for code.
|
||||||
|
This script replaces the project's category list with a coding-focused one.
|
||||||
|
|
||||||
|
The change is project-level (per the platform docs, per-request overrides are
|
||||||
|
not supported on the managed API). Run once per project; future memories will
|
||||||
|
be tagged using the new list automatically.
|
||||||
|
|
||||||
|
Usage:
|
||||||
|
python setup_coding_categories.py # dry-run: show current vs proposed, no changes
|
||||||
|
python setup_coding_categories.py --apply # actually call project.update()
|
||||||
|
|
||||||
|
Requires the mem0ai Python SDK and MEM0_API_KEY to be set.
|
||||||
|
"""
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import argparse
|
||||||
|
import json
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
|
||||||
|
CODING_CATEGORIES = [
|
||||||
|
{
|
||||||
|
"architecture_decisions": (
|
||||||
|
"Design choices, system structure, technology selection, trade-offs evaluated, "
|
||||||
|
"and architectural patterns adopted in the project."
|
||||||
|
)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"anti_patterns": (
|
||||||
|
"Approaches that failed, debugging dead-ends, common mistakes to avoid, "
|
||||||
|
"and lessons learned from things that didn't work."
|
||||||
|
)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"task_learnings": (
|
||||||
|
"Strategies and approaches that succeeded for specific tasks, including tooling "
|
||||||
|
"tricks, workflow shortcuts, and effective problem-solving patterns."
|
||||||
|
)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"tooling_setup": (
|
||||||
|
"Development environment, build tools, dependencies, package managers, deploy "
|
||||||
|
"pipelines, and configuration steps for the project."
|
||||||
|
)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"bug_fixes": (
|
||||||
|
"Specific bug fixes with root cause analysis, the fix applied, and how the bug "
|
||||||
|
"was diagnosed -- useful for recognising similar issues later."
|
||||||
|
)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"coding_conventions": (
|
||||||
|
"Code style, naming patterns, file organisation, error-handling conventions, "
|
||||||
|
"and team agreements about how code is written in this project."
|
||||||
|
)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"user_preferences": (
|
||||||
|
"User's stated preferences for tools, libraries, languages, formatting, "
|
||||||
|
"and ways of working."
|
||||||
|
)
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
def _print_categories(label: str, cats):
|
||||||
|
print(f"=== {label} ===")
|
||||||
|
if cats:
|
||||||
|
print(json.dumps(cats, indent=2))
|
||||||
|
else:
|
||||||
|
print("(none / using mem0 defaults)")
|
||||||
|
print()
|
||||||
|
|
||||||
|
|
||||||
|
def main() -> int:
|
||||||
|
ap = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter)
|
||||||
|
ap.add_argument(
|
||||||
|
"--apply",
|
||||||
|
action="store_true",
|
||||||
|
help="Actually call project.update(). Without this flag, runs in dry-run mode.",
|
||||||
|
)
|
||||||
|
args = ap.parse_args()
|
||||||
|
|
||||||
|
if not os.environ.get("MEM0_API_KEY"):
|
||||||
|
print("ERROR: MEM0_API_KEY is not set. Export it and try again.", file=sys.stderr)
|
||||||
|
return 1
|
||||||
|
|
||||||
|
try:
|
||||||
|
from mem0 import MemoryClient
|
||||||
|
except ImportError:
|
||||||
|
print(
|
||||||
|
"ERROR: the mem0ai Python SDK is not installed.\n"
|
||||||
|
"Install with: pip install mem0ai\n"
|
||||||
|
"Then re-run this script.",
|
||||||
|
file=sys.stderr,
|
||||||
|
)
|
||||||
|
return 1
|
||||||
|
|
||||||
|
try:
|
||||||
|
client = MemoryClient()
|
||||||
|
except Exception as e:
|
||||||
|
print(
|
||||||
|
f"ERROR initialising MemoryClient: {e}\n"
|
||||||
|
"Most commonly this is an invalid MEM0_API_KEY -- check the key at "
|
||||||
|
"https://app.mem0.ai/dashboard/api-keys",
|
||||||
|
file=sys.stderr,
|
||||||
|
)
|
||||||
|
return 1
|
||||||
|
|
||||||
|
try:
|
||||||
|
current = client.project.get(fields=["custom_categories"])
|
||||||
|
current_cats = current.get("custom_categories") if isinstance(current, dict) else None
|
||||||
|
except Exception as e:
|
||||||
|
print(f"ERROR fetching current categories: {e}", file=sys.stderr)
|
||||||
|
return 1
|
||||||
|
|
||||||
|
_print_categories("Current project categories", current_cats)
|
||||||
|
_print_categories("Proposed coding categories", CODING_CATEGORIES)
|
||||||
|
|
||||||
|
if not args.apply:
|
||||||
|
print("Dry-run only -- no changes made. Re-run with --apply to write.")
|
||||||
|
return 0
|
||||||
|
|
||||||
|
print("Applying coding categories...")
|
||||||
|
try:
|
||||||
|
response = client.project.update(custom_categories=CODING_CATEGORIES)
|
||||||
|
except Exception as e:
|
||||||
|
print(f"ERROR applying update: {e}", file=sys.stderr)
|
||||||
|
return 1
|
||||||
|
|
||||||
|
print("Done.", response if response else "")
|
||||||
|
return 0
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
sys.exit(main())
|
||||||
@@ -97,6 +97,8 @@ Extract key learnings and store them using the `add_memory` tool:
|
|||||||
- **Environment/setup discoveries** -> Include metadata `{"type": "environmental"}`
|
- **Environment/setup discoveries** -> Include metadata `{"type": "environmental"}`
|
||||||
- **Conventions established** -> Include metadata `{"type": "convention"}`
|
- **Conventions established** -> Include metadata `{"type": "convention"}`
|
||||||
|
|
||||||
|
> `metadata.type` (which you set explicitly) and `categories` (which the platform auto-tags after the project's custom-category list — see `scripts/setup_coding_categories.py`) are complementary. Always set `metadata.type` for explicit filtering; the platform fills in `categories` on its own. Don't try to set `categories` on `add_memory` calls — per-request overrides aren't supported on the managed API.
|
||||||
|
|
||||||
Memories can be as detailed as needed -- include full context, reasoning, code snippets, file paths, and examples. Longer, searchable memories are more valuable than vague one-liners.
|
Memories can be as detailed as needed -- include full context, reasoning, code snippets, file paths, and examples. Longer, searchable memories are more valuable than vague one-liners.
|
||||||
|
|
||||||
### Use `infer=False` for already-structured content
|
### Use `infer=False` for already-structured content
|
||||||
|
|||||||
Reference in New Issue
Block a user