From fcf49855cef2e6da138898bd042af76f800ac41a Mon Sep 17 00:00:00 2001 From: Ishaan Gupta Date: Thu, 13 Aug 2026 17:08:50 +0530 Subject: [PATCH 1/5] Upgrade Nova model picker to current runtime models (#1404) --- .../components/chat/home-chat-composer.tsx | 4 ++-- apps/web/components/chat/index.tsx | 4 ++-- apps/web/components/chat/model-selector.tsx | 3 +-- apps/web/lib/chat-stream-error.ts | 6 ++--- apps/web/lib/models.tsx | 24 +++++++++---------- 5 files changed, 20 insertions(+), 21 deletions(-) diff --git a/apps/web/components/chat/home-chat-composer.tsx b/apps/web/components/chat/home-chat-composer.tsx index 7f9d28af5..d3328d73a 100644 --- a/apps/web/components/chat/home-chat-composer.tsx +++ b/apps/web/components/chat/home-chat-composer.tsx @@ -36,9 +36,9 @@ export function HomeChatComposer({ const [attachmentDrafts, setAttachmentDrafts] = useState< ChatAttachmentDraft[] >([]) - const [selectedModel, setSelectedModel] = useState("grok-4.3") + const [selectedModel, setSelectedModel] = useState("grok-4.5") const [reasoningEffort, setReasoningEffort] = useState( - getDefaultReasoningEffort("grok-4.3"), + getDefaultReasoningEffort("grok-4.5"), ) const { selectedProject } = useProject() const [chatSpaceProjects, setChatSpaceProjects] = useState([ diff --git a/apps/web/components/chat/index.tsx b/apps/web/components/chat/index.tsx index c78df7f7b..70f01d062 100644 --- a/apps/web/components/chat/index.tsx +++ b/apps/web/components/chat/index.tsx @@ -206,11 +206,11 @@ export function ChatSidebar({ >([]) const [isChatDraggingFiles, setIsChatDraggingFiles] = useState(false) const [selectedModel, setSelectedModel] = useState( - initialSelectedModel ?? "grok-4.3", + initialSelectedModel ?? "grok-4.5", ) const [reasoningEffort, setReasoningEffort] = useState( initialReasoningEffort ?? - getDefaultReasoningEffort(initialSelectedModel ?? "grok-4.3"), + getDefaultReasoningEffort(initialSelectedModel ?? "grok-4.5"), ) const selectedModelRef = useRef(selectedModel) selectedModelRef.current = selectedModel diff --git a/apps/web/components/chat/model-selector.tsx b/apps/web/components/chat/model-selector.tsx index ca9935ee7..b65cbad77 100644 --- a/apps/web/components/chat/model-selector.tsx +++ b/apps/web/components/chat/model-selector.tsx @@ -23,8 +23,7 @@ export default function ChatModelSelector({ minimal = false, dropdownDirection = "up", }: ChatModelSelectorProps = {}) { - const [internalModel, setInternalModel] = - useState("claude-sonnet-4.6") + const [internalModel, setInternalModel] = useState("claude-sonnet-5") const [isOpen, setIsOpen] = useState(false) const containerRef = useRef(null) diff --git a/apps/web/lib/chat-stream-error.ts b/apps/web/lib/chat-stream-error.ts index 2e17135df..f31dc53b9 100644 --- a/apps/web/lib/chat-stream-error.ts +++ b/apps/web/lib/chat-stream-error.ts @@ -1,9 +1,9 @@ import type { ModelId } from "@/lib/models" const OTHER_MODELS: ModelId[] = [ - "gpt-5.1", - "claude-sonnet-4.6", - "gemini-2.5-pro", + "gpt-5.6-terra", + "claude-sonnet-5", + "gemini-3.1-pro-preview", ] function flattenError(e: unknown): string { diff --git a/apps/web/lib/models.tsx b/apps/web/lib/models.tsx index 5d3479efb..fe0e75844 100644 --- a/apps/web/lib/models.tsx +++ b/apps/web/lib/models.tsx @@ -1,22 +1,22 @@ export const models = [ { - id: "grok-4.3", - name: "Grok 4.3", + id: "grok-4.5", + name: "Grok 4.5", description: "xAI's latest model", }, { - id: "gpt-5.1", - name: "GPT 5.1", + id: "gpt-5.6-terra", + name: "GPT 5.6", description: "OpenAI's latest model", }, { - id: "claude-sonnet-4.6", - name: "Claude Sonnet 4.6", + id: "claude-sonnet-5", + name: "Claude Sonnet 5", description: "Anthropic's advanced model", }, { - id: "gemini-2.5-pro", - name: "Gemini 3 Pro", + id: "gemini-3.1-pro-preview", + name: "Gemini 3.1 Pro", description: "Google's most capable model", }, ] as const @@ -25,10 +25,10 @@ export type ModelId = (typeof models)[number]["id"] export type ReasoningEffort = "instant" | "thinking" export const modelNames: Record = { - "grok-4.3": { name: "Grok", version: "4.3" }, - "gpt-5.1": { name: "GPT", version: "5.1" }, - "claude-sonnet-4.6": { name: "Claude", version: "4.6" }, - "gemini-2.5-pro": { name: "Gemini", version: "3 Pro" }, + "grok-4.5": { name: "Grok", version: "4.5" }, + "gpt-5.6-terra": { name: "GPT", version: "5.6" }, + "claude-sonnet-5": { name: "Claude", version: "Sonnet 5" }, + "gemini-3.1-pro-preview": { name: "Gemini", version: "3.1 Pro" }, } export const reasoningOptions: Array<{ From 1356affbd16d7d88ef6dd223936be36f6fc2cabe Mon Sep 17 00:00:00 2001 From: James Yang Date: Thu, 13 Aug 2026 08:25:16 -0400 Subject: [PATCH 2/5] fix(extension): finish Included Memories leftovers on T3 (#1257) (#1421) Co-authored-by: abhay-codes07 Co-authored-by: Vedant Mahajan --- .../entrypoints/content/memory-suggestion.ts | 7 ++ .../entrypoints/content/t3.ts | 95 +++++++++++-------- 2 files changed, 64 insertions(+), 38 deletions(-) diff --git a/apps/browser-extension/entrypoints/content/memory-suggestion.ts b/apps/browser-extension/entrypoints/content/memory-suggestion.ts index 18861fe30..27b65b08c 100644 --- a/apps/browser-extension/entrypoints/content/memory-suggestion.ts +++ b/apps/browser-extension/entrypoints/content/memory-suggestion.ts @@ -45,6 +45,13 @@ export function parseMemoriesFromDataset( .filter((memory) => memory.length > 0 && memory !== ",") } +export function renumberIncludedMemories(memories: string[]): string[] { + return memories.map((memory, index) => { + const text = memory.replace(/^\d+\.\s*/, "").replace(/\s+$/, "") + return `${index + 1}. ${text} \n` + }) +} + export function showMemorySuggestion( platform: string, input: SuggestionInput, diff --git a/apps/browser-extension/entrypoints/content/t3.ts b/apps/browser-extension/entrypoints/content/t3.ts index 39a05f03e..bddd83ed9 100644 --- a/apps/browser-extension/entrypoints/content/t3.ts +++ b/apps/browser-extension/entrypoints/content/t3.ts @@ -11,7 +11,9 @@ import { } from "../../utils/storage" import { createT3InputBarElement, DOMUtils } from "../../utils/ui-components" import { + buildSupermemoryText, parseMemoriesFromDataset, + renumberIncludedMemories, serializeMemoriesForDataset, } from "./memory-suggestion" @@ -19,6 +21,19 @@ let t3DebounceTimeout: NodeJS.Timeout | null = null let t3RouteObserver: MutationObserver | null = null let t3UrlCheckInterval: NodeJS.Timeout | null = null let t3ObserverThrottle: NodeJS.Timeout | null = null +let t3IncludedPopup: { + el: HTMLElement + onClick: (event: MouseEvent) => void + timer: ReturnType +} | null = null + +function disposeT3IncludedPopup() { + if (!t3IncludedPopup) return + document.removeEventListener("click", t3IncludedPopup.onClick) + clearTimeout(t3IncludedPopup.timer) + t3IncludedPopup.el.remove() + t3IncludedPopup = null +} export function initializeT3() { if (!DOMUtils.isOnDomain(DOMAINS.T3)) { @@ -57,6 +72,7 @@ function setupT3RouteChangeDetection() { const checkForRouteChange = () => { if (window.location.href !== currentUrl) { + disposeT3IncludedPopup() currentUrl = window.location.href setTimeout(() => { addSupermemoryIconToT3Input() @@ -235,7 +251,9 @@ async function getRelatedMemoriesForT3(actionSource: string) { } if (textareaElement) { - textareaElement.dataset.supermemories = `\n\nSupermemories of user (only for the reference): ${response.data}` + textareaElement.dataset.supermemories = buildSupermemoryText( + response.data, + ) iconElement.dataset.memoriesData = serializeMemoriesForDataset( response.data, @@ -274,6 +292,8 @@ function updateT3IconFeedback( iconElement.dataset.originalHtml = iconElement.innerHTML } + disposeT3IncludedPopup() + const feedbackDiv = document.createElement("div") feedbackDiv.style.cssText = ` display: flex; @@ -409,68 +429,65 @@ function updateT3IconFeedback( popup.style.display = "block" }) - document.addEventListener("click", (e) => { + const onClick = (e: MouseEvent) => { if (!popup.contains(e.target as Node)) { popup.style.display = "none" } - }) + } + document.addEventListener("click", onClick) + t3IncludedPopup = { + el: popup, + onClick, + timer: setTimeout(disposeT3IncludedPopup, 300000), + } content.querySelectorAll("button[data-memory-index]").forEach((button) => { const htmlButton = button as HTMLButtonElement htmlButton.addEventListener("click", () => { const index = Number.parseInt(htmlButton.dataset.memoryIndex || "0", 10) - const memoryItem = htmlButton.parentElement - - if (memoryItem) { - content.removeChild(memoryItem) - } + htmlButton.parentElement?.remove() - const currentMemories = parseMemoriesFromDataset( + const remainingMemories = parseMemoriesFromDataset( iconElement.dataset.memoriesData, ) - currentMemories.splice(index, 1) - - // Injected prompt keeps its existing joined-text form; the popup's - // own data is stored as JSON so comma-bearing memories stay intact. - const updatedMemories = currentMemories.join(" ,") - - iconElement.dataset.memoriesData = - serializeMemoriesForDataset(currentMemories) + remainingMemories.splice(index, 1) + const remaining = renumberIncludedMemories(remainingMemories) const textareaElement = (document.querySelector("textarea") as HTMLTextAreaElement) || (document.querySelector('div[contenteditable="true"]') as HTMLElement) + + // Only wipe when nothing remains — `<= 1` used to discard the last kept memory. + if (remaining.length === 0) { + if (textareaElement?.dataset.supermemories) { + delete textareaElement.dataset.supermemories + } + delete iconElement.dataset.memoriesData + iconElement.innerHTML = iconElement.dataset.originalHtml || "" + delete iconElement.dataset.originalHtml + disposeT3IncludedPopup() + return + } + + iconElement.dataset.memoriesData = + serializeMemoriesForDataset(remaining) if (textareaElement) { - textareaElement.dataset.supermemories = `\n\nSupermemories of user (only for the reference): ${updatedMemories}` + textareaElement.dataset.supermemories = + buildSupermemoryText(remaining) } content .querySelectorAll("button[data-memory-index]") .forEach((btn, newIndex) => { const htmlBtn = btn as HTMLButtonElement - htmlBtn.dataset.memoryIndex = newIndex.toString() + htmlBtn.dataset.memoryIndex = String(newIndex) + const label = htmlBtn.previousElementSibling + if (label) { + label.textContent = remaining[newIndex].trim() + } }) - - if (currentMemories.length <= 1) { - if (textareaElement?.dataset.supermemories) { - delete textareaElement.dataset.supermemories - delete iconElement.dataset.memoriesData - iconElement.innerHTML = iconElement.dataset.originalHtml || "" - delete iconElement.dataset.originalHtml - } - popup.style.display = "none" - if (document.body.contains(popup)) { - document.body.removeChild(popup) - } - } }) }) - - setTimeout(() => { - if (document.body.contains(popup)) { - document.body.removeChild(popup) - } - }, 300000) } iconElement.innerHTML = "" @@ -562,6 +579,7 @@ function setupT3PromptCapture() { if (textareaElement?.dataset.supermemories) { delete textareaElement.dataset.supermemories } + disposeT3IncludedPopup() } const handleT3SendButtonClick = async (event: Event) => { @@ -717,6 +735,7 @@ async function setupT3AutoFetch() { if (textareaElement.dataset.supermemories) { delete textareaElement.dataset.supermemories } + disposeT3IncludedPopup() } }, UI_CONFIG.AUTO_SEARCH_DEBOUNCE_DELAY) } From 9d64e0f9504d958f79d9fe482ac2e6397ee2f112 Mon Sep 17 00:00:00 2001 From: Abhinav Kumar Singh <152812718+abhinavkr26104@users.noreply.github.com> Date: Thu, 13 Aug 2026 17:55:50 +0530 Subject: [PATCH 3/5] fix: add type checks for TypeScript workspaces (#1447) --- apps/browser-extension/package.json | 1 + apps/memory-graph-playground/package.json | 1 + apps/web/package.json | 1 + packages/hooks/package.json | 5 ++++- packages/lib/package.json | 3 +++ packages/ui/package.json | 3 +++ packages/validation/package.json | 5 ++++- 7 files changed, 17 insertions(+), 2 deletions(-) diff --git a/apps/browser-extension/package.json b/apps/browser-extension/package.json index f40426a89..43f3a56ae 100644 --- a/apps/browser-extension/package.json +++ b/apps/browser-extension/package.json @@ -9,6 +9,7 @@ "dev:firefox": "wxt -b firefox", "build": "wxt build", "build:firefox": "wxt build -b firefox", + "check-types": "bun run compile", "zip": "wxt zip", "zip:firefox": "wxt zip -b firefox", "compile": "tsc --noEmit", diff --git a/apps/memory-graph-playground/package.json b/apps/memory-graph-playground/package.json index 67e31a0bb..debe23c71 100644 --- a/apps/memory-graph-playground/package.json +++ b/apps/memory-graph-playground/package.json @@ -7,6 +7,7 @@ "dev": "portless", "dev:app": "next dev --port ${PORT:-3004}", "build": "next build", + "check-types": "tsc --noEmit", "start": "next start" }, "dependencies": { diff --git a/apps/web/package.json b/apps/web/package.json index cddbcd0af..63c4acee4 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -10,6 +10,7 @@ "dev": "portless", "dev:app": "next dev --port ${PORT:-3000}", "build": "next build", + "check-types": "tsc --noEmit", "start": "next start", "lint": "biome check --write", "preview": "opennextjs-cloudflare build && opennextjs-cloudflare preview", diff --git a/packages/hooks/package.json b/packages/hooks/package.json index 63a7d0e57..780a171f0 100644 --- a/packages/hooks/package.json +++ b/packages/hooks/package.json @@ -1,5 +1,8 @@ { "name": "@repo/hooks", "version": "0.0.0", - "private": true + "private": true, + "scripts": { + "check-types": "tsc --noEmit" + } } diff --git a/packages/lib/package.json b/packages/lib/package.json index 99b9d262d..c83e27db9 100644 --- a/packages/lib/package.json +++ b/packages/lib/package.json @@ -3,6 +3,9 @@ "version": "0.0.0", "private": true, "type": "module", + "scripts": { + "check-types": "tsc --noEmit" + }, "exports": { "./*": "./*" }, diff --git a/packages/ui/package.json b/packages/ui/package.json index 2a504670f..8234997a1 100644 --- a/packages/ui/package.json +++ b/packages/ui/package.json @@ -3,6 +3,9 @@ "version": "0.0.0", "private": true, "type": "module", + "scripts": { + "check-types": "tsc --noEmit" + }, "exports": { "./*": "./*" }, diff --git a/packages/validation/package.json b/packages/validation/package.json index ea9f5fc17..8ed191144 100644 --- a/packages/validation/package.json +++ b/packages/validation/package.json @@ -2,5 +2,8 @@ "name": "@repo/validation", "version": "0.0.0", "private": true, - "type": "module" + "type": "module", + "scripts": { + "check-types": "tsc --noEmit" + } } From 7f448d55d83a9a5db467d9b3f77f6a72de055fcd Mon Sep 17 00:00:00 2001 From: Sarath Donepudi <68329935+dupenodi@users.noreply.github.com> Date: Thu, 13 Aug 2026 17:56:49 +0530 Subject: [PATCH 4/5] docs: document pinned install for supermemory-server (#1238) Co-authored-by: Vedant Mahajan --- apps/docs/self-hosting/quickstart.mdx | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/apps/docs/self-hosting/quickstart.mdx b/apps/docs/self-hosting/quickstart.mdx index cb86ee33a..d0b37991c 100644 --- a/apps/docs/self-hosting/quickstart.mdx +++ b/apps/docs/self-hosting/quickstart.mdx @@ -27,6 +27,28 @@ bunx supermemory local The installer detects your OS and architecture, downloads the right binary, verifies it, and (when run interactively) prompts you for an LLM API key. Supported platforms: macOS (Apple Silicon & Intel), Linux (x64 & arm64). +### Pin or change versions + +Pass an explicit version to install (or roll back to) a specific release instead of `latest`: + +```bash +curl -fsSL https://supermemory.ai/install | bash -s -- 0.0.3 +``` + + +Before rolling back, back up your [data directory](#where-things-live). The installer replaces the binary, but an older server may not understand data or schema changes made by a newer release. + + +Release tags are `server-v` on [GitHub Releases](https://github.com/supermemoryai/supermemory/releases) (for example [`server-v0.0.3`](https://github.com/supermemoryai/supermemory/releases/tag/server-v0.0.3)). + +To move to the newest release later: + +```bash +supermemory-server upgrade +``` + +The binary may also print an “update available” notification on startup. If you intentionally pinned an older version (for example while debugging a regression), you can ignore that message until you are ready to upgrade. + ## Run ```bash From 82dae50ef458139823b3bfd3ebaaaac90ffd8a7c Mon Sep 17 00:00:00 2001 From: Abhinav Kumar Singh <152812718+abhinavkr26104@users.noreply.github.com> Date: Thu, 13 Aug 2026 19:11:00 +0530 Subject: [PATCH 5/5] fix(tools): bound memory forget requests (#1451) --- packages/tools/src/shared/forget-memory.ts | 7 +++++++ packages/tools/src/tool-operations.test.ts | 16 ++++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/packages/tools/src/shared/forget-memory.ts b/packages/tools/src/shared/forget-memory.ts index 50a3a5294..8691c92ac 100644 --- a/packages/tools/src/shared/forget-memory.ts +++ b/packages/tools/src/shared/forget-memory.ts @@ -1,4 +1,5 @@ const DEFAULT_BASE_URL = "https://api.supermemory.ai" +const FETCH_TIMEOUT_MS = 30_000 export interface ForgetMemoryParams { containerTag: string @@ -7,6 +8,10 @@ export interface ForgetMemoryParams { reason?: string } +export interface ForgetMemoryRequestOptions { + signal?: AbortSignal +} + /** * Marks a memory as forgotten via `DELETE /v4/memories`. * @@ -19,6 +24,7 @@ export async function forgetMemoryRequest( apiKey: string, params: ForgetMemoryParams, baseUrl: string = DEFAULT_BASE_URL, + options?: ForgetMemoryRequestOptions, ): Promise { const response = await fetch(`${baseUrl}/v4/memories`, { method: "DELETE", @@ -27,6 +33,7 @@ export async function forgetMemoryRequest( Authorization: `Bearer ${apiKey}`, }, body: JSON.stringify(params), + signal: options?.signal ?? AbortSignal.timeout(FETCH_TIMEOUT_MS), }) if (!response.ok) { diff --git a/packages/tools/src/tool-operations.test.ts b/packages/tools/src/tool-operations.test.ts index 69f125940..136a19bea 100644 --- a/packages/tools/src/tool-operations.test.ts +++ b/packages/tools/src/tool-operations.test.ts @@ -109,6 +109,22 @@ describe("memoryForget", () => { id: "mem_1", reason: "outdated", }) + expect(init.signal).toBeInstanceOf(AbortSignal) + }) + + it("uses a caller-provided signal instead of creating a timeout", async () => { + const fetchMock = stubFetch() + const controller = new AbortController() + + await forgetMemoryRequest( + API_KEY, + { containerTag: "user_1", id: "mem_1" }, + undefined, + { signal: controller.signal }, + ) + + const [, init] = fetchMock.mock.calls[0] as [string, RequestInit] + expect(init.signal).toBe(controller.signal) }) it("throws a descriptive error on non-2xx responses", async () => {