feat(skills): add mem0-integrate + mem0-test-integration pipeline skills (#4961)
This commit is contained in:
@@ -27,7 +27,7 @@ This is a **polyglot monorepo** containing Python and TypeScript packages, CLIs,
|
||||
| `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) |
|
||||
| `mem0-plugin/` | AI editor plugins (Claude Code, Cursor, Codex) — MCP server connection, lifecycle hooks, skills |
|
||||
| `skills/` | Claude Code skill definitions — `mem0/`, `mem0-cli/`, `mem0-vercel-ai-sdk/` |
|
||||
| `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) |
|
||||
| `tests/` | Python SDK tests (pytest) |
|
||||
| `evaluation/` | Benchmarking framework — LOCOMO evals, experiment runner, score generation |
|
||||
@@ -387,7 +387,9 @@ Model Context Protocol support in multiple places:
|
||||
### Plugin & Skills System
|
||||
|
||||
- `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, covering SDK usage, CLI workflows, and Vercel AI SDK patterns.
|
||||
- `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).
|
||||
- **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.
|
||||
|
||||
### Adding a New Provider
|
||||
|
||||
|
||||
@@ -147,6 +147,27 @@ mem0 search "What does Alice prefer?" --user-id alice
|
||||
|
||||
See the [CLI documentation](https://docs.mem0.ai/platform/cli) for the full command reference.
|
||||
|
||||
### Agent Skills
|
||||
|
||||
Teach your AI coding assistant (Claude Code, Codex, Cursor, Windsurf, OpenCode, OpenClaw, and any tool that supports the skills standard) how to build with Mem0. Two categories:
|
||||
|
||||
**Reference skills — always on** (SDK knowledge loaded into the assistant's context):
|
||||
|
||||
```bash
|
||||
npx skills add https://github.com/mem0ai/mem0 --skill mem0
|
||||
npx skills add https://github.com/mem0ai/mem0 --skill mem0-cli
|
||||
npx skills add https://github.com/mem0ai/mem0 --skill mem0-vercel-ai-sdk
|
||||
```
|
||||
|
||||
**Pipeline skills — run on demand** (execute an end-to-end workflow in an existing repo):
|
||||
|
||||
```bash
|
||||
npx skills add https://github.com/mem0ai/mem0 --skill mem0-integrate
|
||||
npx skills add https://github.com/mem0ai/mem0 --skill mem0-test-integration
|
||||
```
|
||||
|
||||
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.
|
||||
|
||||
### Basic Usage
|
||||
|
||||
Mem0 requires an LLM to function, with `gpt-5-mini` from OpenAI as the default. However, it supports a variety of LLMs; for details, refer to our [Supported LLMs documentation](https://docs.mem0.ai/components/llms/overview).
|
||||
|
||||
+24
-2
@@ -22,13 +22,35 @@ We follow the llms.txt standard:
|
||||
|
||||
## Agent Skills
|
||||
|
||||
Teach your coding assistant how to build with Mem0:
|
||||
Mem0 ships two kinds of skills for AI coding assistants. Both work with Claude Code, Codex, Cursor, Windsurf, OpenCode, OpenClaw, and any assistant that supports the skills standard.
|
||||
|
||||
### Reference skills — always on
|
||||
|
||||
Teach your assistant Mem0's SDK surface so it writes correct code in everyday development:
|
||||
|
||||
```bash
|
||||
npx skills add https://github.com/mem0ai/mem0 --skill mem0
|
||||
npx skills add https://github.com/mem0ai/mem0 --skill mem0-cli
|
||||
npx skills add https://github.com/mem0ai/mem0 --skill mem0-vercel-ai-sdk
|
||||
```
|
||||
|
||||
Works with Claude Code, Cursor, Windsurf, and any assistant that supports skills. Once installed, your assistant understands Mem0's full API, framework integrations, and common patterns.
|
||||
- `mem0` — Python and TypeScript SDKs (Platform + OSS), plus framework integrations (LangChain, CrewAI, OpenAI Agents, LangGraph, LlamaIndex, etc.)
|
||||
- `mem0-cli` — terminal workflows for the `mem0` CLI (both Node and Python builds)
|
||||
- `mem0-vercel-ai-sdk` — `@mem0/vercel-ai-provider` and `createMem0`
|
||||
|
||||
### Pipeline skills — run on demand
|
||||
|
||||
Let your assistant execute an end-to-end workflow in an existing repo. Invoked as slash commands:
|
||||
|
||||
```bash
|
||||
npx skills add https://github.com/mem0ai/mem0 --skill mem0-integrate
|
||||
npx skills add https://github.com/mem0ai/mem0 --skill mem0-test-integration
|
||||
```
|
||||
|
||||
- `/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.
|
||||
|
||||
See the [skills index](https://github.com/mem0ai/mem0/tree/main/skills) for the full catalog.
|
||||
|
||||
## MCP Server Setup
|
||||
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
# Mem0 Skills for AI Coding Assistants
|
||||
|
||||
Mem0 ships structured skill definitions for Claude Code, Codex, Cursor, OpenCode, OpenClaw, and any assistant that supports the [skills standard](https://github.com/anthropic-experimental/skills). Skills teach the assistant how to work with Mem0 — either by loading SDK knowledge into context, or by executing an end-to-end workflow on demand.
|
||||
|
||||
## Two Categories
|
||||
|
||||
### Reference skills — always on
|
||||
|
||||
Installed once, loaded into context so the assistant writes correct Mem0 code. Use these for day-to-day development.
|
||||
|
||||
| Skill | Surface | Install |
|
||||
|-------|---------|---------|
|
||||
| [`mem0`](./mem0/) | Python + TypeScript SDKs (Platform + OSS), framework integrations | `npx skills add https://github.com/mem0ai/mem0 --skill mem0` |
|
||||
| [`mem0-cli`](./mem0-cli/) | Terminal workflows (`mem0` CLI, both Node and Python) | `npx skills add https://github.com/mem0ai/mem0 --skill mem0-cli` |
|
||||
| [`mem0-vercel-ai-sdk`](./mem0-vercel-ai-sdk/) | `@mem0/vercel-ai-provider` and `createMem0` | `npx skills add https://github.com/mem0ai/mem0 --skill mem0-vercel-ai-sdk` |
|
||||
|
||||
### Pipeline skills — run on demand
|
||||
|
||||
Invoked as a slash command to execute a specific end-to-end workflow. These do real work: they create branches, write tests, run code.
|
||||
|
||||
| Skill | Trigger | Install |
|
||||
|-------|---------|---------|
|
||||
| [`mem0-integrate`](./mem0-integrate/) | `/mem0-integrate` — wire Mem0 into an existing repo via TDD | `npx skills add https://github.com/mem0ai/mem0 --skill mem0-integrate` |
|
||||
| [`mem0-test-integration`](./mem0-test-integration/) | `/mem0-test-integration` — verify what `/mem0-integrate` produced | `npx skills add https://github.com/mem0ai/mem0 --skill mem0-test-integration` |
|
||||
|
||||
The two pipeline skills are designed to run in sequence on the same workspace:
|
||||
|
||||
```
|
||||
/mem0-integrate → mem0-integrate/<slug> branch + .mem0-integration/ artifacts
|
||||
/mem0-test-integration → scorecard (compile + runtime verification, real API smoke test)
|
||||
```
|
||||
|
||||
## Choosing a Skill
|
||||
|
||||
- **Writing Mem0 code in a new or existing project?** → `mem0`
|
||||
- **Using the terminal CLI?** → `mem0-cli`
|
||||
- **Building with `@ai-sdk/*`?** → `mem0-vercel-ai-sdk`
|
||||
- **Want the assistant to wire Mem0 into an existing repo for you?** → `mem0-integrate`, then `mem0-test-integration`
|
||||
|
||||
## Links
|
||||
|
||||
- [Vibecoding with Mem0](https://docs.mem0.ai/vibecoding) — canonical landing page
|
||||
- [Claude Code integration](https://docs.mem0.ai/integrations/claude-code)
|
||||
- [Mem0 Platform Dashboard](https://app.mem0.ai)
|
||||
- [Mem0 Documentation](https://docs.mem0.ai)
|
||||
|
||||
## License
|
||||
|
||||
Apache-2.0
|
||||
@@ -0,0 +1,189 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but not
|
||||
limited to compiled object code, generated documentation, and
|
||||
conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work.
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to the Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by the Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding any notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
Copyright 2024 Mem0.ai
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
@@ -0,0 +1,89 @@
|
||||
# mem0-integrate — Pipeline Skill
|
||||
|
||||
Wire [Mem0](https://mem0.ai) into an existing repository end-to-end, using a goal-driven, test-first pipeline.
|
||||
|
||||
> **This is a pipeline skill, not a reference skill.** Invoke it as `/mem0-integrate` when you want your assistant to do the work of integrating Mem0 into a target repo. For day-to-day SDK coding help, install [`mem0`](../mem0/SKILL.md) instead.
|
||||
>
|
||||
> **Part of the Mem0 Skill Graph:**
|
||||
> - Reference: [mem0](../mem0/SKILL.md) · [mem0-cli](../mem0-cli/SKILL.md) · [mem0-vercel-ai-sdk](../mem0-vercel-ai-sdk/SKILL.md)
|
||||
> - Pipeline: **mem0-integrate** (this skill) → [mem0-test-integration](../mem0-test-integration/SKILL.md)
|
||||
|
||||
## What This Skill Does
|
||||
|
||||
When invoked, your assistant will:
|
||||
|
||||
- **Detect** the target repo's language and stack automatically
|
||||
- **Ask** whether to integrate with Mem0 Platform (managed) or Mem0 Open Source (self-hosted)
|
||||
- **Write failing tests first** — no implementation until tests exist
|
||||
- **Keep the integration additive and feature-flagged** — existing behavior stays byte-for-byte identical when the flag is unset
|
||||
- **Produce a local feature branch** (`mem0-integrate/...`) and a `.mem0-integration/` directory of artifacts (`goal.md`, `plan.md`, `product.json`) consumed by the companion verification skill
|
||||
|
||||
## When to Use
|
||||
|
||||
Trigger phrases:
|
||||
|
||||
- "Integrate Mem0 into this repo"
|
||||
- "Add Mem0 to my project"
|
||||
- "Wire Mem0 into `<repo>`"
|
||||
- "How do I add memory to an existing project?"
|
||||
|
||||
Do **not** use this skill for general SDK usage (install [`mem0`](../mem0/SKILL.md)), terminal workflows (install [`mem0-cli`](../mem0-cli/SKILL.md)), or Vercel AI SDK integration (install [`mem0-vercel-ai-sdk`](../mem0-vercel-ai-sdk/SKILL.md)).
|
||||
|
||||
## Installation
|
||||
|
||||
### CLI (Claude Code, Codex, OpenCode, OpenClaw, or any tool that supports skills)
|
||||
|
||||
```bash
|
||||
npx skills add https://github.com/mem0ai/mem0 --skill mem0-integrate
|
||||
```
|
||||
|
||||
For verification on the same branch, also install the companion skill:
|
||||
|
||||
```bash
|
||||
npx skills add https://github.com/mem0ai/mem0 --skill mem0-test-integration
|
||||
```
|
||||
|
||||
### Claude.ai
|
||||
|
||||
1. Download this `skills/mem0-integrate` folder as a ZIP
|
||||
2. Go to **Settings > Capabilities > Skills**
|
||||
3. Click **Upload skill** and select the ZIP
|
||||
|
||||
### Claude API (Skills API)
|
||||
|
||||
```bash
|
||||
curl -X POST https://api.anthropic.com/v1/skills \
|
||||
-H "x-api-key: $ANTHROPIC_API_KEY" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"name": "mem0-integrate", "source": "https://github.com/mem0ai/mem0/tree/main/skills/mem0-integrate"}'
|
||||
```
|
||||
|
||||
### Prerequisites
|
||||
|
||||
- A Mem0 Platform API key ([get one](https://app.mem0.ai/dashboard/api-keys)) *or* a working OSS setup (LLM + vector store)
|
||||
- Python 3.10+ or Node.js 18+ in the target repo
|
||||
- A clean working tree on the target repo's default branch
|
||||
|
||||
## Workflow
|
||||
|
||||
```
|
||||
/mem0-integrate → creates mem0-integrate/<slug> branch,
|
||||
writes .mem0-integration/ artifacts,
|
||||
implements against failing tests
|
||||
/mem0-test-integration → runs the repo's native test suite,
|
||||
executes a real end-to-end smoke flow,
|
||||
produces a scorecard
|
||||
```
|
||||
|
||||
The two skills are loosely coupled — they share the same workspace and branch via `.mem0-integration/`, but the verifier never modifies source.
|
||||
|
||||
## Links
|
||||
|
||||
- [Mem0 Platform Dashboard](https://app.mem0.ai)
|
||||
- [Mem0 Documentation](https://docs.mem0.ai)
|
||||
- [Mem0 GitHub](https://github.com/mem0ai/mem0)
|
||||
- [Platform vs OSS comparison](https://docs.mem0.ai/platform/platform-vs-oss)
|
||||
|
||||
## License
|
||||
|
||||
Apache-2.0
|
||||
@@ -0,0 +1,620 @@
|
||||
---
|
||||
name: mem0-integrate
|
||||
description: >
|
||||
Integrate Mem0 into an existing repository using a goal-driven, TDD pipeline.
|
||||
Detects the repo's language automatically and asks the user to pick between
|
||||
Mem0 Platform (managed) and Mem0 Open Source (self-hosted). Writes failing
|
||||
tests before any implementation. Produces a local feature branch plus
|
||||
`.mem0-integration/` artifacts consumed by the paired verification skill.
|
||||
TRIGGER when: user says "integrate mem0", "add mem0 to this repo", "wire
|
||||
mem0 into <repo>", or asks how to add memory to an existing project.
|
||||
DO NOT TRIGGER when: the user wants general SDK usage (use skill:mem0),
|
||||
CLI usage (use skill:mem0-cli), or Vercel AI SDK (use skill:mem0-vercel-ai-sdk).
|
||||
After success, invoke skill:mem0-test-integration to verify in the same
|
||||
workspace (loose coupling).
|
||||
license: Apache-2.0
|
||||
metadata:
|
||||
author: mem0ai
|
||||
version: "0.1.0"
|
||||
category: ai-memory
|
||||
tags: "memory, integration, tdd, platform, oss"
|
||||
mem0_tested_versions: "mem0ai (PyPI) >=2.0.0,<3.0.0; mem0ai (npm) >=3.0.0,<4.0.0"
|
||||
---
|
||||
|
||||
# mem0-integrate
|
||||
|
||||
Wire Mem0 into an existing repo with a goal-driven, test-first pipeline.
|
||||
Pairs with `mem0-test-integration` for verification.
|
||||
|
||||
## Canonical sources (fetch before deciding anything)
|
||||
|
||||
The skill MUST `WebFetch` these URLs before step 3 and cite them in
|
||||
`plan.md`. They are the ground truth — do not rely on ambient knowledge
|
||||
of the Mem0 API.
|
||||
|
||||
### Agent-ready docs
|
||||
- Scope-tagged docs index: https://docs.mem0.ai/llms.txt
|
||||
- Full docs (single file, deep dives): https://docs.mem0.ai/llms-full.txt
|
||||
- OpenAPI spec (Platform REST, machine-readable): https://docs.mem0.ai/openapi.json
|
||||
- Hosted MCP server: https://mcp.mem0.ai (requires Platform API key)
|
||||
- Integrations index: https://docs.mem0.ai/integrations
|
||||
|
||||
### Published Mem0 skills — delegate; do not reimplement
|
||||
Prefer these over writing your own call-site patterns. Each is a
|
||||
standalone `SKILL.md` with triggers, examples, and version-pinned code.
|
||||
|
||||
- SDK (Python + TS, Platform + OSS): https://raw.githubusercontent.com/mem0ai/mem0/main/skills/mem0/SKILL.md
|
||||
- CLI: https://raw.githubusercontent.com/mem0ai/mem0/main/skills/mem0-cli/SKILL.md
|
||||
- Vercel AI SDK: https://raw.githubusercontent.com/mem0ai/mem0/main/skills/mem0-vercel-ai-sdk/SKILL.md
|
||||
- Editor/MCP plugin glue (9 MCP tools): https://github.com/mem0ai/mem0/tree/main/mem0-plugin
|
||||
|
||||
### SDK source (read when docs are ambiguous)
|
||||
Public repo. Cross-check against the `mem0_tested_versions` range in this
|
||||
skill's frontmatter if the `main` branch has moved past a major.
|
||||
|
||||
- Repo root: https://github.com/mem0ai/mem0
|
||||
- Python SDK: https://github.com/mem0ai/mem0/tree/main/mem0
|
||||
- TypeScript SDK: https://github.com/mem0ai/mem0/tree/main/mem0-ts
|
||||
|
||||
### Quickstarts (for bootstrapping unfamiliar stacks)
|
||||
- Platform: https://docs.mem0.ai/platform/quickstart
|
||||
- OSS Python: https://docs.mem0.ai/open-source/python-quickstart
|
||||
- OSS Node: https://docs.mem0.ai/open-source/node-quickstart
|
||||
- Platform vs OSS comparison: https://docs.mem0.ai/platform/platform-vs-oss
|
||||
|
||||
## Integration principles (non-negotiable)
|
||||
|
||||
The true goal of this skill is to produce a **PR the maintainers can accept
|
||||
without argument**. That rules out anything invasive.
|
||||
|
||||
1. **Additive, not replacing.** If the target repo already has a memory
|
||||
system, a session store, a user-context layer, or anything named
|
||||
`Memory` / `memory_*`, Mem0 sits **alongside** it, not in place of it.
|
||||
The existing system keeps working unchanged.
|
||||
2. **Opt-in by default.** Gate all new Mem0 code behind a feature flag
|
||||
(env var like `MEM0_ENABLED=1`, a config key, or a strategy selector).
|
||||
With the flag unset, behavior is the repo's original behavior,
|
||||
byte-for-byte.
|
||||
3. **No breakage.** No removed exports, no renamed public functions,
|
||||
no changed method signatures, no modified existing tests, no changed
|
||||
behavior of existing tests. All pre-existing tests must pass unchanged
|
||||
both with the flag set and unset.
|
||||
4. **Minimal dependency surface.** Add `mem0ai` (plus any deps the
|
||||
delegated skill requires) and nothing else. No new vector stores, no
|
||||
graph databases, no provider SDKs the repo does not already use.
|
||||
5. **Separable commits.** Code, tests, and config/docs land in separate
|
||||
commits so reviewers can cherry-pick.
|
||||
6. **The null hypothesis wins.** If no additive, gated fit exists after
|
||||
step 6 (plan), exit with code 1 and a rationale. A bad PR is worse
|
||||
than no PR.
|
||||
7. **Backend only.** Mem0 integration lives in server-side code. API keys,
|
||||
memory scope, and user-identity resolution are not safe client-side.
|
||||
If the repo has both backend and frontend, the call sites live in
|
||||
backend files. Frontend-only repos are rejected at preconditions.
|
||||
|
||||
Enforced at four gates: **preconditions** (reject frontend-only repos
|
||||
and repos where additive fit is impossible), **step 2 comprehension**
|
||||
(confirm a backend exists and name candidate surfaces), **step 6 plan
|
||||
review** (reject plans that mutate existing exports or name client-side
|
||||
call sites), and **step 10 self-healing loop** (refuse to "fix" principle
|
||||
violations — surface them instead).
|
||||
|
||||
## Skill delegation rules
|
||||
|
||||
Before writing any code, check whether a published skill already covers
|
||||
the target stack. If yes, delegate — copy its call-site pattern into
|
||||
`plan.md` and into the tests; do not paraphrase.
|
||||
|
||||
| Detected in target repo | Delegate to | Why |
|
||||
|---|---|---|
|
||||
| `@ai-sdk/*` + `ai` in `package.json` | `skills/mem0-vercel-ai-sdk` | Integration is via `createMem0` provider wrapper, not raw `MemoryClient`. |
|
||||
| CLI-only repo (Typer, Commander, Click, Cobra) with no LLM call sites | `skills/mem0-cli` | Call sites are command handlers, not model wrappers. Consider whether mem0 actually fits first. |
|
||||
| Target is an MCP client / editor config (Claude Code, Cursor, Codex settings) | `mem0-plugin` | Wire via MCP server URL + hooks; no SDK code usually needed. |
|
||||
| Any other Python or TS repo with an LLM call site | `skills/mem0` | Default SDK integration path. |
|
||||
|
||||
Record the delegated skill's raw URL in `plan.md` under a
|
||||
**"Delegated skill:"** field. The test writer in step 7 and the
|
||||
implementation subagent in step 8 both read this field.
|
||||
|
||||
## Preconditions
|
||||
|
||||
Refuse to start unless ALL of the following are true:
|
||||
|
||||
- Current working directory is inside a git repository with a clean index
|
||||
(no uncommitted changes). Protects the user's work — every edit lands on
|
||||
a feature branch, not on top of in-progress changes.
|
||||
- Repo has a detectable language (`package.json` / `pyproject.toml` /
|
||||
`requirements.txt`). No language → exit cleanly with a written rationale.
|
||||
- Repo has a **backend**. Detected by: a `backend/` or `server/` or `api/`
|
||||
directory; a Python package with FastAPI/Flask/Django/Starlette; a Node
|
||||
package with Express/Fastify/Koa/NestJS/Next-API-routes; an agent-loop
|
||||
framework (LangGraph, LangChain, LlamaIndex, Agno). Frontend-only repos
|
||||
(pure React/Vue/Svelte SPAs, static sites, mobile-only) → exit with
|
||||
code 1 and a rationale. Mem0 is not installed client-side.
|
||||
- The user has already decided Mem0 fits this repo. This skill does NOT
|
||||
survey the codebase to justify fit — bring a concrete goal. (Step 2
|
||||
*does* read the repo to understand what it does and locate backend
|
||||
integration surfaces; that is mechanics, not fit-justification.)
|
||||
|
||||
Exit with a written rationale if any precondition fails. Do not try to
|
||||
"make it work anyway."
|
||||
|
||||
## Pipeline
|
||||
|
||||
### 1. Language detection
|
||||
|
||||
| Signal | Track |
|
||||
|---|---|
|
||||
| `package.json` + TypeScript config | Node / TypeScript |
|
||||
| `package.json` (no TS config) | Node / JavaScript |
|
||||
| `pyproject.toml` or `requirements.txt` | Python |
|
||||
|
||||
Monorepo with both → ask which subdirectory to operate in, then recurse.
|
||||
|
||||
### 2. Repo comprehension — what does this repo do, and where is the backend?
|
||||
|
||||
Before any decision (product, goal, plan), understand the repo enough
|
||||
to locate *where in the backend* the integration belongs. This is not
|
||||
fit-surveying — the user already decided Mem0 fits. This is mechanics:
|
||||
you cannot write a plan without knowing what files matter.
|
||||
|
||||
Read, in order, with a token budget — do not scan the whole tree:
|
||||
|
||||
1. `README.md` (root) + first-page of any `README_*.md` variants.
|
||||
2. `CONTRIBUTING.md` / `AGENTS.md` / `CLAUDE.md` at root if present —
|
||||
these often spell out architecture and entry points.
|
||||
3. `package.json` / `pyproject.toml` scripts + entry points.
|
||||
4. The layout of the top two directory levels (not recursive).
|
||||
5. Key config files: `docker-compose.yml`, `Dockerfile`, `Makefile`,
|
||||
`langgraph.json`, `next.config.*`, `nuxt.config.*`.
|
||||
|
||||
Produce `.mem0-integration/repo-summary.md`:
|
||||
|
||||
# Repo comprehension
|
||||
|
||||
**What this repo does:** <one paragraph in plain English. Who is
|
||||
the end user? What does the app do for them? What LLM / agent
|
||||
behavior is central? Do not list dependencies — describe behavior.>
|
||||
|
||||
**Architecture at a glance:**
|
||||
- Backend: <path(s), framework, primary entry point>
|
||||
- Frontend: <path(s) if any, framework — for context only; no
|
||||
integration here>
|
||||
- Agent loop / orchestration: <LangGraph? custom? none?>
|
||||
- Existing memory/session/state systems: <name them — these are
|
||||
what step 6 Coexistence must preserve>
|
||||
|
||||
**Candidate backend integration surfaces** (ranked, best first):
|
||||
1. `<backend-file>:<line_range>` — <function> — <one-sentence
|
||||
reason this is where write/read could slot in without
|
||||
replacing anything existing>
|
||||
2. ...
|
||||
3. ...
|
||||
|
||||
**Not a fit here:** <list anything the skill considered but ruled
|
||||
out — e.g., "frontend chat component: client-side, excluded by
|
||||
backend-only rule"; "existing memory subsystem X: would require
|
||||
replacement, excluded by additive principle">
|
||||
|
||||
**Sources read:** <list the files actually opened, with line counts,
|
||||
so reviewers can verify coverage.>
|
||||
|
||||
Show the user the rendered summary and ask: *"Is this understanding
|
||||
correct? Which of the candidate surfaces (1, 2, 3 ...) should step 3
|
||||
forward target?"*
|
||||
|
||||
Gate rules:
|
||||
|
||||
- If no backend surface is found → exit code 1. The preconditions
|
||||
should already have caught frontend-only repos; reaching this point
|
||||
means a more subtle miss (e.g., the "backend" is actually just a
|
||||
static build). Do not force a fit.
|
||||
- If every candidate surface would require replacing an existing
|
||||
memory/session system → exit code 1 with the "additive principle"
|
||||
rationale. The user can manually point at a non-conflicting location
|
||||
and re-run.
|
||||
- User corrections update `repo-summary.md` and re-confirm. Max 3
|
||||
rounds; beyond that, exit code 1.
|
||||
|
||||
The user's chosen surface index is baked into `product.json` as
|
||||
`preferred_site` and referenced by steps 5 and 6.
|
||||
|
||||
### 3. Product selection — Platform vs OSS (ask with a recommendation)
|
||||
|
||||
Read the `## Identify the User's Setup` block in
|
||||
`https://docs.mem0.ai/llms.txt` for the Platform-first routing rules, then
|
||||
apply the heuristics below. Ask, but never blank:
|
||||
|
||||
- Other managed-service SDKs present (`@clerk/*`, `stripe`, `@supabase/*`,
|
||||
`openai`, `@upstash/*`, `posthog-*`) — 3+ → recommend **Platform**.
|
||||
- Local-infra signals (`docker-compose.yml` with postgres / redis / qdrant /
|
||||
neo4j, ollama configs, self-hosted auth) — 2+ → recommend **OSS**.
|
||||
- No strong signal → default recommendation: **Platform** (lower integration
|
||||
cost; migration later is supported).
|
||||
|
||||
Example:
|
||||
|
||||
> I see `stripe`, `@clerk/nextjs`, and `@supabase/supabase-js` — managed
|
||||
> services throughout. I recommend **Mem0 Platform** (4-line integration).
|
||||
> Override and use open source?
|
||||
|
||||
Bake the choice into the goal doc in step 5. Do not re-decide later.
|
||||
|
||||
### 4. API key check (env-first, then ask)
|
||||
|
||||
| Track | Key | Where to find |
|
||||
|---|---|---|
|
||||
| Platform | `MEM0_API_KEY` | https://app.mem0.ai |
|
||||
| OSS (default LLM) | `OPENAI_API_KEY` | https://platform.openai.com/api-keys |
|
||||
|
||||
If present in env → continue.
|
||||
If missing → **interactive mode** asks; **CI mode** (`MEM0_INTEGRATE_CI=1`)
|
||||
exits with code 2 and the name of the missing key.
|
||||
|
||||
Never echo key values into `trace.jsonl`. Persist to `.env` only with
|
||||
explicit user consent, and append `.env` to `.gitignore` if not already there.
|
||||
|
||||
If the user is on OSS and wants a non-OpenAI LLM, route them to the
|
||||
`components/llms/*` docs and re-run this step with the chosen provider's key.
|
||||
|
||||
### 5. Goal doc — the hard gate
|
||||
|
||||
Write `.mem0-integration/goal.md` and **require user approval before step 6**.
|
||||
|
||||
Template:
|
||||
|
||||
# Mem0 Integration Goal
|
||||
|
||||
**What gets stored:** <one sentence — user utterances? extracted
|
||||
preferences? a specific domain fact like "dietary restrictions"?>
|
||||
|
||||
**When it gets retrieved:** <one sentence — on each user turn? before a
|
||||
specific tool call? at session start?>
|
||||
|
||||
**Why:** <one sentence — the user-visible behavior change. "Assistant
|
||||
remembers previous orders across sessions," not "we added memory.">
|
||||
|
||||
**Product:** Platform | OSS (locked from step 3, do not change)
|
||||
|
||||
**Delegated skill:** <raw URL of the published skill being used
|
||||
from "Skill delegation rules" above, or "none — custom integration
|
||||
against `skills/mem0`">.
|
||||
|
||||
**Out of scope:** <anything explicitly excluded: "no graph memory,"
|
||||
"no multimodal," "no migration from existing store">
|
||||
|
||||
Rules:
|
||||
|
||||
- User must approve explicitly. If they edit the doc, reload and re-confirm.
|
||||
- `goal.md` is the contract the test suite is written against. Never
|
||||
rewrite it after step 6 starts.
|
||||
- Max 3 rejection rounds. On the 4th, exit with code 3 and the rejection
|
||||
notes — the integration is not well-specified enough to proceed.
|
||||
|
||||
### 6. Integration plan — how and where (hard gate)
|
||||
|
||||
Given `goal.md` is "what and why," this step produces "where and how" and
|
||||
gets explicit user sign-off before any code is written.
|
||||
|
||||
The skill does a **scoped** read of the repo (no wide survey):
|
||||
|
||||
- Grep for the LLM call sites that match the goal (e.g., `openai.chat.`,
|
||||
`anthropic.messages.`, `model.generateContent`, `ChatOpenAI`, `createLLM`).
|
||||
- Grep for the user-identity source (`req.user`, `session.user`, `auth()`,
|
||||
`ctx.userId`, cookies).
|
||||
- Check `package.json` / `pyproject.toml` / `requirements.txt` for
|
||||
conflicts (e.g., existing `mem0ai` at a different version).
|
||||
|
||||
Then write `.mem0-integration/plan.md`:
|
||||
|
||||
# Mem0 Integration Plan
|
||||
|
||||
**Write pattern:** <one sentence — e.g., "After each assistant reply,
|
||||
call client.add([user_msg, assistant_msg], user_id=<source>).">
|
||||
|
||||
**Read pattern:** <one sentence — e.g., "Before building the LLM prompt,
|
||||
call client.search(query=latest_user_msg, user_id=<source>, limit=5)
|
||||
and inject results as a system message.">
|
||||
|
||||
**User identifier source:** <code path — e.g., `req.auth.userId`,
|
||||
`session.user.email`, `ctx.params.user_id`. If none, ask the user.>
|
||||
|
||||
**Session scoping:**
|
||||
- user_id: <source>
|
||||
- agent_id: <static slug | null>
|
||||
- run_id: <source | null>
|
||||
|
||||
**Write call site:** `<file:line_range>` — inside `<function>`
|
||||
**Read call site:** `<file:line_range>` — inside `<function>`
|
||||
|
||||
**Dependencies to add:**
|
||||
- `<package>@<version pinned in frontmatter>`
|
||||
|
||||
**Preserved behavior:** <list the existing repo behaviors that must
|
||||
keep working after this edit — e.g., "existing OpenAI streaming still
|
||||
works," "existing Redis session store still used," "existing tests
|
||||
still pass unchanged.">
|
||||
|
||||
**Coexistence:** <one bullet per existing system the integration sits
|
||||
alongside. Name the files/classes. Example: "The existing
|
||||
`agents/memory/storage.py` MemoryStorage class remains untouched and
|
||||
keeps its LangGraph SummarizationEvent flow. Mem0 is added as a
|
||||
parallel long-term-facts store, in a new file, invoked only when
|
||||
MEM0_ENABLED=1 is set.">
|
||||
|
||||
**Feature flag:** <the exact mechanism and the default. Required.
|
||||
Example: `env MEM0_ENABLED=1`, default unset / off; `config.mem0.enabled`,
|
||||
default false. With the flag in its default state, the repo must
|
||||
behave exactly like `main`.>
|
||||
|
||||
**Sources consulted:** <minimum 2 URLs from "Canonical sources" above
|
||||
that informed this plan. At least one `docs.mem0.ai` URL and one
|
||||
delegated-skill URL. Cite the specific section or heading.>
|
||||
|
||||
**E2E recipe:** <how the verification skill should drive the app
|
||||
end-to-end. Omit only if the repo is a pure library with no runnable
|
||||
entry point — in which case the E2E step will skip with a warning.>
|
||||
|
||||
start: <shell command to launch the app locally,
|
||||
using $PORT for any network port>
|
||||
ready_probe: <one of: url=<URL> status=<code> /
|
||||
log="<substring to wait for>" /
|
||||
sleep=<seconds, last resort>>
|
||||
compose_services: <optional: whitespace-separated service
|
||||
names in docker-compose.yml to start first;
|
||||
use label mem0-e2e: "true" to mark them>
|
||||
write_call: <command that triggers the Mem0 write path
|
||||
exactly once; ≤ 60s runtime>
|
||||
write_async_wait_ms: <milliseconds to wait after write_call for
|
||||
async memory flush; default 0>
|
||||
read_call: <command that triggers the Mem0 read path,
|
||||
typically a fresh session / new request>
|
||||
read_assert: <substring, regex, or jsonpath=<expr>=<value>
|
||||
that MUST appear in read_call's output for
|
||||
the E2E to pass. Derived from goal.md's
|
||||
"What gets stored.">
|
||||
|
||||
**Rejected alternatives:** <briefly, 1–2 bullets — patterns the skill
|
||||
considered but did not pick, and why. Helps the user decide.>
|
||||
|
||||
Rules:
|
||||
|
||||
- Show the user the proposed call sites with 10 lines of context around
|
||||
each before asking for approval.
|
||||
- If the skill can't find a plausible call site for either write or read,
|
||||
it exits with code 5 and asks the user to name the file(s) manually
|
||||
(this is the "no fit here" signal — don't guess).
|
||||
- Max 3 rejection rounds on the plan. On the 4th, exit code 5 with the
|
||||
last plan and the user's notes.
|
||||
- If the user edits `plan.md` by hand, reload and re-confirm.
|
||||
|
||||
`plan.md` (not `goal.md`) is the contract the subagent implements against
|
||||
in step 8.
|
||||
|
||||
### 7. Tests first (TDD)
|
||||
|
||||
Main agent writes failing tests against `goal.md` in the repo's native
|
||||
test framework:
|
||||
|
||||
| Track | Default framework |
|
||||
|---|---|
|
||||
| Python | `pytest` |
|
||||
| TypeScript | `vitest` if detected, else `jest` |
|
||||
| JavaScript | same |
|
||||
|
||||
Test assertion shapes must match the **canonical signatures**:
|
||||
|
||||
- Platform method signatures: `https://docs.mem0.ai/openapi.json`
|
||||
(request body schemas for `/v1/memories/` and `/v1/memories/search/`).
|
||||
- OSS method signatures: the delegated skill named in `plan.md`
|
||||
(fetched from its raw URL) or `skills/mem0/SKILL.md` as the default.
|
||||
- Do not hand-roll request shapes. If the delegated skill has an
|
||||
example block, lift it verbatim.
|
||||
|
||||
Minimum two test files (paths taken from `plan.md` call sites):
|
||||
|
||||
- `test_mem0_write.<ext>` — asserts `add()` is called at the Write call
|
||||
site with the right payload shape (Platform messages-array vs OSS string)
|
||||
and the right `user_id` source.
|
||||
- `test_mem0_read.<ext>` — asserts `search()` runs before the Read call
|
||||
site and the result is wired into the LLM prompt / response path.
|
||||
|
||||
Tests MUST be importable with `MEM0_API_KEY` unset. This is the design
|
||||
pressure that forces step 8's lazy `MemoryClient()` / `Memory()`
|
||||
construction — eager module-level init hits the API on import and
|
||||
breaks pre-existing test collection when the key is missing.
|
||||
|
||||
Run the tests. They **must fail**. If they pass before any implementation,
|
||||
the tests are wrong — rewrite them.
|
||||
|
||||
### 8. Implementation (subagent, fresh context)
|
||||
|
||||
Spawn a subagent with:
|
||||
|
||||
- **Inputs**: the repo, `goal.md`, `plan.md`, the two test files, and
|
||||
direct URLs to: the delegated skill (from `plan.md`), the SDK source
|
||||
(pinned per `mem0_tested_versions`), `https://docs.mem0.ai/llms.txt`,
|
||||
and `https://docs.mem0.ai/openapi.json`.
|
||||
- **No access** to main agent's reasoning trace or scratchpad.
|
||||
- **System prompt** (verbatim):
|
||||
|
||||
You are implementing a Mem0 integration for an existing repo.
|
||||
|
||||
Read these first:
|
||||
- plan.md (the mechanical contract)
|
||||
- goal.md (the intent — do not change it)
|
||||
- the test files (do not change them either)
|
||||
- <delegated skill raw URL from plan.md>
|
||||
- https://docs.mem0.ai/llms.txt
|
||||
- https://docs.mem0.ai/openapi.json (Platform only)
|
||||
|
||||
Constraints — all required, all enforced at review:
|
||||
|
||||
1. Touch only the files named in plan.md's call sites, or add
|
||||
strictly new files.
|
||||
2. Do not remove or rename any existing symbol. Do not change
|
||||
any public signature.
|
||||
3. Do not modify any existing test.
|
||||
4. Gate every line of new Mem0 code behind the feature flag from
|
||||
plan.md. With the flag in its default state, the repo must
|
||||
behave exactly like `main` — byte-for-byte, including stdout
|
||||
and return values.
|
||||
5. Use only the <Platform | OSS> SDK surface. No new dependencies
|
||||
beyond those listed under plan.md's "Dependencies to add."
|
||||
6. Preserve everything listed under plan.md's "Preserved behavior"
|
||||
and "Coexistence."
|
||||
7. Lazy client construction. `MemoryClient()` validates the API
|
||||
key in `__init__` (it makes a network call). Never instantiate
|
||||
it at module-import time — construct on first use inside the
|
||||
request / handler path. The same rule applies to OSS `Memory()`,
|
||||
which can eagerly initialize embedding and LLM providers. Use
|
||||
a function-local singleton (`functools.lru_cache`, a module-level
|
||||
`_client = None` + getter, or DI scope) — never a top-level
|
||||
global. Eager init breaks the pre-existing test suite at
|
||||
collection time whenever the key is missing or invalid, which
|
||||
is a non-invasiveness violation.
|
||||
|
||||
Implement the plan to make the new tests pass while all
|
||||
pre-existing tests continue to pass unchanged.
|
||||
|
||||
Subagent returns a diff. Main agent reviews against `plan.md` (the
|
||||
mechanical contract) and `goal.md` (the intent):
|
||||
|
||||
- Approved → apply the diff, commit.
|
||||
- Rejected → return with specific, actionable feedback (not "try again").
|
||||
- Max 3 review loops. Beyond that → exit code 4 with the last diff and
|
||||
reviewer feedback.
|
||||
|
||||
### 9. Commit + handoff
|
||||
|
||||
Create branch `mem0-integrate/<short-goal-slug>` and commit in
|
||||
**separate commits** so reviewers can cherry-pick:
|
||||
|
||||
1. `mem0: add gated dependency` — just the `pyproject.toml` / `package.json`
|
||||
change.
|
||||
2. `mem0: add integration module` — the new file(s).
|
||||
3. `mem0: wire into <call site>` — the call-site edit(s), still gated.
|
||||
4. `mem0: add tests` — the new test files.
|
||||
|
||||
If `--no-heal` is set → print `Run /mem0-test-integration to verify.`
|
||||
and exit. Otherwise proceed to step 10.
|
||||
|
||||
### 10. Self-healing loop (default ON; disable with `--no-heal`)
|
||||
|
||||
Run `/mem0-test-integration --ci` in a subprocess. If `scorecard.json`
|
||||
reports `overall: pass` → done, exit 0.
|
||||
|
||||
Otherwise loop:
|
||||
|
||||
1. **Categorize the failing check** from `scorecard.json`. Route per
|
||||
category:
|
||||
- `install` / `static_checks` → dependency or import fix.
|
||||
- `unit_tests` → wiring or assertion fix.
|
||||
- `smoke_test` → API key or SDK call-shape fix.
|
||||
- `e2e_test` → recipe, flag-wiring, or integration-point fix.
|
||||
- **Pre-existing test failure (test skill exit code 7,
|
||||
`non_invasive: false` in scorecard) → STOP.** This is a
|
||||
non-invasiveness violation. Do NOT attempt to "fix" it (that
|
||||
breaks principle 3). Exit code 6 with rationale.
|
||||
|
||||
2. **Spawn a remediation subagent**, fresh context. Inputs:
|
||||
`plan.md`, `goal.md`, `scorecard.md`, `scorecard.json`, the last
|
||||
committed diff, and the relevant log file for the failing category
|
||||
(`test-stdout.log` / `smoke-stdout.log` / `e2e-app.log` /
|
||||
`e2e-calls.log`).
|
||||
|
||||
System prompt (verbatim):
|
||||
|
||||
You are fixing a failing Mem0 integration test.
|
||||
|
||||
Non-negotiable constraints:
|
||||
- Do not modify test files.
|
||||
- Do not remove or rename any existing symbol or signature.
|
||||
- Do not change pre-existing behavior. The feature flag from
|
||||
plan.md must still default to OFF, and with the flag in its
|
||||
default state the repo must behave exactly like main.
|
||||
- Touch only the files named in plan.md's call sites, or add
|
||||
strictly new files.
|
||||
- Return the smallest possible diff that fixes the single
|
||||
failing check listed in scorecard.md. No drive-by cleanup.
|
||||
|
||||
3. **Apply the diff**; commit on the same branch with message
|
||||
`mem0-heal: <category> attempt <N>`. Do NOT amend earlier commits
|
||||
(reviewers need the heal trail).
|
||||
|
||||
4. **Re-run `/mem0-test-integration --ci`**. Outcomes:
|
||||
- `overall: pass` → done, exit 0.
|
||||
- Same check still failing → increment attempt counter; loop.
|
||||
- A *different* check now failing → regression. Revert the heal
|
||||
commit (`git revert HEAD --no-edit`), record the regression in
|
||||
`.mem0-integration/heal-trace.md`, exit code 6.
|
||||
|
||||
5. **Bounded iterations.** Default 3 attempts per failing category.
|
||||
Override with `--heal-max N` (hard cap 10). On exhaustion, exit 6
|
||||
with the full attempt trace: each diff, each scorecard, final log
|
||||
tail.
|
||||
|
||||
6. **Post-loop summary** written to `.mem0-integration/heal-trace.md`:
|
||||
which category failed, how many attempts, each diff's intent, final
|
||||
status, and — on success — the delta from initial scorecard to final.
|
||||
|
||||
## Artifacts (all under `.mem0-integration/`)
|
||||
|
||||
| File | Purpose | Retention |
|
||||
|---|---|---|
|
||||
| `repo-summary.md` | Repo comprehension + candidate backend surfaces (step 2). | Keep across runs. |
|
||||
| `goal.md` | Approved intent. Never rewritten after step 6. | Keep across runs. |
|
||||
| `plan.md` | Approved mechanics (where, how, call sites, preserved behavior). | Keep across runs. |
|
||||
| `trace.jsonl` | Every tool call, decision, and subagent exchange this run. | Overwritten per run. |
|
||||
| `diff.patch` | The committed integration as a reviewable patch. | Overwritten per run. |
|
||||
| `heal-trace.md` | Per-attempt record of the self-healing loop (step 10). | Overwritten per run. |
|
||||
| `product.json` | `{"product": "platform"\|"oss", "language": "...", "mem0_version": "...", "write_site": "file:line", "read_site": "file:line", "feature_flag": "MEM0_ENABLED"}` — consumed by the verification skill. | Overwritten per run. |
|
||||
|
||||
`.mem0-integration/` is added to `.gitignore` on first run. Nothing is
|
||||
written outside this directory and the repo's source tree.
|
||||
|
||||
## Modes
|
||||
|
||||
| Mode | Trigger | Behavior |
|
||||
|---|---|---|
|
||||
| Interactive (default) | TTY present, `MEM0_INTEGRATE_CI` unset | Asks for keys, confirms goal doc, shows recommendations. |
|
||||
| CI | `MEM0_INTEGRATE_CI=1` | Requires keys in env, requires `--product`, auto-approves goal doc from `goal.md` if present, fails fast otherwise. |
|
||||
|
||||
## Invocation
|
||||
|
||||
/mem0-integrate # interactive, heal ON
|
||||
/mem0-integrate --no-heal # stop after commit; manual verify
|
||||
/mem0-integrate --heal-max 5 # cap heal attempts per category (default 3)
|
||||
/mem0-integrate --product platform # skip the product ask
|
||||
/mem0-integrate --product oss
|
||||
/mem0-integrate --ci # non-interactive (for test harness)
|
||||
|
||||
## Exit codes
|
||||
|
||||
| Code | Meaning |
|
||||
|---|---|
|
||||
| 0 | Success. Feature branch committed; verification skill ready to run. |
|
||||
| 1 | Precondition failed (dirty repo, no detectable language, etc.). |
|
||||
| 2 | Missing env key in CI mode. |
|
||||
| 3 | Goal doc rejected 3+ times — integration is not well-specified. |
|
||||
| 4 | Subagent review loop did not converge in 3 rounds. |
|
||||
| 5 | Integration plan rejected 3+ times, or no plausible additive call site found. |
|
||||
| 6 | Self-healing loop did not converge, detected a non-invasiveness violation, or a pre-existing test failed. |
|
||||
|
||||
## Explicitly out of scope
|
||||
|
||||
- Surveying the repo for fit points. Humans decide where Mem0 helps before
|
||||
invoking this skill.
|
||||
- Replacing any existing memory / session / state system. Always additive
|
||||
and feature-flagged; see "Integration principles."
|
||||
- Modifying pre-existing tests, even to "fix" them under self-heal. Tests
|
||||
that fail after integration with the flag unset are a non-invasiveness
|
||||
violation, not a bug to patch.
|
||||
- Deciding Platform vs OSS silently. Always ask with a recommendation.
|
||||
- Switching branches, pushing, or opening PRs. Commits locally and stops
|
||||
(or enters the heal loop, still local).
|
||||
- Data migration between stores. Point user at `migration/oss-to-platform`
|
||||
docs if they ask.
|
||||
- Provider selection beyond the default LLM for OSS. If they need a custom
|
||||
LLM / embedder / vector store, route to `components/*` docs and re-run
|
||||
step 4 with the new key.
|
||||
@@ -0,0 +1,189 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but not
|
||||
limited to compiled object code, generated documentation, and
|
||||
conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work.
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to the Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by the Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding any notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
Copyright 2024 Mem0.ai
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
@@ -0,0 +1,81 @@
|
||||
# mem0-test-integration — Pipeline Skill
|
||||
|
||||
Verify a Mem0 integration produced by [`/mem0-integrate`](../mem0-integrate/SKILL.md). Runs in the same workspace on the same branch — installs dependencies, runs the repo's native test suite, then exercises a real end-to-end smoke flow against the user's API key.
|
||||
|
||||
> **This is a pipeline skill, not a reference skill.** Invoke it as `/mem0-test-integration` after `/mem0-integrate` has produced a branch to verify. It catches compile and runtime bugs by design — logical integration errors (wrong data stored, wrong scoping) are for human review.
|
||||
>
|
||||
> **Part of the Mem0 Skill Graph:**
|
||||
> - Reference: [mem0](../mem0/SKILL.md) · [mem0-cli](../mem0-cli/SKILL.md) · [mem0-vercel-ai-sdk](../mem0-vercel-ai-sdk/SKILL.md)
|
||||
> - Pipeline: [mem0-integrate](../mem0-integrate/SKILL.md) → **mem0-test-integration** (this skill)
|
||||
|
||||
## What This Skill Does
|
||||
|
||||
When invoked, your assistant will:
|
||||
|
||||
- **Refuse to start** unless the branch has `.mem0-integration/` artifacts, the working tree is clean, and the right API key is in the environment
|
||||
- **Install** the repo's dependencies using its native tooling (pip, pnpm, npm, hatch, etc.)
|
||||
- **Run the native test suite** in two passes: flag-unset (must behave like `main`) and flag-set (new tests run)
|
||||
- **Execute a real end-to-end smoke flow** against Mem0 Platform (`MEM0_API_KEY`) or OSS (`OPENAI_API_KEY`)
|
||||
- **Produce a scorecard** — `overall: pass | fail`, per-check reasons, and the reproduction command for each failure
|
||||
|
||||
## When to Use
|
||||
|
||||
Trigger phrases:
|
||||
|
||||
- "Verify the integration"
|
||||
- "Test the Mem0 integration"
|
||||
- "Run `/mem0-test-integration`"
|
||||
|
||||
Do **not** use this skill to run general project tests (defer to the repo's native test command) or before `/mem0-integrate` has produced a branch on the current workspace.
|
||||
|
||||
## Installation
|
||||
|
||||
### CLI (Claude Code, Codex, OpenCode, OpenClaw, or any tool that supports skills)
|
||||
|
||||
```bash
|
||||
npx skills add https://github.com/mem0ai/mem0 --skill mem0-test-integration
|
||||
```
|
||||
|
||||
Typically installed alongside the companion pipeline skill:
|
||||
|
||||
```bash
|
||||
npx skills add https://github.com/mem0ai/mem0 --skill mem0-integrate
|
||||
```
|
||||
|
||||
### Claude.ai
|
||||
|
||||
1. Download this `skills/mem0-test-integration` folder as a ZIP
|
||||
2. Go to **Settings > Capabilities > Skills**
|
||||
3. Click **Upload skill** and select the ZIP
|
||||
|
||||
### Claude API (Skills API)
|
||||
|
||||
```bash
|
||||
curl -X POST https://api.anthropic.com/v1/skills \
|
||||
-H "x-api-key: $ANTHROPIC_API_KEY" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"name": "mem0-test-integration", "source": "https://github.com/mem0ai/mem0/tree/main/skills/mem0-test-integration"}'
|
||||
```
|
||||
|
||||
### Preconditions
|
||||
|
||||
The skill refuses to start unless all of the following are true:
|
||||
|
||||
- `.mem0-integration/` directory exists in the repo root
|
||||
- Current branch starts with `mem0-integrate/`
|
||||
- Working tree is clean
|
||||
- The same API key used during `/mem0-integrate` is exported in the environment
|
||||
|
||||
## What This Skill Does *Not* Catch
|
||||
|
||||
By design, this skill only catches compile and runtime bugs. Logical errors — memories stored with the wrong scoping, retrieval returning the wrong user's data, filter mismatches — are the human reviewer's responsibility.
|
||||
|
||||
## Links
|
||||
|
||||
- [Mem0 Documentation](https://docs.mem0.ai)
|
||||
- [Mem0 GitHub](https://github.com/mem0ai/mem0)
|
||||
- [API Reference](https://docs.mem0.ai/api-reference)
|
||||
|
||||
## License
|
||||
|
||||
Apache-2.0
|
||||
@@ -0,0 +1,368 @@
|
||||
---
|
||||
name: mem0-test-integration
|
||||
description: >
|
||||
Verify a Mem0 integration produced by /mem0-integrate. Runs in the same
|
||||
workspace on the same branch (loose coupling) — installs dependencies,
|
||||
runs the repo's native test suite, then exercises a real end-to-end
|
||||
smoke flow against the user's API key. Produces a scorecard.
|
||||
TRIGGER when: user has just run /mem0-integrate and says "verify",
|
||||
"test the integration", "run /mem0-test-integration", or when a
|
||||
.mem0-integration/ directory exists and tests have not been run yet
|
||||
on the current branch.
|
||||
DO NOT TRIGGER when: the user wants to run general project tests
|
||||
(defer to the repo's native test command), or when no prior /mem0-integrate
|
||||
run exists in the current branch (ask them to run /mem0-integrate first).
|
||||
This skill ONLY catches compile and runtime bugs by design. Logical
|
||||
integration errors — wrong data stored, wrong time retrieved, wrong
|
||||
user scoping — are on the human reviewer.
|
||||
license: Apache-2.0
|
||||
metadata:
|
||||
author: mem0ai
|
||||
version: "0.1.0"
|
||||
category: ai-memory
|
||||
tags: "memory, integration, testing, tdd, platform, oss"
|
||||
coupling: loose
|
||||
mem0_tested_versions: "mem0ai (PyPI) >=2.0.0,<3.0.0; mem0ai (npm) >=3.0.0,<4.0.0"
|
||||
---
|
||||
|
||||
# mem0-test-integration
|
||||
|
||||
Verifies what `/mem0-integrate` produced. Runs in the same workspace,
|
||||
on the same feature branch. Loose coupling — fast, catches compile and
|
||||
runtime bugs, does not catch logical errors.
|
||||
|
||||
## Canonical sources (use these, not ambient knowledge)
|
||||
|
||||
All static checks and smoke-test shapes validate against these URLs.
|
||||
`WebFetch` each before running step 3.
|
||||
|
||||
- Scope-tagged docs index: https://docs.mem0.ai/llms.txt
|
||||
- OpenAPI (Platform REST): https://docs.mem0.ai/openapi.json
|
||||
- Published SDK skill (canonical call patterns): https://raw.githubusercontent.com/mem0ai/mem0/main/skills/mem0/SKILL.md
|
||||
- Vercel AI SDK skill (if the target repo uses `@ai-sdk/*`): https://raw.githubusercontent.com/mem0ai/mem0/main/skills/mem0-vercel-ai-sdk/SKILL.md
|
||||
- SDK source (cross-check version against frontmatter `mem0_tested_versions`):
|
||||
- Repo root: https://github.com/mem0ai/mem0
|
||||
- Python: https://github.com/mem0ai/mem0/tree/main/mem0
|
||||
- TypeScript: https://github.com/mem0ai/mem0/tree/main/mem0-ts
|
||||
|
||||
Read the `Delegated skill:` field in `.mem0-integration/plan.md` — if it
|
||||
names a skill URL, fetch that skill and use its example blocks as the
|
||||
reference for both static checks (step 3) and the smoke test (step 5).
|
||||
|
||||
## Non-invasiveness contract
|
||||
|
||||
Every check in this skill assumes the integration is **additive and
|
||||
feature-flagged** (see `/mem0-integrate` "Integration principles").
|
||||
Specifically:
|
||||
|
||||
- `product.json` must contain a `feature_flag` field.
|
||||
- Steps 4–6 run in two passes:
|
||||
- **Pass A — flag unset.** All pre-existing tests must pass, smoke/E2E
|
||||
skip. The repo must behave like `main`. Any failure here is a
|
||||
**hard fail** — do not let the self-heal loop attempt a patch.
|
||||
- **Pass B — flag set.** New tests must pass, smoke and E2E run.
|
||||
- If Pass A fails, the scorecard marks `non_invasive: false` and sets
|
||||
`overall: fail` with a distinct reason code the integrator's heal
|
||||
loop refuses to touch.
|
||||
|
||||
## Preconditions
|
||||
|
||||
Refuse to start unless ALL of the following are true:
|
||||
|
||||
- `.mem0-integration/` directory exists in the repo root.
|
||||
- `.mem0-integration/product.json`, `goal.md`, and `plan.md` are readable
|
||||
and internally consistent (JSON parses, docs non-empty).
|
||||
- Current branch name begins with `mem0-integrate/` (set by the companion
|
||||
skill). Prevents accidental runs on unrelated branches.
|
||||
- Working tree is clean. The skill never modifies source files; any dirty
|
||||
state means the integration is mid-edit and not ready to verify.
|
||||
- The same API key the integration used is available in the environment
|
||||
(`MEM0_API_KEY` for Platform, `OPENAI_API_KEY` for OSS — read which from
|
||||
`product.json`). Interactive mode asks if missing; CI mode exits 2.
|
||||
|
||||
Exit with a written rationale on any precondition failure. Never attempt
|
||||
to "fix up" state.
|
||||
|
||||
## Pipeline
|
||||
|
||||
### 1. Read the contract
|
||||
|
||||
Load:
|
||||
|
||||
- `product.json` → which language, which product (Platform vs OSS), which
|
||||
mem0 version, `write_site`, `read_site`.
|
||||
- `plan.md` → the mechanical contract (write pattern, read pattern,
|
||||
preserved behavior).
|
||||
- `goal.md` → the intent (displayed in the scorecard only; not tested).
|
||||
|
||||
### 2. Install dependencies
|
||||
|
||||
Route by language from `product.json`:
|
||||
|
||||
| Language | Command |
|
||||
|---|---|
|
||||
| Python | `pip install -e .` if editable, else `pip install -r requirements.txt`. Then `pip install mem0ai` if not already present at the pinned version. |
|
||||
| TypeScript / JavaScript | `npm install` (or `pnpm install` / `yarn install` if detected by lockfile). |
|
||||
|
||||
If install fails → exit code 2 with stderr tail. Never move to testing
|
||||
if dependencies don't resolve.
|
||||
|
||||
### 3. Static sanity checks (fast, local, no API calls)
|
||||
|
||||
- **Import check**: does the write-site file import the expected Mem0
|
||||
surface? Authoritative list comes from `## Identify the User's Setup`
|
||||
in `https://docs.mem0.ai/llms.txt`:
|
||||
- Platform Python → `from mem0 import MemoryClient`
|
||||
- Platform TS → `import MemoryClient from "mem0ai"`
|
||||
- OSS Python → `from mem0 import Memory`
|
||||
- OSS TS → `import { Memory } from "mem0ai/oss"`
|
||||
|
||||
If `plan.md` names a delegated skill (e.g., Vercel AI), use *that*
|
||||
skill's import signature instead of the list above. Mismatch → fail
|
||||
with line number.
|
||||
- **Version check**: installed `mem0ai` version falls in the range from
|
||||
this skill's `mem0_tested_versions`. Out of range → warn but continue.
|
||||
- **Type check** (TS tracks only): run `tsc --noEmit` or `tsup --dts`.
|
||||
Non-zero → fail.
|
||||
- **Lint** (if the repo has a linter configured): run the repo's own
|
||||
lint command. Lint failures from this skill's changes → fail; pre-existing
|
||||
lint failures → surface as a warning.
|
||||
- **Eager-init check**: grep the `write_site` and `read_site` files (paths
|
||||
from `product.json`) for `MemoryClient(` or `Memory(` at module scope —
|
||||
i.e., not inside a function, method, or class body. `MemoryClient()`
|
||||
validates the API key in `__init__` (network call) and OSS `Memory()`
|
||||
can eagerly initialize embedding/LLM providers — module-level
|
||||
instantiation hits the wire on import and breaks Pass A's test
|
||||
collection whenever the key is unset. Hit → fail with `file:line` and
|
||||
the lazy-init guidance from `/mem0-integrate` step 8 constraint #7.
|
||||
|
||||
### 4. Run the repo's native test suite (two passes)
|
||||
|
||||
| Language | Test command (in priority order) |
|
||||
|---|---|
|
||||
| Python | `pytest` with the test files from step 5 of the companion skill, else `python -m unittest discover`. |
|
||||
| TypeScript / JavaScript | `npm test` if defined in package.json; else auto-detect `vitest` or `jest`. |
|
||||
|
||||
**Pass A — `feature_flag` unset.** Run the *entire* pre-existing suite
|
||||
(excluding the new `test_mem0_*` files). **Must be 100% green.** Any
|
||||
failure here marks `non_invasive: false` in the scorecard and is
|
||||
a **hard fail** — the integrator's self-heal loop refuses to touch it.
|
||||
|
||||
**Pass B — `feature_flag` set** (value from `product.json`). Run the
|
||||
full suite including the new tests. All must pass.
|
||||
|
||||
Isolate integration-introduced failures using `git diff main..HEAD
|
||||
--name-only`. A test file that exists on `main` and fails only under
|
||||
the integration branch (flag set *or* unset) counts against the
|
||||
scorecard regardless of pass. A test file that already failed on `main`
|
||||
is surfaced as `pre_existing_unrelated` and does not count — but is
|
||||
still reported so the user can clean it up.
|
||||
|
||||
Capture output to `.mem0-integration/test-stdout-flag-off.log` and
|
||||
`.mem0-integration/test-stdout-flag-on.log`. Scorecard reports pass/fail
|
||||
per pass.
|
||||
|
||||
### 5. Smoke test (real API call, shortest round-trip)
|
||||
|
||||
Scripted end-to-end flow tailored to `product.json`. The call shapes
|
||||
below are the minimal ones; if `plan.md` names a delegated skill, use
|
||||
*that skill's* minimal example verbatim instead — it is the canonical
|
||||
shape for the detected stack.
|
||||
|
||||
**Platform (Python):**
|
||||
|
||||
from mem0 import MemoryClient
|
||||
c = MemoryClient() # uses MEM0_API_KEY
|
||||
uid = f"mem0-test-integration-{os.urandom(4).hex()}"
|
||||
c.add([{"role": "user", "content": "I prefer aisle seats"}], user_id=uid)
|
||||
hits = c.search("seat preference", user_id=uid)
|
||||
assert any("aisle" in h.get("memory", "") for h in hits), hits
|
||||
c.delete_all(user_id=uid) # clean up
|
||||
|
||||
**Platform (TS):** same shape with `MemoryClient` from `"mem0ai"`.
|
||||
|
||||
**OSS (Python / TS):** uses `Memory()` / `new Memory()` with default config
|
||||
(OpenAI LLM via `OPENAI_API_KEY`, local Qdrant). If the repo ships a
|
||||
`docker-compose.yml` with a Qdrant service, the skill starts it first and
|
||||
tears it down after. If no backing store is reachable → fail with a
|
||||
clear message naming the fix.
|
||||
|
||||
The smoke test always uses a **disposable random user_id** prefixed with
|
||||
`mem0-test-integration-` so a failed cleanup doesn't pollute the user's
|
||||
real data. A background tidy step deletes any prefix-matching entries
|
||||
older than 24 hours on the next run.
|
||||
|
||||
Capture output to `.mem0-integration/smoke-stdout.log`.
|
||||
|
||||
### 6. E2E integration test (run the app, exercise the flow)
|
||||
|
||||
Unit tests + smoke prove the SDK works in isolation. This step is the
|
||||
real signal: **does memory actually appear in the app's user-visible
|
||||
output when the integration runs end-to-end?**
|
||||
|
||||
Requires `plan.md` to contain an `E2E recipe:` section (authored by
|
||||
`/mem0-integrate` step 5). If absent → status `skipped` (not `fail`),
|
||||
note in scorecard that the repo has no runnable entry point.
|
||||
|
||||
Recipe fields the skill reads:
|
||||
|
||||
- `start` — shell command to launch the app using `$PORT` for any network
|
||||
port. Run in background with stdout/stderr teed to
|
||||
`.mem0-integration/e2e-app.log`.
|
||||
- `ready_probe` — how to detect readiness. `url=... status=...` polls an
|
||||
HTTP endpoint; `log="..."` waits for a substring in `e2e-app.log`;
|
||||
`sleep=N` waits N seconds (last resort). 60-second hard timeout.
|
||||
- `compose_services` — optional. If set, bring them up via
|
||||
`docker compose up -d <services>` before `start`, tear them down with
|
||||
`docker compose down` at the end.
|
||||
- `write_call` — triggers the Mem0 write path exactly once. Output is
|
||||
captured and surfaced on failure. 60-second hard timeout.
|
||||
- `write_async_wait_ms` — pause after `write_call` to let async memory
|
||||
flushes land. Default 0.
|
||||
- `read_call` — triggers the Mem0 read path. Typically a fresh session
|
||||
or new request that should surface the stored memory.
|
||||
- `read_assert` — substring, `regex=...`, or `jsonpath=<expr>=<value>`
|
||||
that must appear in `read_call`'s stdout. This is the E2E pass gate.
|
||||
|
||||
Execution order:
|
||||
|
||||
1. Allocate an ephemeral TCP port; export as `PORT`.
|
||||
2. Set `MEM0_USER_ID` to a disposable `mem0-test-integration-<rand>` value
|
||||
and export it, so the app can use the same scoping the smoke test does
|
||||
if the recipe wants cleanup.
|
||||
3. Bring up `compose_services` if named.
|
||||
4. Run `start` in the background.
|
||||
5. Poll `ready_probe` until success or 60s timeout. Timeout → fail.
|
||||
6. Run `write_call`. Non-zero exit → fail (but continue to cleanup).
|
||||
7. Sleep `write_async_wait_ms`.
|
||||
8. Run `read_call`.
|
||||
9. Evaluate `read_assert` against `read_call`'s stdout. Miss → fail.
|
||||
10. Cleanup (always, even on failure): SIGTERM the app, SIGKILL after
|
||||
5s, `docker compose down` if services were started, `delete_all`
|
||||
memories matching `mem0-test-integration-*` on Platform scenarios.
|
||||
|
||||
On any failure, the scorecard includes:
|
||||
|
||||
- Last 40 lines of `e2e-app.log`
|
||||
- Full `write_call` output
|
||||
- Full `read_call` output
|
||||
- The expected vs actual for `read_assert`
|
||||
|
||||
### 7. Scorecard
|
||||
|
||||
Write `.mem0-integration/scorecard.md` and `.mem0-integration/scorecard.json`:
|
||||
|
||||
{
|
||||
"timestamp": "2026-04-20T14:03:11Z",
|
||||
"branch": "mem0-integrate/remember-user-preferences",
|
||||
"product": "platform",
|
||||
"language": "python",
|
||||
"mem0_version": "2.0.0",
|
||||
"non_invasive": true,
|
||||
"feature_flag": "MEM0_ENABLED",
|
||||
"results": {
|
||||
"install": {"status": "pass", "duration_ms": 12043},
|
||||
"static_checks":{"status": "pass", "duration_ms": 812},
|
||||
"unit_tests_flag_off": {"status": "pass", "duration_ms": 3920, "count": 47,
|
||||
"reason": "all pre-existing tests green with flag unset"},
|
||||
"unit_tests_flag_on": {"status": "pass", "duration_ms": 4321, "count": 49},
|
||||
"smoke_test": {"status": "pass", "duration_ms": 2890, "memory_id": "mem_..."},
|
||||
"e2e_test": {"status": "pass", "duration_ms": 14200,
|
||||
"ready_probe_ms": 3100, "write_exit": 0,
|
||||
"read_assert_matched": true}
|
||||
},
|
||||
"friction": {
|
||||
"dependency_install_retries": 0,
|
||||
"pre_existing_test_failures": 0,
|
||||
"warnings": ["mem0ai 2.0.0 pinned; consider 2.0.1 for fix X"]
|
||||
},
|
||||
"overall": "pass"
|
||||
}
|
||||
|
||||
The markdown version is human-readable and includes:
|
||||
|
||||
- Goal doc + plan doc reprinted at top (so reviewers don't have to hunt).
|
||||
- Each check with pass/fail + log excerpt.
|
||||
- Friction summary.
|
||||
- Verbatim warnings from mem0 SDK (if any — e.g., deprecated field usage).
|
||||
- **Explicit "NOT checked" section** listing what loose coupling misses:
|
||||
"Whether the stored data is what the user wants stored. Whether search
|
||||
runs at the right moment. Whether user_id matches the actual session
|
||||
scope. Human review required."
|
||||
|
||||
### 8. Report + exit
|
||||
|
||||
- Print the scorecard path + overall pass/fail to stdout.
|
||||
- **Do not commit the scorecard files.** They live in `.mem0-integration/`,
|
||||
which is gitignored. The user can inspect and optionally pin.
|
||||
- On fail: print the first failing step's log tail (last 40 lines) and
|
||||
stop. Do not attempt to fix anything.
|
||||
|
||||
## Artifacts (all under `.mem0-integration/`)
|
||||
|
||||
| File | Purpose | Retention |
|
||||
|---|---|---|
|
||||
| `scorecard.md` | Human-readable verdict. | Overwritten per run. |
|
||||
| `scorecard.json` | Machine-readable verdict. Consumed by the CI scorecard workflow later. | Overwritten per run. |
|
||||
| `test-stdout-flag-off.log` | Step 4 Pass A (pre-existing suite, flag unset). | Overwritten per run. |
|
||||
| `test-stdout-flag-on.log` | Step 4 Pass B (full suite, flag set). | Overwritten per run. |
|
||||
| `smoke-stdout.log` | Full output from step 5. | Overwritten per run. |
|
||||
| `e2e-app.log` | Background app stdout/stderr from step 6. | Overwritten per run. |
|
||||
| `e2e-calls.log` | write_call + read_call invocations and outputs. | Overwritten per run. |
|
||||
|
||||
## Modes
|
||||
|
||||
| Mode | Trigger | Behavior |
|
||||
|---|---|---|
|
||||
| Interactive (default) | TTY present, `MEM0_TEST_CI` unset | Asks for missing keys, prints friendly summaries. |
|
||||
| CI | `MEM0_TEST_CI=1` | Keys must be in env, no prompts, non-zero exit on any fail. JSON scorecard goes to stdout's tail for workflow parsing. |
|
||||
|
||||
## Invocation
|
||||
|
||||
/mem0-test-integration # interactive, all steps
|
||||
/mem0-test-integration --ci # non-interactive
|
||||
/mem0-test-integration --skip-smoke # no API calls, no E2E
|
||||
/mem0-test-integration --skip-e2e # unit + smoke only (faster CI)
|
||||
/mem0-test-integration --only-smoke # just smoke
|
||||
/mem0-test-integration --only-e2e # just E2E (assumes deps installed)
|
||||
|
||||
Composition: `--skip-*` can stack (`--skip-smoke --skip-e2e` = static +
|
||||
unit only, zero API cost). `--only-*` is mutually exclusive with all
|
||||
other flags.
|
||||
|
||||
## Exit codes
|
||||
|
||||
| Code | Meaning |
|
||||
|---|---|
|
||||
| 0 | All checks passed. |
|
||||
| 1 | Precondition failed (no `.mem0-integration/`, wrong branch, dirty tree). |
|
||||
| 2 | Missing env key (CI mode) or dependency install failure. |
|
||||
| 3 | Static sanity check failed (wrong import, type error). |
|
||||
| 4 | Unit tests failed (Pass B — integration itself broken). |
|
||||
| 5 | Smoke test failed. |
|
||||
| 6 | E2E test failed (ready_probe timeout, write/read call failed, or read_assert miss). |
|
||||
| 7 | Non-invasiveness violation: Pass A failed (pre-existing tests broke). Integrator's heal loop refuses to touch this. |
|
||||
| 8 | Internal error (skill bug — report it). |
|
||||
|
||||
## Explicitly out of scope
|
||||
|
||||
- **Modifying source files.** The skill is read-only against the repo.
|
||||
If verification exposes a bug, re-run `/mem0-integrate` on the same
|
||||
goal + plan; do not hand-patch.
|
||||
- **Fixing broken tests.** Failing unit tests are a signal that the
|
||||
integration is wrong, not that the tests are wrong. The skill does
|
||||
not "try a different test."
|
||||
- **Deep logical correctness.** The E2E step proves "something the user
|
||||
said earlier comes back later," which is a useful but shallow signal.
|
||||
It does NOT prove the integration picks the *right* facts to store,
|
||||
scopes `user_id` correctly across real users, or handles conflict
|
||||
resolution well. That's human review territory.
|
||||
- **Self-healing.** This skill never modifies source files. The paired
|
||||
`/mem0-integrate` skill in its default `--heal` mode consumes the
|
||||
scorecard produced here and drives its own remediation loop. Exit
|
||||
code 7 (non-invasiveness violation) is the explicit signal the heal
|
||||
loop must stop and surface to the user.
|
||||
- **Cross-branch comparisons.** No `main` baseline diffing. The
|
||||
scorecard reflects this branch only.
|
||||
- **Running against production data.** Every smoke test uses a disposable
|
||||
random user_id and cleans up after. Never touches any other user's data.
|
||||
Reference in New Issue
Block a user