From 651953de08859ff07c3c79ec9bd6c081f3e0fff5 Mon Sep 17 00:00:00 2001 From: Dhravya <63950637+Dhravya@users.noreply.github.com> Date: Sun, 2 Aug 2026 20:08:03 +0000 Subject: [PATCH 1/2] fix: forget search result memories --- src/index.ts | 24 ++++++++++++++++------ src/services/client.ts | 46 ++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 62 insertions(+), 8 deletions(-) diff --git a/src/index.ts b/src/index.ts index 03ed953..517bad6 100644 --- a/src/index.ts +++ b/src/index.ts @@ -524,9 +524,16 @@ export const SupermemoryPlugin: Plugin = async (ctx: PluginInput) => { } const scope = args.scope || "project"; + const readTags = + args.scope === "user" + ? tags.personalReads + : args.scope === "project" + ? tags.projectReads + : tags.allReads; const result = await supermemoryClient.deleteMemory( - args.memoryId + args.memoryId, + [tags.canonical, ...readTags], ); if (!result.success) { @@ -593,10 +600,15 @@ function formatSearchResults( query, scope, count: memoryResults.length, - results: memoryResults.slice(0, limit || 10).map((r) => ({ - id: r.id, - content: r.memory || r.chunk, - similarity: Math.round((r.similarity ?? 0) * 100), - })), + results: memoryResults.slice(0, limit || 10).map((r) => { + const result = { + content: r.memory ?? r.chunk, + similarity: Math.round((r.similarity ?? 0) * 100), + }; + + return r.memory === undefined + ? { ...result, forgettable: false } + : { id: r.id, ...result, forgettable: true }; + }), }); } diff --git a/src/services/client.ts b/src/services/client.ts index bb73f69..b6f7b82 100644 --- a/src/services/client.ts +++ b/src/services/client.ts @@ -89,6 +89,15 @@ function supportsScopedCanonicalTag(containerTag: string): boolean { return /^repo_.+__[0-9a-f]{16}$/i.test(containerTag); } +function isNotFoundError(error: unknown): boolean { + return ( + typeof error === "object" && + error !== null && + "status" in error && + error.status === 404 + ); +} + function withTimeout(promise: Promise, ms: number): Promise { let id: ReturnType; const timeout = new Promise((_, reject) => { @@ -378,7 +387,7 @@ export class SupermemoryClient { } } - async deleteMemory(memoryId: string) { + async deleteMemory(memoryId: string, containerTags: string[] = []) { log("deleteMemory: start", { memoryId }); try { await withTimeout( @@ -388,8 +397,41 @@ export class SupermemoryClient { log("deleteMemory: success", { memoryId }); return { success: true as const }; } catch (error) { + if (!isNotFoundError(error)) { + const errorMessage = + error instanceof Error ? error.message : String(error); + log("deleteMemory: error", { memoryId, error: errorMessage }); + return { success: false as const, error: errorMessage }; + } + + const uniqueTags = [...new Set(containerTags.filter(Boolean))]; + let lastNotFoundError: unknown = error; + + for (const containerTag of uniqueTags) { + try { + await withTimeout( + this.getClient().memories.forget({ id: memoryId, containerTag }), + TIMEOUT_MS, + ); + log("deleteMemory: forgotten", { memoryId }); + return { success: true as const }; + } catch (forgetError) { + if (!isNotFoundError(forgetError)) { + const errorMessage = + forgetError instanceof Error + ? forgetError.message + : String(forgetError); + log("deleteMemory: forget error", { memoryId, error: errorMessage }); + return { success: false as const, error: errorMessage }; + } + lastNotFoundError = forgetError; + } + } + const errorMessage = - error instanceof Error ? error.message : String(error); + lastNotFoundError instanceof Error + ? lastNotFoundError.message + : String(lastNotFoundError); log("deleteMemory: error", { memoryId, error: errorMessage }); return { success: false as const, error: errorMessage }; } From 01d29ccf49fd8534aa27cf7a1751fc1a549ab6aa Mon Sep 17 00:00:00 2001 From: Dhravya <63950637+Dhravya@users.noreply.github.com> Date: Sun, 2 Aug 2026 20:40:44 +0000 Subject: [PATCH 2/2] fix: prefer v4 memory forget --- src/index.ts | 4 +-- src/services/client.ts | 77 +++++++++++++++++++++++------------------- 2 files changed, 44 insertions(+), 37 deletions(-) diff --git a/src/index.ts b/src/index.ts index 517bad6..cb090e5 100644 --- a/src/index.ts +++ b/src/index.ts @@ -525,9 +525,9 @@ export const SupermemoryPlugin: Plugin = async (ctx: PluginInput) => { const scope = args.scope || "project"; const readTags = - args.scope === "user" + scope === "user" ? tags.personalReads - : args.scope === "project" + : scope === "project" ? tags.projectReads : tags.allReads; diff --git a/src/services/client.ts b/src/services/client.ts index b6f7b82..d9454fc 100644 --- a/src/services/client.ts +++ b/src/services/client.ts @@ -98,6 +98,15 @@ function isNotFoundError(error: unknown): boolean { ); } +function isAuthorizationError(error: unknown): boolean { + return ( + typeof error === "object" && + error !== null && + "status" in error && + (error.status === 401 || error.status === 403) + ); +} + function withTimeout(promise: Promise, ms: number): Promise { let id: ReturnType; const timeout = new Promise((_, reject) => { @@ -389,49 +398,47 @@ export class SupermemoryClient { async deleteMemory(memoryId: string, containerTags: string[] = []) { log("deleteMemory: start", { memoryId }); + const uniqueTags = [...new Set(containerTags.filter(Boolean))]; + let retainedAuthorizationError: unknown; + + for (const [index, containerTag] of uniqueTags.entries()) { + try { + await withTimeout( + this.getClient().memories.forget({ id: memoryId, containerTag }), + TIMEOUT_MS, + ); + log("deleteMemory: forgotten", { memoryId }); + return { success: true as const }; + } catch (error) { + if (isNotFoundError(error)) continue; + if (index > 0 && isAuthorizationError(error)) { + retainedAuthorizationError ??= error; + continue; + } + + const errorMessage = + error instanceof Error ? error.message : String(error); + log("deleteMemory: forget error", { memoryId, error: errorMessage }); + return { success: false as const, error: errorMessage }; + } + } + try { await withTimeout( this.getClient().memories.delete(memoryId), TIMEOUT_MS, ); - log("deleteMemory: success", { memoryId }); + log("deleteMemory: deleted document", { memoryId }); return { success: true as const }; } catch (error) { - if (!isNotFoundError(error)) { - const errorMessage = - error instanceof Error ? error.message : String(error); - log("deleteMemory: error", { memoryId, error: errorMessage }); - return { success: false as const, error: errorMessage }; - } - - const uniqueTags = [...new Set(containerTags.filter(Boolean))]; - let lastNotFoundError: unknown = error; - - for (const containerTag of uniqueTags) { - try { - await withTimeout( - this.getClient().memories.forget({ id: memoryId, containerTag }), - TIMEOUT_MS, - ); - log("deleteMemory: forgotten", { memoryId }); - return { success: true as const }; - } catch (forgetError) { - if (!isNotFoundError(forgetError)) { - const errorMessage = - forgetError instanceof Error - ? forgetError.message - : String(forgetError); - log("deleteMemory: forget error", { memoryId, error: errorMessage }); - return { success: false as const, error: errorMessage }; - } - lastNotFoundError = forgetError; - } - } - + const errorToReturn = + isNotFoundError(error) && retainedAuthorizationError !== undefined + ? retainedAuthorizationError + : error; const errorMessage = - lastNotFoundError instanceof Error - ? lastNotFoundError.message - : String(lastNotFoundError); + errorToReturn instanceof Error + ? errorToReturn.message + : String(errorToReturn); log("deleteMemory: error", { memoryId, error: errorMessage }); return { success: false as const, error: errorMessage }; }