diff options
Diffstat (limited to 'packages/tools/test/vercel.test.ts')
| -rw-r--r-- | packages/tools/test/vercel.test.ts | 549 |
1 files changed, 0 insertions, 549 deletions
diff --git a/packages/tools/test/vercel.test.ts b/packages/tools/test/vercel.test.ts deleted file mode 100644 index 32197977..00000000 --- a/packages/tools/test/vercel.test.ts +++ /dev/null @@ -1,549 +0,0 @@ -import { describe, it, expect, beforeEach, vi, afterEach } from "vitest" -import { withSupermemory } from "../src/vercel" -import { createSupermemoryMiddleware } from "../src/vercel/middleware" -import type { - LanguageModelV2, - LanguageModelV2CallOptions, -} from "@ai-sdk/provider" -import Supermemory from "supermemory" -import "dotenv/config" - -// Test configuration -const TEST_CONFIG = { - apiKey: process.env.SUPERMEMORY_API_KEY || "test-api-key", - baseURL: process.env.SUPERMEMORY_BASE_URL, - containerTag: "test-vercel-wrapper", -} - -// Mock language model for testing -const createMockLanguageModel = (): LanguageModelV2 => ({ - specificationVersion: "v2", - provider: "test-provider", - modelId: "test-model", - supportedUrls: {}, - doGenerate: vi.fn(), - doStream: vi.fn(), -}) - -// Mock supermemory search response -const createMockSearchResponse = (contents: string[]) => ({ - results: contents.map((content) => ({ - chunks: [{ content }], - })), -}) - -// Helper to call transformParams with proper signature -const callTransformParams = async ( - middleware: ReturnType<typeof createSupermemoryMiddleware>, - params: LanguageModelV2CallOptions, -) => { - const mockModel = createMockLanguageModel() - return middleware.transformParams?.({ - type: "generate", - params, - model: mockModel, - }) -} - -describe("withSupermemory / wrapVercelLanguageModel", () => { - let originalEnv: string | undefined - - beforeEach(() => { - originalEnv = process.env.SUPERMEMORY_API_KEY - vi.clearAllMocks() - }) - - afterEach(() => { - if (originalEnv) { - process.env.SUPERMEMORY_API_KEY = originalEnv - } else { - delete process.env.SUPERMEMORY_API_KEY - } - }) - - describe("Environment validation", () => { - it("should throw error if SUPERMEMORY_API_KEY is not set", () => { - delete process.env.SUPERMEMORY_API_KEY - - const mockModel = createMockLanguageModel() - - expect(() => { - withSupermemory(mockModel, TEST_CONFIG.containerTag) - }).toThrow("SUPERMEMORY_API_KEY is not set") - }) - - it("should successfully create wrapped model with valid API key", () => { - process.env.SUPERMEMORY_API_KEY = "test-key" - - const mockModel = createMockLanguageModel() - const wrappedModel = withSupermemory(mockModel, TEST_CONFIG.containerTag) - - expect(wrappedModel).toBeDefined() - expect(wrappedModel.specificationVersion).toBe("v2") - }) - }) - - describe("createSupermemoryMiddleware", () => { - // biome-ignore lint/suspicious/noExplicitAny: Mock object for testing - let mockSupermemory: any - - beforeEach(() => { - mockSupermemory = { - search: { - execute: vi.fn(), - }, - } - }) - - it("should return params unchanged when there is no user message", async () => { - const middleware = createSupermemoryMiddleware( - mockSupermemory, - TEST_CONFIG.containerTag, - ) - - const params: LanguageModelV2CallOptions = { - prompt: [ - { - role: "system", - content: "You are a helpful assistant", - }, - ], - } - - const result = await callTransformParams(middleware, params) - - expect(result).toEqual(params) - expect(mockSupermemory.search.execute).not.toHaveBeenCalled() - }) - - it("should extract last user message with text content", async () => { - mockSupermemory.search.execute.mockResolvedValue( - createMockSearchResponse([]), - ) - - const middleware = createSupermemoryMiddleware( - mockSupermemory, - TEST_CONFIG.containerTag, - ) - - const params: LanguageModelV2CallOptions = { - prompt: [ - { - role: "user", - content: [{ type: "text", text: "Hello, how are you?" }], - }, - ], - } - - await callTransformParams(middleware, params) - - expect(mockSupermemory.search.execute).toHaveBeenCalledWith({ - q: "Hello, how are you?", - containerTags: [TEST_CONFIG.containerTag], - }) - }) - - it("should handle multiple user messages and extract the last one", async () => { - mockSupermemory.search.execute.mockResolvedValue( - createMockSearchResponse([]), - ) - - const middleware = createSupermemoryMiddleware( - mockSupermemory, - TEST_CONFIG.containerTag, - ) - - const params: LanguageModelV2CallOptions = { - prompt: [ - { - role: "user", - content: [{ type: "text", text: "First message" }], - }, - { - role: "assistant", - content: [{ type: "text", text: "Response" }], - }, - { - role: "user", - content: [{ type: "text", text: "Last message" }], - }, - ], - } - - await callTransformParams(middleware, params) - - expect(mockSupermemory.search.execute).toHaveBeenCalledWith({ - q: "Last message", - containerTags: [TEST_CONFIG.containerTag], - }) - }) - - it("should concatenate multiple text parts in user message", async () => { - mockSupermemory.search.execute.mockResolvedValue( - createMockSearchResponse([]), - ) - - const middleware = createSupermemoryMiddleware( - mockSupermemory, - TEST_CONFIG.containerTag, - ) - - const params: LanguageModelV2CallOptions = { - prompt: [ - { - role: "user", - content: [ - { type: "text", text: "Part 1" }, - { type: "text", text: "Part 2" }, - { type: "text", text: "Part 3" }, - ], - }, - ], - } - - await callTransformParams(middleware, params) - - expect(mockSupermemory.search.execute).toHaveBeenCalledWith({ - q: "Part 1 Part 2 Part 3", - containerTags: [TEST_CONFIG.containerTag], - }) - }) - - it("should create new system prompt when none exists", async () => { - mockSupermemory.search.execute.mockResolvedValue( - createMockSearchResponse([ - "Memory 1: User likes TypeScript", - "Memory 2: User prefers clean code", - ]), - ) - - const middleware = createSupermemoryMiddleware( - mockSupermemory, - TEST_CONFIG.containerTag, - ) - - const params: LanguageModelV2CallOptions = { - prompt: [ - { - role: "user", - content: [{ type: "text", text: "Tell me about TypeScript" }], - }, - ], - } - - const result = await callTransformParams(middleware, params) - - expect(result?.prompt).toHaveLength(2) - expect(result?.prompt[0]?.role).toBe("system") - expect(result?.prompt[0]?.content).toContain( - "Memory 1: User likes TypeScript Memory 2: User prefers clean code", - ) - expect(result?.prompt[1]?.role).toBe("user") - }) - - it("should append memories to existing system prompt", async () => { - mockSupermemory.search.execute.mockResolvedValue( - createMockSearchResponse(["Memory: User is an expert developer"]), - ) - - const middleware = createSupermemoryMiddleware( - mockSupermemory, - TEST_CONFIG.containerTag, - ) - - const params: LanguageModelV2CallOptions = { - prompt: [ - { - role: "system", - content: "You are a helpful coding assistant", - }, - { - role: "user", - content: [{ type: "text", text: "Help me code" }], - }, - ], - } - - const result = await callTransformParams(middleware, params) - - expect(result?.prompt).toHaveLength(2) - expect(result?.prompt[0]?.role).toBe("system") - expect(result?.prompt[0]?.content).toContain( - "You are a helpful coding assistant", - ) - expect(result?.prompt[0]?.content).toContain( - "Memory: User is an expert developer", - ) - }) - - it("should handle empty memory results", async () => { - mockSupermemory.search.execute.mockResolvedValue( - createMockSearchResponse([]), - ) - - const middleware = createSupermemoryMiddleware( - mockSupermemory, - TEST_CONFIG.containerTag, - ) - - const params: LanguageModelV2CallOptions = { - prompt: [ - { - role: "user", - content: [{ type: "text", text: "Hello" }], - }, - ], - } - - const result = await callTransformParams(middleware, params) - - // Should still create system prompt even if memories are empty - expect(result?.prompt).toHaveLength(2) - expect(result?.prompt[0]?.role).toBe("system") - }) - - it("should filter out non-text content from user message", async () => { - mockSupermemory.search.execute.mockResolvedValue( - createMockSearchResponse([]), - ) - - const middleware = createSupermemoryMiddleware( - mockSupermemory, - TEST_CONFIG.containerTag, - ) - - const params: LanguageModelV2CallOptions = { - prompt: [ - { - role: "user", - content: [ - { type: "text", text: "Text part" }, - // File part is non-text content - { type: "file", data: "base64...", mimeType: "image/png" }, - { type: "text", text: "Another text part" }, - ], - }, - ], - } - - await callTransformParams(middleware, params) - - // Should only extract text content - expect(mockSupermemory.search.execute).toHaveBeenCalledWith({ - q: "Text part Another text part", - containerTags: [TEST_CONFIG.containerTag], - }) - }) - - it("should handle multiple memory chunks correctly", async () => { - mockSupermemory.search.execute.mockResolvedValue({ - results: [ - { - chunks: [ - { content: "Chunk 1" }, - { content: "Chunk 2" }, - { content: "Chunk 3" }, - ], - }, - { - chunks: [{ content: "Chunk 4" }, { content: "Chunk 5" }], - }, - ], - }) - - const middleware = createSupermemoryMiddleware( - mockSupermemory, - TEST_CONFIG.containerTag, - ) - - const params: LanguageModelV2CallOptions = { - prompt: [ - { - role: "user", - content: [{ type: "text", text: "Query" }], - }, - ], - } - - const result = await callTransformParams(middleware, params) - - const systemContent = result?.prompt[0]?.content as string - // Chunks from same result should be joined with space - expect(systemContent).toContain("Chunk 1 Chunk 2 Chunk 3") - // Results should be joined with newline - expect(systemContent).toContain("Chunk 4 Chunk 5") - }) - }) - - describe("Integration with real Supermemory", () => { - // Skip these tests if no API key is available - const shouldRunIntegration = !!process.env.SUPERMEMORY_API_KEY - - it.skipIf(!shouldRunIntegration)( - "should work with real Supermemory API", - async () => { - const supermemory = new Supermemory({ - apiKey: process.env.SUPERMEMORY_API_KEY ?? "", - baseURL: TEST_CONFIG.baseURL, - }) - - const middleware = createSupermemoryMiddleware( - supermemory, - TEST_CONFIG.containerTag, - ) - - const params: LanguageModelV2CallOptions = { - prompt: [ - { - role: "user", - content: [{ type: "text", text: "Tell me about programming" }], - }, - ], - } - - const result = await callTransformParams(middleware, params) - - expect(result?.prompt).toBeDefined() - expect(result?.prompt.length).toBeGreaterThanOrEqual(1) - }, - ) - - it.skipIf(!shouldRunIntegration)( - "should create wrapped model and use it", - async () => { - process.env.SUPERMEMORY_API_KEY = TEST_CONFIG.apiKey - - const mockModel = createMockLanguageModel() - const wrappedModel = withSupermemory( - mockModel, - TEST_CONFIG.containerTag, - ) - - expect(wrappedModel).toBeDefined() - expect(wrappedModel.provider).toBe("test-provider") - expect(wrappedModel.modelId).toBe("test-model") - }, - ) - }) - - describe("Edge cases", () => { - // biome-ignore lint/suspicious/noExplicitAny: Mock object for testing - let mockSupermemory: any - - beforeEach(() => { - mockSupermemory = { - search: { - execute: vi.fn(), - }, - } - }) - - it("should handle Supermemory API errors gracefully", async () => { - mockSupermemory.search.execute.mockRejectedValue(new Error("API Error")) - - const middleware = createSupermemoryMiddleware( - mockSupermemory, - TEST_CONFIG.containerTag, - ) - - const params: LanguageModelV2CallOptions = { - prompt: [ - { - role: "user", - content: [{ type: "text", text: "Hello" }], - }, - ], - } - - await expect(callTransformParams(middleware, params)).rejects.toThrow( - "API Error", - ) - }) - - it("should handle empty prompt array", async () => { - const middleware = createSupermemoryMiddleware( - mockSupermemory, - TEST_CONFIG.containerTag, - ) - - const params: LanguageModelV2CallOptions = { - prompt: [], - } - - const result = await callTransformParams(middleware, params) - - expect(result).toEqual(params) - expect(mockSupermemory.search.execute).not.toHaveBeenCalled() - }) - - it("should handle user message with empty content array", async () => { - const middleware = createSupermemoryMiddleware( - mockSupermemory, - TEST_CONFIG.containerTag, - ) - - const params: LanguageModelV2CallOptions = { - prompt: [ - { - role: "user", - content: [], - }, - ], - } - - const result = await callTransformParams(middleware, params) - - expect(result).toEqual(params) - expect(mockSupermemory.search.execute).not.toHaveBeenCalled() - }) - - it("should use correct container tag", async () => { - mockSupermemory.search.execute.mockResolvedValue( - createMockSearchResponse([]), - ) - - const customTag = "my-custom-project" - const middleware = createSupermemoryMiddleware(mockSupermemory, customTag) - - const params: LanguageModelV2CallOptions = { - prompt: [ - { - role: "user", - content: [{ type: "text", text: "Query" }], - }, - ], - } - - await callTransformParams(middleware, params) - - expect(mockSupermemory.search.execute).toHaveBeenCalledWith({ - q: "Query", - containerTags: [customTag], - }) - }) - - it("should not mutate the original params.prompt array", async () => { - mockSupermemory.search.execute.mockResolvedValue( - createMockSearchResponse([]), - ) - - const middleware = createSupermemoryMiddleware( - mockSupermemory, - TEST_CONFIG.containerTag, - ) - - const originalPrompt = [ - { role: "user" as const, content: [{ type: "text" as const, text: "First" }] }, - { role: "user" as const, content: [{ type: "text" as const, text: "Last" }] } - ] - const params: LanguageModelV2CallOptions = { prompt: [...originalPrompt] } - - await callTransformParams(middleware, params) - - // Verify order is unchanged - expect(params.prompt[0]?.content[0]).toBe("First") - expect(params.prompt[1]?.content[0]).toBe("Last") - }) - - }) -}) |