Skip to main content
Glama
index.test.ts7.84 kB
import { describe, test, expect } from "vitest"; import { generateText, stepCountIs, tool } from "ai"; import { createAmazonBedrock } from "@ai-sdk/amazon-bedrock"; import { z } from "zod"; import { resolveLibrary, getLibraryDocs, Context7Agent, SYSTEM_PROMPT, AGENT_PROMPT, RESOLVE_LIBRARY_DESCRIPTION, } from "./index"; const bedrock = createAmazonBedrock({ region: process.env.AWS_REGION, apiKey: process.env.AWS_BEARER_TOKEN_BEDROCK, }); describe("@upstash/context7-tools-ai-sdk", () => { describe("Tool structure", () => { test("resolveLibrary() should return a tool object with correct structure", () => { const tool = resolveLibrary(); expect(tool).toBeDefined(); expect(tool).toHaveProperty("execute"); expect(tool).toHaveProperty("inputSchema"); expect(tool).toHaveProperty("description"); expect(tool.description).toContain("library"); }); test("getLibraryDocs() should return a tool object with correct structure", () => { const tool = getLibraryDocs(); expect(tool).toBeDefined(); expect(tool).toHaveProperty("execute"); expect(tool).toHaveProperty("inputSchema"); expect(tool).toHaveProperty("description"); expect(tool.description).toContain("documentation"); }); test("tools should accept custom config", () => { const resolveTool = resolveLibrary({ apiKey: "ctx7sk-test-key", }); const docsTool = getLibraryDocs({ apiKey: "ctx7sk-test-key", defaultMaxResults: 5, }); expect(resolveTool).toHaveProperty("execute"); expect(docsTool).toHaveProperty("execute"); }); }); describe("Tool usage with generateText", () => { test("resolveLibrary tool should be called when searching for a library", async () => { const result = await generateText({ model: bedrock("anthropic.claude-3-haiku-20240307-v1:0"), tools: { resolveLibrary: resolveLibrary(), }, toolChoice: { type: "tool", toolName: "resolveLibrary" }, stopWhen: stepCountIs(2), prompt: "Search for 'react' library", }); expect(result.toolCalls.length).toBeGreaterThan(0); expect(result.toolCalls[0].toolName).toBe("resolveLibrary"); expect(result.toolResults.length).toBeGreaterThan(0); const toolResult = result.toolResults[0] as unknown as { output: { success: boolean } }; expect(toolResult.output.success).toBe(true); }, 30000); test("getLibraryDocs tool should fetch documentation", async () => { const result = await generateText({ model: bedrock("anthropic.claude-3-haiku-20240307-v1:0"), tools: { getLibraryDocs: getLibraryDocs(), }, toolChoice: { type: "tool", toolName: "getLibraryDocs" }, stopWhen: stepCountIs(2), prompt: "Fetch documentation for library ID '/facebook/react' with topic 'hooks'", }); expect(result.toolCalls.length).toBeGreaterThan(0); expect(result.toolCalls[0].toolName).toBe("getLibraryDocs"); expect(result.toolResults.length).toBeGreaterThan(0); const toolResult = result.toolResults[0] as unknown as { output: { success: boolean } }; expect(toolResult.output.success).toBe(true); }, 30000); test("both tools can work together in a multi-step flow", async () => { const result = await generateText({ model: bedrock("anthropic.claude-3-haiku-20240307-v1:0"), tools: { resolveLibrary: resolveLibrary(), getLibraryDocs: getLibraryDocs(), }, stopWhen: stepCountIs(5), prompt: "First use resolveLibrary to find the Next.js library, then use getLibraryDocs to get documentation about routing", }); const allToolCalls = result.steps.flatMap((step) => step.toolCalls); const toolNames = allToolCalls.map((call) => call.toolName); expect(toolNames).toContain("resolveLibrary"); expect(toolNames).toContain("getLibraryDocs"); }, 60000); }); describe("Context7Agent class", () => { test("should create an agent instance with model", () => { const agent = new Context7Agent({ model: bedrock("anthropic.claude-3-haiku-20240307-v1:0"), }); expect(agent).toBeDefined(); expect(agent).toHaveProperty("generate"); expect(agent).toHaveProperty("stream"); }); test("should accept custom stopWhen condition", () => { const agent = new Context7Agent({ model: bedrock("anthropic.claude-3-haiku-20240307-v1:0"), stopWhen: stepCountIs(3), }); expect(agent).toBeDefined(); }); test("should accept custom system prompt", () => { const agent = new Context7Agent({ model: bedrock("anthropic.claude-3-haiku-20240307-v1:0"), system: "Custom system prompt for testing", }); expect(agent).toBeDefined(); }); test("should accept Context7 config options", () => { const agent = new Context7Agent({ model: bedrock("anthropic.claude-3-haiku-20240307-v1:0"), apiKey: "ctx7sk-test-key", defaultMaxResults: 5, }); expect(agent).toBeDefined(); }); test("should accept additional tools alongside Context7 tools", () => { const customTool = tool({ description: "A custom test tool", inputSchema: z.object({ input: z.string().describe("Test input"), }), execute: async ({ input }) => ({ result: `processed: ${input}` }), }); const agent = new Context7Agent({ model: bedrock("anthropic.claude-3-haiku-20240307-v1:0"), tools: { customTool, }, }); expect(agent).toBeDefined(); }); test("should generate response using agent workflow", async () => { const agent = new Context7Agent({ model: bedrock("anthropic.claude-3-haiku-20240307-v1:0"), stopWhen: stepCountIs(5), }); const result = await agent.generate({ prompt: "Find the React library and get documentation about hooks", }); expect(result).toBeDefined(); expect(result.steps.length).toBeGreaterThan(0); const allToolCalls = result.steps.flatMap((step) => step.toolCalls); const toolNames = allToolCalls.map((call) => call.toolName); expect(toolNames).toContain("resolveLibrary"); }, 60000); test("should include Context7 tools in generate result", async () => { const agent = new Context7Agent({ model: bedrock("anthropic.claude-3-haiku-20240307-v1:0"), stopWhen: stepCountIs(5), }); const result = await agent.generate({ prompt: "Use resolveLibrary to search for Next.js, then use getLibraryDocs to get routing documentation", }); expect(result).toBeDefined(); const allToolCalls = result.steps.flatMap((step) => step.toolCalls); const toolNames = allToolCalls.map((call) => call.toolName); expect(toolNames).toContain("resolveLibrary"); expect(toolNames).toContain("getLibraryDocs"); }, 60000); }); describe("Prompt exports", () => { test("should export SYSTEM_PROMPT", () => { expect(SYSTEM_PROMPT).toBeDefined(); expect(typeof SYSTEM_PROMPT).toBe("string"); expect(SYSTEM_PROMPT.length).toBeGreaterThan(0); }); test("should export AGENT_PROMPT", () => { expect(AGENT_PROMPT).toBeDefined(); expect(typeof AGENT_PROMPT).toBe("string"); expect(AGENT_PROMPT).toContain("Context7"); }); test("should export RESOLVE_LIBRARY_DESCRIPTION", () => { expect(RESOLVE_LIBRARY_DESCRIPTION).toBeDefined(); expect(typeof RESOLVE_LIBRARY_DESCRIPTION).toBe("string"); expect(RESOLVE_LIBRARY_DESCRIPTION).toContain("library"); }); }); });

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/upstash/context7-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server