Skip to content

fix(tools): ship 12 community fixes as 2.4.0 - #1755

Draft
MaheshtheDev wants to merge 21 commits into
mainfrom
mtd/tools-community-fixes
Draft

MaheshtheDev wants to merge 21 commits into
mainfrom
mtd/tools-community-fixes

Conversation

@MaheshtheDev

@MaheshtheDev MaheshtheDev commented Oct 3, 2026 •

Copy link
Copy Markdown
Member

Bundles 12 community fixes for @supermemory/tools into one release and bumps it to 2.4.0. Each fix keeps its original author.

Heads up: withSupermemory now 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

abhinav7x94 and others added 21 commits October 2, 2026 18:35
…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.
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
`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.
Port contributor tests to the current SDK mocks, keep str_replace new_str required, merge the #1504 scope check with main's multi-tag default, and drop the unrelated image-url change from #1678.
@mintlify

mintlify Bot commented Oct 3, 2026 •

Copy link
Copy Markdown
Contributor

Preview deployment for your docs. Learn more about Mintlify Previews.

Project Status Preview Updated
supermemory 🟢 Ready View Preview Oct 3, 2026, 1:42 AM

💡 Tip: Enable Automations to automatically generate PRs for you.

@MaheshtheDev MaheshtheDev changed the title fix(tools): isolate OpenAI middleware clients fix(tools): ship 12 community fixes as 2.4.0 Oct 3, 2026

Copy link
Copy Markdown
Member Author

How to use the Graphite Merge Queue

Add 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.

@cloudflare-workers-and-pages

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Updated (UTC)
✅ Deployment successful!
View logs
supermemory-mcp 9fd2e98 Oct 03 2026, 01:42 AM

@cloudflare-workers-and-pages

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

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

1 active deployment
staging - apps/docs — 9fd2e989 Deployed Oct 3, 2026 by mintlify[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

9 participants