From 069b8c373ca279772bd5a982fc42c0b2263061c3 Mon Sep 17 00:00:00 2001 From: sohamd22 <85427822+sohamd22@users.noreply.github.com> Date: Thu, 6 Aug 2026 09:32:32 +0000 Subject: [PATCH] =?UTF-8?q?docs(memories):=20forget-matching=20accepts=20a?= =?UTF-8?q?n=20id=20list=20(bound=20preview=E2=86=92apply)=20(#1367)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ### TL;DR Documents the new `ids` parameter for the `forget-matching` endpoint, allowing exact memory deletion without semantic search. ### What changed? The `forget-matching` endpoint now accepts either a `query` (semantic search-based forgetting) or an explicit `ids` list (direct deletion by memory ID) — one or the other must be provided. The docs have been updated to reflect this: - The `query` parameter is now marked as `one of*` rather than required, and `ids` is introduced as an alternative with the same mutual-exclusivity constraint. - `threshold` is clarified as applying to `query` mode only. - Code examples for both JavaScript and cURL now show the recommended two-step pattern: run a `dryRun` with `query`, then apply using the `ids` returned from the preview — avoiding drift if the container changes between steps. - A new `` block explains why passing `ids` on the apply step produces a more deterministic delete than re-running the `query`. ### How to test? 1. Call `forget-matching` with `dryRun: true` and a `query` to retrieve candidate `id`s. 2. Re-call with `dryRun: false` and the `ids` from step 1 to confirm only those exact memories are forgotten. 3. Verify that passing `ids` belonging to a different `containerTag` are ignored. 4. Confirm that providing both `query` and `ids`, or neither, returns an appropriate validation error. ### Why make this change? Re-running a `query` on the apply step can produce different results if the container was modified between the preview and the apply. Exposing `ids` as a first-class parameter lets callers pin the delete to exactly the set they reviewed, making bulk forgetting safer and more predictable. --- apps/docs/recall/memory-operations.mdx | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/apps/docs/recall/memory-operations.mdx b/apps/docs/recall/memory-operations.mdx index 6126b1f9d..6e58e8e25 100644 --- a/apps/docs/recall/memory-operations.mdx +++ b/apps/docs/recall/memory-operations.mdx @@ -173,7 +173,7 @@ The memory will no longer appear in search results but remains in the database ( ## Forget Matching -Forget **everything** about a topic in one call. You give a prompt or a query; the service semantically searches the container's memories, an LLM decides which ones are genuinely about your target, and those are soft-deleted. Use this for "forget everything about X" rather than deleting memories one by one. +Forget in bulk in one call, two ways. Give a **`query`** (a prompt or topic) and the service semantically searches the container, an LLM decides which memories are genuinely about your target, and those are soft-deleted — use this for "forget everything about X". Or give an explicit **`ids`** list to forget exactly those memories with no search. Provide one or the other. This is a bulk, destructive operation. Always **`dryRun` first** to review what would be forgotten, then re-run with `dryRun: false`. The match is semantic, so a too-broad query can select more than you intend — `threshold` and `maxForget` bound the blast radius. @@ -197,7 +197,7 @@ This is a bulk, destructive operation. Always **`dryRun` first** to review what }).then((r) => r.json()); // preview.candidates → [{ id, memory, score }, ...] - // 2) Apply + // 2) Apply — pass the ids from the preview to forget exactly that set const result = await fetch("https://api.supermemory.ai/v4/memories/forget-matching", { method: "POST", headers: { @@ -205,7 +205,7 @@ This is a bulk, destructive operation. Always **`dryRun` first** to review what "Content-Type": "application/json" }, body: JSON.stringify({ - query: "forget everything about Project Titan", + ids: preview.candidates.map((c) => c.id), containerTag: "user_123", dryRun: false, reason: "project cancelled" @@ -227,12 +227,12 @@ This is a bulk, destructive operation. Always **`dryRun` first** to review what "dryRun": true }' - # Apply + # Apply — pass the ids from the preview to forget exactly that set curl -X POST "https://api.supermemory.ai/v4/memories/forget-matching" \ -H "Authorization: Bearer $SUPERMEMORY_API_KEY" \ -H "Content-Type: application/json" \ -d '{ - "query": "forget everything about Project Titan", + "ids": ["abc123", "def456", "ghi789"], "containerTag": "user_123", "dryRun": false, "reason": "project cancelled" @@ -245,13 +245,16 @@ This is a bulk, destructive operation. Always **`dryRun` first** to review what | Parameter | Type | Required | Description | |-----------|------|----------|-------------| -| `query` | string | yes | What to forget — a natural-language instruction ("forget everything about Project Titan") or a bare topic ("Project Titan") | +| `query` | string | one of* | What to forget — a natural-language instruction ("forget everything about Project Titan") or a bare topic ("Project Titan") | +| `ids` | string[] | one of* | Exact memory ids to forget instead of a `query` — no semantic search. Ids are validated against `containerTag`, so unknown or out-of-scope ids are ignored | | `containerTag` | string | yes | Container tag / space to scope the operation to | | `dryRun` | boolean | no | When `true`, returns what *would* be forgotten without changing anything. Defaults to `false` | -| `threshold` | number | no | Similarity floor (0–1) for candidate memories. Lower casts a wider net. Defaults to `0.5` | -| `maxForget` | number | no | Safety cap on how many memories may be forgotten in one call (1–500). Defaults to `100` | +| `threshold` | number | no | Similarity floor (0–1) for candidate memories (`query` mode only). Lower casts a wider net. Defaults to `0.5` | +| `maxForget` | number | no | Safety cap for **query mode** — the most matches one call may forget (1–500). Defaults to `100`. Ignored in id mode, which forgets exactly the ids you pass (bounded only by the 500-item array limit) | | `reason` | string | no | Reason recorded as `forgetReason` on each forgotten memory | +\* Provide either `query` or `ids`. + ### Response ```json @@ -279,6 +282,10 @@ This is a bulk, destructive operation. Always **`dryRun` first** to review what Identity is server-owned: the LLM only ever references opaque handles for the memories a search returned, so it can never forget a memory outside the results it reviewed, and every operation is scoped to the `containerTag` you pass. + +**Exact, bound deletes.** Applying with a `query` re-runs the semantic match, so the result can drift from the preview if the container changed in between. To forget *precisely* what you reviewed, take the `id`s from a `dryRun` preview and send them back as `ids` on the apply — the delete is then bound to exactly that set. (`ids` with `dryRun: true` returns the validated set as `candidates` without deleting, so you can confirm first.) + + --- ## Update Memory (Versioned)