UNPKG

@veris-ai/sdk

Version:
476 lines (379 loc) 12.6 kB
# Veris AI TypeScript SDK [![npm version](https://img.shields.io/npm/v/@veris-ai/sdk.svg)](https://www.npmjs.com/package/@veris-ai/sdk) [![npm downloads](https://img.shields.io/npm/dm/@veris-ai/sdk.svg)](https://www.npmjs.com/package/@veris-ai/sdk) [![License](https://img.shields.io/npm/l/@veris-ai/sdk.svg)](https://github.com/veris-ai/veris-typescript-sdk/blob/main/LICENSE) [![TypeScript](https://img.shields.io/badge/TypeScript-Ready-blue.svg)](https://www.typescriptlang.org/) [![CI Status](https://img.shields.io/github/actions/workflow/status/veris-ai/veris-typescript-sdk/ci.yml?branch=main&label=CI)](https://github.com/veris-ai/veris-typescript-sdk/actions) [![GitHub Stars](https://img.shields.io/github/stars/veris-ai/veris-typescript-sdk.svg)](https://github.com/veris-ai/veris-typescript-sdk/stargazers) A TypeScript SDK for testing and mocking AI agent tool calls in development and simulation environments. This SDK enables you to mock tool calls during development, record interactions, and seamlessly integrate with popular AI frameworks like OpenAI Agents SDK and LlamaIndex. ## Features - **Tool Mocking**: Replace real tool calls with mocked responses during development - **Session Management**: Control mocking behavior with session IDs - **Framework Integration**: Works with OpenAI Agents SDK, LlamaIndex, Langchain, and MCP servers - **Type Safety**: Full TypeScript support with Zod schema validation - **Flexible Modes**: Support for `tool` and `function` modes - **MCP Server**: Built-in Model Context Protocol server for AI agent integration ## Installation ```bash npm install @veris-ai/sdk # or yarn add @veris-ai/sdk # or pnpm add @veris-ai/sdk ``` ## Quick Start ### Basic Usage ```typescript import { veris } from '@veris-ai/sdk'; import { z } from 'zod'; // Define your function async function getWeather(args: { city: string; unit?: 'celsius' | 'fahrenheit' }) { // Your actual implementation return { temperature: 22, unit: args.unit || 'celsius', description: 'Sunny' }; } // Define schemas for type safety const parametersSchema = z.object({ city: z.string().describe('The city to get weather for'), unit: z.enum(['celsius', 'fahrenheit']).optional() }); const outputSchema = z.object({ temperature: z.number(), unit: z.string(), description: z.string() }); // Wrap your function with Veris mocking const wrappedGetWeather = veris.mockFunction(getWeather, { name: 'get_weather', description: 'Get current weather for a city', parametersSchema, outputSchema }); // Use the wrapped function normally const result = await wrappedGetWeather({ city: 'San Francisco' }); ``` ### Session Management Control when mocking is active using session IDs: ```typescript // Enable mocking with a session ID veris.setSessionId('dev-session-123'); // Now tool calls will be mocked when a session ID is present const result = await wrappedGetWeather({ city: 'Tokyo' }); // Clear session to disable mocking veris.clearSessionId(); // Now the original function executes const realResult = await wrappedGetWeather({ city: 'London' }); ``` ## Environment Configuration Set these environment variables to configure the SDK: ```bash # API key for Veris mocking service VERIS_API_KEY=your-api-key-here # Optional: Custom timeout for mock requests (ms) VERIS_API_TIMEOUT=300000 ``` ## Framework Integration ### OpenAI Agents SDK ```typescript import { veris } from '@veris-ai/sdk'; import { tool } from '@openai/agents'; import { z } from 'zod'; // Define and wrap your function const searchDocuments = async (args: { query: string; limit?: number }) => { return []; // Your implementation }; const wrappedSearch = veris.mockFunction(searchDocuments, { name: 'search_documents', description: 'Search for relevant documents', parametersSchema: z.object({ query: z.string(), limit: z.number().optional().default(10) }) }); // Create OpenAI tool const searchTool = tool({ name: 'search_documents', description: 'Search for relevant documents', parameters: z.object({ query: z.string(), limit: z.number().optional() }), execute: wrappedSearch }); // Use in your agent const agent = new Agent({ tools: [searchTool] }); ``` ### LlamaIndex ```typescript import { veris } from '@veris-ai/sdk'; import { FunctionTool } from 'llamaindex'; import { z } from 'zod'; // Define and wrap your function const calculateSum = async (args: { a: number; b: number }) => { return { result: args.a + args.b }; }; const wrappedCalculate = veris.mockFunction(calculateSum, { name: 'calculate_sum', description: 'Add two numbers', parametersSchema: z.object({ a: z.number(), b: z.number() }) }); // Create LlamaIndex FunctionTool const calculateTool = new FunctionTool(wrappedCalculate, { name: 'calculate_sum', description: 'Add two numbers', parameters: { type: 'object', properties: { a: { type: 'number' }, b: { type: 'number' } }, required: ['a', 'b'] } }); ``` ### Langchain ```typescript import { veris } from '@veris-ai/sdk'; import { DynamicStructuredTool } from '@langchain/core/tools'; import { z } from 'zod'; // Define and wrap your function const getWeatherData = async (args: { city: string; units?: string }) => { return { temperature: 22, units: args.units || 'celsius' }; }; const wrappedWeather = veris.mockFunction(getWeatherData, { name: 'get_weather', description: 'Get weather information', parametersSchema: z.object({ city: z.string(), units: z.string().optional() }), outputSchema: z.object({ temperature: z.number(), units: z.string() }) }); // Create Langchain DynamicStructuredTool const weatherTool = new DynamicStructuredTool({ name: 'get_weather', description: 'Get weather information', schema: z.object({ city: z.string(), units: z.string().optional() }), func: wrappedWeather }); // Use with Langchain agents or Langgraph import { ChatOpenAI } from '@langchain/openai'; import { AgentExecutor, createStructuredChatAgent } from 'langchain/agents'; const llm = new ChatOpenAI({ modelName: 'gpt-4o-mini' }); const agent = await createStructuredChatAgent({ llm, tools: [weatherTool], prompt: /* your prompt template */ }); ``` ## MCP Server Create a Model Context Protocol server to expose your AI agent via HTTP: ```typescript import { VerisMCPServer, veris } from '@veris-ai/sdk'; import { Agent, run, tool } from '@openai/agents'; import { z } from 'zod'; // Create a simple OpenAI agent with a tool const getInfoTool = tool({ name: 'get_info', description: 'Get information about a topic', parameters: z.object({ topic: z.string() }), execute: veris.mockFunction( async ({ topic }: { topic: string }) => { return `Information about ${topic}`; }, { name: 'get_info', description: 'Get information about a topic', parametersSchema: z.object({ topic: z.string() }) } ) }); // Create the agent const agent = new Agent({ name: 'Simple Assistant', instructions: 'You are a helpful assistant. Use the get_info tool to answer questions.', tools: [getInfoTool] }); // Create MCP server const mcpServer = new VerisMCPServer({ name: 'Simple Agent Server', description: 'MCP server for OpenAI agent with Veris instrumentation', port: 3000 }); // Register the agent's run function mcpServer.registerFunction( async ({ query }: { query: string }) => { const result = await run(agent, query); return result.finalOutput; }, { name: 'run_agent', description: 'Send a query to the AI agent', parametersSchema: z.object({ query: z.string().describe('The query to send to the agent') }) } ); // Start server await mcpServer.start(); console.log('MCP server running at http://localhost:3000/mcp'); // Session IDs from Bearer tokens automatically enable mocking ``` ### Authentication with MCP The MCP server automatically extracts session IDs from Bearer tokens: ```bash # With session ID (mocking enabled) curl -X POST http://localhost:3000/mcp \ -H "Authorization: Bearer dev-session-123" \ -H "Content-Type: application/json" \ -d '{"jsonrpc":"2.0","method":"tools/call","params":{"name":"search","arguments":{"query":"test"}},"id":1}' # Without session ID (mocking disabled) curl -X POST http://localhost:3000/mcp \ -H "Content-Type: application/json" \ -d '{"jsonrpc":"2.0","method":"tools/call","params":{"name":"search","arguments":{"query":"test"}},"id":1}' ``` ## Decorator Pattern Use decorators for class methods: ```typescript import { veris } from '@veris-ai/sdk'; import { z } from 'zod'; class AITools { @veris.mock({ mode: 'tool', description: 'Search the web', parametersSchema: z.object({ query: z.string(), maxResults: z.number().optional() }), outputSchema: z.object({ results: z.array(z.string()), timestamp: z.string() }) }) async webSearch(args: { query: string; maxResults?: number }) { // Your implementation return { results: [], timestamp: new Date().toISOString() }; } } ``` ## Modes The SDK supports three modes: - **`tool`** (default): Expects a response from the mock server - **`function`**: Fire-and-forget mode, no response expected - **`spy`**: Logs calls but executes the original function ```typescript // Tool mode - expects response const wrappedTool = veris.mockFunction(myFunc, { name: 'my_tool', mode: 'tool', // Default parametersSchema }); // Function mode - no response expected const wrappedFunction = veris.mockFunction(myFunc, { name: 'my_function', mode: 'function', parametersSchema }); // Spy mode - logs and executes original const wrappedSpy = veris.mockFunction(myFunc, { name: 'my_spy', mode: 'spy', parametersSchema }); ``` ## Response Expectations Control how the SDK handles responses: ```typescript const wrapped = veris.mockFunction(myFunc, { name: 'my_tool', parametersSchema, expectsResponse: true, // Always expect response cacheResponse: true // Cache responses for reuse }); ``` ## Error Handling The SDK provides proper error handling: ```typescript try { const result = await wrappedFunction({ invalid: 'args' }); } catch (error) { // Zod validation errors for invalid arguments // Network errors for failed mock requests // Original function errors in production mode } ``` ## Testing The SDK works seamlessly in test environments: ```typescript import { veris } from '@veris-ai/sdk'; describe('My AI Agent', () => { beforeEach(() => { // Set up mock environment process.env.VERIS_API_URL = 'http://mock.test'; veris.setSessionId('test-session'); }); afterEach(() => { veris.clearSessionId(); }); it('should handle tool calls', async () => { // Your tests }); }); ``` ## Examples Check out the `/examples` directory for complete examples: - **Agent Example** (`/examples/agent-example`): Full OpenAI agent with weather tool and MCP server - **Langchain Example** (`/examples/langchain-example`): Langchain agent with multiple tools, includes Langgraph support - Standard Langchain agent with weather and calculator tools - Alternative Langgraph implementation for complex workflows - MCP server integration for external access ## API Reference ### `veris.mockFunction(func, params)` Wraps a function with mocking capabilities. **Parameters:** - `func`: The original async function to wrap - `params`: Configuration object - `name`: Function name for identification - `description`: Human-readable description - `parametersSchema`: Zod schema for input validation - `outputSchema?`: Zod schema for output validation - `mode?`: 'tool' | 'function' | 'spy' (default: 'tool') - `expectsResponse?`: Whether to expect a response - `cacheResponse?`: Whether to cache responses ### `veris.setSessionId(sessionId)` Sets the session ID to enable mocking. ### `veris.clearSessionId()` Clears the session ID to disable mocking. ### `VerisMCPServer` Creates an MCP server for exposing tools. **Constructor Options:** - `name`: Server name - `description`: Server description - `transport?`: 'http' | 'stdio' (default: 'http') - `port?`: Port number for HTTP transport - `requireAuth?`: Require authentication ## License MIT ## Contributing Contributions are welcome! Please feel free to submit a Pull Request. ## Support For issues and questions, please visit our [GitHub repository](https://github.com/veris-ai/veris-typescript-sdk/issues).