aboutsummaryrefslogtreecommitdiff
path: root/packages/tools/src
diff options
context:
space:
mode:
Diffstat (limited to 'packages/tools/src')
-rw-r--r--packages/tools/src/ai-sdk.ts44
-rw-r--r--packages/tools/src/index.ts2
-rw-r--r--packages/tools/src/openai.ts104
-rw-r--r--packages/tools/src/shared.ts16
-rw-r--r--packages/tools/src/tools.test.ts232
-rw-r--r--packages/tools/src/types.ts6
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;
}