ai-tool-adapter
v1.0.2
Published
Universal tool schema adapter for AI providers (OpenAI, Anthropic, Gemini, Mistral)
Maintainers
Readme
ai-tool-adapter
Universal AI tool schema adapter for function calling across multiple LLM providers.
Write your tool definitions once, convert to any provider format instantly. No more duplicating schemas for OpenAI, Anthropic, Google, and Mistral.
Features
- Zero dependencies - Lightweight and secure
- Type-safe - Full TypeScript support with strict typing
- Provider-agnostic - One schema, multiple formats
- Pure functions - Predictable transformations with no side effects
- Well-tested - Comprehensive test coverage across all adapters
Supported Providers
- OpenAI - GPT-4, GPT-3.5 function calling
- Anthropic - Claude tool use
- Google Gemini - Gemini function calling
- Mistral - Mistral AI function calling
Installation
npm install ai-tool-adapterQuick Start
import { adapt } from 'ai-tool-adapter';
// Define your tool once using the universal schema
const weatherTool = {
name: 'get_weather',
description: 'Get current weather for a location',
params: {
location: {
type: 'string',
description: 'City name',
required: true,
},
units: {
type: 'string',
description: 'Temperature units',
enum: ['celsius', 'fahrenheit'],
},
},
};
// Convert to any provider format
const openaiTool = adapt(weatherTool, 'openai');
const anthropicTool = adapt(weatherTool, 'anthropic');
const geminiTool = adapt(weatherTool, 'gemini');
const mistralTool = adapt(weatherTool, 'mistral');API Reference
adapt(tool, provider)
Convert a single universal tool definition to a specific provider's format.
Parameters:
tool(UniversalTool) - Your universal tool definitionprovider(Provider) - Target provider:'openai'|'anthropic'|'gemini'|'mistral'
Returns: Provider-specific tool format
Throws: Error if provider is not supported
const tool = {
name: 'calculate',
description: 'Perform arithmetic calculation',
params: {
operation: {
type: 'string',
enum: ['add', 'subtract', 'multiply', 'divide'],
required: true,
},
a: { type: 'number', required: true },
b: { type: 'number', required: true },
},
};
const openaiTool = adapt(tool, 'openai');adaptAll(tools, provider)
Convert multiple tools at once.
Parameters:
tools(UniversalTool[]) - Array of universal tool definitionsprovider(Provider) - Target provider
Returns: Array of provider-specific tool formats
const tools = [weatherTool, calculatorTool, searchTool];
const openaiTools = adaptAll(tools, 'openai');getProviders()
Get list of all supported providers.
Returns: Array of provider names
const providers = getProviders();
console.log(providers); // ['openai', 'anthropic', 'gemini', 'mistral']Universal Tool Schema
Basic Structure
interface UniversalTool {
name: string; // Function name
description: string; // What the tool does
params: Record<string, ToolParam>; // Parameter definitions
}Parameter Definition
interface ToolParam {
type: 'string' | 'number' | 'boolean' | 'array' | 'object';
description?: string; // Parameter description
required?: boolean; // Whether required (default: false)
default?: unknown; // Default value
enum?: string[]; // Allowed values
items?: { // For array types
type: ParamType;
};
}Examples
Simple Tool
const statusTool = {
name: 'get_status',
description: 'Get current system status',
params: {}, // No parameters
};Tool with Required Parameters
const searchTool = {
name: 'search',
description: 'Search for items',
params: {
query: {
type: 'string',
description: 'Search query',
required: true,
},
},
};Tool with Enums
const sortTool = {
name: 'sort_results',
description: 'Sort search results',
params: {
order: {
type: 'string',
enum: ['asc', 'desc'],
default: 'asc',
},
},
};Tool with Array Parameters
const batchTool = {
name: 'process_batch',
description: 'Process multiple items',
params: {
items: {
type: 'array',
description: 'Items to process',
items: { type: 'string' },
required: true,
},
},
};Complex Tool
const apiTool = {
name: 'api_request',
description: 'Make an API request',
params: {
endpoint: {
type: 'string',
description: 'API endpoint path',
required: true,
},
method: {
type: 'string',
description: 'HTTP method',
enum: ['GET', 'POST', 'PUT', 'DELETE'],
default: 'GET',
},
headers: {
type: 'object',
description: 'Request headers',
},
params: {
type: 'array',
description: 'Query parameters',
items: { type: 'string' },
},
timeout: {
type: 'number',
description: 'Request timeout in milliseconds',
default: 5000,
},
},
};Provider Output Formats
OpenAI
Wraps function definition in a type object:
{
"type": "function",
"function": {
"name": "get_weather",
"description": "Get weather",
"parameters": {
"type": "object",
"properties": {...},
"required": [...]
}
}
}Anthropic
Flat structure with input_schema:
{
"name": "get_weather",
"description": "Get weather",
"input_schema": {
"type": "object",
"properties": {...},
"required": [...]
}
}Gemini
Flat structure with UPPERCASE types:
{
"name": "get_weather",
"description": "Get weather",
"parameters": {
"type": "OBJECT",
"properties": {
"location": { "type": "STRING" }
},
"required": [...]
}
}Mistral
OpenAI-compatible format:
{
"type": "function",
"function": {
"name": "get_weather",
"description": "Get weather",
"parameters": {...}
}
}Real-World Usage
With OpenAI SDK
import OpenAI from 'openai';
import { adapt } from 'ai-tool-adapter';
const client = new OpenAI();
const tools = [weatherTool, calculatorTool].map(tool =>
adapt(tool, 'openai')
);
const response = await client.chat.completions.create({
model: 'gpt-4',
messages: [{ role: 'user', content: 'What\'s the weather in Paris?' }],
tools,
});With Anthropic SDK
import Anthropic from '@anthropic-ai/sdk';
import { adaptAll } from 'ai-tool-adapter';
const client = new Anthropic();
const tools = adaptAll([weatherTool, calculatorTool], 'anthropic');
const response = await client.messages.create({
model: 'claude-3-5-sonnet-20241022',
max_tokens: 1024,
messages: [{ role: 'user', content: 'What\'s the weather in Paris?' }],
tools,
});Multi-Provider Support
import { adapt } from 'ai-tool-adapter';
// Single source of truth for your tools
const myTools = [weatherTool, calculatorTool, searchTool];
// Support all providers effortlessly
const providerClients = {
openai: { tools: myTools.map(t => adapt(t, 'openai')) },
anthropic: { tools: myTools.map(t => adapt(t, 'anthropic')) },
gemini: { tools: myTools.map(t => adapt(t, 'gemini')) },
mistral: { tools: myTools.map(t => adapt(t, 'mistral')) },
};
// Use whichever provider you need
function callLLM(provider: string, prompt: string) {
const config = providerClients[provider];
// Make API call with provider-specific tools
}TypeScript Support
Full type definitions included:
import type {
UniversalTool,
ToolParam,
Provider,
ParamType
} from 'ai-tool-adapter';
const tool: UniversalTool = {
name: 'my_tool',
description: 'My custom tool',
params: {
param1: {
type: 'string',
required: true,
},
},
};Development
# Install dependencies
npm install
# Build
npm run build
# Run tests
npm test
# Watch mode for tests
npm run test:watch
# Commit changes (uses Commitizen for consistent commit messages)
npm run commit
# or
git czCommit Messages
This project uses Commitizen for standardized commit messages following the Conventional Commits specification.
Instead of git commit, use:
git czornpm run commit- Interactive commit message builder
This ensures all commits follow a consistent format, making it easier to generate changelogs and understand project history.
Architecture
This library follows the Strategy Pattern with each provider adapter as an independent, interchangeable strategy. This design ensures:
- Orthogonality - Adapters are completely independent
- Open/Closed Principle - Easy to add new providers without modifying existing code
- Single Responsibility - Each adapter handles exactly one provider's format
- Pure Functions - Predictable, testable transformations
For detailed architecture documentation, see CLAUDE.md.
Contributing
Contributions are welcome! To add a new provider:
- Create adapter in
src/adapters/yourprovider.ts - Add provider to
Providertype insrc/types.ts - Register adapter in
src/index.ts - Add comprehensive tests
- Update documentation
See CLAUDE.md for detailed guidelines.
License
ISC
