diff options
| author | Dhravya Shah <[email protected]> | 2025-09-18 20:34:18 -0700 |
|---|---|---|
| committer | Dhravya Shah <[email protected]> | 2025-09-18 21:03:49 -0700 |
| commit | 1fcb56908920da386900abb4ce2383374a625c72 (patch) | |
| tree | 0f9d7f695d4c9b1b85be3950fc869e0061dff3ed /packages/tools/src | |
| parent | refetching logic change (diff) | |
| download | supermemory-09-18-formatting.tar.xz supermemory-09-18-formatting.zip | |
formatting09-18-formatting
Diffstat (limited to 'packages/tools/src')
| -rw-r--r-- | packages/tools/src/ai-sdk.ts | 44 | ||||
| -rw-r--r-- | packages/tools/src/index.ts | 2 | ||||
| -rw-r--r-- | packages/tools/src/openai.ts | 104 | ||||
| -rw-r--r-- | packages/tools/src/shared.ts | 16 | ||||
| -rw-r--r-- | packages/tools/src/tools.test.ts | 232 | ||||
| -rw-r--r-- | packages/tools/src/types.ts | 6 |
6 files changed, 204 insertions, 200 deletions
diff --git a/packages/tools/src/ai-sdk.ts b/packages/tools/src/ai-sdk.ts index 703175e7..37f346c2 100644 --- a/packages/tools/src/ai-sdk.ts +++ b/packages/tools/src/ai-sdk.ts @@ -1,13 +1,13 @@ -import Supermemory from "supermemory" -import { tool } from "ai" -import { z } from "zod" +import { tool } from "ai"; +import Supermemory from "supermemory"; +import { z } from "zod"; import { DEFAULT_VALUES, + getContainerTags, PARAMETER_DESCRIPTIONS, TOOL_DESCRIPTIONS, - getContainerTags, -} from "./shared" -import type { SupermemoryToolsConfig } from "./types" +} from "./shared"; +import type { SupermemoryToolsConfig } from "./types"; // Export individual tool creators export const searchMemoriesTool = ( @@ -17,9 +17,9 @@ export const searchMemoriesTool = ( const client = new Supermemory({ apiKey, ...(config?.baseUrl ? { baseURL: config.baseUrl } : {}), - }) + }); - const containerTags = getContainerTags(config) + const containerTags = getContainerTags(config); return tool({ description: TOOL_DESCRIPTIONS.searchMemories, @@ -50,22 +50,22 @@ export const searchMemoriesTool = ( 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, @@ -74,9 +74,9 @@ export const addMemoryTool = ( const client = new Supermemory({ apiKey, ...(config?.baseUrl ? { baseURL: config.baseUrl } : {}), - }) + }); - const containerTags = getContainerTags(config) + const containerTags = getContainerTags(config); return tool({ description: TOOL_DESCRIPTIONS.addMemory, @@ -85,27 +85,27 @@ export const addMemoryTool = ( }), execute: async ({ memory }) => { try { - const metadata: Record<string, string | number | boolean> = {} + const metadata: Record<string, string | number | boolean> = {}; const response = await client.memories.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", - } + }; } }, - }) -} + }); +}; /** * Create Supermemory tools for AI SDK @@ -117,5 +117,5 @@ export function supermemoryTools( return { searchMemories: searchMemoriesTool(apiKey, config), addMemory: addMemoryTool(apiKey, config), - } + }; } diff --git a/packages/tools/src/index.ts b/packages/tools/src/index.ts index 4f21246e..588a4fb3 100644 --- a/packages/tools/src/index.ts +++ b/packages/tools/src/index.ts @@ -1,2 +1,2 @@ // Export shared types and utilities -export type { SupermemoryToolsConfig } from "./types" +export type { SupermemoryToolsConfig } from "./types"; diff --git a/packages/tools/src/openai.ts b/packages/tools/src/openai.ts index 5c79a9c1..197a5829 100644 --- a/packages/tools/src/openai.ts +++ b/packages/tools/src/openai.ts @@ -1,27 +1,27 @@ -import type OpenAI from "openai" -import Supermemory from "supermemory" +import type OpenAI from "openai"; +import Supermemory from "supermemory"; import { DEFAULT_VALUES, + getContainerTags, PARAMETER_DESCRIPTIONS, TOOL_DESCRIPTIONS, - getContainerTags, -} from "./shared" -import type { SupermemoryToolsConfig } from "./types" +} from "./shared"; +import type { SupermemoryToolsConfig } from "./types"; /** * Result types for memory operations */ export interface MemorySearchResult { - success: boolean - results?: Awaited<ReturnType<Supermemory["search"]["execute"]>>["results"] - count?: number - error?: string + success: boolean; + results?: Awaited<ReturnType<Supermemory["search"]["execute"]>>["results"]; + count?: number; + error?: string; } export interface MemoryAddResult { - success: boolean - memory?: Awaited<ReturnType<Supermemory["memories"]["add"]>> - error?: string + success: boolean; + memory?: Awaited<ReturnType<Supermemory["memories"]["add"]>>; + error?: string; } /** @@ -67,7 +67,7 @@ export const memoryToolSchemas = { required: ["memory"], }, } satisfies OpenAI.FunctionDefinition, -} as const +} as const; /** * Create a Supermemory client with configuration @@ -76,11 +76,11 @@ function createClient(apiKey: string, config?: SupermemoryToolsConfig) { const client = new Supermemory({ apiKey, ...(config?.baseUrl && { baseURL: config.baseUrl }), - }) + }); - const containerTags = getContainerTags(config) + const containerTags = getContainerTags(config); - return { client, containerTags } + return { client, containerTags }; } /** @@ -90,16 +90,16 @@ export function createSearchMemoriesFunction( apiKey: string, config?: SupermemoryToolsConfig, ) { - const { client, containerTags } = createClient(apiKey, config) + const { client, containerTags } = createClient(apiKey, config); return async function searchMemories({ informationToGet, includeFullDocs = DEFAULT_VALUES.includeFullDocs, limit = DEFAULT_VALUES.limit, }: { - informationToGet: string - includeFullDocs?: boolean - limit?: number + informationToGet: string; + includeFullDocs?: boolean; + limit?: number; }): Promise<MemorySearchResult> { try { const response = await client.search.execute({ @@ -108,20 +108,20 @@ export function createSearchMemoriesFunction( 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", - } + }; } - } + }; } /** @@ -131,33 +131,33 @@ export function createAddMemoryFunction( apiKey: string, config?: SupermemoryToolsConfig, ) { - const { client, containerTags } = createClient(apiKey, config) + const { client, containerTags } = createClient(apiKey, config); return async function addMemory({ memory, }: { - memory: string + memory: string; }): Promise<MemoryAddResult> { try { - const metadata: Record<string, string | number | boolean> = {} + const metadata: Record<string, string | number | boolean> = {}; const response = await client.memories.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", - } + }; } - } + }; } /** @@ -167,13 +167,13 @@ export function supermemoryTools( apiKey: string, config?: SupermemoryToolsConfig, ) { - const searchMemories = createSearchMemoriesFunction(apiKey, config) - const addMemory = createAddMemoryFunction(apiKey, config) + const searchMemories = createSearchMemoriesFunction(apiKey, config); + const addMemory = createAddMemoryFunction(apiKey, config); return { searchMemories, addMemory, - } + }; } /** @@ -183,7 +183,7 @@ export function getToolDefinitions(): OpenAI.Chat.Completions.ChatCompletionTool return [ { type: "function", function: memoryToolSchemas.searchMemories }, { type: "function", function: memoryToolSchemas.addMemory }, - ] + ]; } /** @@ -193,26 +193,26 @@ export function createToolCallExecutor( apiKey: string, config?: SupermemoryToolsConfig, ) { - const tools = supermemoryTools(apiKey, config) + const tools = supermemoryTools(apiKey, config); return async function executeToolCall( toolCall: OpenAI.Chat.Completions.ChatCompletionMessageToolCall, ): Promise<string> { - const functionName = toolCall.function.name - const args = JSON.parse(toolCall.function.arguments) + const functionName = toolCall.function.name; + const args = JSON.parse(toolCall.function.arguments); switch (functionName) { case "searchMemories": - return JSON.stringify(await tools.searchMemories(args)) + return JSON.stringify(await tools.searchMemories(args)); case "addMemory": - return JSON.stringify(await tools.addMemory(args)) + return JSON.stringify(await tools.addMemory(args)); default: return JSON.stringify({ success: false, error: `Unknown function: ${functionName}`, - }) + }); } - } + }; } /** @@ -222,24 +222,24 @@ export function createToolCallsExecutor( apiKey: string, config?: SupermemoryToolsConfig, ) { - const executeToolCall = createToolCallExecutor(apiKey, config) + const executeToolCall = createToolCallExecutor(apiKey, config); return async function executeToolCalls( toolCalls: OpenAI.Chat.Completions.ChatCompletionMessageToolCall[], ): Promise<OpenAI.Chat.Completions.ChatCompletionToolMessageParam[]> { const results = await Promise.all( toolCalls.map(async (toolCall) => { - const result = await executeToolCall(toolCall) + const result = await executeToolCall(toolCall); return { tool_call_id: toolCall.id, role: "tool" as const, content: result, - } + }; }), - ) + ); - return results - } + return results; + }; } /** @@ -249,7 +249,7 @@ export function createSearchMemoriesTool( apiKey: string, config?: SupermemoryToolsConfig, ) { - const searchMemories = createSearchMemoriesFunction(apiKey, config) + const searchMemories = createSearchMemoriesFunction(apiKey, config); return { definition: { @@ -257,14 +257,14 @@ export function createSearchMemoriesTool( function: memoryToolSchemas.searchMemories, }, execute: searchMemories, - } + }; } export function createAddMemoryTool( apiKey: string, config?: SupermemoryToolsConfig, ) { - const addMemory = createAddMemoryFunction(apiKey, config) + const addMemory = createAddMemoryFunction(apiKey, config); return { definition: { @@ -272,5 +272,5 @@ export function createAddMemoryTool( function: memoryToolSchemas.addMemory, }, execute: addMemory, - } + }; } diff --git a/packages/tools/src/shared.ts b/packages/tools/src/shared.ts index 0ff14e86..ffe07a11 100644 --- a/packages/tools/src/shared.ts +++ b/packages/tools/src/shared.ts @@ -8,7 +8,7 @@ export const TOOL_DESCRIPTIONS = { "Search (recall) memories/details/information about the user or other facts or entities. Run when explicitly asked or when context about user's past choices would be helpful.", addMemory: "Add (remember) memories/details/information about the user or other facts or entities. Run when explicitly asked or when the user mentions any information generalizable beyond the context of the current conversation.", -} as const +} as const; // Parameter descriptions export const PARAMETER_DESCRIPTIONS = { @@ -18,30 +18,30 @@ export const PARAMETER_DESCRIPTIONS = { limit: "Maximum number of results to return", memory: "The text content of the memory to add. This should be a single sentence or a short paragraph.", -} as const +} as const; // Default values export const DEFAULT_VALUES = { includeFullDocs: true, limit: 10, chunkThreshold: 0.6, -} as const +} as const; // Container tag constants export const CONTAINER_TAG_CONSTANTS = { projectPrefix: "sm_project_", defaultTags: ["sm_project_default"] as string[], -} as const +} as const; /** * Helper function to generate container tags based on config */ export function getContainerTags(config?: { - projectId?: string - containerTags?: string[] + projectId?: string; + containerTags?: string[]; }): string[] { if (config?.projectId) { - return [`${CONTAINER_TAG_CONSTANTS.projectPrefix}${config.projectId}`] + return [`${CONTAINER_TAG_CONSTANTS.projectPrefix}${config.projectId}`]; } - return config?.containerTags ?? CONTAINER_TAG_CONSTANTS.defaultTags + return config?.containerTags ?? CONTAINER_TAG_CONSTANTS.defaultTags; } diff --git a/packages/tools/src/tools.test.ts b/packages/tools/src/tools.test.ts index 5cde729d..bcff0f35 100644 --- a/packages/tools/src/tools.test.ts +++ b/packages/tools/src/tools.test.ts @@ -1,70 +1,72 @@ -import { createOpenAI } from "@ai-sdk/openai" -import { generateText } from "ai" -import { describe, expect, it } from "vitest" -import * as aiSdk from "./ai-sdk" -import * as openAi from "./openai" -import type { SupermemoryToolsConfig } from "./types" +import { createOpenAI } from "@ai-sdk/openai"; +import { generateText } from "ai"; +import { describe, expect, it } from "vitest"; +import * as aiSdk from "./ai-sdk"; +import * as openAi from "./openai"; +import type { SupermemoryToolsConfig } from "./types"; -import "dotenv/config" +import "dotenv/config"; describe("@supermemory/tools", () => { // Required API keys - tests will fail if not provided - const testApiKey = process.env.SUPERMEMORY_API_KEY - const testOpenAIKey = process.env.OPENAI_API_KEY + const testApiKey = process.env.SUPERMEMORY_API_KEY; + const testOpenAIKey = process.env.OPENAI_API_KEY; if (!testApiKey) { throw new Error( "SUPERMEMORY_API_KEY environment variable is required for tests", - ) + ); } if (!testOpenAIKey) { - throw new Error("OPENAI_API_KEY environment variable is required for tests") + throw new Error( + "OPENAI_API_KEY environment variable is required for tests", + ); } // Optional configuration with defaults - const testBaseUrl = process.env.SUPERMEMORY_BASE_URL ?? undefined - const testModelName = process.env.MODEL_NAME || "gpt-4o-mini" + const testBaseUrl = process.env.SUPERMEMORY_BASE_URL ?? undefined; + const testModelName = process.env.MODEL_NAME || "gpt-4o-mini"; describe("aiSdk module", () => { describe("client initialization", () => { it("should create tools with default configuration", () => { - const config: SupermemoryToolsConfig = {} - const tools = aiSdk.supermemoryTools(testApiKey, config) + const config: SupermemoryToolsConfig = {}; + const tools = aiSdk.supermemoryTools(testApiKey, config); - expect(tools).toBeDefined() - expect(tools.searchMemories).toBeDefined() - expect(tools.addMemory).toBeDefined() - }) + expect(tools).toBeDefined(); + expect(tools.searchMemories).toBeDefined(); + expect(tools.addMemory).toBeDefined(); + }); it("should create tools with custom baseUrl", () => { const config: SupermemoryToolsConfig = { baseUrl: testBaseUrl, - } - const tools = aiSdk.supermemoryTools(testApiKey, config) + }; + const tools = aiSdk.supermemoryTools(testApiKey, config); - expect(tools).toBeDefined() - expect(tools.searchMemories).toBeDefined() - expect(tools.addMemory).toBeDefined() - }) + expect(tools).toBeDefined(); + expect(tools.searchMemories).toBeDefined(); + expect(tools.addMemory).toBeDefined(); + }); it("should create individual tools", () => { const searchTool = aiSdk.searchMemoriesTool(testApiKey, { projectId: "test-project-123", - }) + }); const addTool = aiSdk.addMemoryTool(testApiKey, { projectId: "test-project-123", - }) + }); - expect(searchTool).toBeDefined() - expect(addTool).toBeDefined() - }) - }) + expect(searchTool).toBeDefined(); + expect(addTool).toBeDefined(); + }); + }); describe("AI SDK integration", () => { it("should work with AI SDK generateText", async () => { const openai = createOpenAI({ apiKey: testOpenAIKey, - }) + }); const result = await generateText({ model: openai(testModelName), @@ -85,22 +87,22 @@ describe("@supermemory/tools", () => { baseUrl: testBaseUrl, }), }, - }) + }); - expect(result).toBeDefined() - expect(result.text).toBeDefined() - expect(typeof result.text).toBe("string") - }) + expect(result).toBeDefined(); + expect(result.text).toBeDefined(); + expect(typeof result.text).toBe("string"); + }); it("should use tools when prompted", async () => { const openai = createOpenAI({ apiKey: testOpenAIKey, - }) + }); const tools = aiSdk.supermemoryTools(testApiKey, { projectId: "test-tool-usage", baseUrl: testBaseUrl, - }) + }); const result = await generateText({ model: openai(testModelName), @@ -118,157 +120,159 @@ describe("@supermemory/tools", () => { tools: { addMemory: tools.addMemory, }, - }) + }); - expect(result).toBeDefined() - expect(result.text).toBeDefined() - }) - }) - }) + expect(result).toBeDefined(); + expect(result.text).toBeDefined(); + }); + }); + }); describe("openAi module", () => { describe("function-based tools", () => { it("should create function-based tools", () => { const tools = openAi.supermemoryTools(testApiKey, { projectId: "test-openai-functions", - }) + }); - expect(tools).toBeDefined() - expect(tools.searchMemories).toBeDefined() - expect(tools.addMemory).toBeDefined() - }) + expect(tools).toBeDefined(); + expect(tools.searchMemories).toBeDefined(); + expect(tools.addMemory).toBeDefined(); + }); it("should create individual tool functions", () => { const searchFunction = openAi.createSearchMemoriesFunction(testApiKey, { projectId: "test-individual", - }) + }); const addFunction = openAi.createAddMemoryFunction(testApiKey, { projectId: "test-individual", - }) + }); - expect(searchFunction).toBeDefined() - expect(addFunction).toBeDefined() - expect(typeof searchFunction).toBe("function") - expect(typeof addFunction).toBe("function") - }) - }) + expect(searchFunction).toBeDefined(); + expect(addFunction).toBeDefined(); + expect(typeof searchFunction).toBe("function"); + expect(typeof addFunction).toBe("function"); + }); + }); describe("tool definitions", () => { it("should return proper OpenAI function definitions", () => { - const definitions = openAi.getToolDefinitions() + const definitions = openAi.getToolDefinitions(); - expect(definitions).toBeDefined() - expect(definitions.length).toBe(2) + expect(definitions).toBeDefined(); + expect(definitions.length).toBe(2); // Check searchMemories const searchTool = definitions.find( (d) => d.function.name === "searchMemories", - ) - expect(searchTool).toBeDefined() - expect(searchTool!.type).toBe("function") + ); + expect(searchTool).toBeDefined(); + expect(searchTool!.type).toBe("function"); expect(searchTool!.function.parameters?.required).toContain( "informationToGet", - ) + ); // Check addMemory - const addTool = definitions.find((d) => d.function.name === "addMemory") - expect(addTool).toBeDefined() - expect(addTool!.type).toBe("function") - expect(addTool!.function.parameters?.required).toContain("memory") - }) - }) + const addTool = definitions.find( + (d) => d.function.name === "addMemory", + ); + expect(addTool).toBeDefined(); + expect(addTool!.type).toBe("function"); + expect(addTool!.function.parameters?.required).toContain("memory"); + }); + }); describe("tool execution", () => { it("should create tool call executor", () => { const executor = openAi.createToolCallExecutor(testApiKey, { containerTags: ["test-executor"], baseUrl: testBaseUrl, - }) + }); - expect(executor).toBeDefined() - expect(typeof executor).toBe("function") - }) + expect(executor).toBeDefined(); + expect(typeof executor).toBe("function"); + }); it("should create tool calls executor", () => { const executor = openAi.createToolCallsExecutor(testApiKey, { containerTags: ["test-executors"], baseUrl: testBaseUrl, - }) + }); - expect(executor).toBeDefined() - expect(typeof executor).toBe("function") - }) - }) + expect(executor).toBeDefined(); + expect(typeof executor).toBe("function"); + }); + }); describe("individual tool creators", () => { it("should create individual search tool", () => { const searchTool = openAi.createSearchMemoriesTool(testApiKey, { projectId: "test-individual", - }) + }); - expect(searchTool).toBeDefined() - expect(searchTool.definition).toBeDefined() - expect(searchTool.execute).toBeDefined() - expect(searchTool.definition.function.name).toBe("searchMemories") - }) + expect(searchTool).toBeDefined(); + expect(searchTool.definition).toBeDefined(); + expect(searchTool.execute).toBeDefined(); + expect(searchTool.definition.function.name).toBe("searchMemories"); + }); it("should create individual add tool", () => { const addTool = openAi.createAddMemoryTool(testApiKey, { projectId: "test-individual", - }) + }); - expect(addTool).toBeDefined() - expect(addTool.definition).toBeDefined() - expect(addTool.execute).toBeDefined() - expect(addTool.definition.function.name).toBe("addMemory") - }) - }) + expect(addTool).toBeDefined(); + expect(addTool.definition).toBeDefined(); + expect(addTool.execute).toBeDefined(); + expect(addTool.definition.function.name).toBe("addMemory"); + }); + }); describe("memory operations", () => { it("should search memories", async () => { const searchFunction = openAi.createSearchMemoriesFunction(testApiKey, { projectId: "test-search", baseUrl: testBaseUrl, - }) + }); const result = await searchFunction({ informationToGet: "test preferences", limit: 5, - }) + }); - expect(result).toBeDefined() - expect(result.success).toBeDefined() - expect(typeof result.success).toBe("boolean") + expect(result).toBeDefined(); + expect(result.success).toBeDefined(); + expect(typeof result.success).toBe("boolean"); if (result.success) { - expect(result.results).toBeDefined() - expect(result.count).toBeDefined() - expect(typeof result.count).toBe("number") + expect(result.results).toBeDefined(); + expect(result.count).toBeDefined(); + expect(typeof result.count).toBe("number"); } else { - expect(result.error).toBeDefined() + expect(result.error).toBeDefined(); } - }) + }); it("should add memory", async () => { const addFunction = openAi.createAddMemoryFunction(testApiKey, { containerTags: ["test-add-memory"], baseUrl: testBaseUrl, - }) + }); const result = await addFunction({ memory: "User prefers dark roast coffee in the morning - test memory", - }) + }); - expect(result).toBeDefined() - expect(result.success).toBeDefined() - expect(typeof result.success).toBe("boolean") + expect(result).toBeDefined(); + expect(result.success).toBeDefined(); + expect(typeof result.success).toBe("boolean"); if (result.success) { - expect(result.memory).toBeDefined() + expect(result.memory).toBeDefined(); } else { - expect(result.error).toBeDefined() + expect(result.error).toBeDefined(); } - }) - }) - }) -}) + }); + }); + }); +}); diff --git a/packages/tools/src/types.ts b/packages/tools/src/types.ts index dfff0f00..86c7fc16 100644 --- a/packages/tools/src/types.ts +++ b/packages/tools/src/types.ts @@ -3,7 +3,7 @@ * Only one of `projectId` or `containerTags` can be provided. */ export interface SupermemoryToolsConfig { - baseUrl?: string - containerTags?: string[] - projectId?: string + baseUrl?: string; + containerTags?: string[]; + projectId?: string; } |