mirror of
https://github.com/supermemoryai/supermemory.git
synced 2026-09-10 22:41:17 +00:00
Some checks failed
Publish Tools / publish (push) Has been cancelled
Cherry-picks four contributor PRs for `@supermemory/tools` onto one branch, and bumps the package to 2.2.0. - #1244 (@rajarshidattapy): `withSupermemory` accepts `options.apiKey` instead of only reading `SUPERMEMORY_API_KEY`, matching the Vercel, Mastra and Voltagent integrations. Unblocks secrets managers, edge runtimes and per-request keys. - #1574 (@Agnik47): re-exports `PromptTemplate`, `MemoryPromptData` and `WithSupermemoryOptions` from `ai-sdk`. `./vercel` is not a published subpath, so the documented custom-template example did not compile. - #1488 (@abhinav7x94): malformed tool-call JSON returns an error result instead of throwing out of the request. - #1507 (@abhinav7x94): VoltAgent `onEnd` awaits the conversation save, which was fire-and-forget and could be dropped when a serverless runtime tore down. Dropped the `middleware.test.ts` added by #1244. Note that editing `packages/tools/package.json` triggers the npm publish workflow on merge. Co-Authored-By: rajarshidattapy <138959719+rajarshidattapy@users.noreply.github.com> Co-Authored-By: Agnik47 <140933190+Agnik47@users.noreply.github.com> Co-Authored-By: abhinav7x94 <204053250+abhinav7x94@users.noreply.github.com>
381 lines
9.1 KiB
TypeScript
381 lines
9.1 KiB
TypeScript
import Supermemory from "supermemory"
|
|
import { tool } from "ai"
|
|
import { z } from "zod"
|
|
import {
|
|
DEFAULT_VALUES,
|
|
PARAMETER_DESCRIPTIONS,
|
|
TOOL_DESCRIPTIONS,
|
|
getContainerTags,
|
|
} from "./tools-shared"
|
|
import { forgetMemoryRequest } from "./shared/forget-memory"
|
|
import type { SupermemoryToolsConfig } from "./types"
|
|
|
|
// Export individual tool creators
|
|
export const searchMemoriesTool = (
|
|
apiKey: string,
|
|
config?: SupermemoryToolsConfig,
|
|
) => {
|
|
const client = new Supermemory({
|
|
apiKey,
|
|
...(config?.baseUrl ? { baseURL: config.baseUrl } : {}),
|
|
})
|
|
|
|
const containerTags = getContainerTags(config)
|
|
const strict = config?.strict ?? false
|
|
|
|
return tool({
|
|
description: TOOL_DESCRIPTIONS.searchMemories,
|
|
inputSchema: z.object({
|
|
informationToGet: z
|
|
.string()
|
|
.describe(PARAMETER_DESCRIPTIONS.informationToGet),
|
|
includeFullDocs: strict
|
|
? z
|
|
.boolean()
|
|
.default(DEFAULT_VALUES.includeFullDocs)
|
|
.describe(PARAMETER_DESCRIPTIONS.includeFullDocs)
|
|
: z
|
|
.boolean()
|
|
.optional()
|
|
.default(DEFAULT_VALUES.includeFullDocs)
|
|
.describe(PARAMETER_DESCRIPTIONS.includeFullDocs),
|
|
limit: strict
|
|
? z.coerce
|
|
.number()
|
|
.default(DEFAULT_VALUES.limit)
|
|
.describe(PARAMETER_DESCRIPTIONS.limit)
|
|
: z.coerce
|
|
.number()
|
|
.optional()
|
|
.default(DEFAULT_VALUES.limit)
|
|
.describe(PARAMETER_DESCRIPTIONS.limit),
|
|
}),
|
|
execute: async ({
|
|
informationToGet,
|
|
includeFullDocs = DEFAULT_VALUES.includeFullDocs,
|
|
limit = DEFAULT_VALUES.limit,
|
|
}) => {
|
|
try {
|
|
const response = await client.search.execute({
|
|
q: informationToGet,
|
|
containerTags,
|
|
limit,
|
|
chunkThreshold: DEFAULT_VALUES.chunkThreshold,
|
|
includeFullDocs,
|
|
})
|
|
|
|
return {
|
|
success: true,
|
|
results: response.results,
|
|
count: response.results?.length || 0,
|
|
}
|
|
} catch (error) {
|
|
return {
|
|
success: false,
|
|
error: error instanceof Error ? error.message : "Unknown error",
|
|
}
|
|
}
|
|
},
|
|
})
|
|
}
|
|
|
|
export const addMemoryTool = (
|
|
apiKey: string,
|
|
config?: SupermemoryToolsConfig,
|
|
) => {
|
|
const client = new Supermemory({
|
|
apiKey,
|
|
...(config?.baseUrl ? { baseURL: config.baseUrl } : {}),
|
|
})
|
|
|
|
const containerTags = getContainerTags(config)
|
|
|
|
return tool({
|
|
description: TOOL_DESCRIPTIONS.addMemory,
|
|
inputSchema: z.object({
|
|
memory: z.string().describe(PARAMETER_DESCRIPTIONS.memory),
|
|
}),
|
|
execute: async ({ memory }) => {
|
|
try {
|
|
const metadata: Record<string, string | number | boolean> = {}
|
|
|
|
const response = await client.add({
|
|
content: memory,
|
|
containerTags,
|
|
...(Object.keys(metadata).length > 0 && { metadata }),
|
|
})
|
|
|
|
return {
|
|
success: true,
|
|
memory: response,
|
|
}
|
|
} catch (error) {
|
|
return {
|
|
success: false,
|
|
error: error instanceof Error ? error.message : "Unknown error",
|
|
}
|
|
}
|
|
},
|
|
})
|
|
}
|
|
|
|
export const getProfileTool = (
|
|
apiKey: string,
|
|
config?: SupermemoryToolsConfig,
|
|
) => {
|
|
const client = new Supermemory({
|
|
apiKey,
|
|
...(config?.baseUrl ? { baseURL: config.baseUrl } : {}),
|
|
})
|
|
|
|
const containerTags = getContainerTags(config)
|
|
const strict = config?.strict ?? false
|
|
|
|
return tool({
|
|
description: TOOL_DESCRIPTIONS.getProfile,
|
|
inputSchema: z.object({
|
|
containerTag: strict
|
|
? z.string().describe(PARAMETER_DESCRIPTIONS.containerTag)
|
|
: z.string().optional().describe(PARAMETER_DESCRIPTIONS.containerTag),
|
|
query: z.string().optional().describe(PARAMETER_DESCRIPTIONS.query),
|
|
}),
|
|
execute: async ({ containerTag, query }) => {
|
|
try {
|
|
const tag = containerTag || containerTags[0]
|
|
|
|
const response = await client.profile({
|
|
containerTag: tag,
|
|
...(query && { q: query }),
|
|
})
|
|
|
|
return {
|
|
success: true,
|
|
profile: response.profile,
|
|
searchResults: response.searchResults,
|
|
}
|
|
} catch (error) {
|
|
return {
|
|
success: false,
|
|
error: error instanceof Error ? error.message : "Unknown error",
|
|
}
|
|
}
|
|
},
|
|
})
|
|
}
|
|
|
|
export const documentListTool = (
|
|
apiKey: string,
|
|
config?: SupermemoryToolsConfig,
|
|
) => {
|
|
const client = new Supermemory({
|
|
apiKey,
|
|
...(config?.baseUrl ? { baseURL: config.baseUrl } : {}),
|
|
})
|
|
|
|
const containerTags = getContainerTags(config)
|
|
const strict = config?.strict ?? false
|
|
|
|
return tool({
|
|
description: TOOL_DESCRIPTIONS.documentList,
|
|
inputSchema: z.object({
|
|
containerTag: z
|
|
.string()
|
|
.optional()
|
|
.describe(PARAMETER_DESCRIPTIONS.containerTag),
|
|
limit: strict
|
|
? z.coerce
|
|
.number()
|
|
.default(DEFAULT_VALUES.limit)
|
|
.describe(PARAMETER_DESCRIPTIONS.limit)
|
|
: z.coerce
|
|
.number()
|
|
.optional()
|
|
.default(DEFAULT_VALUES.limit)
|
|
.describe(PARAMETER_DESCRIPTIONS.limit),
|
|
page: z.coerce.number().optional().describe(PARAMETER_DESCRIPTIONS.page),
|
|
}),
|
|
execute: async ({ containerTag, limit, page }) => {
|
|
try {
|
|
const tag = containerTag || containerTags[0]
|
|
|
|
const response = await client.documents.list({
|
|
containerTags: [tag],
|
|
limit: limit || DEFAULT_VALUES.limit,
|
|
...(page !== undefined && { page }),
|
|
})
|
|
|
|
return {
|
|
success: true,
|
|
documents: response.memories,
|
|
pagination: response.pagination,
|
|
}
|
|
} catch (error) {
|
|
return {
|
|
success: false,
|
|
error: error instanceof Error ? error.message : "Unknown error",
|
|
}
|
|
}
|
|
},
|
|
})
|
|
}
|
|
|
|
export const documentDeleteTool = (
|
|
apiKey: string,
|
|
config?: SupermemoryToolsConfig,
|
|
) => {
|
|
const client = new Supermemory({
|
|
apiKey,
|
|
...(config?.baseUrl ? { baseURL: config.baseUrl } : {}),
|
|
})
|
|
|
|
return tool({
|
|
description: TOOL_DESCRIPTIONS.documentDelete,
|
|
inputSchema: z.object({
|
|
documentId: z.string().describe(PARAMETER_DESCRIPTIONS.documentId),
|
|
}),
|
|
execute: async ({ documentId }) => {
|
|
try {
|
|
await client.documents.delete(documentId)
|
|
|
|
return {
|
|
success: true,
|
|
message: `Document ${documentId} deleted successfully`,
|
|
}
|
|
} catch (error) {
|
|
return {
|
|
success: false,
|
|
error: error instanceof Error ? error.message : "Unknown error",
|
|
}
|
|
}
|
|
},
|
|
})
|
|
}
|
|
|
|
export const documentAddTool = (
|
|
apiKey: string,
|
|
config?: SupermemoryToolsConfig,
|
|
) => {
|
|
const client = new Supermemory({
|
|
apiKey,
|
|
...(config?.baseUrl ? { baseURL: config.baseUrl } : {}),
|
|
})
|
|
|
|
const containerTags = getContainerTags(config)
|
|
|
|
return tool({
|
|
description: TOOL_DESCRIPTIONS.documentAdd,
|
|
inputSchema: z.object({
|
|
content: z.string().describe(PARAMETER_DESCRIPTIONS.content),
|
|
title: z.string().optional().describe(PARAMETER_DESCRIPTIONS.title),
|
|
description: z
|
|
.string()
|
|
.optional()
|
|
.describe(PARAMETER_DESCRIPTIONS.description),
|
|
}),
|
|
execute: async ({ content, title, description }) => {
|
|
try {
|
|
const metadata: Record<string, string> = {}
|
|
if (title) metadata.title = title
|
|
if (description) metadata.description = description
|
|
|
|
const response = await client.documents.add({
|
|
content,
|
|
containerTags,
|
|
...(Object.keys(metadata).length > 0 && { metadata }),
|
|
})
|
|
|
|
return {
|
|
success: true,
|
|
document: response,
|
|
}
|
|
} catch (error) {
|
|
return {
|
|
success: false,
|
|
error: error instanceof Error ? error.message : "Unknown error",
|
|
}
|
|
}
|
|
},
|
|
})
|
|
}
|
|
|
|
export const memoryForgetTool = (
|
|
apiKey: string,
|
|
config?: SupermemoryToolsConfig,
|
|
) => {
|
|
const containerTags = getContainerTags(config)
|
|
|
|
return tool({
|
|
description: TOOL_DESCRIPTIONS.memoryForget,
|
|
inputSchema: z.object({
|
|
containerTag: z
|
|
.string()
|
|
.optional()
|
|
.describe(PARAMETER_DESCRIPTIONS.containerTag),
|
|
memoryId: z.string().optional().describe(PARAMETER_DESCRIPTIONS.memoryId),
|
|
memoryContent: z
|
|
.string()
|
|
.optional()
|
|
.describe(PARAMETER_DESCRIPTIONS.memoryContent),
|
|
reason: z.string().optional().describe(PARAMETER_DESCRIPTIONS.reason),
|
|
}),
|
|
execute: async ({ containerTag, memoryId, memoryContent, reason }) => {
|
|
try {
|
|
if (!memoryId && !memoryContent) {
|
|
return {
|
|
success: false,
|
|
error: "Either memoryId or memoryContent must be provided",
|
|
}
|
|
}
|
|
|
|
const tag = containerTag || containerTags[0]
|
|
|
|
await forgetMemoryRequest(
|
|
apiKey,
|
|
{
|
|
containerTag: tag as string,
|
|
...(memoryId && { id: memoryId }),
|
|
...(memoryContent && { content: memoryContent }),
|
|
...(reason && { reason }),
|
|
},
|
|
config?.baseUrl,
|
|
)
|
|
|
|
return {
|
|
success: true,
|
|
message: "Memory forgotten successfully",
|
|
}
|
|
} catch (error) {
|
|
return {
|
|
success: false,
|
|
error: error instanceof Error ? error.message : "Unknown error",
|
|
}
|
|
}
|
|
},
|
|
})
|
|
}
|
|
|
|
/**
|
|
* Create Supermemory tools for AI SDK
|
|
*/
|
|
export function supermemoryTools(
|
|
apiKey: string,
|
|
config?: SupermemoryToolsConfig,
|
|
) {
|
|
return {
|
|
searchMemories: searchMemoriesTool(apiKey, config),
|
|
addMemory: addMemoryTool(apiKey, config),
|
|
getProfile: getProfileTool(apiKey, config),
|
|
documentList: documentListTool(apiKey, config),
|
|
documentDelete: documentDeleteTool(apiKey, config),
|
|
documentAdd: documentAddTool(apiKey, config),
|
|
memoryForget: memoryForgetTool(apiKey, config),
|
|
}
|
|
}
|
|
|
|
// `./vercel` is not a published subpath, so this is the only way consumers reach the middleware types.
|
|
export {
|
|
withSupermemory,
|
|
type WithSupermemoryOptions,
|
|
type PromptTemplate,
|
|
type MemoryPromptData,
|
|
} from "./vercel"
|