Repository navigation
fix(tools): ship 12 community fixes as 2.4.0 - #1755
Draft
MaheshtheDev wants to merge 21 commits into
Draft
MaheshtheDev wants to merge 21 commits into
MaheshtheDev wants to merge 21 commits into
Conversation
…ntics Anthropic's memory_20250818 spec defines insert as: insert_text is inserted AFTER line insert_line, 0 inserts at the beginning of the file, and the valid range is [0, n_lines]. The implementation treated insert_line as a 1-based insert-BEFORE index with range [1, n_lines + 1]. Since the caller of this tool is Claude itself, which is trained on the spec semantics, every model-driven insert landed one line earlier than intended, insert_line: 0 (insert at top of file) was rejected as invalid, and insert_line: n_lines (append) inserted before the last line instead of after it. Fix the validation range to [0, n_lines], splice at insert_line directly (0-based insert-after), and update the error and success messages to match. One existing tool-operations test encoded the old insert-before behavior; its insert_line is adjusted so its expected output is unchanged under spec semantics. Adds four regression tests covering top-of-file, middle, append, and both out-of-range directions.
…event path ambiguity
Three places where ClaudeMemoryTool diverges from the documented memory_20250818 wire format: - rename sends old_path/new_path, not path. handleCommand validated command.path, so every rename coming from a real model died with "Cannot read properties of undefined (reading 'startsWith')". path is still accepted as the source for existing callers. - insert_line means "insert after this line" (0 = top of file), but we spliced at insertLine - 1 and rejected 0, so every insert landed one line above where Claude asked and inserting at the top was impossible. - str_replace with new_str omitted is a deletion per the spec; we rejected it. The new tests mock the supermemory client so they run without an API key. Also fixed the rename example in the docs, which showed the same path shape the code expected.
`forgetMemoryRequest` combined the caller's signal and the 30s abort with `??`, making them mutually exclusive. Passing a cancellation signal removed the timeout, so a hung `DELETE /v4/memories` could wedge the tool call again — the exact condition #1451 set out to remove. There was also no way for a caller to ask for both cancellation and a timeout. Compose the two with `AbortSignal.any` instead of choosing between them. `AbortSignal.any` is available in Node 20.3+, Bun and workerd. No production call site passes `options` today (`ai-sdk.ts` and `openai/tools.ts` both omit it), so this was latent rather than live. The existing test asserted the buggy behaviour (`init.signal` being the caller's own signal), so it is replaced by two tests that pin the composed semantics: aborting the caller aborts the request, and the timeout leg still aborts the request on its own. Both fail against the previous implementation. Fixes #1549
Same pattern as forgetMemoryRequest: `options?.signal ?? AbortSignal.timeout(...)` dropped the 30s bound whenever a caller supplied its own signal. Compose the two with AbortSignal.any so the caller signal adds cancellation instead of replacing the timeout.
`supermemoryProfileSearch` in `shared/memory-client.ts` is the only Supermemory HTTP call in this package with neither a request timeout nor redirect handling. The identical `/v4/profile` call in `openai/middleware.ts` sets both, and `/v4/conversations` (`conversations-client.ts`) and `/v4/memories` (`shared/forget-memory.ts`) each set a 30s budget. Two consequences: - **Unbounded request.** A timeout only applied when the caller supplied a signal. `withSupermemory` passes one (5s), but `buildMemoriesText` is called with no signal by the Mastra processor and the VoltAgent middleware, and by the exported `buildMemoriesText` / `addSystemPrompt` helpers. `fetch` has no default deadline, so a stalled connection blocks the agent turn indefinitely — the failure both integrations' surrounding try/catch is written to absorb, but which never surfaces as an error. - **Redirects followed.** The request carries `Authorization: Bearer <apiKey>`; a 3xx from a misconfigured or attacker-influenced `baseUrl` was followed silently rather than refused. Apply a 30s `PROFILE_REQUEST_TIMEOUT_MS` unconditionally and set `redirect: "error"`. A caller signal is composed with the timeout via `AbortSignal.any` rather than replacing it, so a caller-side budget can only shorten the request, never leave it unbounded — the wrapper is kept separate so the composition is stated once rather than re-derived at the call site. `src/shared/memory-client.test.ts` existed but was absent from the `test:unit` file list CI runs, so its assertions never ran on a pull request; add it alongside the new coverage. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01L7GkmUn6skD6dCzKtcHDbe
…ect args
`getProfile`, `documentList` and `memoryForget` all declare `required: []`,
so a model may legitimately call them with no arguments at all. The OpenAI
API serialises that as `arguments: ""`, and `parseToolArguments` handed the
empty string straight to `JSON.parse`, so every no-argument call came back as
{"success":false,"error":"Invalid JSON arguments for getProfile"}
Those three tools were unreachable in their documented no-argument form.
The same gate also lets non-object JSON through. `"null"` parses cleanly and
then rejects in the destructuring parameter of every tool function --
`TypeError: Cannot destructure property 'containerTag' of 'object null'` --
which escapes `executeToolCall`, since it has no catch, and fails the whole
request. That is precisely the throw #1488 added this gate to contain. `"5"`
and `"\"text\""` are quieter but worse: they destructure to `undefined` and
call the API with no container tag at all.
Treat blank arguments as `{}`, and require the parsed value to be a non-null,
non-array object. Malformed JSON still returns the tool error #1488 added.
Adds eight regression tests. Six of them fail against the current
implementation -- two on the blank-argument path and four on the non-object
path, one carrying the raw TypeError. The two guard tests, malformed JSON and
an ordinary well-formed call, pass both before and after, so the behaviour
…l and addConversation
`claude-memory.ts` moved to src/ and five files in test/ kept importing `./claude-memory`; the Mastra and AI-SDK fixtures drifted behind their installed types. Together these left `bunx tsc --noEmit` unusable for the package. - repoint the five `./claude-memory` imports at `../src/claude-memory` - add the `state` property Mastra now requires on ProcessInputArgs and ProcessOutputResultArgs (35 fixtures) - add `totalTokens` to the two LanguageModelV2Usage fixtures and drop the `rawCall` property the type no longer has - iterate with `.entries()` instead of indexing, which was tripping noUncheckedIndexedAccess once the files started resolving - pass containerTag/customId through options in test-supermemory.ts, matching the current `withSupermemory` signature - exclude test/chatapp: a standalone Next.js demo with its own package.json, lockfile and tsconfig that has no business in this package's program Repointing the import also made test/claude-memory.test.ts loadable again, and it turned out to be a live-API suite: gate it behind SUPERMEMORY_API_KEY the same way the other integration suites are, so `vitest run` no longer collects a dozen 401s.
Replace the bare `block.input as MemoryCommand` assertions in the Anthropic example with an isMemoryCommand type guard, so unexpected tool input is skipped instead of silently mistyped.
Contributor
|
Preview deployment for your docs. Learn more about Mintlify Previews.
💡 Tip: Enable Automations to automatically generate PRs for you. |
Member
Author
How to use the Graphite Merge QueueAdd the label Main to this PR to add it to the merge queue. You must have a Graphite account in order to use the merge queue. Sign up using this link. An organization admin has enabled the Graphite Merge Queue in this repository. Please do not merge from GitHub as this will restart CI on PRs being processed by the merge queue. This stack of pull requests is managed by Graphite. Learn more about stacking. |
Deploying with
|
| Status | Name | Latest Commit | Updated (UTC) |
|---|---|---|---|
| ✅ Deployment successful! View logs |
supermemory-mcp | 9fd2e98 | Oct 03 2026, 01:42 AM |
Deploying with
|
| Status | Name | Latest Commit | Preview URL | Updated (UTC) |
|---|---|---|---|---|
| ✅ Deployment successful! View logs |
supermemory-app | 9fd2e98 | Commit Preview URL Branch Preview URL |
Oct 03 2026, 01:42 AM |
This branch was successfully deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

Bundles 12 community fixes for
@supermemory/toolsinto one release and bumps it to2.4.0. Each fix keeps its original author.containerTagmust be in the configured scope), fix(tools): reject parent-directory segments in Claude memory paths #1652 (reject..in Claude memory paths)insertandrename), fix(tools): prevent customId collisions in claude memory tool (#1547) #1676 (collision-free customIds with legacy fallback)/v4/profilerequest), fix(tools): escape delimiters in makeTurnKey to prevent cache collision #1679 (cache key escaping), fix(tools): accept zero-argument OpenAI tool calls and reject non-object args #1612 (zero-arg tool calls), fix(tools): handle trailing slashes and whitespace in normalizeBaseUrl and addConversation #1678 (normalizeBaseUrltrim)packages/tools/testHeads up:
withSupermemorynow returns a new client instead of changing the one passed in.Co-Authored-By: abhinav7x94 204053250+abhinav7x94@users.noreply.github.com
Co-Authored-By: rohitsux 71192000+rohitsux@users.noreply.github.com
Co-Authored-By: aniruddhaadak80 127435065+aniruddhaadak80@users.noreply.github.com
Co-Authored-By: Adityakk9031 143548997+Adityakk9031@users.noreply.github.com
Co-Authored-By: Rikinshah787 87516554+Rikinshah787@users.noreply.github.com
Co-Authored-By: Agnik47 140933190+Agnik47@users.noreply.github.com
Co-Authored-By: therahul-yo 137375203+therahul-yo@users.noreply.github.com
Co-Authored-By: shamAnimates 145093437+shamAnimates@users.noreply.github.com
Co-Authored-By: rajarshidattapy 138959719+rajarshidattapy@users.noreply.github.com