Compare commits

..
Author SHA1 Message Date
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
331 changed files with 5228 additions and 4834 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",
+1 -1
View File
@@ -10,7 +10,7 @@
"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.9"
} }
+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",
+1 -1
View File
@@ -10,7 +10,7 @@
"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.9"
} }
+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
+43 -24
View File
@@ -22,11 +22,13 @@ 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/` | | `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) |
@@ -49,8 +51,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 +75,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 +164,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 +182,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 +344,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,11 +383,11 @@ 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.
@@ -402,19 +404,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)
+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,
},
}); });
+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")
+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`):
@@ -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",
@@ -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.
@@ -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",
@@ -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.

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 13 KiB

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