docs(skills): refresh mem0 skills against SDK 2.2.1 / TS 3.3.1 (#7548)
This commit is contained in:
@@ -1,16 +1,17 @@
|
||||
# OSS → Platform API mapping
|
||||
|
||||
Exact translation of the mem0 OSS (self-hosted `Memory`) API to the hosted `MemoryClient` API.
|
||||
**Always confirm against the installed package** (see SKILL.md Phase 2) — versions drift. The facts
|
||||
below match `mem0ai` 2.0.x (the v3 platform API) and the official guide:
|
||||
https://docs.mem0.ai/migration/oss-v2-to-v3
|
||||
**Always confirm against the installed package** (see SKILL.md Phase 2), since versions drift. The
|
||||
facts below match Python `mem0ai` 2.2.x and TypeScript `mem0ai` 3.3.x (the `/v3/memories/*` platform
|
||||
API). Moving stored data: https://docs.mem0.ai/migration/oss-to-platform. OSS upgrade changes
|
||||
(Python 1.x to 2.x, TS 2.x to 3.x): https://docs.mem0.ai/migration/oss-v2-to-v3
|
||||
|
||||
## Contents
|
||||
- [Python](#python)
|
||||
- [TypeScript / JavaScript](#typescript--javascript)
|
||||
- [Return shapes](#return-shapes)
|
||||
- [Dependencies & environment](#dependencies--environment)
|
||||
- [v2→v3 default/behavior changes](#v2v3-defaultbehavior-changes)
|
||||
- [OSS vs Platform defaults and behavior](#oss-vs-platform-defaults-and-behavior)
|
||||
|
||||
---
|
||||
|
||||
@@ -35,28 +36,38 @@ memory = MemoryClient() # reads MEM0_API_KEY from the env
|
||||
```
|
||||
Notes:
|
||||
- The client reads `MEM0_API_KEY` from the environment when `api_key` is omitted.
|
||||
- **Drop** `vector_store`, `llm`, `embedder`, `graph_store`, `history_db_path` — these are managed
|
||||
server-side now.
|
||||
- **Drop** `org_id` / `project_id` constructor args if present — they're resolved from the API key
|
||||
in v3.
|
||||
- **Drop** `vector_store`, `llm`, `embedder`, `reranker`, `history_db_path`, `version` (and
|
||||
`graph_store` if a pre-2.0 config still has it): these are managed server-side now.
|
||||
- `custom_instructions` does have a hosted equivalent: `client.project.update(custom_instructions=...)`
|
||||
(project-wide) or `custom_instructions=` on `add()`.
|
||||
- **Drop** `org_id` / `project_id` constructor args if present, they're resolved from the API key.
|
||||
- For async codebases, use `AsyncMemoryClient` (same methods, `await`-ed).
|
||||
|
||||
### Method calls
|
||||
| Operation | OSS `Memory` | Hosted `MemoryClient` |
|
||||
|---|---|---|
|
||||
| add | `memory.add(messages, user_id="u")` | `memory.add(messages, user_id="u")` — unchanged (top-level entity IDs accepted) |
|
||||
| search | `memory.search(q, user_id="u", limit=N)` *(older)* or `…, filters={"user_id":"u"}, top_k=N` *(newer)* | `memory.search(q, filters={"user_id": "u"}, top_k=N)` — entity IDs **must** be inside `filters`; top-level `user_id`/`agent_id`/`app_id`/`run_id` raise `ValueError` |
|
||||
| get_all | `memory.get_all(user_id="u")` or `…, filters={"user_id":"u"}` | `memory.get_all(filters={"user_id": "u"}, page=1, page_size=N)` — entity IDs in `filters`; paginated with `page`/`page_size` (**not** `top_k`) |
|
||||
| delete_all | `memory.delete_all(user_id="u")` | `memory.delete_all(user_id="u")` — unchanged |
|
||||
| add | `memory.add(messages, user_id="u")` | `memory.add(messages, user_id="u")`: same call (top-level entity IDs accepted, plus `app_id`), but the return value differs (see Return shapes) |
|
||||
| search | `memory.search(q, filters={"user_id": "u"}, top_k=N)` (pre-2.0 code used top-level `user_id=` and `limit=`) | `memory.search(q, filters={"user_id": "u"}, top_k=N)`: entity IDs **must** be inside `filters`; top-level `user_id`/`agent_id`/`app_id`/`run_id` raise `ValueError` (on OSS 2.x too) |
|
||||
| get_all | `memory.get_all(filters={"user_id": "u"}, top_k=N)` (not paginated) | `memory.get_all(filters={"user_id": "u"}, page=1, page_size=N)`: entity IDs in `filters`; paginated with `page`/`page_size` (**not** `top_k`) |
|
||||
| delete_all | `memory.delete_all(user_id="u")` | `memory.delete_all(user_id="u")`: same call (entity IDs are query params, at least one is required, `"*"` is a wildcard). `delete_all(filters=...)` is **not** a Platform form |
|
||||
| get | `memory.get(memory_id)` | `memory.get(memory_id)` |
|
||||
| update | `memory.update(memory_id, text=...)` *(`data=` is a deprecated alias)* | `memory.update(memory_id, text=...)` — unchanged |
|
||||
| update | `memory.update(memory_id, text=...)` *(`data=` is a deprecated alias)* | `memory.update(memory_id, text=..., metadata=...)`: use keyword `text=`. A positional string (`update(id, "new text")`) breaks because the second positional is `options`, and there is no `data=` alias |
|
||||
| delete | `memory.delete(memory_id)` | `memory.delete(memory_id)` |
|
||||
| reset | `memory.reset()` (wipes the local store) | **No global reset.** Use `memory.delete_all(filters=...)` scoped to the relevant entity. Flag this. |
|
||||
| history | `memory.history(memory_id)` | `memory.history(memory_id)`: same call, extra fields on each entry (`input`, `user_id`, `categories`, `metadata`); OSS-only `is_deleted`/`actor_id`/`role` are absent (see Return shapes) |
|
||||
| reset | `memory.reset()` (wipes the local store) | `memory.reset()` exists but calls `delete_users()`, which deletes **all** users, agents, sessions and memories (first page of entities only, see gotchas). Prefer `delete_all` scoped to an entity. Flag this |
|
||||
|
||||
Key rule: for **search** and **get_all**, the hosted client requires entity IDs (`user_id`,
|
||||
`agent_id`, `app_id`, `run_id`) inside a `filters` dict and will raise if you pass them top-level.
|
||||
For **add** and **delete_all**, top-level entity IDs are accepted.
|
||||
|
||||
Filter differences: Platform validates each top-level filter key against a fixed allowlist
|
||||
(`AND`/`OR`/`NOT`, `user_id`, `agent_id`, `app_id`, `run_id`, `created_at`, `updated_at`, `timestamp`,
|
||||
`expiration_date`, `categories`, `metadata`, `memory_ids`, `keywords`) and
|
||||
returns 400 for anything else, so custom metadata keys must be nested under `"metadata"`
|
||||
(`{"metadata": {"plan": "pro"}}`). Platform `metadata` supports only `eq`/`ne`/`contains` (`contains` is case-sensitive and matches the whole value or one list member, not a substring), and there is
|
||||
no `nin` (use `{"NOT": [{"categories": {"in": [...]}}]}`; `NOT` must be a list). OSS accepts arbitrary
|
||||
metadata keys and a wider operator set. Flag any OSS filter that depends on either. Do not filter on `text`: search fails with a 503 and `get_all` rejects it. Pass the text as the search `query`.
|
||||
|
||||
---
|
||||
|
||||
## TypeScript / JavaScript
|
||||
@@ -66,36 +77,64 @@ Confirm option names against `node_modules/mem0ai/` types.
|
||||
|
||||
### Import & client construction
|
||||
```typescript
|
||||
// OSS (self-hosted) — note the "/oss" subpath
|
||||
// OSS (self-hosted): note the "/oss" subpath
|
||||
import { Memory } from "mem0ai/oss";
|
||||
const memory = new Memory({ /* vectorStore, embedder, llm, historyStore … */ });
|
||||
const memory = new Memory({ /* vectorStore, embedder, llm, historyStore, reranker, customInstructions … */ });
|
||||
|
||||
// Platform (hosted) — default export from the package root
|
||||
// Platform (hosted): default export from the package root
|
||||
import MemoryClient from "mem0ai";
|
||||
const memory = new MemoryClient({ apiKey: process.env.MEM0_API_KEY });
|
||||
// Drop organizationId / projectId — resolved from the API key in v3.
|
||||
const memory = new MemoryClient({ apiKey: process.env.MEM0_API_KEY! });
|
||||
```
|
||||
Notes:
|
||||
- Unlike Python, the TS client does **not** read `MEM0_API_KEY` itself: `apiKey` is required and the
|
||||
constructor throws if it is empty. Pass it explicitly.
|
||||
- Drop `organizationId` / `projectId` if present, they're resolved from the API key.
|
||||
- Drop `vectorStore`, `embedder`, `llm`, `historyStore`, `historyDbPath`, `reranker`, `disableHistory`,
|
||||
`version`. `customInstructions` maps to `client.updateProject({ customInstructions })` or
|
||||
`customInstructions` on `add()`.
|
||||
|
||||
### Method calls (option-object differences)
|
||||
| Operation | OSS / old client | Hosted client (v3) |
|
||||
| Operation | OSS `Memory` | Hosted client |
|
||||
|---|---|---|
|
||||
| add | `memory.add(messages, { userId: "u" })` | `memory.add(messages, { userId: "u" })` — unchanged |
|
||||
| search | `memory.search(q, { userId: "u", limit: 20 })` | `memory.search(q, { filters: { userId: "u" }, topK: 20 })` — entity IDs into `filters`; `limit` → `topK` |
|
||||
| getAll | `memory.getAll({ userId: "u" })` | `memory.getAll({ filters: { userId: "u" } })` — entity IDs into `filters` |
|
||||
| deleteAll | `memory.deleteAll({ userId: "u" })` | `memory.deleteAll({ userId: "u" })` |
|
||||
| get / update / delete | `memory.get(id)` etc. | same, by memory id |
|
||||
| add | `memory.add(messages, { userId: "u" })` (`messages` may be a string or `Message[]`) | `memory.add(messages, { userId: "u" })`: `messages` must be `Message[]` (wrap a bare string as `[{ role: "user", content: str }]`); the response is an async event (see Return shapes) |
|
||||
| search | `memory.search(q, { filters: { user_id: "u" }, topK: 20 })` (pre-3.0 code used top-level `userId` and `limit`) | `memory.search(q, { filters: { user_id: "u" }, topK: 20 })`: entity IDs go inside `filters` with **snake_case** keys (`user_id`, not `userId`); top-level `userId` throws; `limit` → `topK` |
|
||||
| getAll | `memory.getAll({ filters: { user_id: "u" }, topK: 20 })` (not paginated) | `memory.getAll({ filters: { user_id: "u" }, page: 1, pageSize: 50 })`: paginated with `page`/`pageSize` (not `topK`) |
|
||||
| deleteAll | `memory.deleteAll({ userId: "u" })` | `memory.deleteAll({ userId: "u" })`: same call (at least one entity ID is required) |
|
||||
| update | `memory.update(id, "new text")` or `memory.update(id, { text, metadata })` | `memory.update(id, { text: "new text" })`: the options object is required, a bare string throws |
|
||||
| get / delete / history | `memory.get(id)` etc. | same, by memory id (`history` field names differ, see Return shapes) |
|
||||
| reset | `memory.reset()` (wipes the local store) | No `reset()` on the TS client. `deleteUsers()` with no arguments deletes all users, agents, sessions and memories (first page of entities only, see gotchas). Prefer `deleteAll` scoped to an entity. Flag this |
|
||||
|
||||
Also drop legacy options that no longer apply on v3: `async_mode`, `output_format`, `enable_graph`.
|
||||
Also drop legacy options that no longer apply: `async_mode`, `output_format`, `enable_graph`.
|
||||
|
||||
---
|
||||
|
||||
## Return shapes
|
||||
- `search(...)` and `get_all(...)` return `{"results": [...]}`; each item has at least a `memory`
|
||||
(text) field, plus `id` and (for search) `score`. Code that reads `result["results"]` and pulls
|
||||
`item["memory"]` keeps working.
|
||||
- `get_all(...)` on the hosted client is paginated: `{"count", "next", "previous", "results": [...]}`.
|
||||
- `add(...)` returns the created memories. On v3 it returns **only ADD events** — if the old code
|
||||
branched on `event == "UPDATE"` / `"DELETE"` from `add()` results, that branch is now dead.
|
||||
- `search(...)` returns `{"results": [...]}` on both sides; each item has at least a `memory` (text)
|
||||
field, plus `id` and `score`. Code that reads `result["results"]` and pulls `item["memory"]` keeps
|
||||
working.
|
||||
- `get_all(...)`: OSS returns `{"results": [...]}` (no pagination). The hosted client is paginated:
|
||||
`{"count", "next", "previous", "results": [...]}`.
|
||||
- `add(...)`: OSS extracts synchronously on both runtimes, but the event sits in a different place:
|
||||
Python OSS returns `{"results": [{"id", "memory", "event": "ADD"}]}`, TS OSS returns
|
||||
`{ results: [{ id, memory, metadata: { event: "ADD" } }] }` (no top-level `event`).
|
||||
The hosted `add` is **asynchronous by default** and returns `{"status": "PENDING", "event_id": "..."}`
|
||||
from Python. The TS hosted client camelCases response keys, so it returns
|
||||
`{ status: "PENDING", eventId: "..." }` (its typed return `Array<Memory>` does not reflect this).
|
||||
New memories may not be searchable yet. Only `infer=False` is synchronous and returns `results`.
|
||||
Neither SDK has an event-poll method: poll `GET /v1/event/{event_id}/` over REST if you must wait.
|
||||
Code that reads `id`/`memory` from `add()` results must change, and any 1.x-era branch on
|
||||
`event == "UPDATE"` / `"DELETE"` is dead on both sides (add is ADD-only since 2.0).
|
||||
- `history(...)` field names differ on all four runtimes:
|
||||
|
||||
| Runtime | Entry fields |
|
||||
|---|---|
|
||||
| Python OSS | `id`, `memory_id`, `old_memory`, `new_memory`, `event`, `created_at`, `updated_at`, `is_deleted`, `actor_id`, `role` (oldest first) |
|
||||
| TS OSS | `id`, `memory_id`, `previous_value`, `new_value`, `action`, `created_at`, `updated_at`, `is_deleted` (raw rows, snake_case, newest first) |
|
||||
| Hosted Python | `id`, `memory_id`, `input`, `old_memory`, `new_memory`, `event`, `user_id`, `categories`, `metadata`, `created_at`, `updated_at` |
|
||||
| Hosted TS | `id`, `memoryId`, `input`, `oldMemory`, `newMemory`, `event`, `userId`, `categories`, `metadata`, `createdAt`, `updatedAt` |
|
||||
|
||||
Code that reads `previous_value` / `new_value` / `action` from TS OSS history must switch to
|
||||
`oldMemory` / `newMemory` / `event` on the hosted TS client.
|
||||
|
||||
---
|
||||
|
||||
@@ -109,9 +148,18 @@ Also drop legacy options that no longer apply on v3: `async_mode`, `output_forma
|
||||
- Local-infra services (e.g. a Qdrant docker-compose service) that existed only for mem0 can be
|
||||
retired — flag this rather than deleting infrastructure unilaterally.
|
||||
|
||||
## v2→v3 default/behavior changes
|
||||
From the official migration guide — surface any that affect the project:
|
||||
- Python `top_k` default changed 100 → 20; TS `limit` renamed to `topK`.
|
||||
- New `threshold` default `0.1` (was none); new `rerank` default `false` (was true).
|
||||
- `custom_fact_extraction_prompt` → `custom_instructions`; `custom_update_memory_prompt` deprecated.
|
||||
- Graph memory (`enable_graph`, `graph_store`) removed from the OSS v3 surface — see gotchas.
|
||||
## OSS vs Platform defaults and behavior
|
||||
Surface any that affect the project. Defaults differ between the two sides even when a call looks
|
||||
identical:
|
||||
- `search`: OSS `top_k=20`, `threshold=0.1`, `rerank=False`. Platform `top_k=10` (allowed 1 to 1000),
|
||||
`rerank=false`, and `threshold` is a server-side cutoff, not a floor on the returned `score`. Pass `top_k` explicitly to keep the old result count.
|
||||
- `get_all`: OSS `top_k=20`, not paginated. Platform `page=1`, `page_size=100`.
|
||||
- `custom_fact_extraction_prompt` (TS `customPrompt`) was renamed `custom_instructions`
|
||||
(`customInstructions`) in OSS 2.0/3.0; `custom_update_memory_prompt` is deprecated. See the
|
||||
constructor notes for the hosted equivalent.
|
||||
- Graph memory (`enable_graph`, `graph_store`) was removed from OSS (Python 2.0.0, TS 3.0.0). On the
|
||||
Platform graph is built in and always on, with no flag. See gotchas.
|
||||
- Platform-only: `app_id`, webhooks, custom categories, batch update/delete, feedback, memory export,
|
||||
user profiles. `timestamp`, `reference_date` and `decay` raise on OSS.
|
||||
- OSS-only (no Platform option): `reranker` and `history_db_path` config, `memory_type` and `prompt`
|
||||
on `add`, `explain` on `search`.
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -51,13 +51,15 @@ unambiguous. Example:
|
||||
## Concerns & decisions needed
|
||||
The non-1:1 items from the gotchas that apply here, each phrased as a decision for the developer.
|
||||
Cover, where relevant: data not migrating, self-hosting/data-residency, local models moving server-
|
||||
side, graph memory, custom prompts (now dashboard settings), network/latency/cost on hot paths,
|
||||
return-shape changes (`add` ADD-only, `get_all` pagination, default `top_k`/threshold/rerank), and
|
||||
any `reset()` usage. Be specific about which file/line each concern affects.
|
||||
side, graph memory, custom prompts (now project-level `custom_instructions`), network/latency/cost on
|
||||
hot paths, return-shape changes (`add` is async and returns an `event_id` (`eventId` on TS), `get_all` pagination,
|
||||
default `top_k` 20 vs 10), metadata filters that need rewriting, and any `reset()` usage. Be specific
|
||||
about which file/line each concern affects.
|
||||
|
||||
## Out of scope
|
||||
- Existing memory **data** is not migrated (code only). If wanted, it's a separate opt-in task
|
||||
(export from the OSS store, re-add to the hosted client).
|
||||
(for hosted Qdrant + Python OSS, `scripts/oss-to-platform-migrate.sh`; otherwise export from the
|
||||
OSS store and re-add to the hosted client).
|
||||
- No unrelated refactors, renames, or behavior changes.
|
||||
|
||||
## Verification plan
|
||||
@@ -65,7 +67,8 @@ How execution will be confirmed end-to-end:
|
||||
- Imports / type-checks / byte-compiles cleanly.
|
||||
- Smoke test against the hosted API with a real `MEM0_API_KEY`: `add` a fact → `search`/`get_all`
|
||||
returns it → `delete_all` clears it. Plus: the app's own entry point still runs.
|
||||
- Confirm no local mem0 storage dir is created anymore (e.g. `.mem0/`) — proof memory is hosted.
|
||||
- Confirm no local OSS storage is created anymore (e.g. `~/.mem0/history.db`, a local Qdrant path).
|
||||
The client still creates `~/.mem0/config.json`, so the bare `.mem0/` directory is not the check.
|
||||
|
||||
## Rollback
|
||||
- All changes are in version control; revert with git if needed. Note the branch/commit strategy.
|
||||
|
||||
Reference in New Issue
Block a user