Summary
In packages/tools/src/vercel/middleware.ts, convertToConversationMessages
(lines 18–76) only maps text and file content parts. Any other part type,
including tool-call (assistant) and tool-result (tool role), hits return null
and is removed by .filter((part) => part !== null).
Because a pure tool-call assistant turn has only tool-call parts, all its parts
become null, contentParts.length is 0, and the entire message is skipped.
The same happens to tool-role messages carrying tool-result.
Result: conversations that use tool calling via the Vercel middleware are saved to
Supermemory with all tool interactions stripped. The tool that was called, its
arguments, and its result are lost from the stored conversation.
Evidence
convertToConversationMessages handles only c.type === "text" and
c.type === "file"; everything else returns null (map at ~line 35–50).
- Searching the vercel folder for
tool-call / tool-result / toolCallId
returns nothing, there is no tool handling at all.
- The OpenAI middleware (
openai/middleware.ts) does preserve tool metadata, so
Vercel-based memories are inconsistent with OpenAI-based ones.
ConversationMessage (conversations-client.ts) already supports
tool_calls?: ToolCall[] and tool_call_id?: string, and the
/v4/conversations endpoint doc states it "supports tool calls and responses",
the receiving side is ready; the Vercel adapter just never sends them.
SDK version
packages/tools/package.json pins ai: ^5.0.29 (AI SDK v5), where tool parts are:
- assistant:
{ type: "tool-call", toolCallId, toolName, input }
- tool:
{ type: "tool-result", toolCallId, toolName, output }
Proposed fix
Extend the content-part mapping in convertToConversationMessages to handle v5
tool parts:
tool-call → append to the message's tool_calls as
{ id: toolCallId, type: "function", function: { name: toolName, arguments: JSON.stringify(input) } }
tool-result → emit a tool-role message with tool_call_id: toolCallId and
the serialized output as content
Happy to submit a PR with unit tests covering a tool-call + tool-result round trip.
Want me to proceed?
Summary
In
packages/tools/src/vercel/middleware.ts,convertToConversationMessages(lines 18–76) only maps
textandfilecontent parts. Any other part type,including
tool-call(assistant) andtool-result(tool role), hitsreturn nulland is removed by
.filter((part) => part !== null).Because a pure tool-call assistant turn has only tool-call parts, all its parts
become
null,contentParts.lengthis0, and the entire message is skipped.The same happens to tool-role messages carrying
tool-result.Result: conversations that use tool calling via the Vercel middleware are saved to
Supermemory with all tool interactions stripped. The tool that was called, its
arguments, and its result are lost from the stored conversation.
Evidence
convertToConversationMessageshandles onlyc.type === "text"andc.type === "file"; everything else returnsnull(map at ~line 35–50).tool-call/tool-result/toolCallIdreturns nothing, there is no tool handling at all.
openai/middleware.ts) does preserve tool metadata, soVercel-based memories are inconsistent with OpenAI-based ones.
ConversationMessage(conversations-client.ts) already supportstool_calls?: ToolCall[]andtool_call_id?: string, and the/v4/conversationsendpoint doc states it "supports tool calls and responses",the receiving side is ready; the Vercel adapter just never sends them.
SDK version
packages/tools/package.jsonpinsai: ^5.0.29(AI SDK v5), where tool parts are:{ type: "tool-call", toolCallId, toolName, input }{ type: "tool-result", toolCallId, toolName, output }Proposed fix
Extend the content-part mapping in
convertToConversationMessagesto handle v5tool parts:
tool-call→ append to the message'stool_callsas{ id: toolCallId, type: "function", function: { name: toolName, arguments: JSON.stringify(input) } }tool-result→ emit atool-role message withtool_call_id: toolCallIdandthe serialized
outputas contentHappy to submit a PR with unit tests covering a tool-call + tool-result round trip.
Want me to proceed?