Compare commits

...
29 Commits
Author SHA1 Message Date
KartikandGitHub b3ede5b7c0 chore: update changelog, bump SDK and package versions to 3.0.8 and 2.0.6 (#5522) 2026-06-13 20:59:53 +05:30
youneshimaandGitHub 3553fc79dd feat(memory): add OSS-to-Platform notices (#5494) 2026-06-13 18:34:20 +05:30
KartikandGitHub f322cf82b9 chore: consolidate cookbooks/ into an indexed examples/ directory (#5517) 2026-06-13 18:25:50 +05:30
KartikandGitHub 73c975ba68 chore: bump version to 0.1.3, update mem0ai to ^3.0.7, and adjust CHANGELOG (#5521) 2026-06-13 18:10:50 +05:30
KartikandGitHub 931d579ba5 chore(openclaw): release v1.0.13 and backfill v1.0.12 changelog (#5519) 2026-06-13 17:59:04 +05:30
KartikandGitHub f4773a0baf fix(mem0-plugin): accurate per-editor telemetry attribution + OpenCode telemetry (#5518) 2026-06-13 16:48:29 +05:30
KartikandGitHub 06d33f6cc4 fix: relax flaky entity boost parallelism timing threshold (#5511) 2026-06-12 21:07:47 +05:30
Hrushikesh YadavandGitHub 8f3b60f3e1 fix: prevent crash in parse_vision_messages when vision is disabled (#5487) 2026-06-12 20:41:18 +05:30
Harsh Vardhan GuptaandGitHub a6e27dcc9c fix(@mem0/community): upgrade @langchain/community to ^1.1.18 (CVE-2026-27795, CVE-2026-26019) (#5510) 2026-06-12 20:07:03 +05:30
Yufeng HeandGitHub 4f10c986b5 fix: expose Qdrant https option (#5380) 2026-06-12 20:06:26 +05:30
821152bd14 Fix OpenClaw Mem0 custom categories payload (#5345)
Co-authored-by: Kartik <kartik.labhshetwar@mem0.ai>
2026-06-12 19:48:53 +05:30
f48b133101 feat(skills): add mem0-oss-to-platform migration skill (#5455)
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Co-authored-by: kartik-mem0 <kartik.labhshetwar@mem0.ai>
2026-06-12 19:48:37 +05:30
1d56f85705 fix(cli): resolve Windows environment compatibility issues in python CLI tests (#5464)
Co-authored-by: Kartik <kartik.labhshetwar@mem0.ai>
2026-06-12 19:40:26 +05:30
Hrushikesh YadavandGitHub ced852033b fix: return 400 instead of 502 for invalid search filters (#5482) 2026-06-12 19:35:24 +05:30
Yufeng HeandGitHub b9ad8fa8b2 fix(openclaw): skip runtime setup during metadata registration (#5383) 2026-06-12 19:32:59 +05:30
e3f5ce7b41 fix: use valid S3 entity index names (#5416)
Co-authored-by: Kartik <kartik.labhshetwar@mem0.ai>
2026-06-12 19:22:32 +05:30
KartikandGitHub f681889b14 fix(pi-agent-plugin): make command results visible and relevance-filtered (#5504) 2026-06-12 19:13:31 +05:30
KartikandGitHub b5ec46be5b fix(plugin): guard bare $USER refs in on_session_start.sh for Windows (#5492) 2026-06-12 19:13:19 +05:30
168ad358d5 fix(deps): resolve all open MEDIUM Dependabot alerts (npm overrides + Python pins) (#5489)
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-12 15:15:26 +05:30
2c796d144f refactor: consolidate agent/editor plugins under integrations/ (#5491)
Co-authored-by: Claude <noreply@anthropic.com>
2026-06-12 10:31:35 +05:30
c676c2c458 fix(dashboard): pin pnpm to 10.34.2 so docker build works on node:20-alpine (#5483)
Co-authored-by: Kartik <kartik.labhshetwar@mem0.ai>
2026-06-11 22:45:52 +05:30
b36847622d fix(langchain): search() crashes with TypeError when score is None (#5072)
Co-authored-by: Kartik <kartik.labhshetwar@mem0.ai>
2026-06-11 22:34:06 +05:30
Hrushikesh YadavandGitHub 32c8849044 fix: remove dead _process_config method in Memory and AsyncMemory (#5486) 2026-06-11 22:26:53 +05:30
Hrushikesh YadavandGitHub 2dd2872c08 fix: use 'is not None' instead of truthiness for vector/payload in pgvector update (#5488) 2026-06-11 22:12:38 +05:30
cf268da19d fix(demo): guard against undefined data in useMemories hook (v2 async response) (#5029)
Co-authored-by: Kartik <kartik.labhshetwar@mem0.ai>
2026-06-11 21:50:35 +05:30
Sense_wangandGitHub 7a5df64746 fix: allow dashboard refresh cookie on http deployments (#5026) 2026-06-11 21:29:54 +05:30
4c41f6deeb fix(vector-stores): index Valkey 'memory' field as TEXT not TAG (#5443)
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Co-authored-by: kartik-mem0 <kartik.labhshetwar@mem0.ai>
2026-06-11 21:28:42 +05:30
Hrushikesh YadavandGitHub f84aa1eb31 fix: implement $not filter support in ChromaDB vector store (#5485) 2026-06-11 20:12:39 +05:30
Saket AryanandGitHub 9226ee2229 ci: aggregate all PR testing behind a single required CI Gate workflow (#5476) 2026-06-11 15:24:51 +05:30
393 changed files with 16318 additions and 4997 deletions
+1 -1
View File
@@ -8,7 +8,7 @@
"name": "mem0", "name": "mem0",
"source": { "source": {
"source": "local", "source": "local",
"path": "./mem0-plugin" "path": "./integrations/mem0-plugin"
}, },
"policy": { "policy": {
"installation": "AVAILABLE", "installation": "AVAILABLE",
+2 -2
View File
@@ -10,9 +10,9 @@
"plugins": [ "plugins": [
{ {
"name": "mem0", "name": "mem0",
"source": "./mem0-plugin", "source": "./integrations/mem0-plugin",
"description": "Mem0 memory layer for AI applications. Add persistent memory, personalization, and semantic search to Claude workflows.", "description": "Mem0 memory layer for AI applications. Add persistent memory, personalization, and semantic search to Claude workflows.",
"version": "0.2.9" "version": "0.2.10"
} }
] ]
} }
+1 -1
View File
@@ -8,7 +8,7 @@
"name": "mem0", "name": "mem0",
"source": { "source": {
"source": "local", "source": "local",
"path": "./mem0-plugin" "path": "./integrations/mem0-plugin"
}, },
"policy": { "policy": {
"installation": "AVAILABLE", "installation": "AVAILABLE",
+2 -2
View File
@@ -10,9 +10,9 @@
"plugins": [ "plugins": [
{ {
"name": "mem0", "name": "mem0",
"source": "./mem0-plugin", "source": "./integrations/mem0-plugin",
"description": "Mem0 memory layer for AI applications. Add persistent memory, personalization, and semantic search.", "description": "Mem0 memory layer for AI applications. Add persistent memory, personalization, and semantic search.",
"version": "0.2.9" "version": "0.2.10"
} }
] ]
} }
+171
View File
@@ -0,0 +1,171 @@
name: CI Gate
# Single required status check for all PRs.
#
# Path-filtered CI workflows can't be marked as required in branch
# protection: on a PR that doesn't touch their paths they never report, and
# the required check hangs at "Expected" forever. This gate solves that. It
# runs on every PR, detects which packages changed, calls only the relevant
# package CI workflows (as reusable workflows), and the final "CI Gate" job
# reports the aggregate result — success when every invoked pipeline passed
# (skipped pipelines are fine), failure when any failed.
#
# Branch protection should require exactly one status check: "CI Gate".
#
# Package CI workflows keep their own push-to-main and workflow_dispatch
# triggers; only their pull_request triggers moved here. To wire in a new
# package: add a filter under the `changes` job, a call job that `uses:` the
# package workflow, and list the call job in the gate's `needs`.
on:
pull_request:
concurrency:
group: ci-gate-${{ github.event.pull_request.number }}
cancel-in-progress: true
permissions:
contents: read
pull-requests: read
jobs:
changes:
name: Detect changed packages
runs-on: ubuntu-latest
outputs:
python_sdk: ${{ steps.filter.outputs.python_sdk }}
ts_sdk: ${{ steps.filter.outputs.ts_sdk }}
cli_python: ${{ steps.filter.outputs.cli_python }}
cli_node: ${{ steps.filter.outputs.cli_node }}
openclaw: ${{ steps.filter.outputs.openclaw }}
opencode_plugin: ${{ steps.filter.outputs.opencode_plugin }}
pi_agent_plugin: ${{ steps.filter.outputs.pi_agent_plugin }}
docs_llms_txt: ${{ steps.filter.outputs.docs_llms_txt }}
steps:
- uses: dorny/paths-filter@v3
id: filter
with:
# Each filter mirrors the package workflow's old pull_request
# paths, plus the package workflow file itself and this gate file
# (changing either must re-exercise the pipeline).
filters: |
python_sdk:
- 'mem0/**'
- 'tests/**'
- 'pyproject.toml'
- '.github/workflows/ci.yml'
- '.github/workflows/ci-gate.yml'
ts_sdk:
- 'mem0-ts/**'
- '.github/workflows/ts-sdk-ci.yml'
- '.github/workflows/ci-gate.yml'
cli_python:
- 'cli/python/**'
- '.github/workflows/cli-python-ci.yml'
- '.github/workflows/ci-gate.yml'
cli_node:
- 'cli/node/**'
- '.github/workflows/cli-node-ci.yml'
- '.github/workflows/ci-gate.yml'
openclaw:
- 'integrations/openclaw/**'
- '.github/workflows/openclaw-checks.yml'
- '.github/workflows/ci-gate.yml'
opencode_plugin:
- 'integrations/mem0-plugin/.opencode-plugin/**'
- '.github/workflows/opencode-plugin-checks.yml'
- '.github/workflows/ci-gate.yml'
pi_agent_plugin:
- 'integrations/pi-agent-plugin/**'
- '.github/workflows/pi-agent-plugin-checks.yml'
- '.github/workflows/ci-gate.yml'
docs_llms_txt:
- 'docs/**/*.mdx'
- 'docs/llms.txt'
- 'scripts/check-llms-txt-coverage.py'
- 'scripts/llms-txt-ignore.txt'
- '.github/workflows/docs-llms-txt-check.yml'
- '.github/workflows/ci-gate.yml'
python-sdk:
name: Python SDK
needs: changes
if: needs.changes.outputs.python_sdk == 'true'
uses: ./.github/workflows/ci.yml
secrets: inherit
ts-sdk:
name: TypeScript SDK
needs: changes
if: needs.changes.outputs.ts_sdk == 'true'
uses: ./.github/workflows/ts-sdk-ci.yml
secrets: inherit
cli-python:
name: Python CLI
needs: changes
if: needs.changes.outputs.cli_python == 'true'
uses: ./.github/workflows/cli-python-ci.yml
secrets: inherit
cli-node:
name: Node CLI
needs: changes
if: needs.changes.outputs.cli_node == 'true'
uses: ./.github/workflows/cli-node-ci.yml
secrets: inherit
openclaw:
name: OpenClaw
needs: changes
if: needs.changes.outputs.openclaw == 'true'
uses: ./.github/workflows/openclaw-checks.yml
secrets: inherit
opencode-plugin:
name: OpenCode Plugin
needs: changes
if: needs.changes.outputs.opencode_plugin == 'true'
uses: ./.github/workflows/opencode-plugin-checks.yml
secrets: inherit
pi-agent-plugin:
name: Pi Agent Plugin
needs: changes
if: needs.changes.outputs.pi_agent_plugin == 'true'
uses: ./.github/workflows/pi-agent-plugin-checks.yml
secrets: inherit
docs-llms-txt:
name: docs llms.txt
needs: changes
if: needs.changes.outputs.docs_llms_txt == 'true'
uses: ./.github/workflows/docs-llms-txt-check.yml
secrets: inherit
gate:
name: CI Gate
needs:
- changes
- python-sdk
- ts-sdk
- cli-python
- cli-node
- openclaw
- opencode-plugin
- pi-agent-plugin
- docs-llms-txt
if: always()
runs-on: ubuntu-latest
steps:
- name: Evaluate pipeline results
env:
NEEDS: ${{ toJSON(needs) }}
run: |
echo "$NEEDS" | jq -r 'to_entries[] | "\(.key): \(.value.result)"'
failed=$(echo "$NEEDS" | jq -r '[to_entries[] | select(.value.result == "failure" or .value.result == "cancelled") | .key] | join(", ")')
if [ -n "$failed" ]; then
echo "::error::Failing pipelines: $failed"
exit 1
fi
echo "All pipelines relevant to this change passed."
+3 -1
View File
@@ -1,9 +1,11 @@
name: ci name: ci
# On PRs this is invoked by ci-gate.yml (the single required check);
# push-to-main runs remain standalone.
on: on:
push: push:
branches: [main] branches: [main]
pull_request: workflow_call:
jobs: jobs:
changelog_check: changelog_check:
+3 -4
View File
@@ -1,5 +1,7 @@
name: CLI Node CI name: CLI Node CI
# On PRs this is invoked by ci-gate.yml (the single required check);
# push-to-main and manual runs remain standalone.
on: on:
workflow_dispatch: workflow_dispatch:
push: push:
@@ -7,10 +9,7 @@ on:
paths: paths:
- 'cli/node/**' - 'cli/node/**'
- '.github/workflows/cli-node-ci.yml' - '.github/workflows/cli-node-ci.yml'
pull_request: workflow_call:
paths:
- 'cli/node/**'
- '.github/workflows/cli-node-ci.yml'
jobs: jobs:
lint: lint:
+3 -4
View File
@@ -1,5 +1,7 @@
name: CLI Python CI name: CLI Python CI
# On PRs this is invoked by ci-gate.yml (the single required check);
# push-to-main and manual runs remain standalone.
on: on:
workflow_dispatch: workflow_dispatch:
push: push:
@@ -7,10 +9,7 @@ on:
paths: paths:
- 'cli/python/**' - 'cli/python/**'
- '.github/workflows/cli-python-ci.yml' - '.github/workflows/cli-python-ci.yml'
pull_request: workflow_call:
paths:
- 'cli/python/**'
- '.github/workflows/cli-python-ci.yml'
jobs: jobs:
lint: lint:
+3 -6
View File
@@ -6,13 +6,10 @@ name: docs - llms.txt check
# python scripts/check-llms-txt-coverage.py # read-only # python scripts/check-llms-txt-coverage.py # read-only
# python scripts/check-llms-txt-coverage.py --write # scaffold placeholders # python scripts/check-llms-txt-coverage.py --write # scaffold placeholders
# On PRs this is invoked by ci-gate.yml (the single required check);
# manual runs remain standalone.
on: on:
pull_request: workflow_call:
paths:
- 'docs/**/*.mdx'
- 'docs/llms.txt'
- 'scripts/check-llms-txt-coverage.py'
- 'scripts/llms-txt-ignore.txt'
workflow_dispatch: {} workflow_dispatch: {}
permissions: permissions:
+2 -2
View File
@@ -25,7 +25,7 @@ jobs:
id-token: write id-token: write
defaults: defaults:
run: run:
working-directory: openclaw working-directory: integrations/openclaw
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
with: with:
@@ -42,7 +42,7 @@ jobs:
node-version: '22' node-version: '22'
registry-url: 'https://registry.npmjs.org' registry-url: 'https://registry.npmjs.org'
cache: 'pnpm' cache: 'pnpm'
cache-dependency-path: openclaw/pnpm-lock.yaml cache-dependency-path: integrations/openclaw/pnpm-lock.yaml
- name: Install dependencies - name: Install dependencies
run: pnpm install --frozen-lockfile run: pnpm install --frozen-lockfile
+16 -17
View File
@@ -1,16 +1,15 @@
name: openclaw checks name: openclaw checks
# On PRs this is invoked by ci-gate.yml (the single required check);
# push-to-main and manual runs remain standalone.
on: on:
workflow_dispatch: workflow_dispatch:
push: push:
branches: [main] branches: [main]
paths: paths:
- 'openclaw/**' - 'integrations/openclaw/**'
- '.github/workflows/openclaw-checks.yml'
pull_request:
paths:
- 'openclaw/**'
- '.github/workflows/openclaw-checks.yml' - '.github/workflows/openclaw-checks.yml'
workflow_call:
jobs: jobs:
lint: lint:
@@ -28,13 +27,13 @@ jobs:
with: with:
node-version: 20 node-version: 20
cache: 'pnpm' cache: 'pnpm'
cache-dependency-path: openclaw/pnpm-lock.yaml cache-dependency-path: integrations/openclaw/pnpm-lock.yaml
- name: Install dependencies - name: Install dependencies
run: cd openclaw && pnpm install --frozen-lockfile run: cd integrations/openclaw && pnpm install --frozen-lockfile
- name: Type check - name: Type check
run: cd openclaw && pnpm exec tsc --noEmit run: cd integrations/openclaw && pnpm exec tsc --noEmit
test: test:
runs-on: ubuntu-latest runs-on: ubuntu-latest
@@ -54,20 +53,20 @@ jobs:
with: with:
node-version: ${{ matrix.node-version }} node-version: ${{ matrix.node-version }}
cache: 'pnpm' cache: 'pnpm'
cache-dependency-path: openclaw/pnpm-lock.yaml cache-dependency-path: integrations/openclaw/pnpm-lock.yaml
- name: Install dependencies - name: Install dependencies
run: cd openclaw && pnpm install --frozen-lockfile run: cd integrations/openclaw && pnpm install --frozen-lockfile
- name: Run tests with coverage - name: Run tests with coverage
run: cd openclaw && pnpm exec vitest run --coverage run: cd integrations/openclaw && pnpm exec vitest run --coverage
- name: Upload coverage to Codecov - name: Upload coverage to Codecov
if: matrix.node-version == 20 if: matrix.node-version == 20
uses: codecov/codecov-action@v4 uses: codecov/codecov-action@v4
with: with:
flags: openclaw flags: openclaw
directory: openclaw/coverage directory: integrations/openclaw/coverage
env: env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
@@ -86,15 +85,15 @@ jobs:
with: with:
node-version: 20 node-version: 20
cache: 'pnpm' cache: 'pnpm'
cache-dependency-path: openclaw/pnpm-lock.yaml cache-dependency-path: integrations/openclaw/pnpm-lock.yaml
- name: Install dependencies - name: Install dependencies
run: cd openclaw && pnpm install --frozen-lockfile run: cd integrations/openclaw && pnpm install --frozen-lockfile
- name: Build - name: Build
run: cd openclaw && pnpm build run: cd integrations/openclaw && pnpm build
- name: Verify dist output exists - name: Verify dist output exists
run: | run: |
test -f openclaw/dist/index.js || (echo "Build output missing: dist/index.js" && exit 1) test -f integrations/openclaw/dist/index.js || (echo "Build output missing: dist/index.js" && exit 1)
test -f openclaw/dist/index.d.ts || (echo "Build output missing: dist/index.d.ts" && exit 1) test -f integrations/openclaw/dist/index.d.ts || (echo "Build output missing: dist/index.d.ts" && exit 1)
+1 -1
View File
@@ -25,7 +25,7 @@ jobs:
id-token: write id-token: write
defaults: defaults:
run: run:
working-directory: mem0-plugin/.opencode-plugin working-directory: integrations/mem0-plugin/.opencode-plugin
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
with: with:
+5 -6
View File
@@ -1,23 +1,22 @@
name: opencode-plugin checks name: opencode-plugin checks
# On PRs this is invoked by ci-gate.yml (the single required check);
# push-to-main and manual runs remain standalone.
on: on:
workflow_dispatch: workflow_dispatch:
push: push:
branches: [main] branches: [main]
paths: paths:
- 'mem0-plugin/.opencode-plugin/**' - 'integrations/mem0-plugin/.opencode-plugin/**'
- '.github/workflows/opencode-plugin-checks.yml'
pull_request:
paths:
- 'mem0-plugin/.opencode-plugin/**'
- '.github/workflows/opencode-plugin-checks.yml' - '.github/workflows/opencode-plugin-checks.yml'
workflow_call:
jobs: jobs:
build: build:
runs-on: ubuntu-latest runs-on: ubuntu-latest
defaults: defaults:
run: run:
working-directory: mem0-plugin/.opencode-plugin working-directory: integrations/mem0-plugin/.opencode-plugin
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
+2 -2
View File
@@ -25,7 +25,7 @@ jobs:
id-token: write id-token: write
defaults: defaults:
run: run:
working-directory: pi-agent-plugin working-directory: integrations/pi-agent-plugin
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
with: with:
@@ -42,7 +42,7 @@ jobs:
node-version: '22' node-version: '22'
registry-url: 'https://registry.npmjs.org' registry-url: 'https://registry.npmjs.org'
cache: 'pnpm' cache: 'pnpm'
cache-dependency-path: pi-agent-plugin/pnpm-lock.yaml cache-dependency-path: integrations/pi-agent-plugin/pnpm-lock.yaml
- name: Install dependencies - name: Install dependencies
run: pnpm install --frozen-lockfile run: pnpm install --frozen-lockfile
+17 -18
View File
@@ -1,16 +1,15 @@
name: pi-agent-plugin checks name: pi-agent-plugin checks
# On PRs this is invoked by ci-gate.yml (the single required check);
# push-to-main and manual runs remain standalone.
on: on:
workflow_dispatch: workflow_dispatch:
push: push:
branches: [main] branches: [main]
paths: paths:
- 'pi-agent-plugin/**' - 'integrations/pi-agent-plugin/**'
- '.github/workflows/pi-agent-plugin-checks.yml'
pull_request:
paths:
- 'pi-agent-plugin/**'
- '.github/workflows/pi-agent-plugin-checks.yml' - '.github/workflows/pi-agent-plugin-checks.yml'
workflow_call:
jobs: jobs:
lint: lint:
@@ -28,13 +27,13 @@ jobs:
with: with:
node-version: 20 node-version: 20
cache: 'pnpm' cache: 'pnpm'
cache-dependency-path: pi-agent-plugin/pnpm-lock.yaml cache-dependency-path: integrations/pi-agent-plugin/pnpm-lock.yaml
- name: Install dependencies - name: Install dependencies
run: cd pi-agent-plugin && pnpm install --frozen-lockfile run: cd integrations/pi-agent-plugin && pnpm install --frozen-lockfile
- name: Type check - name: Type check
run: cd pi-agent-plugin && pnpm exec tsc --noEmit run: cd integrations/pi-agent-plugin && pnpm exec tsc --noEmit
test: test:
runs-on: ubuntu-latest runs-on: ubuntu-latest
@@ -54,13 +53,13 @@ jobs:
with: with:
node-version: ${{ matrix.node-version }} node-version: ${{ matrix.node-version }}
cache: 'pnpm' cache: 'pnpm'
cache-dependency-path: pi-agent-plugin/pnpm-lock.yaml cache-dependency-path: integrations/pi-agent-plugin/pnpm-lock.yaml
- name: Install dependencies - name: Install dependencies
run: cd pi-agent-plugin && pnpm install --frozen-lockfile run: cd integrations/pi-agent-plugin && pnpm install --frozen-lockfile
- name: Run tests - name: Run tests
run: cd pi-agent-plugin && pnpm exec vitest run run: cd integrations/pi-agent-plugin && pnpm exec vitest run
build: build:
runs-on: ubuntu-latest runs-on: ubuntu-latest
@@ -77,17 +76,17 @@ jobs:
with: with:
node-version: 20 node-version: 20
cache: 'pnpm' cache: 'pnpm'
cache-dependency-path: pi-agent-plugin/pnpm-lock.yaml cache-dependency-path: integrations/pi-agent-plugin/pnpm-lock.yaml
- name: Install dependencies - name: Install dependencies
run: cd pi-agent-plugin && pnpm install --frozen-lockfile run: cd integrations/pi-agent-plugin && pnpm install --frozen-lockfile
- name: Build - name: Build
run: cd pi-agent-plugin && pnpm build run: cd integrations/pi-agent-plugin && pnpm build
- name: Verify dist output exists - name: Verify dist output exists
run: | run: |
test -f pi-agent-plugin/dist/index.js || (echo "Build output missing: dist/index.js" && exit 1) test -f integrations/pi-agent-plugin/dist/index.js || (echo "Build output missing: dist/index.js" && exit 1)
test -f pi-agent-plugin/dist/index.d.ts || (echo "Build output missing: dist/index.d.ts" && exit 1) test -f integrations/pi-agent-plugin/dist/index.d.ts || (echo "Build output missing: dist/index.d.ts" && exit 1)
test -f pi-agent-plugin/dist/entry.js || (echo "Build output missing: dist/entry.js" && exit 1) test -f integrations/pi-agent-plugin/dist/entry.js || (echo "Build output missing: dist/entry.js" && exit 1)
test -f pi-agent-plugin/dist/entry.d.ts || (echo "Build output missing: dist/entry.d.ts" && exit 1) test -f integrations/pi-agent-plugin/dist/entry.d.ts || (echo "Build output missing: dist/entry.d.ts" && exit 1)
+3 -3
View File
@@ -1,14 +1,14 @@
name: TypeScript SDK CI name: TypeScript SDK CI
# On PRs this is invoked by ci-gate.yml (the single required check);
# push-to-main runs remain standalone.
on: on:
push: push:
branches: [main] branches: [main]
paths: paths:
- 'mem0-ts/**' - 'mem0-ts/**'
- '.github/workflows/ts-sdk-ci.yml' - '.github/workflows/ts-sdk-ci.yml'
pull_request: workflow_call:
paths:
- 'mem0-ts/**'
jobs: jobs:
check_changes: check_changes:
+2 -2
View File
@@ -25,7 +25,7 @@ jobs:
id-token: write id-token: write
defaults: defaults:
run: run:
working-directory: vercel-ai-sdk working-directory: integrations/vercel-ai-sdk
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
with: with:
@@ -42,7 +42,7 @@ jobs:
node-version: '22' node-version: '22'
registry-url: 'https://registry.npmjs.org' registry-url: 'https://registry.npmjs.org'
cache: 'pnpm' cache: 'pnpm'
cache-dependency-path: vercel-ai-sdk/pnpm-lock.yaml cache-dependency-path: integrations/vercel-ai-sdk/pnpm-lock.yaml
- name: Install dependencies - name: Install dependencies
run: pnpm install --frozen-lockfile run: pnpm install --frozen-lockfile
+46 -28
View File
@@ -22,17 +22,18 @@ This is a **polyglot monorepo** containing Python and TypeScript packages, CLIs,
| `mem0-ts/` | TypeScript SDK (`mem0ai` on npm) — client + OSS memory | | `mem0-ts/` | TypeScript SDK (`mem0ai` on npm) — client + OSS memory |
| `cli/python/` | Python CLI (`mem0-cli` on PyPI) — Typer-based, entry point `mem0` | | `cli/python/` | Python CLI (`mem0-cli` on PyPI) — Typer-based, entry point `mem0` |
| `cli/node/` | Node CLI (`@mem0/cli` on npm) — Commander-based, entry point `mem0` | | `cli/node/` | Node CLI (`@mem0/cli` on npm) — Commander-based, entry point `mem0` |
| `vercel-ai-sdk/` | `@mem0/vercel-ai-provider` — Vercel AI SDK memory provider | | `integrations/` | **Agent & editor integrations**, one directory per integration (see "Adding a New Integration") |
| `openclaw/` | `@mem0/openclaw-mem0` — OpenClaw plugin for Claude Code / AI editors | | `integrations/mem0-plugin/` | AI editor plugins (Claude Code, Cursor, Codex) — MCP server connection, lifecycle hooks, skills. Contains nested `.opencode-plugin/` (`@mem0/opencode-plugin`) |
| `integrations/openclaw/` | `@mem0/openclaw-mem0` — OpenClaw plugin for Claude Code / AI editors |
| `integrations/pi-agent-plugin/` | `@mem0/pi-agent-plugin` — Pi Agent plugin |
| `integrations/vercel-ai-sdk/` | `@mem0/vercel-ai-provider` — Vercel AI SDK memory provider |
| `server/` | FastAPI REST server for self-hosted Mem0 (Docker: FastAPI + PostgreSQL/pgvector + Neo4j) | | `server/` | FastAPI REST server for self-hosted Mem0 (Docker: FastAPI + PostgreSQL/pgvector + Neo4j) |
| `openmemory/` | Self-hosted memory platform — `api/` (FastAPI + Alembic + MCP server) and `ui/` (Next.js 15 + React 19) | | `openmemory/` | Self-hosted memory platform — `api/` (FastAPI + Alembic + MCP server) and `ui/` (Next.js 15 + React 19) |
| `mem0-plugin/` | AI editor plugins (Claude Code, Cursor, Codex) — MCP server connection, lifecycle hooks, skills | | `skills/` | Claude Code skill definitions. Reference skills (SDK knowledge, always-on): `mem0/`, `mem0-cli/`, `mem0-vercel-ai-sdk/`. Pipeline skills (run on demand): `mem0-integrate/`, `mem0-test-integration/`, `mem0-oss-to-platform/` |
| `skills/` | Claude Code skill definitions. Reference skills (SDK knowledge, always-on): `mem0/`, `mem0-cli/`, `mem0-vercel-ai-sdk/`. Pipeline skills (run on demand): `mem0-integrate/`, `mem0-test-integration/` |
| `docs/` | Documentation site (Mintlify) | | `docs/` | Documentation site (Mintlify) |
| `tests/` | Python SDK tests (pytest) | | `tests/` | Python SDK tests (pytest) |
| `evaluation/` | Benchmarking framework — LOCOMO evals, experiment runner, score generation | | `evaluation/` | Benchmarking framework — LOCOMO evals, experiment runner, score generation |
| `examples/` | Sample projects — demo apps, Chrome extension, multi-agent patterns | | `examples/` | Sample projects & runnable demos — apps, Chrome extension, multi-agent patterns, and Jupyter notebooks (`notebooks/`) |
| `cookbooks/` | Jupyter notebooks — customer support chatbot, AutoGen integration |
| `pr-reviews/` | Pull request review materials | | `pr-reviews/` | Pull request review materials |
| `scripts/` | Repo-wide utility scripts (e.g., `check-llms-txt-coverage.py` for docs/llms.txt sync) | | `scripts/` | Repo-wide utility scripts (e.g., `check-llms-txt-coverage.py` for docs/llms.txt sync) |
@@ -49,8 +50,8 @@ mem0 (Python SDK) mem0-ts (TypeScript SDK)
cli/python/ ──▶ mem0ai (optional, for OSS mode) cli/python/ ──▶ mem0ai (optional, for OSS mode)
cli/node/ ──▶ mem0ai (npm, for API calls) cli/node/ ──▶ mem0ai (npm, for API calls)
vercel-ai-sdk/ ──▶ ai, @ai-sdk/* providers integrations/vercel-ai-sdk/ ──▶ ai, @ai-sdk/* providers
openclaw/ ──▶ mem0ai (npm) integrations/openclaw/ ──▶ mem0ai (npm)
``` ```
## Development Setup ## Development Setup
@@ -73,8 +74,8 @@ pre-commit install # install git hooks
# TypeScript packages # TypeScript packages
cd mem0-ts && pnpm install # TS SDK cd mem0-ts && pnpm install # TS SDK
cd cli/node && pnpm install # Node CLI cd cli/node && pnpm install # Node CLI
cd vercel-ai-sdk && pnpm install # Vercel AI provider cd integrations/vercel-ai-sdk && pnpm install # Vercel AI provider
cd openclaw && pnpm install # OpenClaw plugin cd integrations/openclaw && pnpm install # OpenClaw plugin
``` ```
## Build, Lint, and Test Commands ## Build, Lint, and Test Commands
@@ -162,10 +163,10 @@ pnpm run dev # tsx src/index.ts (development)
- **Test:** vitest (not jest) - **Test:** vitest (not jest)
- **Framework:** Commander + Chalk + ora + cli-table3 - **Framework:** Commander + Chalk + ora + cli-table3
### Vercel AI SDK Provider (`vercel-ai-sdk/`) ### Vercel AI SDK Provider (`integrations/vercel-ai-sdk/`)
```bash ```bash
cd vercel-ai-sdk cd integrations/vercel-ai-sdk
pnpm install pnpm install
pnpm run build # tsup pnpm run build # tsup
pnpm run lint # eslint pnpm run lint # eslint
@@ -180,10 +181,10 @@ pnpm run test:node # vitest (node runtime)
- **Lint:** ESLint + Prettier - **Lint:** ESLint + Prettier
- **Test:** jest + vitest (edge/node configs) - **Test:** jest + vitest (edge/node configs)
### OpenClaw Plugin (`openclaw/`) ### OpenClaw Plugin (`integrations/openclaw/`)
```bash ```bash
cd openclaw cd integrations/openclaw
pnpm install pnpm install
pnpm run build # tsup pnpm run build # tsup
pnpm run test # vitest run pnpm run test # vitest run
@@ -342,8 +343,8 @@ make run-openai # OpenAI comparison
|---------|--------|-----------|---------------| |---------|--------|-----------|---------------|
| `mem0-ts/` | — | Prettier | jest | | `mem0-ts/` | — | Prettier | jest |
| `cli/node/` | Biome | Biome | vitest | | `cli/node/` | Biome | Biome | vitest |
| `vercel-ai-sdk/` | ESLint | Prettier | jest + vitest | | `integrations/vercel-ai-sdk/` | ESLint | Prettier | jest + vitest |
| `openclaw/` | — | — | vitest | | `integrations/openclaw/` | — | — | vitest |
### Type Checking ### Type Checking
@@ -381,14 +382,14 @@ Model Context Protocol support in multiple places:
- **Remote:** MCP server at `mcp.mem0.ai` - **Remote:** MCP server at `mcp.mem0.ai`
- **Local:** MCP server in `openmemory/api/` (FastAPI-based) - **Local:** MCP server in `openmemory/api/` (FastAPI-based)
- **Plugin:** MCP tools in `mem0-plugin/` — 9 tools: `add_memory`, `search_memories`, `get_memories`, `get_memory`, `update_memory`, `delete_memory`, `delete_all_memories`, `delete_entities`, `list_entities` - **Plugin:** MCP tools in `integrations/mem0-plugin/` — 9 tools: `add_memory`, `search_memories`, `get_memories`, `get_memory`, `update_memory`, `delete_memory`, `delete_all_memories`, `delete_entities`, `list_entities`
### Plugin & Skills System ### Plugin & Skills System
- `mem0-plugin/` provides integrations for Claude Code, Cursor, and Codex via MCP server connections and lifecycle hooks for automatic memory capture. - `integrations/mem0-plugin/` provides integrations for Claude Code, Cursor, and Codex via MCP server connections and lifecycle hooks for automatic memory capture.
- `skills/` contains structured skill definitions for AI agents, split into two categories: - `skills/` contains structured skill definitions for AI agents, split into two categories:
- **Reference skills** (always-on SDK knowledge): `mem0` (Python + TS SDKs, framework integrations), `mem0-cli` (terminal workflows), `mem0-vercel-ai-sdk` (Vercel AI provider). - **Reference skills** (always-on SDK knowledge): `mem0` (Python + TS SDKs, framework integrations), `mem0-cli` (terminal workflows), `mem0-vercel-ai-sdk` (Vercel AI provider).
- **Pipeline skills** (run on demand): `mem0-integrate` wires Mem0 into an existing repo via a TDD pipeline; `mem0-test-integration` verifies what the integrator produced on the same branch. The two are loosely coupled via `.mem0-integration/` artifacts. - **Pipeline skills** (run on demand): `mem0-integrate` wires Mem0 into an existing repo via a TDD pipeline; `mem0-test-integration` verifies what the integrator produced on the same branch (the two are loosely coupled via `.mem0-integration/` artifacts); `mem0-oss-to-platform` migrates an existing project from Mem0 OSS to the hosted Platform SDK (plan, then execute on approval).
### Adding a New Provider ### Adding a New Provider
@@ -402,19 +403,36 @@ To add a new LLM, embedding, vector store, or reranker provider:
6. Add any new dependencies to the appropriate optional group in `pyproject.toml` (never to core `dependencies`) 6. Add any new dependencies to the appropriate optional group in `pyproject.toml` (never to core `dependencies`)
7. Follow the exact pattern of existing providers in the same category — match method signatures, error handling, and config structure 7. Follow the exact pattern of existing providers in the same category — match method signatures, error handling, and config structure
### Adding a New Integration
Agent/editor integrations live under `integrations/`. Each is a self-contained directory (its own `package.json`/lockfile, build, and tests). To add one:
1. Create `integrations/<name>/` and build the integration there.
2. If it publishes to a registry, set `repository.directory: "integrations/<name>"` in its `package.json` so npm provenance links to the correct subdirectory.
3. Add CI/CD under `.github/workflows/` (`<name>-checks.yml`, `<name>-cd.yml`). Use `integrations/<name>` in `paths:` triggers, `working-directory`, and `cache-dependency-path`. Register the release tag prefix in the `case` block in `release.yml` (keep the bare `v*` arm last). Keep workflow **filenames** stable — npm OIDC trusted publishing is pinned to repo + workflow filename.
4. If it is a Claude Code / editor marketplace plugin, register its path in the five `marketplace.json` files (root + `.claude-plugin/`, `.cursor-plugin/`, `.codex-plugin/`, `.agents/plugins/`).
5. Document it under `docs/integrations/` and add the page to `docs/docs.json` and `docs/llms.txt`.
6. Add rows to the "Key Directories" table and the CI/CD tables in this file.
## CI/CD ## CI/CD
### CI Workflows (automated testing) ### CI Workflows (automated testing)
| Workflow | File | Triggers | Tests | PR testing is orchestrated by a single entry point: **`ci-gate.yml` (CI Gate)** runs on every PR, detects which packages changed, and invokes only the relevant package workflows below as reusable workflows (`workflow_call`). Its final **`CI Gate`** job aggregates the results (skipped pipelines pass; failed or cancelled ones fail) and is the **only status check that needs to be required** in branch protection. Package workflows keep their own push-to-main and manual triggers; their `pull_request` triggers moved into the gate's path filters.
|----------|------|----------|-------|
| Python SDK | `ci.yml` | Push to main, PRs on `mem0/`, `tests/`, `pyproject.toml` | Ruff lint + pytest on Python 3.10, 3.11, 3.12 | | Workflow | File | Standalone Triggers | Tests |
| TypeScript SDK | `ts-sdk-ci.yml` | Push to main, PRs on `mem0-ts/` | Prettier + build + jest on Node 20, 22 | |----------|------|---------------------|-------|
| Python CLI | `cli-python-ci.yml` | Push to `cli/python/`, PRs, manual | Ruff lint + pytest + hatch build on Python 3.10, 3.11, 3.12 | | CI Gate | `ci-gate.yml` | All PRs | Routes to and aggregates the workflows below |
| Node CLI | `cli-node-ci.yml` | Push to `cli/node/`, PRs, manual | Biome lint + tsc + vitest + tsup build on Node 20, 22 | | Python SDK | `ci.yml` | Push to main | Ruff lint + pytest on Python 3.10, 3.11, 3.12 |
| OpenClaw | `openclaw-checks.yml` | Push to `openclaw/`, PRs, manual | tsc + vitest (with Codecov) + tsup build on Node 20, 22 | | TypeScript SDK | `ts-sdk-ci.yml` | Push to main (on `mem0-ts/`) | Prettier + build + jest on Node 20, 22 |
| OpenCode Plugin | `opencode-plugin-checks.yml` | Push to `mem0-plugin/.opencode-plugin/`, PRs, manual | Bun: tsc type-check + build + dist artifact check | | Python CLI | `cli-python-ci.yml` | Push to main (on `cli/python/`), manual | Ruff lint + pytest + hatch build on Python 3.10, 3.11, 3.12 |
| Pi Agent Plugin | `pi-agent-plugin-checks.yml` | Push to `pi-agent-plugin/`, PRs, manual | tsc + vitest + tsup build (dist artifact check) on Node 20, 22 | | Node CLI | `cli-node-ci.yml` | Push to main (on `cli/node/`), manual | Biome lint + tsc + vitest + tsup build on Node 20, 22 |
| OpenClaw | `openclaw-checks.yml` | Push to main (on `integrations/openclaw/`), manual | tsc + vitest (with Codecov) + tsup build on Node 20, 22 |
| OpenCode Plugin | `opencode-plugin-checks.yml` | Push to main (on `integrations/mem0-plugin/.opencode-plugin/`), manual | Bun: tsc type-check + build + dist artifact check |
| Pi Agent Plugin | `pi-agent-plugin-checks.yml` | Push to main (on `integrations/pi-agent-plugin/`), manual | tsc + vitest + tsup build (dist artifact check) on Node 20, 22 |
| docs llms.txt | `docs-llms-txt-check.yml` | Manual | `docs/llms.txt` coverage check |
When adding a new package CI workflow: give it `workflow_call` (plus `push`/`workflow_dispatch` as needed, but no `pull_request` trigger), then register it in `ci-gate.yml` — a path filter under the `changes` job, a call job, and an entry in the gate job's `needs` list.
### CD Workflows (automated publishing) ### CD Workflows (automated publishing)
+2 -1
View File
@@ -1026,7 +1026,8 @@ def get_user_preferences(user_id: str):
### AutoGen Integration ### AutoGen Integration
```python ```python
from cookbooks.helper.mem0_teachability import Mem0Teachability # Mem0Teachability lives in examples/notebooks/helper/ — see examples/notebooks/mem0-autogen.ipynb
from helper.mem0_teachability import Mem0Teachability
from mem0 import Memory from mem0 import Memory
# Add memory capability to AutoGen agents # Add memory capability to AutoGen agents
+2 -1
View File
@@ -186,9 +186,10 @@ npx skills add https://github.com/mem0ai/mem0 --skill mem0-vercel-ai-sdk
```bash ```bash
npx skills add https://github.com/mem0ai/mem0 --skill mem0-integrate npx skills add https://github.com/mem0ai/mem0 --skill mem0-integrate
npx skills add https://github.com/mem0ai/mem0 --skill mem0-test-integration npx skills add https://github.com/mem0ai/mem0 --skill mem0-test-integration
npx skills add https://github.com/mem0ai/mem0 --skill mem0-oss-to-platform
``` ```
Use `/mem0-integrate` to wire Mem0 into an existing repo via a test-first pipeline, then `/mem0-test-integration` to verify. See the [skills catalog](./skills/) or [Vibecoding with Mem0](https://docs.mem0.ai/vibecoding) for the full picture. Use `/mem0-integrate` to wire Mem0 into an existing repo via a test-first pipeline, then `/mem0-test-integration` to verify. Use `/mem0-oss-to-platform` to migrate an existing project from Mem0 OSS to the hosted Platform SDK. See the [skills catalog](./skills/) or [Vibecoding with Mem0](https://docs.mem0.ai/vibecoding) for the full picture.
### Basic Usage ### Basic Usage
+17 -16
View File
@@ -9,6 +9,7 @@ overrides:
langsmith@<0.6.0: ^0.6.0 langsmith@<0.6.0: ^0.6.0
tar-fs@>=2.0.0 <2.1.4: ^2.1.4 tar-fs@>=2.0.0 <2.1.4: ^2.1.4
picomatch@<2.3.2: ^2.3.2 picomatch@<2.3.2: ^2.3.2
postcss@<8.5.10: '>=8.5.10'
importers: importers:
@@ -38,7 +39,7 @@ importers:
version: 20.19.37 version: 20.19.37
tsup: tsup:
specifier: ^8.0.0 specifier: ^8.0.0
version: 8.5.1(postcss@8.5.8)(tsx@4.21.0)(typescript@5.9.3) version: 8.5.1(postcss@8.5.15)(tsx@4.21.0)(typescript@5.9.3)
tsx: tsx:
specifier: ^4.7.0 specifier: ^4.7.0
version: 4.21.0 version: 4.21.0
@@ -829,8 +830,8 @@ packages:
mz@2.7.0: mz@2.7.0:
resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==} resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==}
nanoid@3.3.11: nanoid@3.3.12:
resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==} resolution: {integrity: sha512-ZB9RH/39qpq5Vu6Y+NmUaFhQR6pp+M2Xt76XBnEwDaGcVAqhlvxrl3B2bKS5D3NH3QR76v3aSrKaF/Kiy7lEtQ==}
engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
hasBin: true hasBin: true
@@ -871,7 +872,7 @@ packages:
engines: {node: '>= 18'} engines: {node: '>= 18'}
peerDependencies: peerDependencies:
jiti: '>=1.21.0' jiti: '>=1.21.0'
postcss: '>=8.0.9' postcss: '>=8.5.10'
tsx: ^4.8.1 tsx: ^4.8.1
yaml: ^2.4.2 yaml: ^2.4.2
peerDependenciesMeta: peerDependenciesMeta:
@@ -884,8 +885,8 @@ packages:
yaml: yaml:
optional: true optional: true
postcss@8.5.8: postcss@8.5.15:
resolution: {integrity: sha512-OW/rX8O/jXnm82Ey1k44pObPtdblfiuWnrd8X7GJ7emImCOstunGbXUpp7HdBrFQX6rJzn3sPT397Wp5aCwCHg==} resolution: {integrity: sha512-FfR8sjd4em2T6fb3I2MwAJU7HWVMr9zba+enmQeeWFfCbm+UOC/0X4DS8XtpUTMwWMGbjKYP7xjfNekzyGmB3A==}
engines: {node: ^10 || ^12 || >=14} engines: {node: ^10 || ^12 || >=14}
readdirp@4.1.2: readdirp@4.1.2:
@@ -997,7 +998,7 @@ packages:
peerDependencies: peerDependencies:
'@microsoft/api-extractor': ^7.36.0 '@microsoft/api-extractor': ^7.36.0
'@swc/core': ^1 '@swc/core': ^1
postcss: ^8.4.12 postcss: '>=8.5.10'
typescript: '>=4.5.0' typescript: '>=4.5.0'
peerDependenciesMeta: peerDependenciesMeta:
'@microsoft/api-extractor': '@microsoft/api-extractor':
@@ -1671,7 +1672,7 @@ snapshots:
object-assign: 4.1.1 object-assign: 4.1.1
thenify-all: 1.6.0 thenify-all: 1.6.0
nanoid@3.3.11: {} nanoid@3.3.12: {}
object-assign@4.1.1: {} object-assign@4.1.1: {}
@@ -1707,16 +1708,16 @@ snapshots:
mlly: 1.8.2 mlly: 1.8.2
pathe: 2.0.3 pathe: 2.0.3
postcss-load-config@6.0.1(postcss@8.5.8)(tsx@4.21.0): postcss-load-config@6.0.1(postcss@8.5.15)(tsx@4.21.0):
dependencies: dependencies:
lilconfig: 3.1.3 lilconfig: 3.1.3
optionalDependencies: optionalDependencies:
postcss: 8.5.8 postcss: 8.5.15
tsx: 4.21.0 tsx: 4.21.0
postcss@8.5.8: postcss@8.5.15:
dependencies: dependencies:
nanoid: 3.3.11 nanoid: 3.3.12
picocolors: 1.1.1 picocolors: 1.1.1
source-map-js: 1.2.1 source-map-js: 1.2.1
@@ -1837,7 +1838,7 @@ snapshots:
ts-interface-checker@0.1.13: {} ts-interface-checker@0.1.13: {}
tsup@8.5.1(postcss@8.5.8)(tsx@4.21.0)(typescript@5.9.3): tsup@8.5.1(postcss@8.5.15)(tsx@4.21.0)(typescript@5.9.3):
dependencies: dependencies:
bundle-require: 5.1.0(esbuild@0.27.4) bundle-require: 5.1.0(esbuild@0.27.4)
cac: 6.7.14 cac: 6.7.14
@@ -1848,7 +1849,7 @@ snapshots:
fix-dts-default-cjs-exports: 1.0.1 fix-dts-default-cjs-exports: 1.0.1
joycon: 3.1.1 joycon: 3.1.1
picocolors: 1.1.1 picocolors: 1.1.1
postcss-load-config: 6.0.1(postcss@8.5.8)(tsx@4.21.0) postcss-load-config: 6.0.1(postcss@8.5.15)(tsx@4.21.0)
resolve-from: 5.0.0 resolve-from: 5.0.0
rollup: 4.60.0 rollup: 4.60.0
source-map: 0.7.6 source-map: 0.7.6
@@ -1857,7 +1858,7 @@ snapshots:
tinyglobby: 0.2.15 tinyglobby: 0.2.15
tree-kill: 1.2.2 tree-kill: 1.2.2
optionalDependencies: optionalDependencies:
postcss: 8.5.8 postcss: 8.5.15
typescript: 5.9.3 typescript: 5.9.3
transitivePeerDependencies: transitivePeerDependencies:
- jiti - jiti
@@ -1885,7 +1886,7 @@ snapshots:
esbuild: 0.25.12 esbuild: 0.25.12
fdir: 6.5.0(picomatch@4.0.4) fdir: 6.5.0(picomatch@4.0.4)
picomatch: 4.0.4 picomatch: 4.0.4
postcss: 8.5.8 postcss: 8.5.15
rollup: 4.60.0 rollup: 4.60.0
tinyglobby: 0.2.15 tinyglobby: 0.2.15
optionalDependencies: optionalDependencies:
+1
View File
@@ -10,3 +10,4 @@ overrides:
langsmith@<0.6.0: ^0.6.0 langsmith@<0.6.0: ^0.6.0
tar-fs@>=2.0.0 <2.1.4: ^2.1.4 tar-fs@>=2.0.0 <2.1.4: ^2.1.4
picomatch@<2.3.2: ^2.3.2 picomatch@<2.3.2: ^2.3.2
"postcss@<8.5.10": ">=8.5.10"
+6
View File
@@ -8,4 +8,10 @@ export default defineConfig({
define: { define: {
__CLI_VERSION__: JSON.stringify(pkg.version), __CLI_VERSION__: JSON.stringify(pkg.version),
}, },
test: {
// Integration tests spawn the CLI via `npx tsx` (15s subprocess
// timeout); the first spawn in a file pays a cold-start cost that can
// exceed vitest's 5s default on CI runners.
testTimeout: 30_000,
},
}); });
+6 -3
View File
@@ -32,12 +32,13 @@ def _run(args: list[str], home_dir: str | None = None) -> subprocess.CompletedPr
if key.startswith("MEM0_"): if key.startswith("MEM0_"):
del env[key] del env[key]
env.pop("FORCE_COLOR", None) env.pop("FORCE_COLOR", None)
env["PYTHONIOENCODING"] = "utf-8"
if home_dir: if home_dir:
env["HOME"] = home_dir env["HOME"] = home_dir
result = subprocess.run( result = subprocess.run(
[sys.executable, "-m", "mem0_cli", *args], [sys.executable, "-m", "mem0_cli", *args],
capture_output=True, capture_output=True,
text=True, encoding="utf-8",
env=env, env=env,
timeout=15, timeout=15,
) )
@@ -99,12 +100,13 @@ class TestArgvPreprocessing:
result = subprocess.run( result = subprocess.run(
[sys.executable, "-m", "mem0_cli", "init", "--agent"], [sys.executable, "-m", "mem0_cli", "init", "--agent"],
capture_output=True, capture_output=True,
text=True, encoding="utf-8",
env={ env={
**{k: v for k, v in os.environ.items() if not k.startswith("MEM0_")}, **{k: v for k, v in os.environ.items() if not k.startswith("MEM0_")},
"HOME": clean_home, "HOME": clean_home,
"MEM0_BASE_URL": "http://127.0.0.1:1", # blackhole "MEM0_BASE_URL": "http://127.0.0.1:1", # blackhole
"FORCE_COLOR": "0", "FORCE_COLOR": "0",
"PYTHONIOENCODING": "utf-8",
}, },
timeout=15, timeout=15,
) )
@@ -133,12 +135,13 @@ class TestJsonEnvelopeParity:
result = subprocess.run( result = subprocess.run(
[sys.executable, "-m", "mem0_cli", "init", "--agent", "--json"], [sys.executable, "-m", "mem0_cli", "init", "--agent", "--json"],
capture_output=True, capture_output=True,
text=True, encoding="utf-8",
env={ env={
**{k: v for k, v in os.environ.items() if not k.startswith("MEM0_")}, **{k: v for k, v in os.environ.items() if not k.startswith("MEM0_")},
"HOME": clean_home, "HOME": clean_home,
"MEM0_BASE_URL": "http://127.0.0.1:1", "MEM0_BASE_URL": "http://127.0.0.1:1",
"FORCE_COLOR": "0", "FORCE_COLOR": "0",
"PYTHONIOENCODING": "utf-8",
}, },
timeout=15, timeout=15,
) )
+2 -1
View File
@@ -49,6 +49,7 @@ def _run(
if key.startswith("MEM0_"): if key.startswith("MEM0_"):
del env[key] del env[key]
env.pop("FORCE_COLOR", None) env.pop("FORCE_COLOR", None)
env["PYTHONIOENCODING"] = "utf-8"
if home_dir: if home_dir:
env["HOME"] = home_dir env["HOME"] = home_dir
if env_override: if env_override:
@@ -56,7 +57,7 @@ def _run(
result = subprocess.run( result = subprocess.run(
[sys.executable, "-m", "mem0_cli", *args], [sys.executable, "-m", "mem0_cli", *args],
capture_output=True, capture_output=True,
text=True, encoding="utf-8",
env=env, env=env,
) )
return subprocess.CompletedProcess( return subprocess.CompletedProcess(
+7 -7
View File
@@ -8,8 +8,8 @@ from io import StringIO
from unittest.mock import patch from unittest.mock import patch
import pytest import pytest
from click.exceptions import Exit as ClickExit
from rich.console import Console from rich.console import Console
from typer import Exit as TyperExit
from mem0_cli.commands.config_cmd import ( from mem0_cli.commands.config_cmd import (
cmd_config_get, cmd_config_get,
@@ -181,7 +181,7 @@ class TestAddCommand:
patch("mem0_cli.commands.memory.console", console), patch("mem0_cli.commands.memory.console", console),
patch("mem0_cli.commands.memory.err_console", err_console), patch("mem0_cli.commands.memory.err_console", err_console),
patch("mem0_cli.commands.memory._stdin_is_piped", return_value=False), patch("mem0_cli.commands.memory._stdin_is_piped", return_value=False),
pytest.raises((SystemExit, ClickExit)), pytest.raises((SystemExit, TyperExit)),
): ):
cmd_add( cmd_add(
mock_backend, mock_backend,
@@ -206,7 +206,7 @@ class TestAddCommand:
with ( with (
patch("mem0_cli.commands.memory.console", console), patch("mem0_cli.commands.memory.console", console),
patch("mem0_cli.commands.memory.err_console", err_console), patch("mem0_cli.commands.memory.err_console", err_console),
pytest.raises((SystemExit, ClickExit)), pytest.raises((SystemExit, TyperExit)),
): ):
cmd_add( cmd_add(
mock_backend, mock_backend,
@@ -764,7 +764,7 @@ class TestImportCommand:
with ( with (
patch("mem0_cli.commands.utils.console", console), patch("mem0_cli.commands.utils.console", console),
patch("mem0_cli.commands.utils.err_console", err_console), patch("mem0_cli.commands.utils.err_console", err_console),
pytest.raises((SystemExit, ClickExit)), pytest.raises((SystemExit, TyperExit)),
): ):
cmd_import(mock_backend, "/nonexistent/file.json", user_id=None, agent_id=None) cmd_import(mock_backend, "/nonexistent/file.json", user_id=None, agent_id=None)
@@ -801,7 +801,7 @@ class TestEntitiesListCommand:
with ( with (
patch("mem0_cli.commands.entities.console", console), patch("mem0_cli.commands.entities.console", console),
patch("mem0_cli.commands.entities.err_console", err_console), patch("mem0_cli.commands.entities.err_console", err_console),
pytest.raises((SystemExit, ClickExit)), pytest.raises((SystemExit, TyperExit)),
): ):
cmd_entities_list(mock_backend, "invalid", output="table") cmd_entities_list(mock_backend, "invalid", output="table")
@@ -944,7 +944,7 @@ class TestEntitiesDeleteCommand:
with ( with (
patch("mem0_cli.commands.entities.console", console), patch("mem0_cli.commands.entities.console", console),
patch("mem0_cli.commands.entities.err_console", err_console), patch("mem0_cli.commands.entities.err_console", err_console),
pytest.raises((SystemExit, ClickExit)), pytest.raises((SystemExit, TyperExit)),
): ):
cmd_entities_delete( cmd_entities_delete(
mock_backend, mock_backend,
@@ -1308,7 +1308,7 @@ class TestAgentMode:
patch("mem0_cli.commands.memory.console", console), patch("mem0_cli.commands.memory.console", console),
patch("mem0_cli.commands.memory.err_console", err_console), patch("mem0_cli.commands.memory.err_console", err_console),
patch("sys.stdout", captured_stdout), patch("sys.stdout", captured_stdout),
pytest.raises((SystemExit, ClickExit)), pytest.raises((SystemExit, TyperExit)),
): ):
cmd_get(mock_backend, "bad-id", output="text") cmd_get(mock_backend, "bad-id", output="text")
+2 -1
View File
@@ -67,7 +67,8 @@ class TestConfig:
from mem0_cli.config import CONFIG_FILE from mem0_cli.config import CONFIG_FILE
mode = os.stat(CONFIG_FILE).st_mode & 0o777 mode = os.stat(CONFIG_FILE).st_mode & 0o777
assert mode == 0o600 if os.name != "nt":
assert mode == 0o600
def test_defaults_save_and_load(self, isolate_config): def test_defaults_save_and_load(self, isolate_config):
config = Mem0Config() config = Mem0Config()
+33
View File
@@ -4,6 +4,39 @@ description: "Release notes for the OpenClaw plugin and agent harness."
mode: "wide" mode: "wide"
--- ---
<Update label="2026-06-12" description="v1.0.13">
**Fixes:**
- **Custom categories payload:** `customCategories` (a `Record<string, string>` map) is now converted via the new `customCategoryMapToList()` helper into the `Array<Record<string, string>>` shape the Mem0 SDK expects on `add` calls — previously the raw object was passed as `custom_categories` and silently ignored ([#5345](https://github.com/mem0ai/mem0/pull/5345))
- **Skip runtime setup during metadata registration:** `register()` now detects `registrationMode === "cli-metadata"`, registers only the CLI commands, and returns early — avoiding backend initialization, service/tool registration, and hook installation during OpenClaw's metadata-only registration pass ([#5383](https://github.com/mem0ai/mem0/pull/5383))
**Security:**
- Bumped `mem0ai` from `3.0.3` to `3.0.7` (latest Node SDK) — includes the transitive axios CVE remediation shipped in `3.0.6` ([#5460](https://github.com/mem0ai/mem0/pull/5460))
- Added pnpm override `uuid@<11.1.1` → `>=11.1.1` to resolve an open MEDIUM Dependabot alert ([#5489](https://github.com/mem0ai/mem0/pull/5489))
**Improvements:**
- **Repo consolidation:** Plugin moved from repo-root `openclaw/` to `integrations/openclaw/`; `package.json` `repository.directory` updated to match so npm provenance links to the correct subdirectory ([#5491](https://github.com/mem0ai/mem0/pull/5491))
**Tests:**
- Added `customCategoryMapToList` unit tests and a `PlatformProvider` test asserting `custom_categories` is passed to the Mem0 SDK as a list ([#5345](https://github.com/mem0ai/mem0/pull/5345))
- Added a regression test asserting `cli-metadata` registration registers only CLI commands and triggers no runtime side effects ([#5383](https://github.com/mem0ai/mem0/pull/5383))
</Update>
<Update label="2026-06-02" description="v1.0.12">
**Docs:**
- **Agent Mode onboarding:** README now documents an autonomous setup path for AI agents — `mem0 init --agent --json` mints an evaluation Mem0 API key with no email, OTP, or browser and exports it as `MEM0_API_KEY` for `openclaw mem0 init`; a human owner can later run `mem0 init --email <email>` to claim ownership without disrupting the agent ([#5123](https://github.com/mem0ai/mem0/pull/5123))
**Security:**
- Added pnpm overrides to remediate advisories in transitive dependencies: `langsmith@<0.6.0` → `^0.6.0`, `picomatch@<2.3.2` → `^2.3.2`, `vite` → `^8.0.5`, and `@qdrant/js-client-rest` → `^1.18.0` ([#5294](https://github.com/mem0ai/mem0/pull/5294))
**Dependencies:**
- Bumped `mem0ai` from `3.0.2` to `3.0.3` ([#5212](https://github.com/mem0ai/mem0/pull/5212))
- Bumped dev dependencies `@vitest/coverage-v8` and `vitest` from `^4.0.18` to `^4.1.7`; added `vite@^8.0.5` and `@qdrant/js-client-rest@^1.18.0` ([#5294](https://github.com/mem0ai/mem0/pull/5294))
</Update>
<Update label="2026-04-29" description="v1.0.11"> <Update label="2026-04-29" description="v1.0.11">
**New Features:** **New Features:**
+27
View File
@@ -7,6 +7,22 @@ mode: "wide"
<Tabs> <Tabs>
<Tab title="Python"> <Tab title="Python">
<Update label="2026-06-13" description="v2.0.6">
**New Features:**
- **Memory:** Add a contextual OSS-to-Platform notices system that surfaces occasional, situation-aware messages (first run, scale/performance thresholds, slow queries, and when temporal/decay features are relevant) pointing to the corresponding Mem0 Platform capabilities; disable via `MEM0_TELEMETRY=false` ([#5494](https://github.com/mem0ai/mem0/pull/5494))
**Bug Fixes:**
- **Memory:** Prevent a crash in `parse_vision_messages` when vision support is disabled ([#5487](https://github.com/mem0ai/mem0/pull/5487))
- **Vector Stores:** Expose the `https` option on the Qdrant vector store configuration so TLS endpoints can be targeted explicitly ([#5380](https://github.com/mem0ai/mem0/pull/5380))
- **Vector Stores:** Use valid S3 Vectors entity index names, fixing index operations that failed on invalid names ([#5416](https://github.com/mem0ai/mem0/pull/5416))
- **Vector Stores:** Fix `search()` crashing with a `TypeError` in the LangChain vector store when a result score is `None` ([#5072](https://github.com/mem0ai/mem0/pull/5072))
- **Vector Stores:** Use `is not None` instead of a truthiness check for vector/payload in the PGVector `update()` path, so valid empty/zero values are no longer skipped ([#5488](https://github.com/mem0ai/mem0/pull/5488))
- **Vector Stores:** Index the Valkey `memory` field as `TEXT` rather than `TAG` so full-text search behaves correctly ([#5443](https://github.com/mem0ai/mem0/pull/5443))
- **Vector Stores:** Implement `$not` filter support in the ChromaDB vector store ([#5485](https://github.com/mem0ai/mem0/pull/5485))
</Update>
<Update label="2026-06-10" description="v2.0.5"> <Update label="2026-06-10" description="v2.0.5">
**New Features:** **New Features:**
@@ -960,6 +976,17 @@ See the [OSS v1 to v2 migration guide](https://docs.mem0.ai/migration/oss-v1-to-
<Tab title="TypeScript"> <Tab title="TypeScript">
<Update label="2026-06-13" description="v3.0.8">
**New Features:**
- **Memory:** Add a contextual OSS-to-Platform notices system that surfaces occasional, situation-aware messages (first run, scale/performance thresholds, slow queries, and when temporal/decay features are relevant) pointing to the corresponding Mem0 Platform capabilities; disable via `MEM0_TELEMETRY=false` ([#5494](https://github.com/mem0ai/mem0/pull/5494))
**Security:**
- **Dependencies:** Upgrade `@langchain/community` to `^1.1.18` to remediate CVE-2026-27795 and CVE-2026-26019 ([#5510](https://github.com/mem0ai/mem0/pull/5510))
- **Dependencies:** Resolve all open MEDIUM Dependabot alerts via pnpm overrides ([#5489](https://github.com/mem0ai/mem0/pull/5489))
</Update>
<Update label="2026-06-10" description="v3.0.7"> <Update label="2026-06-10" description="v3.0.7">
**New Features:** **New Features:**
+2 -1
View File
@@ -76,6 +76,7 @@ Let's see the available parameters for the `qdrant` config:
| `path` | Path for the qdrant database | `/tmp/qdrant` | | `path` | Path for the qdrant database | `/tmp/qdrant` |
| `url` | Full URL for the qdrant server | `None` | | `url` | Full URL for the qdrant server | `None` |
| `api_key` | API key for the qdrant server | `None` | | `api_key` | API key for the qdrant server | `None` |
| `https` | Whether to force HTTPS on or off. `None` lets the client decide; set `False` for plain HTTP Qdrant with API key authentication. | `None` |
| `on_disk` | For enabling persistent storage | `False` | | `on_disk` | For enabling persistent storage | `False` |
</Tab> </Tab>
<Tab title="TypeScript"> <Tab title="TypeScript">
@@ -90,4 +91,4 @@ Let's see the available parameters for the `qdrant` config:
| `apiKey` | API key for the Qdrant server | `None` | | `apiKey` | API key for the Qdrant server | `None` |
| `onDisk` | For enabling persistent storage | `False` | | `onDisk` | For enabling persistent storage | `False` |
</Tab> </Tab>
</Tabs> </Tabs>
+1 -1
View File
@@ -28,7 +28,7 @@ echo 'export MEM0_API_KEY="m0-your-api-key"' >> ~/.bashrc && source ~/.bashrc
```bash ```bash
# Install the plugin (MCP server, hooks, scripts) # Install the plugin (MCP server, hooks, scripts)
npx degit mem0ai/mem0/mem0-plugin ~/.gemini/config/plugins/mem0 npx degit mem0ai/mem0/integrations/mem0-plugin ~/.gemini/config/plugins/mem0
``` ```
This installs the MCP server, lifecycle hooks, and shared scripts. This installs the MCP server, lifecycle hooks, and shared scripts.
+1 -1
View File
@@ -43,7 +43,7 @@ bunx @mem0/opencode-plugin@latest install
**Or let your agent do it** — paste this into OpenCode: **Or let your agent do it** — paste this into OpenCode:
``` ```
Install @mem0/opencode-plugin by following https://raw.githubusercontent.com/mem0ai/mem0/main/mem0-plugin/.opencode-plugin/README.md Install @mem0/opencode-plugin by following https://raw.githubusercontent.com/mem0ai/mem0/main/integrations/mem0-plugin/.opencode-plugin/README.md
``` ```
All commands auto-add the plugin and MCP server to your `~/.config/opencode/opencode.json`. Restart OpenCode — you get the MCP server, lifecycle hooks, and all `/mem0:` slash commands. All commands auto-add the plugin and MCP server to your `~/.config/opencode/opencode.json`. Restart OpenCode — you get the MCP server, lifecycle hooks, and all `/mem0:` slash commands.
+3
View File
@@ -59,6 +59,7 @@ For advanced settings, create `~/.pi/agent/mem0-config.json`:
"userId": "your-username", "userId": "your-username",
"autoCapture": true, "autoCapture": true,
"defaultScope": "project", "defaultScope": "project",
"searchThreshold": 0.3,
"dream": { "dream": {
"enabled": true, "enabled": true,
"auto": true, "auto": true,
@@ -75,12 +76,14 @@ For advanced settings, create `~/.pi/agent/mem0-config.json`:
| `userId` | `string` | `$MEM0_USER_ID` or `"default"` | User identity for memory scoping | | `userId` | `string` | `$MEM0_USER_ID` or `"default"` | User identity for memory scoping |
| `autoCapture` | `boolean` | `true` | Store facts from conversations automatically | | `autoCapture` | `boolean` | `true` | Store facts from conversations automatically |
| `defaultScope` | `string` | `"project"` | Default memory scope: `project`, `session`, or `global` | | `defaultScope` | `string` | `"project"` | Default memory scope: `project`, `session`, or `global` |
| `searchThreshold` | `number` | `0.3` | Minimum similarity score (0–1) a memory must reach to count as a match for `/mem0-search`, `/mem0-forget`, and `/mem0-pin`, enforced on each result's relevance score. Raise it to be stricter; lower it if relevant results are missed. |
| `dream.enabled` | `boolean` | `true` | Enable dream consolidation | | `dream.enabled` | `boolean` | `true` | Enable dream consolidation |
| `dream.auto` | `boolean` | `true` | Auto-trigger dreams when thresholds are met | | `dream.auto` | `boolean` | `true` | Auto-trigger dreams when thresholds are met |
| `dream.minHours` | `number` | `24` | Minimum hours between auto-dreams | | `dream.minHours` | `number` | `24` | Minimum hours between auto-dreams |
| `dream.minSessions` | `number` | `5` | Minimum sessions before first auto-dream | | `dream.minSessions` | `number` | `5` | Minimum sessions before first auto-dream |
| `dream.minMemories` | `number` | `20` | Minimum memories before auto-dream triggers | | `dream.minMemories` | `number` | `20` | Minimum memories before auto-dream triggers |
## What's Included ## What's Included
| Component | Description | | Component | Description |
+2 -2
View File
@@ -398,9 +398,9 @@ Each subdirectory is a Claude Code Skill (`SKILL.md` + supporting assets). Load
### Editor Plugin (shared glue) ### Editor Plugin (shared glue)
Source: https://github.com/mem0ai/mem0/tree/main/mem0-plugin Source: https://github.com/mem0ai/mem0/tree/main/integrations/mem0-plugin
The `mem0-plugin/` directory provides MCP server connection, lifecycle hooks, and skill bundling for Claude Code, Cursor, Codex, OpenCode, and Antigravity. It exposes 9 MCP tools: `add_memory`, `search_memories`, `get_memories`, `get_memory`, `update_memory`, `delete_memory`, `delete_all_memories`, `delete_entities`, `list_entities`. The `integrations/mem0-plugin/` directory provides MCP server connection, lifecycle hooks, and skill bundling for Claude Code, Cursor, Codex, OpenCode, and Antigravity. It exposes 9 MCP tools: `add_memory`, `search_memories`, `get_memories`, `get_memory`, `update_memory`, `delete_memory`, `delete_all_memories`, `delete_entities`, `list_entities`.
Editor-specific setup docs (already listed above under `## Integrations > AI Coding Tools`): Editor-specific setup docs (already listed above under `## Integrations > AI Coding Tools`):
+19 -4
View File
@@ -6,9 +6,7 @@ versionFrom: "Open Source"
versionTo: "Platform" versionTo: "Platform"
--- ---
# Migrate from Open Source to Platform ## Overview
Move your Mem0 implementation to managed infrastructure with enterprise features.
| Scope | Effort | Downtime | | Scope | Effort | Downtime |
| --------------------- | -------------- | ---------------------------- | | --------------------- | -------------- | ---------------------------- |
@@ -30,12 +28,29 @@ Move your Mem0 implementation to managed infrastructure with enterprise features
- **Production Grade**: Auto-scaling, high availability, dedicated support - **Production Grade**: Auto-scaling, high availability, dedicated support
</Info> </Info>
## Plan ### Plan
1. **Sign up**: Create an account on <a href="https://app.mem0.ai?utm_source=oss&utm_medium=migration-oss-to-platform" rel="nofollow">Mem0 Platform</a>. 1. **Sign up**: Create an account on <a href="https://app.mem0.ai?utm_source=oss&utm_medium=migration-oss-to-platform" rel="nofollow">Mem0 Platform</a>.
2. **Get API Key**: Navigate to **Settings > API Keys** and generate a new key. 2. **Get API Key**: Navigate to **Settings > API Keys** and generate a new key.
3. **Review Usage**: Identify where you instantiate `Memory` and where you call `search` or `get_all`. 3. **Review Usage**: Identify where you instantiate `Memory` and where you call `search` or `get_all`.
## Migrate with Agent Skill
Paste this prompt into your coding agent. It uses a migration skill to produce a plan; once you review and approve it, the agent implements the changes.
```text
Migrate my project from Mem0 OSS to the Mem0 Platform SDK using the
mem0-oss-to-platform skill in the mem0ai/mem0 repo, at
skills/mem0-oss-to-platform/
Get the skill whichever way is easiest:
- install it: npx skills add https://github.com/mem0ai/mem0 --skill mem0-oss-to-platform
- if the mem0 repo is cloned locally, read it from skills/mem0-oss-to-platform/
- otherwise fetch that folder from github.com/mem0ai/mem0 (SKILL.md + references/)
Then read SKILL.md and begin the migration.
```
## Migrate ## Migrate
### 1. Import Memories Into Platform ### 1. Import Memories Into Platform
+2
View File
@@ -45,10 +45,12 @@ Let your assistant execute an end-to-end workflow in an existing repo. Invoked a
```bash ```bash
npx skills add https://github.com/mem0ai/mem0 --skill mem0-integrate npx skills add https://github.com/mem0ai/mem0 --skill mem0-integrate
npx skills add https://github.com/mem0ai/mem0 --skill mem0-test-integration npx skills add https://github.com/mem0ai/mem0 --skill mem0-test-integration
npx skills add https://github.com/mem0ai/mem0 --skill mem0-oss-to-platform
``` ```
- `/mem0-integrate` — wire Mem0 into an existing repository using a goal-driven, test-first pipeline. Detects the stack, asks whether to use Platform or OSS, writes failing tests first, and keeps the integration additive and feature-flagged. - `/mem0-integrate` — wire Mem0 into an existing repository using a goal-driven, test-first pipeline. Detects the stack, asks whether to use Platform or OSS, writes failing tests first, and keeps the integration additive and feature-flagged.
- `/mem0-test-integration` — verify what `/mem0-integrate` produced. Runs the repo's native test suite and a real end-to-end smoke flow against your API key, then produces a scorecard. - `/mem0-test-integration` — verify what `/mem0-integrate` produced. Runs the repo's native test suite and a real end-to-end smoke flow against your API key, then produces a scorecard.
- `/mem0-oss-to-platform` — migrate an existing project from Mem0 OSS to the hosted Platform SDK. Audits where Mem0 is used, writes a reviewable migration plan, then executes it on approval.
See the [skills index](https://github.com/mem0ai/mem0/tree/main/skills) for the full catalog. See the [skills index](https://github.com/mem0ai/mem0/tree/main/skills) for the full catalog.
@@ -16,10 +16,10 @@ type RetrievedMemory = {
type NewMemory = { type NewMemory = {
id: string; id: string;
data: { data?: {
memory: string; memory: string;
}; };
event: "ADD" | "DELETE"; event: "ADD" | "UPDATE" | "DELETE" | "GET";
}; };
type NewMemoryAnnotation = { type NewMemoryAnnotation = {
@@ -47,14 +47,16 @@ const useMemories = (): Memory[] => {
() => () =>
annotations?.filter(isMemoryAnnotation).flatMap((a) => { annotations?.filter(isMemoryAnnotation).flatMap((a) => {
if (a.type === "mem0-update") { if (a.type === "mem0-update") {
return a.memories.map( return a.memories
(m): Memory => ({ .filter((m): m is NewMemory & { data: { memory: string } } => m.data != null)
event: m.event, .map(
id: m.id, (m): Memory => ({
memory: m.data.memory, event: m.event,
score: 1, id: m.id,
}) memory: m.data.memory,
); score: 1,
})
);
} else if (a.type === "mem0-get") { } else if (a.type === "mem0-get") {
return a.memories.map((m) => ({ return a.memories.map((m) => ({
event: "GET", event: "GET",
@@ -555,7 +555,7 @@
"# - Enables creation of AI agents with long-term memory and learning abilities.\n", "# - Enables creation of AI agents with long-term memory and learning abilities.\n",
"# - Improves consistency and reduces repetition in user-agent interactions.\n", "# - Improves consistency and reduces repetition in user-agent interactions.\n",
"\n", "\n",
"from cookbooks.helper.mem0_teachability import Mem0Teachability\n", "from helper.mem0_teachability import Mem0Teachability\n",
"\n", "\n",
"teachability = Mem0Teachability(\n", "teachability = Mem0Teachability(\n",
" verbosity=2, # for visibility of what's happening\n", " verbosity=2, # for visibility of what's happening\n",
@@ -1,6 +1,6 @@
{ {
"name": "mem0", "name": "mem0",
"version": "0.2.9", "version": "0.2.10",
"description": "Persistent memory for Claude Code. Remembers decisions, patterns, and preferences across sessions.", "description": "Persistent memory for Claude Code. Remembers decisions, patterns, and preferences across sessions.",
"author": { "author": {
"name": "Mem0", "name": "Mem0",
@@ -1,6 +1,6 @@
{ {
"name": "mem0", "name": "mem0",
"version": "0.2.9", "version": "0.2.10",
"description": "Persistent memory for Codex. Remembers decisions, patterns, and preferences across sessions.", "description": "Persistent memory for Codex. Remembers decisions, patterns, and preferences across sessions.",
"author": { "author": {
"name": "Mem0", "name": "Mem0",
@@ -1,6 +1,6 @@
{ {
"name": "mem0", "name": "mem0",
"version": "0.2.9", "version": "0.2.10",
"description": "Mem0 memory layer for AI applications. Add persistent memory, personalization, and semantic search using the Mem0 Platform MCP server.", "description": "Mem0 memory layer for AI applications. Add persistent memory, personalization, and semantic search using the Mem0 Platform MCP server.",
"author": { "author": {
"name": "Mem0", "name": "Mem0",
@@ -2,13 +2,14 @@
All notable changes to the `@mem0/opencode-plugin` will be documented in this file. All notable changes to the `@mem0/opencode-plugin` will be documented in this file.
## 0.1.3 — File-context injection, session summaries & activity timeline ## 0.1.3 — File-context injection, session summaries & activity timeline, anonymous telemetry
### Added ### Added
- **File-context injection (`tool.execute.before` / Read):** Before the agent reads a file, the plugin searches mem0 for memories referencing that file path and injects prior work as system context. Gates on file size (>= 1,500 bytes). Gives the agent "I've worked on this file before" awareness automatically. - **File-context injection (`tool.execute.before` / Read):** Before the agent reads a file, the plugin searches mem0 for memories referencing that file path and injects prior work as system context. Gates on file size (>= 1,500 bytes). Gives the agent "I've worked on this file before" awareness automatically.
- **Stop hook session summary (`experimental.session.compacting`):** Enhanced session compaction to store a structured `session_summary` memory with `infer=True`, letting the mem0 backend AI extract key facts (request, decisions, learnings, next steps). Previously only stored a raw stats string. - **Stop hook session summary (`experimental.session.compacting`):** Enhanced session compaction to store a structured `session_summary` memory with `infer=True`, letting the mem0 backend AI extract key facts (request, decisions, learnings, next steps). Previously only stored a raw stats string.
- **SessionStart activity timeline:** The initial memory loading now formats recent memories with type icons (⚖️ decision, 🔴 bug_fix, 🔵 task_learning, etc.) and relative age indicators (2h ago, 1d ago) instead of bare text. Provides a visual "Recent Activity" timeline on first message. - **SessionStart activity timeline:** The initial memory loading now formats recent memories with type icons (⚖️ decision, 🔴 bug_fix, 🔵 task_learning, etc.) and relative age indicators (2h ago, 1d ago) instead of bare text. Provides a visual "Recent Activity" timeline on first message.
- **PostHog telemetry (`telemetry.ts`):** Anonymous, fire-and-forget usage events. Opt out with `MEM0_TELEMETRY=false`. Only fires when an API key is present; never sends memory content, prompts, or the API key — only an anonymized `sha256(apiKey)[:32]` identity plus event type, platform, and plugin version. Emits the same schema as the Mem0 editor plugin (`plugin.*` events, `source: "plugin"`, `platform: "opencode"`) so OpenCode appears as a `platform` in the shared plugin dashboard. Events: `plugin.session_start` (with memory count) and `plugin.tool_use` (`add` / `search` / `update` / `delete`).
### Changed ### Changed
@@ -17,7 +17,7 @@ opencode plugin @mem0/opencode-plugin
**Or let your agent do it** — paste this into OpenCode: **Or let your agent do it** — paste this into OpenCode:
``` ```
Install @mem0/opencode-plugin by following https://raw.githubusercontent.com/mem0ai/mem0/main/mem0-plugin/.opencode-plugin/README.md Install @mem0/opencode-plugin by following https://raw.githubusercontent.com/mem0ai/mem0/main/integrations/mem0-plugin/.opencode-plugin/README.md
``` ```
All commands auto-add the plugin and MCP server to your `~/.config/opencode/opencode.json`. No manual config needed. All commands auto-add the plugin and MCP server to your `~/.config/opencode/opencode.json`. No manual config needed.
@@ -6,7 +6,7 @@
"name": "@mem0/opencode-plugin", "name": "@mem0/opencode-plugin",
"dependencies": { "dependencies": {
"@opencode-ai/plugin": "^1.0.162", "@opencode-ai/plugin": "^1.0.162",
"mem0ai": "^3.0.5", "mem0ai": "^3.0.7",
}, },
"devDependencies": { "devDependencies": {
"bun-types": ">=1.3.14", "bun-types": ">=1.3.14",
@@ -462,7 +462,7 @@
"md5": ["md5@2.3.0", "", { "dependencies": { "charenc": "0.0.2", "crypt": "0.0.2", "is-buffer": "~1.1.6" } }, "sha512-T1GITYmFaKuO91vxyoQMFETst+O71VUPEU3ze5GNzDm0OWdP8v1ziTaAEPUr/3kLsY3Sftgz242A1SetQiDL7g=="], "md5": ["md5@2.3.0", "", { "dependencies": { "charenc": "0.0.2", "crypt": "0.0.2", "is-buffer": "~1.1.6" } }, "sha512-T1GITYmFaKuO91vxyoQMFETst+O71VUPEU3ze5GNzDm0OWdP8v1ziTaAEPUr/3kLsY3Sftgz242A1SetQiDL7g=="],
"mem0ai": ["mem0ai@3.0.5", "", { "dependencies": { "axios": "^1.15.2", "openai": "^4.93.0", "uuid": "9.0.1", "zod": "^3.24.1" }, "peerDependencies": { "@anthropic-ai/sdk": "^0.40.1", "@azure/identity": "^4.0.0", "@azure/search-documents": "^12.0.0", "@cloudflare/workers-types": "^4.20250504.0", "@google/genai": "^1.2.0", "@langchain/core": "^1.1.47", "@mistralai/mistralai": "^1.5.2", "@qdrant/js-client-rest": "1.13.0", "@supabase/supabase-js": "^2.49.1", "@types/jest": "29.5.14", "@types/pg": "8.11.0", "better-sqlite3": "^12.6.2", "cloudflare": "^4.2.0", "compromise": "^14.0.0", "groq-sdk": "0.3.0", "natural": "^8.0.1", "ollama": "^0.5.14", "pg": "8.11.3", "redis": "^4.6.13" } }, "sha512-W/R59d5fMpUGHhPEnyoo36GSz5NFJbAs+vS4BxoIvE+t19mIJfoz/2FJSKIw80mT8AkeNYpDfzc/DYRu2IzYIw=="], "mem0ai": ["mem0ai@3.0.7", "", { "dependencies": { "axios": "^1.16.0", "openai": "^4.93.0", "uuid": "9.0.1", "zod": "^3.24.1" }, "peerDependencies": { "@anthropic-ai/sdk": "^0.40.1", "@azure/identity": "^4.0.0", "@azure/search-documents": "^12.0.0", "@cloudflare/workers-types": "^4.20250504.0", "@google/genai": "^1.40.0", "@langchain/core": "^1.1.47", "@mistralai/mistralai": "^1.5.2", "@qdrant/js-client-rest": "^1.18.0", "@supabase/supabase-js": "^2.49.1", "@types/jest": "29.5.14", "@types/pg": "8.11.0", "better-sqlite3": "^12.6.2", "cloudflare": "^4.2.0", "compromise": "^14.0.0", "groq-sdk": "0.3.0", "natural": "^8.0.1", "ollama": "^0.5.14", "pg": "8.11.3", "redis": "^4.6.13" } }, "sha512-CUHzX7DyeKTHcI3aDsSqY9LXTD7GcFxf988796TuOa4yJgGuF2Xd2NROcBhVFRo3r9y8fVmbo3c5TF9jv1KlKw=="],
"memjs": ["memjs@1.3.2", "", {}, "sha512-qUEg2g8vxPe+zPn09KidjIStHPtoBO8Cttm8bgJFWWabbsjQ9Av9Ky+6UcvKx6ue0LLb/LEhtcyQpRyKfzeXcg=="], "memjs": ["memjs@1.3.2", "", {}, "sha512-qUEg2g8vxPe+zPn09KidjIStHPtoBO8Cttm8bgJFWWabbsjQ9Av9Ky+6UcvKx6ue0LLb/LEhtcyQpRyKfzeXcg=="],
@@ -9,6 +9,7 @@ import { existsSync, readdirSync, cpSync, mkdirSync, readFileSync, writeFileSync
import { homedir } from "os"; import { homedir } from "os";
import { join } from "path"; import { join } from "path";
import { createHash } from "crypto"; import { createHash } from "crypto";
import { captureEvent } from "./telemetry";
async function getUserId(): Promise<string> { async function getUserId(): Promise<string> {
if (process.env.MEM0_USER_ID) return process.env.MEM0_USER_ID; if (process.env.MEM0_USER_ID) return process.env.MEM0_USER_ID;
@@ -368,6 +369,8 @@ const Mem0Plugin: Plugin = async (ctx) => {
}); });
} catch {} } catch {}
} }
captureEvent("session_start", { memory_count: memoryCount }, apiKey);
} }
if (NUDGE_RE.test(safeText)) { if (NUDGE_RE.test(safeText)) {
@@ -602,6 +605,17 @@ const Mem0Plugin: Plugin = async (ctx) => {
if (MEM0_MCP_RE.test(toolName)) { if (MEM0_MCP_RE.test(toolName)) {
if (toolName.includes("add_memory")) stats.adds++; if (toolName.includes("add_memory")) stats.adds++;
if (toolName.includes("search")) stats.searches++; if (toolName.includes("search")) stats.searches++;
const tool = toolName.includes("add_memory")
? "add_memory"
: toolName.includes("search")
? "search_memories"
: toolName.includes("delete")
? "delete_memory"
: toolName.includes("update")
? "update_memory"
: "other";
captureEvent("tool_use", { tool }, apiKey);
} }
if (toolName === "bash" && toolOutput.length >= 50) { if (toolName === "bash" && toolOutput.length >= 50) {
@@ -30,7 +30,7 @@
"repository": { "repository": {
"type": "git", "type": "git",
"url": "https://github.com/mem0ai/mem0", "url": "https://github.com/mem0ai/mem0",
"directory": "mem0-plugin/.opencode-plugin" "directory": "integrations/mem0-plugin/.opencode-plugin"
}, },
"files": [ "files": [
"dist", "dist",
@@ -59,7 +59,7 @@
}, },
"dependencies": { "dependencies": {
"@opencode-ai/plugin": "^1.0.162", "@opencode-ai/plugin": "^1.0.162",
"mem0ai": "^3.0.5" "mem0ai": "^3.0.7"
}, },
"devDependencies": { "devDependencies": {
"bun-types": ">=1.3.14", "bun-types": ">=1.3.14",
@@ -0,0 +1,51 @@
import { afterEach, describe, expect, test } from "bun:test";
import { buildEvent, captureEvent, isTelemetryEnabled } from "./telemetry";
const KEY = "m0-testkey123";
afterEach(() => {
delete process.env.MEM0_TELEMETRY;
});
describe("opencode telemetry", () => {
test("buildEvent uses the shared plugin.* schema with platform=opencode", () => {
const payload = buildEvent("session_start", { memory_count: 5 }, KEY);
expect(payload).not.toBeNull();
const props = payload!.properties as Record<string, unknown>;
expect(payload!.event).toBe("plugin.session_start");
expect(props.source).toBe("plugin");
expect(props.platform).toBe("opencode");
expect(props.memory_count).toBe(5);
expect(props.$process_person_profile).toBe(false);
expect(typeof props.plugin_version).toBe("string");
});
test("distinct_id is sha256(apiKey)[:32] — matches the editor plugin", async () => {
const { createHash } = await import("node:crypto");
const expected = createHash("sha256").update(KEY).digest("hex").slice(0, 32);
expect(buildEvent("session_start", {}, KEY)!.distinct_id).toBe(expected);
});
test("system properties win over caller-supplied ones", () => {
const props = buildEvent("x", { platform: "HACK", source: "HACK" }, KEY)!
.properties as Record<string, unknown>;
expect(props.platform).toBe("opencode");
expect(props.source).toBe("plugin");
});
test("returns null without an API key (no anonymous events)", () => {
expect(buildEvent("session_start", {}, undefined)).toBeNull();
});
test("opt-out via MEM0_TELEMETRY disables events", () => {
process.env.MEM0_TELEMETRY = "false";
expect(isTelemetryEnabled()).toBe(false);
expect(buildEvent("session_start", {}, KEY)).toBeNull();
});
test("captureEvent never throws (and sends nothing when opted out)", () => {
process.env.MEM0_TELEMETRY = "false";
expect(() => captureEvent("session_start", {}, KEY)).not.toThrow();
expect(() => captureEvent("session_start", {}, undefined)).not.toThrow();
});
});
@@ -0,0 +1,104 @@
/**
* Plugin telemetry for the Mem0 OpenCode plugin — anonymous usage tracking
* via PostHog.
*
* Emits the SAME event schema as the Mem0 editor plugin's telemetry.py
* (event names prefixed `plugin.`, `source: "plugin"`, `platform: "opencode"`,
* `distinct_id = sha256(apiKey)[:32]`) so OpenCode shows up as just another
* `platform` value in the shared plugin dashboard instead of a separate
* event namespace.
*
* Fire-and-forget: never throws, never blocks, failures are swallowed. Only
* fires when an API key is present (same as the editor plugin — anonymous
* installs without a key emit nothing). Disable with MEM0_TELEMETRY=false.
*
* Never sends: memory content, API keys, raw user/project IDs. Only sends:
* event type, platform, plugin version, anonymized hash of the API key.
*/
import { createHash } from "node:crypto";
import { readFileSync } from "node:fs";
const POSTHOG_API_KEY = "phc_hgJkUVJFYtmaJqrvf6CYN67TIQ8yhXAkWzUn9AMU4yX";
const POSTHOG_HOST = "https://us.i.posthog.com/i/v0/e/";
const REQUEST_TIMEOUT_MS = 2_000;
function _loadPluginVersion(): string {
// Source context: telemetry.ts sits next to package.json (./).
// Bundled context: dist/index.js sits one level below it (../).
for (const rel of ["./package.json", "../package.json"]) {
try {
const pkg = JSON.parse(readFileSync(new URL(rel, import.meta.url), "utf-8"));
if (pkg?.name === "@mem0/opencode-plugin" && pkg.version) return pkg.version;
} catch {
/* try next candidate */
}
}
return "unknown";
}
const PLUGIN_VERSION = _loadPluginVersion();
export function isTelemetryEnabled(): boolean {
const val = process.env.MEM0_TELEMETRY;
if (val === undefined) return true;
const s = val.toLowerCase();
return s !== "false" && s !== "0" && s !== "no" && s !== "off";
}
function distinctId(apiKey: string): string {
// Matches telemetry.py `_distinct_id()` so the same user is one person in
// PostHog whether they use OpenCode or any other Mem0 editor plugin.
return createHash("sha256").update(apiKey).digest("hex").slice(0, 32);
}
/**
* Build the PostHog event payload, or null when telemetry is disabled or no
* API key is available. Pure (aside from env/version reads) and exported for
* testing. System-controlled properties are applied last so a caller cannot
* override `source`/`platform`/etc.
*/
export function buildEvent(
eventType: string,
properties: Record<string, unknown>,
apiKey: string | undefined,
): Record<string, unknown> | null {
if (!isTelemetryEnabled() || !apiKey) return null;
return {
api_key: POSTHOG_API_KEY,
distinct_id: distinctId(apiKey),
event: `plugin.${eventType}`,
properties: {
...properties,
source: "plugin",
platform: "opencode",
plugin_version: PLUGIN_VERSION,
os: process.platform,
sample_rate: 1.0,
$process_person_profile: false,
$lib: "posthog-node",
},
};
}
/** Send a usage event, fire-and-forget. Never throws, never blocks. */
export function captureEvent(
eventType: string,
properties: Record<string, unknown>,
apiKey: string | undefined,
): void {
const payload = buildEvent(eventType, properties, apiKey);
if (!payload) return;
try {
void fetch(POSTHOG_HOST, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(payload),
signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS),
}).catch(() => {
/* fire-and-forget */
});
} catch {
/* never throw */
}
}
@@ -16,5 +16,5 @@
"emitDeclarationOnly": true "emitDeclarationOnly": true
}, },
"include": ["**/*"], "include": ["**/*"],
"exclude": ["node_modules", "dist"] "exclude": ["node_modules", "dist", "**/*.test.ts"]
} }
@@ -2,6 +2,21 @@
All notable changes to the Mem0 plugin will be documented in this file. All notable changes to the Mem0 plugin will be documented in this file.
## 0.2.10 — Accurate per-editor telemetry attribution
### Fixed
- **Antigravity counted as Claude Code:** `detect_platform()` (`scripts/telemetry.py`) now checks `ANTIGRAVITY_PLUGIN_ROOT` before the `CLAUDE_PLUGIN_ROOT` branch. Antigravity sets both env vars for compatibility, so every Antigravity session was previously attributed to `claude-code`. Telemetry now reports `platform: "antigravity"`.
- **Codex fell back to the generic `plugin` bucket:** Codex installs standalone hooks with absolute paths via `install_codex_hooks.py`, so `PLUGIN_ROOT` is never set at runtime and platform auto-detection failed. Each command in `hooks/codex-hooks.json` now pins `MEM0_PLATFORM=codex` inline (Codex runs hook commands through a shell). Telemetry now reports `platform: "codex"`.
- **Cursor attribution depended on the host env:** Cursor's `*_cursor.sh` wrappers delegate to the shared hook scripts, whose platform detection relied on Cursor exporting `CURSOR_PLUGIN_ROOT` to the subprocess. All five Cursor wrappers now `export MEM0_PLATFORM=cursor` before delegating.
- **`plugin_version` was identical for every editor:** telemetry read `.claude-plugin/plugin.json` for all bash-hook editors, so Antigravity reported `0.2.10` instead of its real `0.1.2`. `_load_plugin_version()` now reads the manifest matching the detected platform, so each editor reports its own version.
### Added
- **`MEM0_PLATFORM` override in `detect_platform()`:** An explicit platform marker that wins over env-var auto-detection, letting each editor label its telemetry reliably. New tests in `tests/test_telemetry.py` cover the override, Antigravity attribution, and the Cursor/Codex platform-pinning contracts.
> Attribution fixes apply to telemetry emitted after users upgrade to this version; PostHog does not backfill past events.
## 0.2.9 — File-context injection, session summaries & activity timeline ## 0.2.9 — File-context injection, session summaries & activity timeline
### Added ### Added
@@ -90,14 +90,14 @@ git clone https://github.com/mem0ai/mem0.git ~/codex-plugins/mem0-source
codex plugin marketplace add ~/codex-plugins/mem0-source codex plugin marketplace add ~/codex-plugins/mem0-source
``` ```
This points Codex at the repo's `.agents/plugins/marketplace.json`, which references `mem0-plugin/` as the local source. Restart Codex, run `/plugins`, and install **Mem0** from the **Mem0 Plugins** marketplace. This points Codex at the repo's `.agents/plugins/marketplace.json`, which references `integrations/mem0-plugin/` as the local source. Restart Codex, run `/plugins`, and install **Mem0** from the **Mem0 Plugins** marketplace.
> **Don't combine with Option A.** The plugin manifest auto-registers `mem0` as an MCP server via `mem0-plugin/.codex-mcp.json` — adding a manual `[mcp_servers.mem0]` block would duplicate the registration. > **Don't combine with Option A.** The plugin manifest auto-registers `mem0` as an MCP server via `integrations/mem0-plugin/.codex-mcp.json` — adding a manual `[mcp_servers.mem0]` block would duplicate the registration.
**Optional — enable lifecycle hooks.** Codex doesn't auto-wire hooks from plugin manifests; it only reads `~/.codex/hooks.json` (or `<repo>/.codex/hooks.json`) ([docs](https://developers.openai.com/codex/hooks)). Run the bundled installer once to merge Mem0's entries: **Optional — enable lifecycle hooks.** Codex doesn't auto-wire hooks from plugin manifests; it only reads `~/.codex/hooks.json` (or `<repo>/.codex/hooks.json`) ([docs](https://developers.openai.com/codex/hooks)). Run the bundled installer once to merge Mem0's entries:
```bash ```bash
python3 ~/codex-plugins/mem0-source/mem0-plugin/scripts/install_codex_hooks.py python3 ~/codex-plugins/mem0-source/integrations/mem0-plugin/scripts/install_codex_hooks.py
``` ```
This merges three entries into `~/.codex/hooks.json` with absolute paths pointing into your clone: This merges three entries into `~/.codex/hooks.json` with absolute paths pointing into your clone:
@@ -190,7 +190,7 @@ See [OpenCode integration docs](https://docs.mem0.ai/integrations/opencode) for
```bash ```bash
# Install the plugin (MCP server, hooks, scripts) # Install the plugin (MCP server, hooks, scripts)
npx degit mem0ai/mem0/mem0-plugin ~/.gemini/config/plugins/mem0 npx degit mem0ai/mem0/integrations/mem0-plugin ~/.gemini/config/plugins/mem0
``` ```
This installs the MCP server, lifecycle hooks, and shared scripts. This installs the MCP server, lifecycle hooks, and shared scripts.
@@ -276,10 +276,10 @@ The background setup is idempotent and runs once per account (cached in `~/.mem0
```bash ```bash
# Dry-run -- prints current vs proposed, no changes: # Dry-run -- prints current vs proposed, no changes:
python mem0-plugin/scripts/setup_coding_categories.py python integrations/mem0-plugin/scripts/setup_coding_categories.py
# Write explicitly: # Write explicitly:
python mem0-plugin/scripts/setup_coding_categories.py --apply python integrations/mem0-plugin/scripts/setup_coding_categories.py --apply
``` ```
Requires the `mem0ai` Python SDK (`pip install mem0ai`) and `MEM0_API_KEY` set. `project.update(custom_categories=[...])` always replaces the full list. Requires the `mem0ai` Python SDK (`pip install mem0ai`) and `MEM0_API_KEY` set. `project.update(custom_categories=[...])` always replaces the full list.
@@ -6,7 +6,7 @@
"hooks": [ "hooks": [
{ {
"type": "command", "type": "command",
"command": "${PLUGIN_ROOT}/scripts/block_memory_write.sh", "command": "MEM0_PLATFORM=codex ${PLUGIN_ROOT}/scripts/block_memory_write.sh",
"timeout": 3 "timeout": 3
} }
] ]
@@ -16,7 +16,7 @@
"hooks": [ "hooks": [
{ {
"type": "command", "type": "command",
"command": "${PLUGIN_ROOT}/scripts/enforce_metadata_defaults.sh", "command": "MEM0_PLATFORM=codex ${PLUGIN_ROOT}/scripts/enforce_metadata_defaults.sh",
"timeout": 3 "timeout": 3
} }
] ]
@@ -26,7 +26,7 @@
"hooks": [ "hooks": [
{ {
"type": "command", "type": "command",
"command": "${PLUGIN_ROOT}/scripts/on_file_read.sh", "command": "MEM0_PLATFORM=codex ${PLUGIN_ROOT}/scripts/on_file_read.sh",
"timeout": 5 "timeout": 5
} }
] ]
@@ -38,7 +38,7 @@
"hooks": [ "hooks": [
{ {
"type": "command", "type": "command",
"command": "${PLUGIN_ROOT}/scripts/on_session_start.sh", "command": "MEM0_PLATFORM=codex ${PLUGIN_ROOT}/scripts/on_session_start.sh",
"statusMessage": "Loading mem0 context..." "statusMessage": "Loading mem0 context..."
} }
] ]
@@ -49,7 +49,7 @@
"hooks": [ "hooks": [
{ {
"type": "command", "type": "command",
"command": "${PLUGIN_ROOT}/scripts/on_user_prompt.sh", "command": "MEM0_PLATFORM=codex ${PLUGIN_ROOT}/scripts/on_user_prompt.sh",
"statusMessage": "Checking memory relevance...", "statusMessage": "Checking memory relevance...",
"timeout": 12 "timeout": 12
} }
@@ -62,7 +62,7 @@
"hooks": [ "hooks": [
{ {
"type": "command", "type": "command",
"command": "${PLUGIN_ROOT}/scripts/on_post_tool_use.sh", "command": "MEM0_PLATFORM=codex ${PLUGIN_ROOT}/scripts/on_post_tool_use.sh",
"timeout": 3 "timeout": 3
} }
] ]
@@ -72,7 +72,7 @@
"hooks": [ "hooks": [
{ {
"type": "command", "type": "command",
"command": "${PLUGIN_ROOT}/scripts/on_bash_output.sh", "command": "MEM0_PLATFORM=codex ${PLUGIN_ROOT}/scripts/on_bash_output.sh",
"timeout": 12 "timeout": 12
} }
] ]
@@ -83,7 +83,7 @@
"hooks": [ "hooks": [
{ {
"type": "command", "type": "command",
"command": "${PLUGIN_ROOT}/scripts/on_stop.sh", "command": "MEM0_PLATFORM=codex ${PLUGIN_ROOT}/scripts/on_stop.sh",
"timeout": 30 "timeout": 30
} }
] ]
@@ -94,7 +94,7 @@
"hooks": [ "hooks": [
{ {
"type": "command", "type": "command",
"command": "${PLUGIN_ROOT}/scripts/on_pre_compact.sh", "command": "MEM0_PLATFORM=codex ${PLUGIN_ROOT}/scripts/on_pre_compact.sh",
"statusMessage": "Preparing pre-compaction summary..." "statusMessage": "Preparing pre-compaction summary..."
} }
] ]

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 13 KiB

@@ -1,7 +1,7 @@
{ {
"id": "mem0", "id": "mem0",
"name": "mem0", "name": "mem0",
"version": "0.1.1", "version": "0.1.2",
"description": "Persistent semantic memory for Antigravity agents. Cross-session, user-level recall via the Mem0 Platform MCP server. 16 slash commands, lifecycle hooks for auto-capture and metadata enforcement.", "description": "Persistent semantic memory for Antigravity agents. Cross-session, user-level recall via the Mem0 Platform MCP server. 16 slash commands, lifecycle hooks for auto-capture and metadata enforcement.",
"author": { "name": "Mem0", "email": "support@mem0.ai" }, "author": { "name": "Mem0", "email": "support@mem0.ai" },
"publisher": "mem0ai", "publisher": "mem0ai",

Some files were not shown because too many files have changed in this diff Show More