docs(skills): refresh mem0 skills against SDK 2.2.1 / TS 3.3.1 (#7548)

This commit is contained in:
Kartik
2026-10-07 18:36:15 +05:30
committed by GitHub
parent d62ce07fac
commit b7ad69afda
33 changed files with 1239 additions and 814 deletions
@@ -9,8 +9,19 @@ section, phrased as a decision for the developer — never silently resolved.
Migrating the *code* does not move the *memories*. Anything stored in the local vector store /
history DB stays there; the hosted account starts empty. This is the most surprising gap, so call
it out prominently. Data migration is **out of scope** unless the developer explicitly asks. If they
do, the rough path is: read everything from the OSS store (`get_all` per user/entity) and re-`add`
it to the hosted client — but treat that as a separate, opt-in task.
do, treat it as a separate, opt-in task:
- **Hosted Qdrant + Python OSS SDK:** the repo ships `scripts/oss-to-platform-migrate.sh`
(`curl -fsSL https://raw.githubusercontent.com/mem0ai/mem0/main/scripts/oss-to-platform-migrate.sh | bash`,
documented at https://docs.mem0.ai/migration/oss-to-platform). It needs `python3`, signs in to the
Platform (`--email`/`--code` or `--api-key`), exports a scope (`--user-id`, `--agent-id`, `--run-id`
or `--all`) from the Qdrant collection (`--qdrant-url`, `--qdrant-api-key`, `--qdrant-collection`,
default `mem0`) to a JSON file under `~/.mem0/migrations/`, and imports it with `infer: False` (stored
verbatim, no re-extraction). `--export-only` / `--import-only` split the two steps so the export can
be reviewed first. Don't run it unprompted: it logs in and writes under `~/.mem0/`.
- **Anything else:** other vector stores are not supported by the script (the docs say hosted Qdrant
only), and its export is written for the Python OSS SDK, so TS-written data is not documented as
supported. The fallback is to read everything from the OSS store (`get_all` per entity) and re-`add`
it with `infer=False`.
## 2. Self-hosting / data residency
A local or self-hosted vector store sometimes exists *on purpose* — compliance, data residency, air-
@@ -24,15 +35,19 @@ the platform with the platform's configuration. Memory *content and quality may
Flag where the project depended on a specific model.
## 4. Graph memory
If the project uses graph memory (`enable_graph`, `graph_store`), this changed in v3 and is handled
differently on the platform. Don't assume a drop-in mapping — verify current platform graph support
in the docs and flag the usage for the developer.
The external graph store (`graph_store`, `enable_graph`; Neo4j/Memgraph/Kuzu/AGE) was removed from OSS
(Python 2.0.0, TS 3.0.0). On the platform graph memory is built in and always on: nothing to enable or
configure, and it only influences ranking (no separate `relations` payload, no typed relationships,
no direct graph queries). Flag any project code that queried its own graph store or read `relations`.
See https://docs.mem0.ai/platform/features/graph-memory.
## 5. Custom prompts / extraction config
`custom_fact_extraction_prompt` → `custom_instructions`, and `custom_update_memory_prompt` is
deprecated. On the platform these tend to be **project-level settings configured in the dashboard**
rather than passed in code. Flag any custom prompt the project relied on so the developer can re-
apply it in the dashboard.
`custom_fact_extraction_prompt` (TS `customPrompt`) was renamed `custom_instructions`
(`customInstructions`), and `custom_update_memory_prompt` is deprecated (fold it into
`custom_instructions`). On the platform `custom_instructions` is a project-level setting:
`client.project.update(custom_instructions=...)` (TS `client.updateProject({ customInstructions })`),
or per call via `custom_instructions=` on `add()`.
Flag any custom prompt the project relied on so the developer can decide where to re-apply it.
## 6. Every call is now a network request
Local calls become remote API calls. That introduces latency, network failures, timeouts, rate
@@ -41,23 +56,44 @@ error handling / retries / timeouts where the old local calls were effectively i
apps, use `AsyncMemoryClient` (Python) so calls don't block the event loop.
## 7. API key & secrets
The hosted client needs `MEM0_API_KEY`. It must come from the environment / a secrets manager — never
The hosted client needs `MEM0_API_KEY`. It must come from the environment / a secrets manager, never
hardcoded. Ensure it's added to `.env.example`, local `.env`, CI, and deployment config. Without it
the client fails to initialize.
the client fails to initialize. The Python client reads `MEM0_API_KEY` itself when `api_key` is
omitted; the TS client does not, so pass `apiKey: process.env.MEM0_API_KEY!` explicitly.
## 8. Dropped constructor args & legacy options
`org_id` / `project_id` (Python) and `organizationId` / `projectId` (TS) are no longer passed to the
constructor in v3 — they're resolved from the API key. Per-call legacy options like `async_mode`,
constructor, they're resolved from the API key. Per-call legacy options like `async_mode`,
`output_format`, and `enable_graph` are gone. Remove them rather than leaving dead args.
## 9. Return-shape drift
- `add()` returns **only ADD events** on v3. Code that inspected `add()` results for `UPDATE` /
`DELETE` events has dead branches now.
- `search` / `get_all` return `{"results": [...]}`; `get_all` is paginated (`count`/`next`/
`previous`/`results`). Code that limited via `top_k` on `get_all` should move to `page`/`page_size`.
- Default `top_k` dropped 100 → 20, `threshold` now `0.1`, `rerank` now `false` — result counts and
ordering can change even when the call looks equivalent.
## 9. Return-shape and default drift
- `add()` is **asynchronous** on the platform: it returns `{"status": "PENDING", "event_id": "..."}`
(`eventId` on the TS client, which camelCases response keys) instead of the created memories, so new memories may not be searchable yet when it returns
(`infer=False` is synchronous and returns `results`). Code that read `id`/`memory` from `add()`
results, or searched immediately after adding (tests, read-your-writes flows), needs a decision.
Neither SDK exposes an event-poll method; `GET /v1/event/{event_id}/` is REST only.
- `search` returns `{"results": [...]}` on both sides; `get_all` is paginated on the platform
(`count`/`next`/`previous`/`results`). Code that limited via `top_k` on `get_all` should move to
`page`/`page_size` (default `page_size` 100).
- Defaults differ: OSS `search` uses `top_k=20`, the platform uses `top_k=10`. Both default to
`rerank=false`. OSS `threshold` defaults to 0.1; on the platform it is a server-side cutoff, not a floor on the returned `score`. Result counts can change even when the call looks equivalent;
pass `top_k` explicitly.
## 10. No global `reset()`
The OSS `reset()` wipes the whole local store. There's no hosted equivalent that nukes everything;
use `delete_all` scoped by `filters`. Flag any `reset()` call.
## 10. `reset()` is much more destructive
The OSS `reset()` wipes the local store. Python `MemoryClient.reset()` exists but calls `delete_users()`,
which deletes all users, agents, sessions and memories on the platform. The TS client has no `reset()`
(`deleteUsers()` with no arguments does the same). Flag any `reset()` call (often test teardown) and
suggest `delete_all` scoped to the test entity instead. `delete_all(filters=...)` is not a valid
platform form: pass `user_id`/`agent_id`/`app_id`/`run_id` directly.
The hosted wipe is also incomplete: Python `reset()` and TS `deleteUsers()` with no arguments call
`users()` once and delete only the entities on that first page, so a project with more entities than
one page keeps the rest. Re-run until it raises `No entities to delete`, or delete per entity
(`delete_users(user_id=...)` / `deleteUsers({ userId })`, paging TS with `users({ page, pageSize })`).
## 11. Filters and update/add signatures
- Platform `filters` only accept an allowlist of top-level keys; custom metadata must be nested under
`"metadata"` and supports only `eq`/`ne`/`contains` (whole value or list member, not a substring; no `nin`; use a `NOT` list, e.g. `{"NOT": [{"categories": {"in": [...]}}]}`). OSS filters on arbitrary metadata
keys or richer operators need rewriting or a decision.
- Python `update` takes `text=` as a keyword (a positional string breaks); TS `update` requires an
options object and TS `add` requires `Message[]`, not a bare string.